Skip to content

Commit 0885c4e

Browse files
committed
feat(binary-object): admit trusted scalar scripts
1 parent 7391d2b commit 0885c4e

16 files changed

Lines changed: 2163 additions & 52 deletions

File tree

README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,10 @@ The file loader follows QuickJS policy: `.json` is strict JSON,
5252
file without that attribute remains a JavaScript module. Main files and
5353
dependencies are read as explicitly sized byte buffers.
5454

55+
Rust embedders can also use `Context::read_trusted_scalar_script` for the
56+
current verified subset of QuickJS 2026-06-04 BC5 Script bytecode. It is a
57+
narrow pre-parity API, not a general untrusted-bytecode loader.
58+
5559
## Status
5660

5761
- [Current implementation status](docs/status.md)

dev-support/quickjs-c-oracles.tsv

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ function-bytecode-nested-closure function-bytecode tests/fixtures/function_bytec
77
function-bytecode-non-string-properties function-bytecode tests/fixtures/function_bytecode_non_string_properties.c 3d15e8f1f88a08c6fa4e36dc07d53a6e8c23c1ca6151468140255115325a7dda tests/fixtures/function_bytecode_non_string_properties.quickjs-2026-06-04.txt db6592def2d6533912f15e56b6498ff70a4d32cd69ac0f96b774653e7ab99e78 enumerable symbol and private property filtering before value traversal in bytecode writes
88
function-bytecode-reference-boundary function-bytecode tests/fixtures/function_bytecode_reference_boundary.c fd31889a9404350cec51d2e6dd16ab886475cb46067296ab8d516fa6446e5116 tests/fixtures/function_bytecode_reference_boundary.quickjs-2026-06-04.txt 392c993f7f48103e3cb4a7b7140c1fe5fec554e75262f79d5a7bbf99157251ea shared object-reference table across nested function constant-pool boundaries
99
function-bytecode-sab-reference function-bytecode tests/fixtures/function_bytecode_sab_reference.c 548f92e81c14f0ceb6e75ba11a2d09c161b8d2f19e39d7e360d32aff15fa887c tests/fixtures/function_bytecode_sab_reference.quickjs-2026-06-04.txt 7b8f31ef9d6e7b9b8720ebc5b34f9b0f01a147dced381e219d8245b8160a6366 whole-image FunctionBytecode, TypedArray, and SharedArrayBuffer reference and redacted side-table contract
10-
function-bytecode-wire function-bytecode tests/fixtures/function_bytecode_wire.c c3f3d0907093a3d9285b3cf4989567adbbeee76005336f880decc160a95b6630 tests/fixtures/function_bytecode_wire.quickjs-2026-06-04.txt f6f4d9650a37529815e7228a5438cb1051190961b2b3771b0465e0f7eb26dfb8 stripped return-42 function bytecode wire and fresh-runtime evaluation contract
10+
function-bytecode-wire function-bytecode tests/fixtures/function_bytecode_wire.c e24109dd0409795227a569266123dc86cec1c5ef3ee0f566f55cd2f976bae502 tests/fixtures/function_bytecode_wire.quickjs-2026-06-04.txt 47b96b15904b1ede1c9e853cb74d66ee63cabd0e14053100ce93c1c3292c6047 stripped return-42 function bytecode wire, compatible scope metadata, fresh-runtime evaluation, and malformed ULEB, atom, string, bytecode length, ArrayBuffer, and TypedArray read diagnostics
1111
function-bytecode-writer-flags function-bytecode tests/fixtures/function_bytecode_writer_flags.c d5494b0bce19e530d8c6f2a8b5a8ae20476e17b03c34335ae58c56544ff367d1 tests/fixtures/function_bytecode_writer_flags.quickjs-2026-06-04.txt 95665dc04cb18780505d0a8c592d8ce66b601c77049aa9eb7f1925b1fda73d95 keep-source, strip-source, and strip-debug nested function bytecode writer and BSWAP identity contract
1212
import-attributes module tests/fixtures/module_import_attributes_loader2.c d243a74b07d59d60f4d811c66447087547a43c5541baf60eb48b7d4c337e2863 tests/fixtures/module_import_attributes_loader2.quickjs-2026-06-04.txt 31121aad6e62055f7389392c83c09efaa225fa126b27bb9c08db6d8daca41e28 loader2 import-attributes contract
1313
import-meta module tests/fixtures/module_import_meta_host.c e695e55164c6c07440e5f05135f14fe959367836e5380f7fc245d409130b503d tests/fixtures/module_import_meta_host.quickjs-2026-06-04.txt 928013ebd2080271e69a56516d5dd024e76cdd94fdb9bdc8fc27c08ece0efc8f canonical host import.meta contract

docs/status.md

Lines changed: 37 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,10 @@ The exact profile, inputs, summary, line counts, and report hashes live in
6262
`import.meta` `url`/`main`; qjs-compatible side-effect-free structured
6363
`print`/`console.log` output with byte-exact WTF-8 String transport; plus a
6464
Rust/WASM browser playground
65+
- a narrow trusted-bytecode Rust API for the pinned BC5 branch-free scalar
66+
Script cohort; it completes the compatible whole-image read, translates an
67+
inert DTO to typed Rust instructions, and enters the ordinary verifier and
68+
transactional publication path before execution
6569

