mirror of
https://github.com/vercel-labs/scriptc.git
synced 2026-11-03 07:54:40 +08:00
`JSON.parse(text) as T` used to build a checked-dynamic ScrDyn tree, copy it into the native layout with the generated dynCheck builder, and then dispose the tree. Together that was about 68% of json-records. For record/array targets with number, boolean and string leaves, the backend now emits a ScrJsonSchema (field offsets in declaration order, constructors, releases) and a wrapper. The wrapper calls the new scr_json_parse_schema, a one-pass parser that writes directly into native records and arrays. Whenever it declines (syntax errors anywhere, kind mismatches, missing or duplicate declared keys, excess depth) it releases its partial value without throwing, and the wrapper reruns the unchanged scr_json_parse + dynCheck route. Every error message and position stays byte-identical. The lexer helpers are shared through a quiet mode and a factored number scanner, so values decode bit-identically. Tests: new differential corpus program json-typed-parse-direct.ts; a dyncheck harness case comparing typed and untyped error messages through the fused path; white-box C tests for accept/decline and leak-freedom in scr_json.test.c; an LLVM emission test (64-bit and wasm32). Linux (sandbox x86_64, runs=15): | workload | baseline ms | candidate ms | change | 95% CI | verdict | size | node ms | candidate/node | | --- | ---: | ---: | ---: | --- | --- | ---: | ---: | ---: | | json-records | 713.2 | 249.3 | -65.0% | -65.6% .. -64.1% | faster | +2.2% | 439.04 | 0.57x | | regex-logs | 350.8 | 353.7 | +0.8% | -0.9% .. +2.3% | neutral | +0.0% | 238.42 | 1.48x | | ast-interp | 379.1 | 376.8 | -0.6% | -1.8% .. +0.4% | neutral | +0.0% | 227.45 | 1.66x | | records-sort | 1200.5 | 1207.8 | +0.6% | -2.4% .. +5.7% | neutral | +0.0% | 232.17 | 5.20x | | template-render | 248.3 | 248.1 | -0.1% | -2.3% .. +1.0% | neutral | +0.0% | 202.16 | 1.23x | | functional-pipeline | 402.0 | 395.3 | -1.6% | -3.8% .. +0.5% | neutral | +0.0% | 254.57 | 1.55x | | async-pipeline | 202.4 | 201.7 | -0.3% | -1.4% .. +2.0% | neutral | +0.0% | 90.14 | 2.24x | | word-graph | 366.9 | 348.2 | -5.1% | -12.9% .. +4.3% | neutral | +0.0% | 576.56 | 0.60x | | alloc-trees | 513.5 | 525.5 | +2.3% | -2.1% .. +4.0% | neutral | +0.0% | 132.99 | 3.95x | | numeric-kernels | 121.4 | 122.5 | +0.8% | -1.9% .. +3.6% | neutral | +0.0% | 135.91 | 0.90x | | validate-errors | 206.0 | 209.2 | +1.5% | -3.6% .. +4.1% | neutral | +0.0% | 703.47 | 0.30x | | csv-numbers | 450.9 | 448.6 | -0.5% | -2.2% .. +2.0% | neutral | +0.0% | 499.25 | 0.90x | | log-summary | 253.5 | 252.6 | -0.3% | -1.5% .. +2.0% | neutral | +0.0% | 279.67 | 0.90x | | inventory-report | 433.7 | 433.2 | -0.1% | -6.0% .. +3.6% | neutral | +0.0% | 413.79 | 1.05x | geomean change -7.4%; geomean candidate/node 1.321x -> 1.223x macOS (arm64, runs=15): | workload | baseline ms | candidate ms | change | 95% CI | verdict | size | node ms | candidate/node | | --- | ---: | ---: | ---: | --- | --- | ---: | ---: | ---: | | json-records | 292.3 | 153.0 | -47.7% | -50.1% .. -46.6% | faster | +0.4% | 248.7 | 0.61x | | (all 13 other workloads neutral; see results/h16-typed-json/local-1.json) | geomean change -4.8%; geomean candidate/node 1.497x -> 1.425x