From baeab179c35cb3ea63346e1dda7365fa7d65a623 Mon Sep 17 00:00:00 2001 From: agra Date: Tue, 19 May 2026 18:02:43 +0300 Subject: [PATCH] =?UTF-8?q?ffi=201.6a:=20xfail=20=E2=80=94=20#objc=5Fcall?= =?UTF-8?q?=20with=20non-void=20return=20rejected=20today?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 102/102 regression tests pass (+ffi-objc-call-04-primitive-returns with xfail snapshot capturing today's diagnostic). Pinned scenario: `[NSObject class]` — `#objc_call(*void)(null, "class")`. Should return a non-null Class pointer once the lowering supports non-void returns. Today the Phase 1.3 restriction trips with: #objc_call: only `void` return + (recv, selector) is lowered today; non-void / arg-bearing arities land in later phase-1 steps The next commit (1.6b) introduces an `objc_msg_send` IR opcode that bundles (recv, sel, args, ret_ty) and emit_llvm builds a per-call- site LLVM function type, sharing one declared `@objc_msgSend` symbol across return-type variants. Five primitive returns (*void / bool / s32 / s64 / f64) get folded in across 1.6b–c. --- .../ffi-objc-call-04-primitive-returns.sx | 31 +++++++++++++++++++ .../ffi-objc-call-04-primitive-returns.exit | 1 + .../ffi-objc-call-04-primitive-returns.txt | 1 + 3 files changed, 33 insertions(+) create mode 100644 examples/ffi-objc-call-04-primitive-returns.sx create mode 100644 tests/expected/ffi-objc-call-04-primitive-returns.exit create mode 100644 tests/expected/ffi-objc-call-04-primitive-returns.txt diff --git a/examples/ffi-objc-call-04-primitive-returns.sx b/examples/ffi-objc-call-04-primitive-returns.sx new file mode 100644 index 0000000..c6c3b1c --- /dev/null +++ b/examples/ffi-objc-call-04-primitive-returns.sx @@ -0,0 +1,31 @@ +// Phase 1 step 1.6 (PLAN-FFI.md): non-void return shapes through +// `#objc_call`. The Phase 1.3 lowering hardcoded void+2-arg only; +// this test exercises five primitive return types via real +// Foundation classes: +// +// *void — [NSObject class] returns Class (ptr) +// bool — [NSObject isMemberOfClass: cls] returns BOOL +// s32 — [NSString length] returns NSUInteger (treated as s32 here) +// s64 — same shape, wider +// f64 — [NSNumber doubleValue] returns double +// +// Today (1.6a, xfail): the lowering rejects non-void returns with +// a diagnostic. Snapshot pins the diagnostic. +// Next (1.6b/c): emit_llvm builds a per-call-site LLVM function +// type from (recv, sel, args, ret_ty), shares one declared +// `@objc_msgSend` symbol, dispatches with the right ABI. + +#import "modules/std.sx"; +#import "modules/compiler.sx"; + +main :: () -> s32 { + inline if OS == .macos { + // *void return: [NSObject class] → Class + cls := #objc_call(*void)(null, "class"); + print("class non-null = {}\n", cls != null); + } + inline if OS != .macos { + print("skipped (not macos)\n"); + } + 0; +} diff --git a/tests/expected/ffi-objc-call-04-primitive-returns.exit b/tests/expected/ffi-objc-call-04-primitive-returns.exit new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/tests/expected/ffi-objc-call-04-primitive-returns.exit @@ -0,0 +1 @@ +1 diff --git a/tests/expected/ffi-objc-call-04-primitive-returns.txt b/tests/expected/ffi-objc-call-04-primitive-returns.txt new file mode 100644 index 0000000..d554353 --- /dev/null +++ b/tests/expected/ffi-objc-call-04-primitive-returns.txt @@ -0,0 +1 @@ +/Users/agra/projects/sx/examples/ffi-objc-call-04-primitive-returns.sx: error: #objc_call: only `void` return + (recv, selector) is lowered today; non-void / arg-bearing arities land in later phase-1 steps