ffi #jni_main: Alias.new(args) constructor dispatch via JNI NewObject
Adds the constructor-invocation arm of the foreign-class DSL:
`SurfaceView.new(ctx)` (where `SurfaceView` is a `#foreign #jni_class`
with `static new :: (ctx: *Context) -> *Self;`) lowers to
`FindClass(env, "android/view/SurfaceView") + GetMethodID(env, cls,
"<init>", "(args)V") + NewObject(env, cls, mid, args...)`. Returns
the fresh jobject.
- inst.zig: `JniMsgSend.is_constructor` flag + `parent_class_path`
re-purposed to carry the class being constructed (alongside its
existing nonvirtual-super-class use). Mutually exclusive with
`is_static` / `is_nonvirtual`.
- lower.zig: `lowerCall.field_access` arm now recognises
`Alias.method(args)` where `Alias` resolves in `foreign_class_map`
and the matching member is `static`. `new` routes to a new
`lowerForeignStaticCall` that derives a `(args)V` JNI descriptor
and emits a `JniMsgSend` with `is_constructor=true`. Non-`new`
static calls report a clear "use #jni_static_call" diagnostic
until that sugar lands.
- emit_llvm.zig: new `NewObject` vtable slot (28) + `emitJniConstructor`
helper expanding the FindClass+GetMethodID+NewObject chain. The
jni_msg_send arm short-circuits to it when `is_constructor` is set.
Smoke `ffi-jni-main-03-ctor.sx` exercises both this slice and the
previous super-dispatch slice in a single `onCreate` body: calls
`super.onCreate(b)` then constructs a `SurfaceView` with the Activity
as Context. IR shows the expected six-stage chain (FindClass+GetMethodID+
CallNonvirtual + FindClass+GetMethodID+NewObject); APK builds clean.
Naming caveat: the Java type `android.content.Context` clashes with
sx stdlib's `Context :: struct {...}` (heap-context). The smoke aliases
it `JContext` — future work could add a path-prefix or `as` rename
form on `#jni_class` to avoid the manual rename.
133 host / 6 cross / zig build test all green.
This commit is contained in:
30
examples/ffi-jni-main-03-ctor.sx
Normal file
30
examples/ffi-jni-main-03-ctor.sx
Normal file
@@ -0,0 +1,30 @@
|
||||
// `Alias.new(args)` constructor dispatch on a `#foreign #jni_class`
|
||||
// (chess-on-Pixel migration, R.6). The sx-side `static new :: (...) ->
|
||||
// *Self;` member lowers to JNI `FindClass + GetMethodID("<init>", sig)
|
||||
// + NewObject(env, clazz, mid, args...)`.
|
||||
//
|
||||
// This smoke instantiates a `SurfaceView` from inside the Activity's
|
||||
// `onCreate` body — chess's render surface starts the same way.
|
||||
|
||||
#import "modules/std.sx";
|
||||
#import "modules/compiler.sx";
|
||||
|
||||
Bundle :: #foreign #jni_class("android/os/Bundle") { }
|
||||
JContext :: #foreign #jni_class("android/content/Context") { }
|
||||
|
||||
SurfaceView :: #foreign #jni_class("android/view/SurfaceView") {
|
||||
static new :: (ctx: *JContext) -> *Self;
|
||||
}
|
||||
|
||||
g_held_view : *void = null;
|
||||
|
||||
SxApp :: #jni_main #jni_class("co/swipelab/sxjnictor/SxApp") {
|
||||
onCreate :: (self: *Self, b: *Bundle) {
|
||||
super.onCreate(b);
|
||||
ctx : *JContext = xx self; // Activity IS a JContext (extends JContext).
|
||||
view := SurfaceView.new(ctx);
|
||||
g_held_view = xx view; // keep alive so LLVM doesn't DCE the construction.
|
||||
}
|
||||
}
|
||||
|
||||
main :: () -> s32 { 0; }
|
||||
Reference in New Issue
Block a user