shape_jit/ffi/references.rs
1// Heap allocation audit (PR-9 V8 Gap Closure):
2// Category A (NaN-boxed returns): 0 sites
3// Category B (intermediate/consumed): 0 sites
4// Category C (heap islands): 0 sites
5// Notes: No jit_box calls. Mutates existing array in-place via jit_unbox_mut.
6//!
7//! Reference FFI Functions for JIT
8//!
9//! Provides the SetIndexRef operation which mutates an array element
10//! in-place through a reference pointer. This is called from JIT code
11//! when a `&array[index] = value` pattern is compiled.
12
13use super::super::jit_array::JitArray;
14use super::super::nan_boxing::*;
15
16/// Set an array element through a reference pointer.
17///
18/// # Arguments
19/// * `ref_ptr` - Pointer to the memory slot holding the NaN-boxed array value
20/// * `index` - NaN-boxed index value (f64 representing integer index)
21/// * `value` - NaN-boxed value to store at arr[index]
22///
23/// # Safety
24/// `ref_ptr` must point to a valid u64 memory location containing a NaN-boxed array.
25#[unsafe(no_mangle)]
26pub extern "C" fn jit_set_index_ref(ref_ptr: *mut u64, index: u64, value: u64) {
27 if ref_ptr.is_null() {
28 return;
29 }
30
31 let array_bits = unsafe { *ref_ptr };
32
33 // Verify it's an array using the unified heap kind check
34 if !is_heap_kind(array_bits, HK_ARRAY) {
35 return;
36 }
37
38 let arr = unsafe { jit_unbox_mut::<JitArray>(array_bits) };
39
40 // Convert index from NaN-boxed f64 to integer
41 let idx = if is_number(index) {
42 unbox_number(index) as i64
43 } else {
44 return;
45 };
46
47 let len = arr.len() as i64;
48 let actual = if idx < 0 { len + idx } else { idx };
49
50 if actual < 0 || actual as usize >= arr.len() {
51 // Out of bounds - extend array if positive index
52 if actual >= 0 {
53 let target = actual as usize;
54 while arr.len() <= target {
55 arr.push(TAG_NULL);
56 }
57 super::gc::jit_write_barrier(TAG_NULL, value);
58 arr.set_boxed(target, value);
59 }
60 return;
61 }
62
63 super::gc::jit_write_barrier(arr[actual as usize], value);
64 arr.set_boxed(actual as usize, value);
65}