ffi 1.15: #jni_call(void) codegen — make-green
New `.jni_msg_send` IR opcode carrying `{env, target, name, sig,
args[], is_static}`. `lowerFfiIntrinsicCall` now dispatches on
`fic.kind`: `.objc_call` keeps the existing path; `.jni_call` and
`.jni_static_call` route through `lowerJniCall`, which emits the new
opcode.
emit_llvm.zig expands `.jni_msg_send` into the JNI vtable
indirection:
%ifs = load ptr, %env ; vtable
%get_obj_class = load ptr, gep(%ifs, i32 31)
%cls = call ptr %get_obj_class(%env, %target)
%get_method_id = load ptr, gep(%ifs, i32 33)
%mid = call ptr %get_method_id(%env, %cls, %name, %sig)
%call_void_method = load ptr, gep(%ifs, i32 61)
call void %call_void_method(%env, %target, %mid, args...)
Per step 1.15's scope: only `.jni_call` (instance) + `void` return
are wired through the switch. `.jni_static_call` (1.23) and the
non-void returns (1.18–1.22) drop to a placeholder `LLVMGetUndef` so
the build doesn't fault — the next-step commits flip those arms one
shape at a time. Method-ID caching is step 1.17.
Two small helpers landed alongside:
- `loadJniFn(ifs, offset, name)` — GEP into the vtable + load.
- `extractSlicePtr(val)` — string literals lower as `{ptr, i64}`
slices in sx IR; JNI's `GetMethodID` expects raw C strings, so
this extracts field 0 when the source is a slice.
Android cross-compile now passes for `examples/ffi-jni-call-02-void.sx`
(2/2 cross targets green). Host run_examples still passes 112/112.
Chess iOS-sim + Android both compile clean.
This commit is contained in:
@@ -321,6 +321,14 @@ fn printInst(instruction: *const Inst, ref_idx: u32, tt: *const TypeTable, write
|
||||
try writeArgs(c.args, writer);
|
||||
try writer.writeAll(") : ");
|
||||
},
|
||||
.jni_msg_send => |c| {
|
||||
const kind: []const u8 = if (c.is_static) "static" else "instance";
|
||||
try writer.print("jni_msg_send {s} env=%{d} target=%{d} name=%{d} sig=%{d}(", .{
|
||||
kind, c.env.index(), c.target.index(), c.name.index(), c.sig.index(),
|
||||
});
|
||||
try writeArgs(c.args, writer);
|
||||
try writer.writeAll(") : ");
|
||||
},
|
||||
.compiler_call => |cc| {
|
||||
const name = tt.getString(@enumFromInt(cc.name));
|
||||
try writer.print("compiler_call \"{s}\"(", .{name});
|
||||
|
||||
Reference in New Issue
Block a user