6670
The public API and Test262 runner now report the same engine diagnostics.
6771
Detached public bytecode/VM execution has been retired, the Test262 runner
@@ -199,14 +203,22 @@ Ordinary-object writes match `JS_WriteObjectTag` by omitting enumerable symbol
199203
and private-name properties before their values can affect atoms, traversal,
200204
references, or resource accounting. A complete encoded-size proof precedes
201205
the final bounded little-endian emission; failed authentication never returns
202-
a partial buffer. This remains an internal archival codec, not an execution or
203-
public bytecode-loading path.
206+
a partial buffer. The canonical writer and general whole-image model remain
207+
internal archival facilities rather than a general public bytecode surface.
208+
The one public read path is deliberately narrower: it accepts only a stripped
209+
Script root with one completion local and the release-pinned
210+
`push_i8; set_loc0; return` family, after the entire image has decoded in
211+
QuickJS-compatible mode.
204212
The decoder and writer planner are physically split into shared-driver,
205213
Function, and Module files while retaining one frame/task stack and one set of
206214
atom, reference, preorder, and budget state. All binary-object submodules are
207215
private. A self-testing architecture gate rejects VM/compiler and executable
208216
bytecode dependencies, runtime consumers, crate-surface exports, and widened
209-
module visibility before fast CI or the parity slice can proceed.
217+
module visibility before fast CI or the parity slice can proceed. Its sole
218+
runtime-facing facade exposes an inert scalar draft to one sibling bridge; a
219+
self-testing consumer gate rejects any second reader, raw image leak, heap/VM
220+
dependency, verifier bypass, direct bytecode root construction, or alternate
221+
publication path.
210222
The same gate rejects shared-memory runtime types, `unsafe`, raw pointers,
211223
`NonNull`, and native raw-ownership bridges anywhere in the archival codec.
212224
An authenticated SharedArrayBuffer C oracle pins writer side-table order,
@@ -216,7 +228,17 @@ tests consume those three exact shapes with non-zero typed tokens and prove
216228
that changing the native token leaves the completed archive identical.
217229
An authenticated public-C-API oracle pins stripped `42;` as a 25-byte
218230
BC5 vector, reads it in a fresh QuickJS runtime, evaluates it to 42, and gates
219-
the Rust prefix codec against the exact bytes. A second authenticated 110-byte
231+
both the Rust codec and trusted scalar execution path against the exact bytes.
232+
The same oracle pins compatible 32-bit `scope_next` wrapping, exact
233+
`SyntaxError` diagnostics for wrong-version, truncated, malformed-ULEB, and
234+
invalid-atom inputs, `InternalError` for an oversized string declaration and
235+
the allocation failure from a signed high-bit bytecode length, and the
236+
`TypeError`/`RangeError` branches for malformed ArrayBuffer and
237+
TypedArray layouts. Rust maps these authenticated reader branches without
238+
collapsing them into one error class; compatible high-bit metadata that
239+
QuickJS accepts but this cohort cannot model, including Module indices,
240+
remains non-JavaScript `Unsupported` with no pending exception. A second
241+
authenticated 110-byte
220242
vector pins a root-to-outer-to-inner constant-pool chain, the captured closure
221243
descriptor, and fresh-runtime evaluation to 42. A third authenticated 75-byte
222244
reference vector proves that neither the outer nor nested FunctionBytecode
@@ -241,8 +263,10 @@ and retains the function code, view/backing identity, reference numbering, and
241263
one backing descriptor in a single `ArchivedBytecodeImage`. Additional
242264
whole-image vectors prove that two complete SAB records with the same token
243265
share one archive backing while distinct tokens retain two ordered backings.
244-
Rust does not execute that archived function; the return-42 receipt remains
245-
the pinned QuickJS C-oracle result. Authenticated negative vectors also pin
266+
Rust does not execute the transport archive's embedded function; its return-42
267+
receipt remains the pinned QuickJS C-oracle result. The separate ordinary
268+
25-byte scalar image is now translated and executed by Rust through the full
269+
verified publication path. Authenticated negative vectors also pin
246270
QuickJS's
247271
three diagnostic classes when FunctionBytecode appears as the
248272
child of ObjectValue, Date, or
@@ -296,14 +320,15 @@ FunctionBytecode, and Module before their payloads; only its inseparable
296320
transport-aware counterpart admits SAB into `ArchivedWireGraph`. The ordinary
297321
`BytecodeImage` reader still rejects SharedArrayBuffer, while its separate
298322
transport-aware counterpart atomically binds the completed image to the
299-
authenticated occurrence table as `ArchivedBytecodeImage`. Neither archive
300-
exposes a bare graph/image or descriptor-table split, and neither reader is a
301-
public binary-object API. The canonical image writer continues to reject every
323+
authenticated occurrence table as `ArchivedBytecodeImage`. Neither transport
324+
archive exposes a bare graph/image or descriptor-table split, and neither
325+
transport reader is a public binary-object API. The scalar API cannot consume
326+
or expose either archive. The canonical image writer continues to reject every
302327
reachable archived SAB because there is no live backing capability, ownership
303328
callback bridge, or occurrence-side-table output; this milestone is decode,
304-
not encode or round-trip support. A heap materializer, native-code semantic
305-
verifier/translator, public read/write flags, and a public authenticated
306-
whole-image host bridge remain future milestones.
329+
not encode or round-trip support. A general heap materializer, broader
330+
native-code translation, public QuickJS-compatible read/write flags, and a
331+
public authenticated whole-image host bridge remain future milestones.
307332
In addition,
308333
`num-bigint` lacks fallible construction, so heap materialization, decoder OOM
309334
mapping, and allocator fault-injection remain hardening gates before untrusted

0 commit comments

Comments
 (0)