From d1e9def0c61ae2813473b933dfc01f86d89f937a Mon Sep 17 00:00:00 2001 From: agra Date: Tue, 19 May 2026 12:48:38 +0300 Subject: [PATCH] ffi 1.3: xfail end-to-end void-return #objc_call (no codegen yet) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 100/100 regression tests pass (+ffi-objc-call-02-void-return xfail snapshot). The intrinsic with no `inline if false` guard reaches sema/codegen and trips an "unresolved: 'unknown_expr'" — the FfiIntrinsicCall AST node from Phase 1.1 has no lowering rules in lower.zig / emit_llvm.zig yet. nil receiver was chosen so the test doesn't need a real Obj-C object graph: the runtime guarantees `[nil msg]` is a no-op with zero result for void returns. macOS-gated via `inline if OS == .macos` so the runner stays portable. Next commit: emit_llvm.zig produces the per-call-site %sel = call ptr @sel_registerName(ptr "init.0") call void @objc_msgSend(ptr null, ptr %sel) lowering. Snapshot flips to "ok". Selector interning (one shared global per unique selector string) lands as a separate step (1.5). --- examples/ffi-objc-call-02-void-return.sx | 25 +++++++++++++++++++ .../ffi-objc-call-02-void-return.exit | 1 + .../expected/ffi-objc-call-02-void-return.txt | 1 + 3 files changed, 27 insertions(+) create mode 100644 examples/ffi-objc-call-02-void-return.sx create mode 100644 tests/expected/ffi-objc-call-02-void-return.exit create mode 100644 tests/expected/ffi-objc-call-02-void-return.txt diff --git a/examples/ffi-objc-call-02-void-return.sx b/examples/ffi-objc-call-02-void-return.sx new file mode 100644 index 0000000..86e114f --- /dev/null +++ b/examples/ffi-objc-call-02-void-return.sx @@ -0,0 +1,25 @@ +// Phase 1 step 1.3 (PLAN-FFI.md): smallest end-to-end `#objc_call`. +// Void return, nil receiver — Obj-C runtime guarantees that messages +// to nil are no-ops with a zero result, so we don't need to set up +// a real object graph to exercise the lowering surface. +// +// Today (step 1.3, test-add): codegen rejects the FfiIntrinsicCall +// AST node. Snapshot pins the failure mode. +// Next (step 1.3, make-green): emit_llvm.zig synthesizes +// %sel = call ptr @sel_registerName(ptr @"sel:init") +// call void @objc_msgSend(ptr null, ptr %sel) +// per call site (no selector interning until step 1.5). + +#import "modules/std.sx"; +#import "modules/compiler.sx"; + +main :: () -> s32 { + inline if OS == .macos { + #objc_call(void)(null, "init"); + print("ok\n"); + } + inline if OS != .macos { + print("skipped (not macos)\n"); + } + 0; +} diff --git a/tests/expected/ffi-objc-call-02-void-return.exit b/tests/expected/ffi-objc-call-02-void-return.exit new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/tests/expected/ffi-objc-call-02-void-return.exit @@ -0,0 +1 @@ +1 diff --git a/tests/expected/ffi-objc-call-02-void-return.txt b/tests/expected/ffi-objc-call-02-void-return.txt new file mode 100644 index 0000000..2214600 --- /dev/null +++ b/tests/expected/ffi-objc-call-02-void-return.txt @@ -0,0 +1 @@ +/Users/agra/projects/sx/examples/ffi-objc-call-02-void-return.sx:18:9: error: unresolved: 'unknown_expr'