Commit Graph

2 Commits

Author SHA1 Message Date
agra
b5694cc42d ffi 1.22: #jni_call(*void) → CallObjectMethod (slot 34) — make-green
Closes the return-type matrix. Pointer-return types aren't a simple
`TypeId` enum case (they're user-defined types interned into the
table), so the dispatch checks `TypeInfo.pointer | .many_pointer`
ahead of the primitive switch:

  const is_pointer_ret = switch (types.get(ret_ty_id)) {
      .pointer, .many_pointer => true,
      else => false,
  };
  const offset = if (is_pointer_ret)
      Jni.CallObjectMethod
  else switch (ret_ty_id) { .void => ..., .s32 => ..., ... };

LocalRef cleanup deferred: returned jobjects are JNI LocalRefs
bounded by the native frame. Chains of calls within one frame
consume them inline; cross-frame use must promote via `NewGlobalRef`
(already wired in the slot-interning path from 1.17). The chess
Android backend will consume objects inline, matching the manual
pattern in `sx_android_jni.c`.

Return-type matrix done: void, s32, s64, f64, bool, *void all
dispatch through their respective vtable slots. Static dispatch
(1.23) is next.
2026-05-19 22:38:09 +03:00
agra
908b6d19a3 ffi 1.22: lock in undef shape for #jni_call(*void)
Last return-type variant in the matrix. JNI's jobject is a pointer
(LocalRef) — sx's `*void` maps to LLVM `ptr` directly. CallObjectMethod
is at vtable slot 34. IR snapshot captures today's `ret ptr undef`.
Next commit adds the `.ptr => Jni.CallObjectMethod` arm.

LocalRef lifetime: the returned jobject is a JNI LocalRef bounded by
the native frame. Chains of calls within one frame consume LocalRefs
inline; calls that need to escape the frame should be promoted via
`NewGlobalRef` (already wired in the slot-interning path). Step 1.22
doesn't introduce automatic cleanup — chess use consumes objects
inline, matching the pattern in sx_android_jni.c.
2026-05-19 22:36:36 +03:00