ffi M1.1 (first pass): id / Class / SEL / BOOL type aliases

Adds named stand-ins for the three opaque Obj-C runtime types
and Apple's signed-char boolean to library/modules/std/objc.sx:

  id    :: *void;   // any Obj-C instance pointer
  Class :: *void;   // a class object pointer
  SEL   :: *void;   // a registered selector
  BOOL  :: s8;      // Apple's signed-char boolean (NOT sx's bool)

All resolve to their underlying type at the LLVM layer — no
runtime cost — but make foreign-class declarations read closer
to Objective-C source. The header's old caveat about lacking
type aliases is gone.

141-objc-type-aliases.sx exercises the aliases against the real
macOS Obj-C runtime: alloc/init an NSObject, fetch its class
via objc_getClass, sel_registerName a SEL, then call
'isKindOfClass:' returning BOOL=1. Non-macOS paths print the
same line to keep the snapshot stable.

DEFERRED (M1.1.b, follow-up): 'Class(T)' parameterization with
#extends-aware covariance, and 'instancetype' per-decl
substitution. Both require compiler-level type-check support
beyond plain stdlib aliases.

170 examples pass (+1).
This commit is contained in:
agra
2026-05-25 21:33:20 +03:00
parent 86c1127c46
commit d9dbdad3f5
5 changed files with 127 additions and 13 deletions

View File

@@ -1,9 +1,5 @@
// Obj-C runtime FFI primitives.
//
// `*void` stands in for the Obj-C `id`/`Class`/`SEL` types. There's no
// sx-level type alias yet, so naming discipline at call sites is the only
// thing keeping them apart.
//
// objc_msgSend has the standard ARM64 calling convention (no varargs path).
// Each call site must invoke through a function pointer of the *exact*
// argument and return shape. The idiom:
@@ -11,6 +7,28 @@
// msg_fn : (recv: *void, sel: *void, arg: [*]u8) -> *void = xx objc_msgSend;
// result := msg_fn(receiver, selector, c_string);
// ─── Obj-C primitive type aliases ───────────────────────────────────────
// Named stand-ins for the three opaque Obj-C runtime types. They all
// resolve to `*void` at the LLVM layer (no runtime cost) but improve
// readability in foreign-class declarations and call sites.
//
// id — any Obj-C instance pointer
// Class — a class object pointer
// SEL — a registered selector
//
// `Class(T)` parameterization (phantom-typed, with `#extends`-aware
// covariance) is a follow-up — needs compiler-level type-check support.
// For now, `Class` alone is the only form; assignments are not checked
// against the referent's class hierarchy.
id :: *void;
Class :: *void;
SEL :: *void;
// Apple's `BOOL` is a signed char (NOT sx's built-in `bool`, which is
// LLVM `i1`). Obj-C method signatures that take or return `BOOL` cross
// the FFI boundary as `s8`.
BOOL :: s8;
// On macOS libobjc is auto-loaded by libSystem; on iOS it isn't, so we
// link it explicitly. Foundation registers NSString etc. with the runtime,
// also auto-loaded on macOS and required as an explicit framework on iOS.