refactor(ffi-linkage): Phase 9.3 — purge 'foreign' from comments (src caps + examples + docs)
src/: ~21 capital-Foreign comments the case-sensitive verify grep missed (Foreign-class→Runtime-class, Foreign path→Runtime path, Foreign decls→Extern decls, FOREIGN function→extern function) across calls/inst/ffi_objc/jni_descriptor/emit_llvm/ c_import/lower.*/ops. src 'foreign' now = ONLY the hash_foreign token + 4 rejection messages (9.0-delete targets). examples/*.sx comments → extern/runtime-class (1219 stdout regen; KEPT 1176). docs/inline-asm-design + debugger purged. Comments only — no build impact. 9.0 ratified: DELETE hash_foreign token next.
This commit is contained in:
@@ -7,7 +7,7 @@
|
||||
// trampoline's first read.
|
||||
//
|
||||
// The fix lives in `abiCoerceParamTypeEx`: the `string`/`slice` →
|
||||
// `ptr` collapse only applies to `is_extern` foreign decls (libc
|
||||
// `ptr` collapse only applies to `is_extern` extern decls (libc
|
||||
// interop). sx-internal `callconv(.c)` keeps the full slice
|
||||
// shape, which lands as `[2 x i64]` at the LLVM signature site
|
||||
// and matches the caller's two-register pass on AArch64.
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Real OS-argv accessor from `modules/std/cli.sx` (#foreign _NSGetArgv).
|
||||
// Real OS-argv accessor from `modules/std/cli.sx` (extern _NSGetArgv).
|
||||
//
|
||||
// Only DETERMINISTIC structural invariants are asserted — the actual arg
|
||||
// contents depend on how the test is invoked (under `sx run` the process
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
// fix-0102c (issue 0102) F3 regression: two flat FILE imports each `#foreign`
|
||||
// fix-0102c (issue 0102) F3 regression: two flat FILE imports each `extern`
|
||||
// the SAME libc symbol under the SAME sx name `absval`. The bare-call resolver
|
||||
// must NOT count `#foreign` (non-plain) authors when deciding ambiguity — it
|
||||
// filters them out, returns "no rerouting", and the existing first-wins foreign
|
||||
// dispatch binds the call. A same-name foreign collision therefore compiles and
|
||||
// must NOT count `extern` (non-plain) authors when deciding ambiguity — it
|
||||
// filters them out, returns "no rerouting", and the existing first-wins extern
|
||||
// dispatch binds the call. A same-name extern collision therefore compiles and
|
||||
// runs (master behavior), it does NOT error as ambiguous.
|
||||
#import "modules/std.sx";
|
||||
#import "0729-modules-flat-same-name-foreign/a.sx";
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// One of two flat authors of `absval`, a `#foreign` libc binding. A consumer
|
||||
// One of two flat authors of `absval`, a `extern` libc binding. A consumer
|
||||
// flat-importing BOTH must NOT see this as an ambiguous bare-call collision —
|
||||
// foreign authors are never rerouted by the bare-call resolver, so the call
|
||||
// falls to the existing first-wins foreign dispatch.
|
||||
// extern authors are never rerouted by the bare-call resolver, so the call
|
||||
// falls to the existing first-wins extern dispatch.
|
||||
absval :: (n: i32) -> i32 extern libc "abs";
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
// The second flat author of `absval` — the identical `#foreign` libc binding.
|
||||
// The second flat author of `absval` — the identical `extern` libc binding.
|
||||
absval :: (n: i32) -> i32 extern libc "abs";
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// A reserved/builtin type name used as a PARAMETER name is rejected inside the
|
||||
// two method-with-body forms that carry their params as bare name lists rather
|
||||
// than `Param` nodes: a protocol default-body method (`u8`) and a sx-defined
|
||||
// foreign-class (`#objc_class`) method (`i16`). The declaration-site diagnostic
|
||||
// runtime-class (`#objc_class`) method (`i16`). The declaration-site diagnostic
|
||||
// underlines the OFFENDING PARAMETER itself, not the enclosing `protocol` /
|
||||
// `#objc_class` block — each method's `param_name_spans` is threaded from the
|
||||
// parser so the caret lands on the parameter token.
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
// reserved-name check, so a bare reserved-name function compiled silently and
|
||||
// became callable — bypassing the backtick rule that handwritten sx must use.
|
||||
// The backtick escape (`` `i2 :: … ``, examples/0153) is the only way to spell
|
||||
// these names; `#import c` foreign decls remain exempt (examples/1220).
|
||||
// these names; `#import c` extern decls remain exempt (examples/1220).
|
||||
//
|
||||
// Regression (issue 0089). Expected: one error per declaration, each caret on
|
||||
// the declared name; exit 1.
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
// examples/1140). Each is a declaration-name binding site: a bare reserved
|
||||
// spelling there mis-classifies and is rejected, exactly like `i2 := …`. The
|
||||
// backtick escape (`` `i2 :: struct{…} ``, examples/0154) is the only way to
|
||||
// spell these names in handwritten sx; `#import c` foreign decls stay exempt
|
||||
// spell these names in handwritten sx; `#import c` extern decls stay exempt
|
||||
// (examples/1220).
|
||||
//
|
||||
// Regression (issue 0089 — attempt-4: 0076 holds across every decl kind).
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// `callconv(.c)` on function pointers passed to foreign callbacks — ensures
|
||||
// `callconv(.c)` on function pointers passed to extern callbacks — ensures
|
||||
// the function uses C ABI so it can be safely invoked from `extern`
|
||||
// functions like SDL_AddEventWatch.
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// Companion module for examples/94-foreign-global.sx (PLAN-FFI 0.10).
|
||||
// Declares the same `#foreign` extern global as the main file; the
|
||||
// Declares the same `extern` extern global as the main file; the
|
||||
// linker should treat both decls as one symbol. We deliberately don't
|
||||
// READ `@__stdinp` from inside a helper fn body — that path is busted
|
||||
// today (see examples/issue-0037.sx) — we just expose a trivial fn so
|
||||
|
||||
@@ -1,16 +1,16 @@
|
||||
// Extern data globals via `<name> : <type> #foreign;`. Lets sx code
|
||||
// Extern data globals via `<name> : <type> extern;`. Lets sx code
|
||||
// reference libSystem / framework symbols (NSConcreteStackBlock,
|
||||
// __stdinp, etc.) for FFI bridges. Mirrors the long-standing
|
||||
// `<fn> :: (...) -> ... #foreign;` form on the function side.
|
||||
// `<fn> :: (...) -> ... extern;` form on the function side.
|
||||
//
|
||||
// Cross-file dimension (PLAN-FFI step 0.10): the helper companion
|
||||
// `94-foreign-global-helper.sx` ALSO declares `__stdinp : *void #foreign;`.
|
||||
// `94-foreign-global-helper.sx` ALSO declares `__stdinp : *void extern;`.
|
||||
// Both files referencing the same extern symbol must link cleanly —
|
||||
// LLVM dedupes the named global, the C linker resolves both refs to
|
||||
// the one libSystem symbol.
|
||||
//
|
||||
// We *don't* check that the helper computes the same address — see
|
||||
// issue-0037 (helper-function-scoped `@foreign_global` lowers to
|
||||
// issue-0037 (helper-function-scoped `@extern_global` lowers to
|
||||
// undef today). When that fixes, fold the helper's address back into
|
||||
// the equality check here.
|
||||
|
||||
@@ -23,7 +23,7 @@ main :: () -> i32 {
|
||||
addr_bits : u64 = xx @__stdinp;
|
||||
print("stdin extern global non-null: {}\n", addr_bits != 0);
|
||||
// Force the helper symbol to participate in linking (otherwise the
|
||||
// imported file's #foreign decl might get dropped by the
|
||||
// imported file's #extern decl might get dropped by the
|
||||
// dead-code stripper). The actual return value is busted today
|
||||
// — see issue-0037.
|
||||
_ := stdinp_addr_present();
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// `xx @<foreign_global>` round-trips through a non-main helper
|
||||
// `xx @<extern_global>` round-trips through a non-main helper
|
||||
// function: the helper's `xx @__stdinp` cast lowers to a `bitcast`
|
||||
// IR opcode that emit_llvm.zig dispatches to `LLVMBuildPtrToInt`
|
||||
// (BitCast doesn't accept ptr↔int on modern LLVM with opaque
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Phase 0 baseline (PLAN-FFI.md step 0.8): `#foreign` C call sites
|
||||
// Phase 0 baseline (PLAN-FFI.md step 0.8): `extern` C call sites
|
||||
// embedded inside the major sx surface constructs. None of these
|
||||
// touch a new ABI shape — they only verify lowering routes the call
|
||||
// through identically regardless of the enclosing context:
|
||||
@@ -16,7 +16,7 @@
|
||||
#source "1216-ffi-08-foreign-in-method.c";
|
||||
};
|
||||
|
||||
// ── 1. Struct method calling a #foreign fn ───────────────────────────
|
||||
// ── 1. Struct method calling a #extern fn ───────────────────────────
|
||||
Counter :: struct {
|
||||
seed: i32 = 0;
|
||||
next :: (self: *Counter) -> i32 {
|
||||
@@ -26,7 +26,7 @@ Counter :: struct {
|
||||
}
|
||||
}
|
||||
|
||||
// ── 2. Protocol impl method calling a #foreign fn ────────────────────
|
||||
// ── 2. Protocol impl method calling a #extern fn ────────────────────
|
||||
Doubler :: protocol {
|
||||
doubled :: (self: *Self) -> i32;
|
||||
}
|
||||
@@ -37,7 +37,7 @@ impl Doubler for Counter {
|
||||
}
|
||||
}
|
||||
|
||||
// ── 3. Closure body calling a #foreign fn ────────────────────────────
|
||||
// ── 3. Closure body calling a #extern fn ────────────────────────────
|
||||
make_adder :: (bias: i32) -> Closure(i32) -> i32 {
|
||||
closure((x: i32) -> i32 => ffi_method_helper(x) + bias)
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// `#foreign` C-variadic tail: trailing `..args: []T` on a foreign fn maps
|
||||
// `extern` C-variadic tail: trailing `..args: []T` on a extern fn maps
|
||||
// to the C calling convention's `...`. Extras at the call site are
|
||||
// passed via the variadic slot with the standard default argument
|
||||
// promotion (i8/i16/bool → i32, f32 → f64) applied implicitly.
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
#import "modules/std/test.sx";
|
||||
pkg :: #import "tests/fixtures/testpkg";
|
||||
|
||||
// --- Foreign function binding ---
|
||||
// --- Extern function binding ---
|
||||
libc :: #library "c";
|
||||
|
||||
c_abs :: (n: i32) -> i32 extern libc "abs";
|
||||
@@ -16,8 +16,8 @@ main :: () {
|
||||
// ========================================================
|
||||
// 15. FOREIGN FUNCTION BINDING
|
||||
// ========================================================
|
||||
print("=== 15. Foreign ===\n");
|
||||
print("=== 15. Extern ===\n");
|
||||
|
||||
// Symbol rename: c_abs maps to C's abs()
|
||||
print("foreign-rename: {}\n", c_abs(xx -42));
|
||||
print("extern-rename: {}\n", c_abs(xx -42));
|
||||
}
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
// `#import c` foreign-name exemption: C names that collide with sx's reserved
|
||||
// `#import c` extern-name exemption: C names that collide with sx's reserved
|
||||
// type spellings import unedited. Foreign decls are treated as RAW — their names
|
||||
// are never type-classified nor reserved-checked — so the generated `extern`
|
||||
// bindings import and call without hand-edits (no backticks needed). This covers
|
||||
// parameter names (`i1`/`i2`), a function whose own NAME is a reserved spelling
|
||||
// (`i2`), and bare-calling that function (its callee spelling parses as a type
|
||||
// but resolves to the foreign fn). Before issue 0089 the params errored with
|
||||
// but resolves to the extern fn). Before issue 0089 the params errored with
|
||||
// "'i1' is a reserved type name and cannot be used as an identifier", and the
|
||||
// bare call errored with "unresolved 'i2'".
|
||||
// Regression (issue 0089).
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// extern function binding (FFI-linkage stream, Phase 1): bind libc's `abs`
|
||||
// directly via the bare `extern` linkage modifier — no `#foreign`, no
|
||||
// directly via the bare `extern` linkage modifier — no `extern`, no
|
||||
// `#library`. `extern` ⇒ external linkage + C ABI + no sx ctx; the symbol
|
||||
// resolves against the default-linked libc at link time. The sx name `abs`
|
||||
// IS the C symbol (no rename — the `extern LIB "csym"` forms land in 1.2).
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// extern with a "csym" rename (FFI-linkage stream, Phase 1.2): the sx name
|
||||
// `c_abs` binds C's `abs` via the optional symbol-name override after the
|
||||
// `extern` keyword — mirrors `#foreign "abs"`. The optional `LIB` ident slot
|
||||
// `extern` keyword — mirrors `extern "abs"`. The optional `LIB` ident slot
|
||||
// (extern_lib) sits before the string; here it's omitted (libc is
|
||||
// default-linked).
|
||||
#import "modules/std.sx";
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// extern data global (FFI-linkage stream, Phase 1.2): reference a symbol
|
||||
// defined elsewhere (here libSystem's __stdinp) via the bare `extern`
|
||||
// linkage modifier on a typed var decl — the extern-named counterpart of
|
||||
// `<name> : <type> #foreign;` (see examples/1205). The optional
|
||||
// `<name> : <type> extern;` (see examples/1205). The optional
|
||||
// `extern [LIB] ["csym"]` tail mirrors the fn form; bare here (the sx name
|
||||
// IS the C symbol, resolved against the default-linked libSystem).
|
||||
#import "modules/std.sx";
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
// `extern` C-variadic tail: a trailing `..args: []T` on an `extern` fn
|
||||
// maps to the C calling convention's `...`, exactly like its `#foreign`
|
||||
// maps to the C calling convention's `...`, exactly like its `extern`
|
||||
// twin (example 1218). Extras at the call site pass through the variadic
|
||||
// slot with standard default argument promotion (i8/i16/bool → i32,
|
||||
// f32 → f64), NOT packed into an sx slice.
|
||||
//
|
||||
// Regression (FFI-linkage Part B): the `is_variadic` drop in
|
||||
// `declareFunction` + the call-site early-out in `packVariadicCallArgs`
|
||||
// were gated on `#foreign` only, so a migrated variadic `extern` lost
|
||||
// were gated on `extern` only, so a migrated variadic `extern` lost
|
||||
// its `...` tail and slice-packed the extras (garbage at the C ABI).
|
||||
|
||||
#import "modules/std.sx";
|
||||
|
||||
@@ -1,16 +1,16 @@
|
||||
// Two flat FILE imports each declare the SAME libc symbol `absval` via the
|
||||
// `extern` keyword (the linkage-keyword twin of example 0729's `#foreign`
|
||||
// `extern` keyword (the linkage-keyword twin of example 0729's `extern`
|
||||
// form). The bare-call resolver must NOT count extern authors when deciding
|
||||
// ambiguity — they are external C symbols, never rerouted by the bare-call
|
||||
// machinery, so the existing first-wins foreign/extern dispatch binds the
|
||||
// machinery, so the existing first-wins extern dispatch binds the
|
||||
// call and a same-name extern collision compiles + runs (prints 7), it does
|
||||
// NOT error as ambiguous.
|
||||
//
|
||||
// Regression (FFI-linkage Part B): `isPlainFreeFn` / `isPlainFreeFnDecl`
|
||||
// excluded a `#foreign` body but classified an empty-block `extern` fn as a
|
||||
// excluded a `extern` body but classified an empty-block `extern` fn as a
|
||||
// plain free function, so the two extern authors were wrongly counted as an
|
||||
// ambiguous bare-call collision. Prerequisite for migrating the fn-decl
|
||||
// `#foreign` path onto `extern`.
|
||||
// `extern` path onto `extern`.
|
||||
#import "modules/std.sx";
|
||||
#import "1230-ffi-extern-same-name-authors/a.sx";
|
||||
#import "1230-ffi-extern-same-name-authors/b.sx";
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// One of two flat authors of `absval`, an `extern` libc binding — the
|
||||
// `extern` twin of example 0729's `#foreign libc "abs"`. A consumer
|
||||
// `extern` twin of example 0729's `extern libc "abs"`. A consumer
|
||||
// flat-importing BOTH must NOT see this as an ambiguous bare-call
|
||||
// collision: extern authors (external C symbols) are excluded from the
|
||||
// bare-call ambiguity verdict, exactly like their `#foreign` twins.
|
||||
// bare-call ambiguity verdict, exactly like their `extern` twins.
|
||||
absval :: (n: i32) -> i32 extern libc "abs";
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
// An `extern LIB "csym"` reference must name something real, exactly like
|
||||
// its `#foreign LIB` twin (example 1620): `nosuchunit` names neither a
|
||||
// its `extern LIB` twin (example 1620): `nosuchunit` names neither a
|
||||
// #library constant nor a named `#import c` unit, so this is a compile-time
|
||||
// diagnostic — the bogus library reference is caught BEFORE the symbol
|
||||
// would silently resolve through whatever image happens to carry it.
|
||||
//
|
||||
// Regression (FFI-linkage Part B): `checkForeignRefs` validated only a
|
||||
// `#foreign` (foreign_expr) library_ref and skipped the `extern` keyword's
|
||||
// `extern` (extern-import shape) library_ref and skipped the `extern` keyword's
|
||||
// `extern_lib`, so a bogus `extern` lib reference compiled silently (the
|
||||
// symbol resolved via the default image and ran). Prerequisite for
|
||||
// migrating the fn-decl `#foreign` path onto `extern`.
|
||||
// migrating the fn-decl `extern` path onto `extern`.
|
||||
#import "modules/std.sx";
|
||||
|
||||
c_abs :: (n: i32) -> i32 extern nosuchunit "abs";
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
// Chained foreign-class method dispatch: `Cls.static().instance(...)`
|
||||
// Chained runtime-class method dispatch: `Cls.static().instance(...)`
|
||||
// resolves the inner call's return type so the outer dispatch's
|
||||
// receiver type is known. Pre-fix this collapsed to i64 in
|
||||
// `inferExprType`, the foreign_class_map lookup missed, and lowering
|
||||
// `inferExprType`, the runtime_class_map lookup missed, and lowering
|
||||
// emitted `error: unresolved 'init'` (or 'initWithWindowScene' etc.)
|
||||
// — see issues/0043 for the chess uikit.sx C4 migration that hit it.
|
||||
//
|
||||
// Two return-type shapes covered: explicit `*ClassName` (alloc here)
|
||||
// and `*Self` (init). Both must propagate through the chain so the
|
||||
// next `.method(...)` finds the foreign-class declaration.
|
||||
// next `.method(...)` finds the runtime-class declaration.
|
||||
|
||||
#import "modules/std.sx";
|
||||
#import "modules/build.sx";
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
// `id`, `Class`, `SEL`, `BOOL` from `modules/ffi/objc.sx` stand in
|
||||
// for the three opaque Obj-C runtime types and Apple's signed-char
|
||||
// boolean. They resolve to `*void` / `i8` at the LLVM layer — no
|
||||
// runtime cost — but make foreign-class and call-site declarations
|
||||
// runtime cost — but make runtime-class and call-site declarations
|
||||
// read closer to Objective-C source.
|
||||
//
|
||||
// `Class(T)` parameterization (phantom T, `#extends`-aware
|
||||
@@ -15,7 +15,7 @@
|
||||
#import "modules/build.sx";
|
||||
#import "modules/ffi/objc.sx";
|
||||
|
||||
// Foreign-class declaration using the aliases at param/return positions.
|
||||
// Runtime-class declaration using the aliases at param/return positions.
|
||||
NSObjectAlias :: #objc_class("NSObject") extern {
|
||||
alloc :: () -> *Self;
|
||||
init :: (self: *Self) -> *Self;
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
// M1.3 — `obj.class` accessor on Obj-C pointers.
|
||||
//
|
||||
// Any Obj-C-class pointer (foreign or sx-defined) can be probed
|
||||
// Any Obj-C-class pointer (runtime or sx-defined) can be probed
|
||||
// for its runtime class object via `obj.class`. Lowers to
|
||||
// `object_getClass(obj)`. Returns `Class` (alias for *void —
|
||||
// parameterized `Class(T)` covariance is M1.1.b).
|
||||
//
|
||||
// Verifies both shapes:
|
||||
// 1. (*SxFoo).class — sx-defined class. Returns the SxFoo Class.
|
||||
// 2. (*NSObject).class — foreign class via stdlib. Returns NSObject's
|
||||
// 2. (*NSObject).class — runtime class via stdlib. Returns NSObject's
|
||||
// Class.
|
||||
|
||||
#import "modules/std.sx";
|
||||
@@ -33,7 +33,7 @@ main :: () -> i32 {
|
||||
expected_f : Class = objc_getClass("SxFoo".ptr);
|
||||
if cls_f != expected_f { print("FAIL: SxFoo.class mismatch\n"); return 1; }
|
||||
|
||||
// foreign class round-trip.
|
||||
// runtime class round-trip.
|
||||
nso := NSObjectFwd.alloc().init();
|
||||
cls_n : Class = nso.class;
|
||||
expected_n : Class = objc_getClass("NSObject".ptr);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// M2.2 (first pass) — `#property` directive on foreign-class
|
||||
// M2.2 (first pass) — `#property` directive on runtime-class
|
||||
// fields synthesizes Obj-C-runtime getter/setter dispatch.
|
||||
//
|
||||
// field: T #property[(modifiers)];
|
||||
@@ -10,7 +10,7 @@
|
||||
// of the field name. Modifiers (strong, weak, copy, readonly, ...)
|
||||
// parse but don't yet drive ARC ops — that's Month 4.
|
||||
//
|
||||
// This slice covers FOREIGN-class properties. sx-defined property
|
||||
// This slice covers RUNTIME-class properties. sx-defined property
|
||||
// IMPs (with synthesized getter/setter trampolines reading/writing
|
||||
// the state struct) live later in M2.2.
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// M2.3 — `#extends ForeignClass` method-resolution chaining.
|
||||
//
|
||||
// When `obj.method()` is called on a foreign-class pointer and
|
||||
// When `obj.method()` is called on a runtime-class pointer and
|
||||
// `method` isn't declared directly on the receiver's class, the
|
||||
// compiler walks the `#extends` chain to find an ancestor that
|
||||
// declared it. The runtime dispatch path is unchanged —
|
||||
@@ -18,7 +18,7 @@ NSObjectBase :: #objc_class("NSObject") extern {
|
||||
hash :: (self: *NSObjectBase) -> u64;
|
||||
}
|
||||
|
||||
// Sx-defined class that extends a foreign one. M1.2 registers
|
||||
// Sx-defined class that extends a runtime one. M1.2 registers
|
||||
// the class at module init; `hash` is reached via the M2.3 chain
|
||||
// walk through NSObjectBase, then dispatched by objc_msgSend.
|
||||
SxThing :: #objc_class("SxThing") {
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
// `xx self` inside a BOOL-returning `#objc_class` method must
|
||||
// resolve to the full receiver pointer at a foreign-class method
|
||||
// resolve to the full receiver pointer at a runtime-class method
|
||||
// call site, not get truncated to i8 by the enclosing function's
|
||||
// BOOL return type. Regression locks in the
|
||||
// `resolveCallParamTypes` fix that threads foreign-class method
|
||||
// `resolveCallParamTypes` fix that threads runtime-class method
|
||||
// param types correctly even when the receiver is a `extern
|
||||
// #objc_class` alias. Every probe round-trips the receiver pointer
|
||||
// — a regression would read only the low byte and the observer
|
||||
@@ -14,7 +14,7 @@
|
||||
|
||||
g_observer : *void = null;
|
||||
|
||||
// Stand-in for NSNotificationCenter — we just need a foreign-class
|
||||
// Stand-in for NSNotificationCenter — we just need a runtime-class
|
||||
// method with several *void args so the call site's arg-target-type
|
||||
// resolution exercises the same path as uikit.sx's keyboard observer.
|
||||
SxIssue44Bus :: #objc_class("NSNotificationCenter") extern {
|
||||
@@ -44,7 +44,7 @@ SxIssue44Foo :: #objc_class("SxIssue44Foo") {
|
||||
// SxAppDelegate-shape: BOOL return + 2 extra *void args. Pre-fix,
|
||||
// the call to addObserver:... would receive `xx this` truncated to
|
||||
// its low byte (because resolveCallParamTypes returned `&.{}` for
|
||||
// foreign-class receivers and `self.target_type` leaked the BOOL
|
||||
// runtime-class receivers and `self.target_type` leaked the BOOL
|
||||
// return type into the call's args).
|
||||
appDelegate_options :: (this: *Self, app: *void, opts: *void) -> BOOL {
|
||||
bus := SxIssue44Bus.defaultCenter();
|
||||
@@ -87,7 +87,7 @@ main :: () -> i32 {
|
||||
print("me: WRONG\n");
|
||||
}
|
||||
|
||||
// The actual repro: BOOL return + foreign-class method call.
|
||||
// The actual repro: BOOL return + runtime-class method call.
|
||||
// Pre-fix: `xx this` truncated to i8, capture_observer receives
|
||||
// (low_byte_of_f) cast back to *void, which won't equal f_void.
|
||||
g_observer = null;
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
NSPoint :: struct { x: f64; y: f64; }
|
||||
|
||||
// 16 B integer aggregate (Apple ARM64 — x0/x1 register pair, coerced
|
||||
// via `[2 x i64]` in our foreign-decl path; same trip-up that
|
||||
// via `[2 x i64]` in our extern-decl path; same trip-up that
|
||||
// issue-0036 surfaced).
|
||||
NSRange :: struct { location: u64; length: u64; }
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
// Register a runtime-built Obj-C class with a method that returns
|
||||
// a fixed `Triple`. The IMP is a plain sx fn (callconv .c) — its
|
||||
// sret-shaped lowering already works (Phase 0.3 fix for plain
|
||||
// `#foreign` returns). The `#objc_call` dispatch side now produces
|
||||
// `extern` returns). The `#objc_call` dispatch side now produces
|
||||
// the matching call shape: `call void @objc_msgSend(ptr sret %slot,
|
||||
// ...)` + load. The two halves must agree on the ABI for the
|
||||
// round-trip to return the right bytes.
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
//
|
||||
// Mirrors JNI's static-dispatch surface (`Alias.new(...)` etc.); the
|
||||
// lowering disambiguates static vs instance by looking at
|
||||
// `method.is_static` on the foreign-class member.
|
||||
// `method.is_static` on the runtime-class member.
|
||||
//
|
||||
// Uses NSObject because the cached class slot is populated by a
|
||||
// constructor at module-load — runtime-created test classes wouldn't
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
// Phase 3.0 (FFI-linkage) — postfix `extern` on an aggregate (`#objc_class`)
|
||||
// is the new spelling of the legacy prefix `#foreign #objc_class` import.
|
||||
// Mirrors 1306's foreign-class chained dispatch with the new syntax:
|
||||
// Name :: #objc_class("X") extern { … } == Name :: #foreign #objc_class("X") { … }
|
||||
// is the new spelling of the legacy prefix `#objc_class(…) extern` import.
|
||||
// Mirrors 1306's runtime-class chained dispatch with the new syntax:
|
||||
// Name :: #objc_class("X") extern { … } == Name :: #objc_class(…) extern("X") { … }
|
||||
//
|
||||
// Red until 3.1 wires the postfix-extern aggregate path through the parser
|
||||
// + lowering (maps `extern` → reference, same as `#foreign`).
|
||||
// + lowering (maps `extern` → reference, same as `extern`).
|
||||
|
||||
#import "modules/std.sx";
|
||||
#import "modules/build.sx";
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// Phase 3 (FFI-linkage) — postfix `export` on an `#objc_class` aggregate, the
|
||||
// explicit spelling for an sx-DEFINED runtime class (define + register). It is
|
||||
// the same lowering as a bare `#objc_class("X") { … }` with no `#foreign`;
|
||||
// the same lowering as a bare `#objc_class("X") { … }` with no `extern`;
|
||||
// `export` just makes the "I define this class" intent explicit (the dual of
|
||||
// `extern` for "I reference an existing class"). Mirrors 1339's defined class.
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// method body item inside a `#jni_class` declaration.
|
||||
//
|
||||
// `name :: (self: *Self, args...) -> Ret;` is the shape — semicolon
|
||||
// terminated (foreign declaration, no body). The 2.1 parser only
|
||||
// terminated (extern declaration, no body). The 2.1 parser only
|
||||
// accepts an empty body; step 2.2 extends `parseJniClassDecl` to
|
||||
// loop over body items and collect method declarations.
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// and `#implements` body items inside a `#jni_class` declaration.
|
||||
//
|
||||
// `#extends Alias;` declares a single-inheritance superclass reference
|
||||
// using the sx-side alias name (not the foreign Java path — that lives
|
||||
// using the sx-side alias name (not the runtime Java path — that lives
|
||||
// in the alias's own `#jni_class(...)` directive arg). `#implements
|
||||
// Alias;` is repeatable and records interface conformance.
|
||||
//
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
// #swift_struct — Swift @frozen value-type binding
|
||||
// #swift_protocol — Swift @objc-bridgeable protocol binding
|
||||
//
|
||||
// Internally the AST collapses into one `foreign_class_decl` node
|
||||
// Internally the AST collapses into one `runtime_class_decl` node
|
||||
// carrying a `runtime` discriminator. Today the parser rejects each
|
||||
// of these because the lexer doesn't recognise the directive name.
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@ g_should_call : bool = false;
|
||||
unused_jni :: (env: *void, act: *Activity) {
|
||||
#jni_env(env) {
|
||||
// Today: this fails — sema doesn't know `Activity` as a type, or
|
||||
// the method dispatch doesn't recognize foreign-class members.
|
||||
// the method dispatch doesn't recognize runtime-class members.
|
||||
win := act.getWindow();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Regression: `obj.method()` foreign-class dispatch with a `float`
|
||||
// Regression: `obj.method()` runtime-class dispatch with a `float`
|
||||
// return type used to silently emit `LLVMGetUndef` because the
|
||||
// `Call<T>Method` switch in `emit_llvm.zig` didn't cover `.f32`.
|
||||
// Combined with multiple such calls inlined as args to a single
|
||||
@@ -8,7 +8,7 @@
|
||||
// `sx_android_push_touch`).
|
||||
//
|
||||
// This test exercises BOTH the `.f32` jdispatch slot AND the
|
||||
// "multiple foreign-class method calls as args to one outer call"
|
||||
// "multiple runtime-class method calls as args to one outer call"
|
||||
// pattern. The bodies are gated behind a runtime-false flag so the
|
||||
// JNI lookups never execute (no JVM in the test runtime), but the
|
||||
// codegen path still has to emit the calls correctly.
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// Phase 3 (FFI-linkage) — postfix `extern` on a `#jni_class` aggregate, the
|
||||
// new spelling of the legacy prefix `#foreign #jni_class` import. Parse-only
|
||||
// on macOS (no JVM at runtime), mirroring 1412's foreign-class reference.
|
||||
// View :: #jni_class("…") extern { … } == View :: #foreign #jni_class("…") { … }
|
||||
// new spelling of the legacy prefix `#jni_class(…) extern` import. Parse-only
|
||||
// on macOS (no JVM at runtime), mirroring 1412's runtime-class reference.
|
||||
// View :: #jni_class("…") extern { … } == View :: #jni_class(…) extern("…") { … }
|
||||
|
||||
#import "modules/std.sx";
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Innermost module: owns the #library and its foreign fn.
|
||||
// Innermost module: owns the #library and its extern fn.
|
||||
#import "modules/std.sx";
|
||||
|
||||
pcaplib :: #library "pcap";
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
=== 15. Foreign ===
|
||||
foreign-rename: 42
|
||||
=== 15. Extern ===
|
||||
extern-rename: 42
|
||||
|
||||
Reference in New Issue
Block a user