ffi #jni_main: drop implicit super call from @Override delegate

The Java @Override no longer injects a `super.<method>(...)` call before
the native delegate. The user calls super from the sx-side body when
needed — via a forthcoming `super.method(args)` dispatch lowered to
`CallNonvirtual<Type>Method` on JNI classes.

Two reasons:

  - Interface method impls (e.g. SurfaceHolder.Callback) have no super
    to call. The previous emit produced javac-rejected code for those.
  - Lifecycle overrides may want to skip super in some cases, or call
    it with different args. The emitter can't second-guess intent.

User-space control of the dispatch keeps the emitter free of "is this
an interface method or a supertype override?" guesswork. The dex
shrinks by one virtual-method bytecode invocation per override.

Caveat: until the sx-side `super.method(args)` dispatch lands, Activity
lifecycle methods (onCreate, onResume, etc.) that mandate `super.<>`
will throw `SuperNotCalledException` at runtime if their bodies don't
do their own JNI dispatch. The slice 2 smoke still launches cleanly
because its onCreate body is empty.

131 host / 4 cross / zig build test all green.
This commit is contained in:
agra
2026-05-20 16:41:13 +03:00
parent bce5448fe9
commit 22768d9adf
2 changed files with 9 additions and 7 deletions

View File

@@ -171,17 +171,20 @@ fn emitOverride(
md: ast.ForeignMethodDecl,
opts: Options,
) EmitError!void {
// The Java @Override only calls the native delegate. `super.<method>(...)`
// is NOT injected — if the user wants to invoke the supertype's
// implementation (e.g. `super.onCreate(b)` for an Activity lifecycle hook
// that requires it) they call super from the sx-side body via JNI
// dispatch. This keeps the emitter free of "is this an interface method
// or a supertype override?" guesswork and matches the sx principle of
// user-space code expressing the dispatch.
try buf.appendSlice(allocator, " @Override\n public ");
try emitJavaReturnType(allocator, buf, md.return_type, opts);
try buf.append(allocator, ' ');
try buf.appendSlice(allocator, md.name);
try buf.append(allocator, '(');
try emitJavaParamList(allocator, buf, md, opts);
try buf.appendSlice(allocator, ") {\n super.");
try buf.appendSlice(allocator, md.name);
try buf.append(allocator, '(');
try emitJavaArgList(allocator, buf, md);
try buf.appendSlice(allocator, ");\n sx_");
try buf.appendSlice(allocator, ") {\n sx_");
try buf.appendSlice(allocator, md.name);
try buf.append(allocator, '(');
try emitJavaArgList(allocator, buf, md);