ffi 1.15: xfail — Android cross-compile of #jni_call(void)
Adds `examples/ffi-jni-call-02-void.sx` exercising `#jni_call(void) (env, target, "name", "sig")` inside an `inline if OS == .android` arm, plus a new tuple in `tests/cross_compile.sh`. Host run_examples passes (the inline-if strips the JNI body, leaving "skipped"); the Android cross-compile FAILs because `lowerFfiIntrinsicCall` still emits the placeholder diagnostic for any `fic.kind != .objc_call`. Per the FFI cadence rule this is a test-add (xfail); the next commit makes the Android cross-compile green by adding the `.jni_msg_send` opcode and its emit_llvm expansion.
This commit is contained in:
49
examples/ffi-jni-call-02-void.sx
Normal file
49
examples/ffi-jni-call-02-void.sx
Normal file
@@ -0,0 +1,49 @@
|
||||
// Phase 1 step 1.15 (PLAN-FFI.md): `#jni_call(void)` codegen.
|
||||
//
|
||||
// `#jni_call(T)(env, target, "method_name", "(Sig)RetSig", args...)`
|
||||
// dispatches a JNI instance-method call. The lowering hand-emits the
|
||||
// vtable indirection:
|
||||
//
|
||||
// ifs = *env // JNINativeInterface*
|
||||
// cls = ifs->GetObjectClass(env, target)
|
||||
// mid = ifs->GetMethodID(env, cls, name, sig)
|
||||
// ifs->Call<Type>Method(env, target, mid, args...)
|
||||
//
|
||||
// Phase 1.17 introduces method-ID caching via static slots populated
|
||||
// at module-init; this step keeps the per-call-site lookup.
|
||||
//
|
||||
// Host can't dlopen libjvm via the JIT, so the JNI body is gated
|
||||
// behind `inline if OS == .android`. The macOS test path strips the
|
||||
// body and prints "skipped"; the cross_compile.sh Android target
|
||||
// verifies that the gated body actually compiles + links against
|
||||
// libjvm in the Android sysroot.
|
||||
|
||||
#import "modules/std.sx";
|
||||
#import "modules/compiler.sx";
|
||||
|
||||
main :: () -> s32 {
|
||||
inline if OS == .android {
|
||||
// Real Android entry passes env + target via android_main /
|
||||
// ANativeActivity (modules/platform/android.sx). For the cross-
|
||||
// compile-only test we just need the lowering to emit valid
|
||||
// IR; runtime correctness is exercised by the chess
|
||||
// sx_android_query_safe_insets path once Phase 1D for
|
||||
// sx_android_jni.c lands.
|
||||
env : *void = null;
|
||||
target : *void = null;
|
||||
#jni_call(void)(env, target, "noop", "()V");
|
||||
}
|
||||
inline if OS != .android {
|
||||
print("skipped (not android)\n");
|
||||
}
|
||||
0;
|
||||
}
|
||||
|
||||
// Android target requires `android_main` as the NDK entry — kept as
|
||||
// a 3-line trampoline so this example can pass through
|
||||
// `--target android` builds in `tests/cross_compile.sh`.
|
||||
android_main :: (app: *void) {
|
||||
inline if OS == .android {
|
||||
main();
|
||||
}
|
||||
}
|
||||
@@ -27,6 +27,7 @@ mkdir -p "$TMP_DIR"
|
||||
# host to actually run it.
|
||||
TUPLES=(
|
||||
"android|examples/ffi-objc-call-10-os-gate.sx"
|
||||
"android|examples/ffi-jni-call-02-void.sx"
|
||||
)
|
||||
|
||||
PASS=0
|
||||
|
||||
1
tests/expected/ffi-jni-call-02-void.exit
Normal file
1
tests/expected/ffi-jni-call-02-void.exit
Normal file
@@ -0,0 +1 @@
|
||||
0
|
||||
1
tests/expected/ffi-jni-call-02-void.txt
Normal file
1
tests/expected/ffi-jni-call-02-void.txt
Normal file
@@ -0,0 +1 @@
|
||||
skipped (not android)
|
||||
Reference in New Issue
Block a user