ffi: accept native-codegen closures + route >3-arg callbacks through sigil_applyN
Two callback fixes:
1. Native-closure callbacks (latent bug). nativefficallbackcreate rejected any procedure that was not a bytecode closure or native primitive. Under sigil build --backend native, every top-level procedure is a native-codegen closure (SIGILOBJNATIVECLOSURE), so c-callback rejected EVERY callback in a native-compiled program with 'c-callback: expected procedure', even though the callback handler and the sigilapply family already dispatch such closures via sigilnativebridgecall. Now accepts sigilisnative_closure too.
2. Callbacks with more than 3 arguments. The dyncall callback handler erred on any callback with >3 args ('not yet supported'). It now routes the >3-arg case through sigilapplyN (the generic-arity apply added to the VM C-API), supporting up to FFIMAX_ARGS. This enables 4-6-arg GTK/WebKit signals such as decide-policy.
Proven with a 4-arg WebKitWebView decide-policy callback firing correctly in a native-compiled binary. The >3-arg routing requires sigil_applyN in the linked VM (sigil release that adds it); the native-closure fix is independent.
native/ffi.c | 18 +++++++++++++-----
1 file changed, 13 insertions(+), 5 deletions(-)native/ffi.cmodified
extern Value sigil_apply1(SigilVM *vm, Value proc, Value arg);extern Value sigil_apply2(SigilVM *vm, Value proc, Value arg1, Value arg2);extern Value sigil_apply3(SigilVM *vm, Value proc, Value arg1, Value arg2, Value arg3);extern Value sigil_applyN(SigilVM *vm, Value proc, int argc, Value *argv);/* ============================================================ * FFI Type System scheme_args[2]); break; default: sigil__vm_error(vm, SIGIL_ERR_RUNTIME, "c-callback: callbacks with more than 3 arguments not yet supported"); return DC_SIGCHAR_VOID; /* >3 args: dispatch through the generic arity variant (added to the VM * C-API alongside sigil_apply0..3). Supports up to FFI_MAX_ARGS. */ ret_val = sigil_applyN(vm, cbd->proc, cbd->arg_count, scheme_args); break; } /* Marshal return value */ return SIGIL_UNDEFINED; } /* Procedure */ /* Procedure. Accept bytecode closures, native primitives, AND * native-codegen closures (SIGIL_OBJ_NATIVE_CLOSURE) - the last is what * top-level procedures become in --backend native builds, and both the * callback handler and the sigil_applyN family already dispatch them via * sigil_native_bridge_call. Without this, c-callback rejects every callback * in a native-compiled program. */ Value proc = args[2]; if (!sigil_is_closure(proc) && !sigil_is_native_proc(proc)) { if (!sigil_is_closure(proc) && !sigil_is_native_proc(proc) && !sigil_is_native_closure(proc)) { sigil__vm_error(vm, SIGIL_ERR_TYPE, "c-callback: expected procedure"); return SIGIL_UNDEFINED;