@@ -151,27 +151,33 @@ QuickJS's `u32`-to-`u16` truncation, while signed negative-size and
151151decrement-overflow spellings remain hard safety rejections.
152152
153153The whole-image reader uses one heterogeneous frame stack, one ` DataMachine ` ,
154- one ` ObjectArena ` , and one preorder function table across the root and every
155- constant pool. FunctionBytecode records never consume object-reference IDs.
156- Function frames retain linear, source-bound data completions until a consuming
157- whole-image finalizer unwraps the root and every constant by move. Function IDs
158- carry the same non-wrapping machine-source token, are checked against reserved
159- function slots before publication, and cannot be used to index a different
160- image. Aggregate limits independently bound function count, mixed traversal
161- depth, constant-pool entries, locals, closures, code bytes, instruction spans,
162- atom relocations, and debug bytes in addition to the existing per-function,
163- wire, and graph limits. Each function prefix receives the intersection of its
164- per-function cap and the remaining whole-image budget before table allocation
165- or code copying/scanning. The completed ` BytecodeImage ` is deliberately
154+ one ` ObjectArena ` , and preorder function and module tables across the root,
155+ every constant pool, every request-attributes value, and every module function
156+ object. FunctionBytecode and Module records never consume object-reference IDs.
157+ Their frames retain linear, source-bound data completions until a consuming
158+ whole-image finalizer unwraps every nested value by move. Function and Module
159+ IDs carry the same non-wrapping machine-source token, are checked against
160+ reserved slots before publication, and cannot index a different image.
161+ Aggregate limits independently bound function and module counts, mixed
162+ traversal depth, constant-pool entries, locals, closures, code bytes,
163+ instruction spans, atom relocations, debug bytes, and all four module metadata
164+ tables in addition to the per-record, wire, and graph limits. Each function
165+ prefix and each staged module table receives the intersection of its
166+ per-record cap and the remaining whole-image budget before table allocation or
167+ payload copying/scanning. The completed ` BytecodeImage ` is deliberately
166168non-executable: it has no heap materializer, verifier bypass, or evaluation
167169entry point.
168170The matching canonical writer consumes that immutable image through a
169171source-bound authentication plan before exposing any bytes. Decode and encode
170172share the same whole-image totals, remaining-budget intersection, and
171173per-function-versus-aggregate error attribution. The plan rebuilds dynamic
172- atoms in QuickJS first-use order, regenerates opcode atom operands from typed
173- relocations, assigns object-reference IDs in one preorder spanning every
174- constant pool, and never assigns those IDs to FunctionBytecode records.
174+ atoms in QuickJS first-use order, including the request-name/attributes
175+ continuation, regenerates opcode atom operands from typed relocations, assigns
176+ object-reference IDs in one preorder spanning every nested value, and never
177+ assigns those IDs to FunctionBytecode or Module records. Module writes preserve
178+ unknown non-zero export types, normalize boolean bytes, and retain arbitrary
179+ request attributes and function-object values without imposing linker-only
180+ relationships on the archival codec.
175181Ordinary-object writes match ` JS_WriteObjectTag ` by omitting enumerable symbol
176182and private-name properties before their values can affect atoms, traversal,
177183references, or resource accounting. A complete encoded-size proof precedes
@@ -209,24 +215,26 @@ through fresh-runtime read, byte-exact reserialization, resolve, evaluation,
209215and a global ` 42 ` receipt. Its ` JS_WRITE_OBJ_BSWAP ` bytes are identical. A
210216second 283-byte vector records the complete request/attribute, local and
211217indirect export, star export, default/named/namespace import, top-level-await,
212- and FunctionBytecode-body topology without pretending that the Rust archival
213- reader can link or execute it yet.
218+ and FunctionBytecode-body topology. The Rust whole-image reader and canonical
219+ writer now preserve both vectors byte exactly without pretending that the
220+ archival image can link or execute them yet.
214221The data decoder separates preorder identity registration from value
215222completion: every parent/root attachment now uses one completed-subtree
216- delivery path owned by the decode state. Its reference state is now an
217- independent generic ` ObjectArena ` , ready for a whole-image decoder to carry one
218- instance through every recursive constant pool without registering
219- FunctionBytecode records themselves. The data-value and container state machine
223+ delivery path owned by the decode state. Its reference state is an independent
224+ generic ` ObjectArena ` ; the whole-image decoder carries one instance through
225+ constant pools and module children without registering FunctionBytecode or
226+ Module records themselves. The data-value and container state machine
220227is now independently generic over value and property-key carriers as
221228` DataMachine ` /` DataFrame ` . The data-only facade still owns its own header
222229interning, key timing, frame stack, root delivery, and unconditional cursor
223- finalization, and still rejects FunctionBytecode without consuming its payload.
224- The separate whole-image driver carries authenticated function identities
225- through ordinary properties, Arrays, and TemplateObjects while reusing the
226- same budgets and arena; TypedArray, ObjectValue, and Date expose typed failures
227- when such an identity is invalid in their child position. The arena represents
228- incomplete identities with kind-checked pending/ready slots. Source-bound linear node
229- reservations, opaque data frames, and linear completed values prevent stale or
230+ finalization, and still rejects FunctionBytecode and Module without consuming
231+ their payloads. The separate whole-image driver carries authenticated function
232+ and module identities through ordinary properties, Arrays, and TemplateObjects
233+ while reusing the same budgets and arena; TypedArray, ObjectValue, and Date
234+ expose typed failures when such an identity is invalid in their child position.
235+ The arena represents incomplete identities with kind-checked pending/ready
236+ slots. Source-bound linear node reservations, opaque data frames, and linear
237+ completed values prevent stale or
230238cross-machine commits; machine identities never wrap, and raw node values
231239cannot be rebranded as caller-produced opaque values. The value adapter is
232240sealed inside the graph reader, so sibling modules cannot substitute a
@@ -237,12 +245,11 @@ another node.
237245Malicious TypedArray placeholder paths are rejected deterministically instead
238246of reproducing pinned QuickJS's native crashes.
239247The data-only graph still rejects SharedArrayBuffer, FunctionBytecode, and
240- Module. The BytecodeImage reader admits FunctionBytecode but still rejects
241- Module and SharedArrayBuffer, and neither reader is a public binary-object API
242- yet. A module-image model, heap materializer, native-code semantic
243- verifier/translator, public read/write flags, and a public authenticated
244- whole-image facade remain future
245- milestones. In addition,
248+ Module. The BytecodeImage reader admits FunctionBytecode and Module but still
249+ rejects SharedArrayBuffer, and neither reader is a public binary-object API yet.
250+ A heap materializer, native-code semantic verifier/translator, public read/write
251+ flags, and a public authenticated whole-image facade remain future milestones.
252+ In addition,
246253` num-bigint ` lacks fallible construction, so heap materialization, decoder OOM
247254mapping, and allocator fault-injection remain hardening gates before untrusted
248255input admission.
0 commit comments