1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
//! FFI function reference building.
//!
//! Populates `FFIFuncRefs` with Cranelift `FuncRef` handles for the subset
//! of FFI entry points the v2 JIT codegen pipeline actually references.
//! Historically this builder declared ~240 functions; the V6 cleanup pruned
//! it to the live native-typed surface.
//!
//! ## Route A close (ADR-006 §2.7.14 / W11-jit-new-array)
//!
//! W11-jit-new-array adopted Route A: kinded `Arc<TypedArrayData>`
//! per-element-kind monomorphization. The kind-blind `jit_new_array` /
//! `jit_array_push_elem` symbols (the deleted ValueWord-shape ABI) are
//! no longer referenced from `FFIFuncRefs`. Array allocation routes
//! through the per-kind `v2_array_new_<f64,i64,i32,bool>` allocators and
//! the size-dispatched `v2_array_push` push helper. Consumers that lack
//! a proven element kind surface-and-stop at JIT compile time per the
//! `Route A surface-and-stop` marker in the MIR lowering — the
//! kind-blind fallback would resurrect the deleted UnifiedArray heap
//! layout (§2.7.14 forbidden list).
//!
//! `r!()` keeps the per-key fallback so that any future agent who
//! re-introduces a deleted symbol gets a structured `RuntimeError`
//! at JIT-init time instead of an unhandled `HashMap` index panic.
//! Map-FFI consumers (the `jit_v2_map_*` family) remain on the same
//! Q15-style deferral until W11-jit-carrier-conversion lands.
use super::setup::JITCompiler;
use crate::ffi_refs::FFIFuncRefs;
use cranelift::prelude::*;
use cranelift_module::Module;
impl JITCompiler {
#[inline(always)]
pub(super) fn build_ffi_refs(
&mut self,
builder: &mut FunctionBuilder,
) -> Result<FFIFuncRefs, String> {
// Helper: declare an already-registered FFI function by key. On a
// missing key we return an Err carrying the §2.7.14 marker so the
// caller can propagate a clean RuntimeError instead of panicking
// on `HashMap::index`.
macro_rules! r {
($key:expr) => {{
let key: &str = $key;
match self.ffi_funcs.get(key) {
Some(&func_id) => self.module.declare_func_in_func(func_id, builder.func),
None => {
return Err(format!(
"phase-2c §2.7.14 / W10 jit-playbook §5: JitArray rebuild required \
for JIT execution path — FFI symbol `{}` is not registered. \
The deleted UnifiedArray / JitArray heap layout removed the \
implementations behind several `register_*_symbols` modules \
(array_symbols, arc_symbols, v2 typed-map family). The kinded \
`TypedArray<T>` rebuild (ADR-006 §2.7.14 Q15) re-introduces \
these entries with element/key kinds threaded from the JIT \
call signature per §2.7.5. See \
docs/adr/006-value-and-memory-model.md §2.7.14.",
key
));
}
}
}};
}
Ok(FFIFuncRefs {
// Object / property access
get_prop: r!("jit_get_prop"),
set_prop: r!("jit_set_prop"),
// Call dispatch
call_value: r!("jit_call_value"),
call_method: r!("jit_call_method"),
// Arrays
//
// Route A (ADR-006 §2.7.14 / W11-jit-new-array close): the
// kind-blind `jit_new_array` / `jit_array_push_elem` symbols are
// deleted. Allocation routes through `v2_array_new_<kind>`
// (registered below) per the producing call signature's element
// kind; push routes through the kinded `v2_array_push`
// dispatcher. Consumers that lack a kind source surface-and-stop
// at JIT compile time per §2.7.5.
//
// Kinded print entries (W11-jit-new-array scalar arms +
// W12-jit-print-heap-arm-classification heap arms). The
// kind-blind `r!("jit_print")` lookup DELETED in Round 8A
// reopen (2026-05-13).
print_i64: r!("jit_print_i64"),
print_u64: r!("jit_print_u64"),
print_f64: r!("jit_print_f64"),
print_bool: r!("jit_print_bool"),
// W12-jit-print-heap-arm-classification (Phase 3 cluster-0
// Round 8A, 2026-05-13): heap-arm kinded print entries —
// ADR-006 §2.7.5 stamp-at-compile-time. The MIR-side
// Call-terminator dispatch in `mir_compiler/terminators.rs`
// routes the operand's `NativeKind` to the matching FuncRef
// (`String` → `print_str`, `Ptr(HeapKind::TypedObject)` →
// `print_typed_object`, `Ptr(HeapKind::Option)` →
// `print_option`, `Ptr(HeapKind::Result)` → `print_result`).
// Each entry takes `(ctx_ptr, bits)` so the FFI body can
// resolve the type schema registry for TypedObject field-
// name rendering and route through the canonical VM-side
// `ValueFormatter::format_kinded`.
print_str: r!("jit_print_str"),
print_typed_object: r!("jit_print_typed_object"),
print_option: r!("jit_print_option"),
print_result: r!("jit_print_result"),
// Phase 3 cluster-2 Round 3 cw-D-fam12 (2026-05-16): Scalar
// Char + Concurrency Mutex/Atomic/Lazy/Channel kinded print
// entries. ADR-006 §2.7.5 stamp-at-compile-time + §2.7.25
// concurrency-primitive printing convention. The MIR-side
// Call-terminator dispatch routes the operand's `NativeKind`
// to the matching FuncRef.
print_char: r!("jit_print_char"),
print_mutex: r!("jit_print_mutex"),
print_atomic: r!("jit_print_atomic"),
print_lazy: r!("jit_print_lazy"),
print_channel: r!("jit_print_channel"),
// Phase 3 cluster-2 Round 4 cw-D-fam3 (2026-05-16):
// Collection family kinded print entries. ADR-006 §2.7.5
// stamp-at-compile-time + §2.7.5.B Family 3 amendment
// extension. The MIR-side Call-terminator dispatch routes
// the operand's `NativeKind` to the matching FuncRef
// (`Ptr(HeapKind::HashMap)` → `print_hashmap`, etc.).
// ADR-006 §2.7.5.B 2026-05-16
print_hashmap: r!("jit_print_hashmap"),
print_hashset: r!("jit_print_hashset"),
print_deque: r!("jit_print_deque"),
print_priority_queue: r!("jit_print_priority_queue"),
print_range: r!("jit_print_range"),
print_iterator: r!("jit_print_iterator"),
// W11-fup-C (Phase 3d, 2026-05-18): v2-raw TypedArray<T> kinded
// print entry (ADR-006 §2.7.5). The MIR-side Call-terminator
// dispatch routes operands with stamped
// `NativeKind::Ptr(HeapKind::TypedArray)` to this FuncRef.
print_typed_array: r!("jit_print_typed_array"),
// Closure construction
make_closure: r!("jit_make_closure"),
finalize_heap_closure: r!("jit_finalize_heap_closure"),
// Track A.1D: OwnedMutable capture cell allocator.
alloc_owned_mut_cell: r!("jit_alloc_owned_mut_cell"),
// Track A.1E: Shared capture FFI helpers.
arc_shared_retain: r!("jit_arc_shared_retain"),
shared_lock_contended: r!("jit_shared_lock_contended"),
shared_unlock_contended: r!("jit_shared_unlock_contended"),
// Session 1 Commit 3: outer-scope Shared-cell lifecycle.
alloc_shared_cell: r!("jit_alloc_shared_cell"),
arc_shared_release: r!("jit_arc_shared_release"),
// Wave C.1: per-FieldKind closure-cell FFI helpers (D1 ABI).
// OwnedMutable allocators
alloc_owned_mut_cell_i64: r!("jit_alloc_owned_mut_cell_i64"),
alloc_owned_mut_cell_u64: r!("jit_alloc_owned_mut_cell_u64"),
alloc_owned_mut_cell_f64: r!("jit_alloc_owned_mut_cell_f64"),
alloc_owned_mut_cell_i32: r!("jit_alloc_owned_mut_cell_i32"),
alloc_owned_mut_cell_u32: r!("jit_alloc_owned_mut_cell_u32"),
alloc_owned_mut_cell_i16: r!("jit_alloc_owned_mut_cell_i16"),
alloc_owned_mut_cell_u16: r!("jit_alloc_owned_mut_cell_u16"),
alloc_owned_mut_cell_i8: r!("jit_alloc_owned_mut_cell_i8"),
alloc_owned_mut_cell_u8: r!("jit_alloc_owned_mut_cell_u8"),
alloc_owned_mut_cell_bool: r!("jit_alloc_owned_mut_cell_bool"),
alloc_owned_mut_cell_ptr: r!("jit_alloc_owned_mut_cell_ptr"),
// OwnedMutable readers
read_owned_mut_cell_i64: r!("jit_read_owned_mut_cell_i64"),
read_owned_mut_cell_u64: r!("jit_read_owned_mut_cell_u64"),
read_owned_mut_cell_f64: r!("jit_read_owned_mut_cell_f64"),
read_owned_mut_cell_i32: r!("jit_read_owned_mut_cell_i32"),
read_owned_mut_cell_u32: r!("jit_read_owned_mut_cell_u32"),
read_owned_mut_cell_i16: r!("jit_read_owned_mut_cell_i16"),
read_owned_mut_cell_u16: r!("jit_read_owned_mut_cell_u16"),
read_owned_mut_cell_i8: r!("jit_read_owned_mut_cell_i8"),
read_owned_mut_cell_u8: r!("jit_read_owned_mut_cell_u8"),
read_owned_mut_cell_bool: r!("jit_read_owned_mut_cell_bool"),
read_owned_mut_cell_ptr: r!("jit_read_owned_mut_cell_ptr"),
// OwnedMutable writers
write_owned_mut_cell_i64: r!("jit_write_owned_mut_cell_i64"),
write_owned_mut_cell_u64: r!("jit_write_owned_mut_cell_u64"),
write_owned_mut_cell_f64: r!("jit_write_owned_mut_cell_f64"),
write_owned_mut_cell_i32: r!("jit_write_owned_mut_cell_i32"),
write_owned_mut_cell_u32: r!("jit_write_owned_mut_cell_u32"),
write_owned_mut_cell_i16: r!("jit_write_owned_mut_cell_i16"),
write_owned_mut_cell_u16: r!("jit_write_owned_mut_cell_u16"),
write_owned_mut_cell_i8: r!("jit_write_owned_mut_cell_i8"),
write_owned_mut_cell_u8: r!("jit_write_owned_mut_cell_u8"),
write_owned_mut_cell_bool: r!("jit_write_owned_mut_cell_bool"),
write_owned_mut_cell_ptr: r!("jit_write_owned_mut_cell_ptr"),
// Shared readers
read_shared_cell_i64: r!("jit_read_shared_cell_i64"),
read_shared_cell_u64: r!("jit_read_shared_cell_u64"),
read_shared_cell_f64: r!("jit_read_shared_cell_f64"),
read_shared_cell_i32: r!("jit_read_shared_cell_i32"),
read_shared_cell_u32: r!("jit_read_shared_cell_u32"),
read_shared_cell_i16: r!("jit_read_shared_cell_i16"),
read_shared_cell_u16: r!("jit_read_shared_cell_u16"),
read_shared_cell_i8: r!("jit_read_shared_cell_i8"),
read_shared_cell_u8: r!("jit_read_shared_cell_u8"),
read_shared_cell_bool: r!("jit_read_shared_cell_bool"),
read_shared_cell_ptr: r!("jit_read_shared_cell_ptr"),
// Shared writers
write_shared_cell_i64: r!("jit_write_shared_cell_i64"),
write_shared_cell_u64: r!("jit_write_shared_cell_u64"),
write_shared_cell_f64: r!("jit_write_shared_cell_f64"),
write_shared_cell_i32: r!("jit_write_shared_cell_i32"),
write_shared_cell_u32: r!("jit_write_shared_cell_u32"),
write_shared_cell_i16: r!("jit_write_shared_cell_i16"),
write_shared_cell_u16: r!("jit_write_shared_cell_u16"),
write_shared_cell_i8: r!("jit_write_shared_cell_i8"),
write_shared_cell_u8: r!("jit_write_shared_cell_u8"),
write_shared_cell_bool: r!("jit_write_shared_cell_bool"),
write_shared_cell_ptr: r!("jit_write_shared_cell_ptr"),
// TypedObject allocation + field store
typed_object_alloc: r!("jit_typed_object_alloc"),
typed_object_set_field: r!("jit_typed_object_set_field"),
// Arc refcount primitives
arc_retain: r!("jit_arc_retain"),
arc_release: r!("jit_arc_release"),
// r5c-2-β-δ-(α): v2-raw TypedArray<T> retain / release.
v2_typed_array_retain: r!("jit_v2_typed_array_retain"),
v2_typed_array_release: r!("jit_v2_typed_array_release"),
// v2 typed-array allocators
v2_array_new_f64: r!("jit_v2_array_new_f64"),
v2_array_new_i64: r!("jit_v2_array_new_i64"),
v2_array_new_i32: r!("jit_v2_array_new_i32"),
v2_array_new_bool: r!("jit_v2_array_new_bool"),
// ckpt-6-prime Group X JIT FFI String/Decimal BUILD (2026-05-15)
v2_array_new_string: r!("jit_new_typed_array_string"),
v2_array_new_decimal: r!("jit_new_typed_array_decimal"),
// Phase 4b Round 4 W16.2-A op_new_array-typed-object-element (2026-05-18).
v2_array_new_typed_object: r!("jit_new_typed_array_typed_object"),
// v2 typed-array push (generic dispatcher — see ffi_refs.rs)
v2_array_push: r!("jit_v2_array_push"),
// v2 struct allocator
v2_alloc_struct: r!("jit_v2_alloc_struct"),
// v2 SIMD reductions
v2_array_sum_f64: r!("jit_v2_array_sum_f64"),
v2_array_sum_i64: r!("jit_v2_array_sum_i64"),
v2_array_min_f64: r!("jit_v2_array_min_f64"),
v2_array_max_f64: r!("jit_v2_array_max_f64"),
v2_array_mean_f64: r!("jit_v2_array_mean_f64"),
v2_array_sum_squares_f64: r!("jit_v2_array_sum_squares_f64"),
// v2 SIMD scalar element-wise ops
v2_array_scale_f64: r!("jit_v2_array_scale_f64"),
v2_array_add_scalar_f64: r!("jit_v2_array_add_scalar_f64"),
// v2 SIMD binary element-wise ops
v2_array_add_f64: r!("jit_v2_array_add_f64"),
v2_array_mul_f64: r!("jit_v2_array_mul_f64"),
// F5.a/F5.b: string `+` FFI (used by MIR BinaryOp::Add on
// NativeKind::String operands, incl. f-string desugared chains).
string_concat: r!("jit_string_concat"),
// W11-fup-A (Phase 3d, 2026-05-18): typed-pow FFI entry points
// for the MIR `BinOp::Pow` JIT codegen path. Native f64 and
// i64 ABI; symbols registered in `ffi_symbols/math_symbols.rs`.
pow_f64: r!("jit_pow_f64"),
pow_i64: r!("jit_pow_i64"),
// W15.2-LANG-6 jit-math-nan-poisoning (Phase 4b Round 2,
// 2026-05-18): typed-f64 math FuncRefs for the JIT Call-
// terminator interception of bare-name math builtins
// (`MirConstant::Function("sqrt"|...)` leaked into MIR by
// `crates/shape-vm/src/mir/lowering/expr.rs:2003`). Symbols
// registered + declared in `ffi_symbols/math_symbols.rs`.
sqrt_f64: r!("jit_sqrt_f64"),
abs_f64: r!("jit_abs_f64"),
floor_f64: r!("jit_floor_f64"),
ceil_f64: r!("jit_ceil_f64"),
round_f64: r!("jit_round_f64"),
sin_f64: r!("jit_sin_f64"),
cos_f64: r!("jit_cos_f64"),
tan_f64: r!("jit_tan_f64"),
asin_f64: r!("jit_asin_f64"),
acos_f64: r!("jit_acos_f64"),
atan_f64: r!("jit_atan_f64"),
exp_f64: r!("jit_exp_f64"),
ln_f64: r!("jit_ln_f64"),
// ADR-006 §2.7.5 — kinded EnumStore producers
// (W12-jit-aggregate-non-array, 2026-05-12). Dispatched from
// the EnumStore consumer based on the MIR statement's
// `variant_name` field.
make_ok: r!("jit_make_ok"),
make_err: r!("jit_make_err"),
make_some: r!("jit_make_some"),
// ADR-006 §2.7.17 / Q18 — Arc-shape Result/Option producers +
// accessors (W12-jit-result-option-trinity, Phase 3 cluster-0
// Round 7A, 2026-05-12). These are the trinity's strict-typed
// EnumStore producers + match-codegen consumers — the legacy
// `make_ok` / `make_err` / `make_some` NaN-box family is NOT
// referenced by the new trinity codegen path (those FuncRefs
// remain for the JIT↔VM trampoline conversion in
// ffi/conversion.rs only).
v2_make_result_ok: r!("jit_v2_make_result_ok"),
v2_make_result_err: r!("jit_v2_make_result_err"),
v2_make_option_some: r!("jit_v2_make_option_some"),
v2_make_option_none: r!("jit_v2_make_option_none"),
arc_result_is_ok: r!("jit_arc_result_is_ok"),
arc_result_is_err: r!("jit_arc_result_is_err"),
arc_result_payload: r!("jit_arc_result_payload"),
arc_option_is_some: r!("jit_arc_option_is_some"),
arc_option_is_none: r!("jit_arc_option_is_none"),
arc_option_payload: r!("jit_arc_option_payload"),
arc_result_retain: r!("jit_arc_result_retain"),
arc_result_release: r!("jit_arc_result_release"),
arc_option_retain: r!("jit_arc_option_retain"),
arc_option_release: r!("jit_arc_option_release"),
// ADR-006 §2.7.5 / §2.7.25 — Typed-Arc collection allocators
// (W12-jit-collection-arc-ffi-ctors-and-refcount, Phase 3
// cluster-0 Round 9 / 8B.1, 2026-05-13). Bodies in
// `ffi/v2/collection_arc.rs` — each produces
// `Arc::into_raw(Arc<XData>) as u64`. The MIR EnumStore
// consumer for collection ctors dispatches here (Round 10
// / 8B.2 work — until then these are inert at the program
// surface but the FuncRefs are populated so consumers can
// pre-resolve them).
v2_make_hashset: r!("jit_v2_make_hashset"),
v2_make_hashmap: r!("jit_v2_make_hashmap"),
v2_make_deque: r!("jit_v2_make_deque"),
v2_make_priorityqueue: r!("jit_v2_make_priorityqueue"),
v2_make_channel: r!("jit_v2_make_channel"),
v2_make_atomic: r!("jit_v2_make_atomic"),
v2_make_lazy: r!("jit_v2_make_lazy"),
v2_make_mutex: r!("jit_v2_make_mutex"),
// ADR-006 §2.7.5 / §2.7.17 — Per-HeapKind kinded retain/
// release for the 8 typed-Arc collection carriers. The
// ownership-aware codegen path in `mir_compiler/ownership.rs`
// (`retain_func_for_place` / `release_func_for_place`)
// dispatches per slot's proven `NativeKind::Ptr(HeapKind::*)`
// to the matching FuncRef. The legacy `arc_retain` /
// `arc_release` fallback stays for kinds NOT in the
// typed-Arc family (Array / TypedObject / etc. still use
// the `UnifiedValue<T>` HeapHeader-refcount shape).
arc_hashset_retain: r!("jit_arc_hashset_retain"),
arc_hashset_release: r!("jit_arc_hashset_release"),
arc_hashmap_retain: r!("jit_arc_hashmap_retain"),
arc_hashmap_release: r!("jit_arc_hashmap_release"),
arc_deque_retain: r!("jit_arc_deque_retain"),
arc_deque_release: r!("jit_arc_deque_release"),
arc_priorityqueue_retain: r!("jit_arc_priorityqueue_retain"),
arc_priorityqueue_release: r!("jit_arc_priorityqueue_release"),
arc_channel_retain: r!("jit_arc_channel_retain"),
arc_channel_release: r!("jit_arc_channel_release"),
arc_mutex_retain: r!("jit_arc_mutex_retain"),
arc_mutex_release: r!("jit_arc_mutex_release"),
arc_atomic_retain: r!("jit_arc_atomic_retain"),
arc_atomic_release: r!("jit_arc_atomic_release"),
arc_lazy_retain: r!("jit_arc_lazy_retain"),
arc_lazy_release: r!("jit_arc_lazy_release"),
// ADR-006 §2.7.5 — `Arc<String>` strict-typed carrier
// retain/release (W12-jit-string-carrier-unification, Phase 3
// cluster-0 Round 12 T2/T3, 2026-05-13). Bodies in
// `ffi/string.rs`. Refcount discipline at slots whose
// `NativeKind` is `String` dispatches here per the
// `ownership::retain_func_for_place` / `release_func_for_place`
// String arm.
arc_string_retain: r!("jit_arc_string_retain"),
arc_string_release: r!("jit_arc_string_release"),
// W15.2-LANG-4 jit-filter-predicate close (2026-05-18).
// ADR-006 §2.7.11/Q12 `Arc<HeapValue::ClosureRaw>` strict-
// typed closure carrier retain/release. Bodies in
// `ffi/object/closure.rs`. Refcount discipline at slots
// whose `NativeKind` is `Ptr(HeapKind::Closure)` dispatches
// here per the `ownership::retain_func_for_place` /
// `release_func_for_place` Closure arm.
arc_closure_retain: r!("jit_arc_closure_retain"),
arc_closure_release: r!("jit_arc_closure_release"),
// v2 typed HashMap<string, ...>
//
// SURFACE (ADR-006 §2.7.14 Q15 / W11-jit-carrier-conversion):
// gated on the kinded `Arc<HashMapData>` + `KindedSlot` rebuild;
// FuncRef slots and r!() lookups are deleted in lockstep with
// the v2_typed_map call-site surface-and-stop.
})
}
}