Move examples/*.sx and their expected/ snapshots into per-category subfolders (examples/<category>/...). Folder = leading filename token, with ffi-objc/ffi-jni kept whole; filenames are unchanged. The corpus runner and LSP sweep now discover each category's expected/ dir, while issues/ stays flat. Example 1058's repo-root-relative companion import is made file-relative. Path strings embedded in 164 snapshots were regenerated (path-only changes). Test-layout docs in CLAUDE.md updated.
36 lines
1.4 KiB
Plaintext
36 lines
1.4 KiB
Plaintext
// ASM stream — the round trip: sx → asm → sx. A global-asm routine (`_caller`)
|
|
// CALLS BACK into an sx function (`cb`) by its symbol, then returns. For the asm
|
|
// `bl _cb` to resolve, the sx callback needs EXTERNAL LINKAGE and a stable C
|
|
// symbol — that is exactly what `export` provides (it also implies the C ABI, so
|
|
// no hidden context parameter). `abi(.c)` alone is NOT enough: it sets the
|
|
// ABI but leaves the function `internal`, so it is dead-code-eliminated (nothing
|
|
// in the IR references it — the `bl` is opaque to the optimizer) and `_cb` is
|
|
// undefined at link. macOS gives `export "cb"` the symbol `_cb` (leading
|
|
// underscore), which the template references. aarch64-macos-pinned; runs under
|
|
// the JIT here (sx run), ir-only elsewhere.
|
|
|
|
// The sx callback — `export` gives it external linkage + the `_cb` symbol + C ABI.
|
|
cb :: (n: i64) -> i64 export "cb" {
|
|
return n + 1;
|
|
}
|
|
|
|
// A global-asm trampoline that calls back into `cb`. It saves/restores the link
|
|
// register (x30) around the `bl` — it was itself reached via `bl`, so the return
|
|
// address must survive the nested call.
|
|
asm {
|
|
#string ASM
|
|
.global _caller
|
|
_caller:
|
|
stp x29, x30, [sp, #-16]!
|
|
bl _cb // x0 = cb(x0) — back into sx
|
|
ldp x29, x30, [sp], #16
|
|
ret
|
|
ASM,
|
|
};
|
|
|
|
caller :: (n: i64) -> i64 extern;
|
|
|
|
main :: () -> i64 {
|
|
return caller(41); // sx main → asm caller → bl _cb → sx cb → 42
|
|
}
|