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
//! JIT-specific heap kinds and allocation types.
//!
//! Contains heap kind constants for JIT-only types (values >= 128),
//! the `JitAlloc<T>` and `UnifiedValue<T>` structs, and allocation helpers.
//!
//! Per ADR-006 §2.7.5, the JIT FFI boundary carries raw `u64` plus a parallel
//! `NativeKind` companion stamped at JIT compile time from the call signature.
//! The `u64` returned by `jit_box` / `unified_box` here is the raw
//! `Box::into_raw(...) as u64` of a `JitAlloc<T>` or `UnifiedValue<T>` heap
//! allocation — there is no tag-bit packing, no payload-mask projection, and
//! no runtime kind discrimination from the bits themselves. Consumers that
//! need a runtime-tier carrier wrap the pair as
//! `KindedSlot::new(ValueSlot::from_raw(bits), kind)` per §2.7.5; consumers
//! that need to read the per-allocation `kind: u16` discriminator (e.g.
//! `read_heap_kind` for matrix/duration/etc. dispatch on the JitAlloc prefix)
//! read it from offset 0 of the allocation directly.
//!
//! `read_heap_kind` reads the `u16` kind discriminator at offset 0 of a
//! `JitAlloc`-prefixed allocation. This is *not* tag-bit dispatch — it reads a
//! field from a heap-resident struct that the producing call placed there.
use HeapKind;
use NativeKind;
// ============================================================================
// JIT-specific heap kinds (values >= 128, outside VM's HeapKind enum range)
// ============================================================================
pub const HK_JIT_FUNCTION: u16 = 128;
pub const HK_JIT_TABLE_REF: u16 = 130;
/// Plain HashMap<String, u64> objects (JIT-only, distinct from TypedObject).
pub const HK_JIT_OBJECT: u16 = 131;
// ============================================================================
// JIT FFI carrier helpers (ADR-006 §2.7.5)
// ============================================================================
/// The canonical JIT-FFI carrier is a `(u64, NativeKind)` pair: raw bits plus
/// a parallel kind companion stamped at JIT compile time from the call
/// signature. Consumers assemble a runtime-tier `KindedSlot` from this pair
/// via `KindedSlot::new(ValueSlot::from_raw(bits), kind)` per §2.7.5/Q7 when
/// crossing into runtime-tier dispatch surfaces.
pub type JitFfiCarrier = ;
/// Build the `NativeKind` companion for a JIT-owned heap allocation whose
/// `JitAlloc` / `UnifiedValue` prefix carries `kind`. JIT-private allocations
/// (`HK_JIT_FUNCTION`, `HK_JIT_TABLE_REF`, `HK_JIT_OBJECT`) and other prefix
/// kinds map to their `HeapKind` counterpart so the §2.7.5 carrier pair can
/// flow into runtime-tier `KindedSlot` dispatch. The mapping is intentionally
/// limited to kinds that have a `HeapKind` variant; sites that need a
/// JIT-only-shape kind on the runtime side surface-and-stop to the W10
/// playbook §5.
// ============================================================================
// JIT Heap Allocation Infrastructure
// ============================================================================
/// Prefix for JIT heap allocations. Stored at offset 0 of every JIT-owned
/// heap value, enabling type discrimination via `read_heap_kind()`.
///
/// Layout: `[kind: u16][_pad: 6 bytes][data: T]` -- data starts at offset 8.
/// Byte offset of `data` within a `JitAlloc<T>`.
pub const JIT_ALLOC_DATA_OFFSET: usize = 8;
// ============================================================================
// Unified Heap Value (refcounted variant of JitAlloc)
// ============================================================================
/// Generic unified heap value with the standard header format.
///
/// Layout: `[kind: u16][flags: u8][_reserved: u8][refcount: AtomicU32][data: T]`
/// Data starts at offset 8, same as `JitAlloc`.
///
/// The `kind: u16` at offset 0 is layout-compatible with `JitAlloc<T>` so
/// `read_heap_kind` works on both shapes uniformly.
/// Allocate a `UnifiedValue<T>` on the heap and return the raw pointer cast
/// to `u64`. Companion `NativeKind` flows through the JIT-emitted call
/// signature per §2.7.5.
/// Read a `&T` from a `UnifiedValue<T>` allocation pointed to by `bits`.
///
/// # Safety
/// `bits` must be a `Box::into_raw`-returned pointer to a live `UnifiedValue<T>`
/// allocation (or, equivalently, a `JitAlloc<T>` — both have `data` at
/// offset 8 with the same `T` layout). The caller's parallel `NativeKind`
/// must be consistent with `T` per §2.7.5.
pub unsafe
/// Read a `&mut T` from a `UnifiedValue<T>` allocation pointed to by `bits`.
///
/// # Safety
/// Same as `unified_unbox`, plus exclusive access must be guaranteed.
pub unsafe
// ============================================================================
// JitAlloc helpers
// ============================================================================
/// Allocate a `JitAlloc<T>` with `kind` prefix on the heap and return the raw
/// pointer cast to `u64`.
///
/// Per §2.7.5 the JIT-FFI boundary carries this `u64` directly alongside a
/// parallel `NativeKind` companion supplied from the call signature; the
/// `kind: u16` field at offset 0 is the per-allocation prefix discriminator
/// readable via `read_heap_kind` (independent of the slot-level `NativeKind`).
/// Read the `kind: u16` discriminator at offset 0 of a `JitAlloc`- or
/// `UnifiedValue`-prefixed allocation.
///
/// # Safety
/// `bits` must be a non-null `Box::into_raw`-returned pointer to a live
/// `JitAlloc<_>` / `UnifiedValue<_>` allocation. The first 2 bytes must be
/// the `kind` prefix.
pub unsafe
/// Get a reference to the data within a `JitAlloc<T>`.
///
/// The returned reference borrows from the heap allocation with an unbounded
/// lifetime. Callers MUST either:
/// - Use the reference only within the current scope (do not store it), OR
/// - Immediately clone/copy the data if it needs to outlive the current call.
///
/// The reference is only valid as long as the `JitAlloc` has not been freed
/// via `jit_drop`. Holding this reference across a `jit_drop` call on the
/// same `bits` value is undefined behavior.
///
/// # Safety
/// - `bits` must be a `Box::into_raw`-returned pointer to a live
/// `JitAlloc<T>`.
/// - The caller must not hold the returned reference past the lifetime of
/// the allocation (i.e., must not use it after `jit_drop` is called).
/// - The pointee must have been allocated as `JitAlloc<T>` (correct type).
pub unsafe
/// Get a mutable reference to the data within a `JitAlloc<T>`.
///
/// Same safety requirements as `jit_unbox`, plus:
/// - The caller must ensure exclusive access (no other references exist).
///
/// # Safety
/// - `bits` must be a `Box::into_raw`-returned pointer to a live
/// `JitAlloc<T>`.
/// - No other references (mutable or shared) to the same allocation may exist.
/// - The caller must not hold the returned reference past the lifetime of
/// the allocation.
pub unsafe
/// Deallocate a `JitAlloc<T>`.
///
/// # Safety
/// Must only be called once per allocation. `bits` must be a
/// `Box::into_raw`-returned pointer to `JitAlloc<T>`.
pub unsafe