ReviewOS

zig-utils/zig-js

Parser errors lost the eval:/ShadowRealm.evaluate: prefix and the " at L:C" suffix; three unit tests and CI are red

#972
Closed glennmichael123 opened this 9 days ago ·
9 days ago

unit (shard 1/4) and tsan-unit (shard 1/4) fail on main (run 35761013166), on three tests:

They are not caused by the zig-regex pin: three test262 binaries built at three different pins (6e805ad, 30c1fa9, 1d3e5c9) produce byte-identical messages.

What changed

A parser error thrown out of eval now carries JSC's prose and nothing else. A lexer error still carries the old eval: <tag> at L:C wrapper. Run on a Debug test262 --eval:

source evaluatedmessage today
eval('var =')Unexpected token '='. Expected a parameter pattern or a ')' in parameter list.
eval("let ok = 1;\nlet bad = ;")Unexpected token ';'
eval("let ok = 1;\n'")eval: UnterminatedString at 2:2
new ShadowRealm().evaluate('let ok = 1;\nlet bad = ;')Unexpected token ';'

The three tests assert the old shape: message.includes('eval:') and includes(' at 1:'), includes('ShadowRealm.evaluate:') and includes(' at 2:'), and for the C API that String(exception) contains app.js:41:12.

The prose itself is right

JavaScriptCore (home-tool), same five sources: Unexpected token '='. Expected a parameter pattern or a ')' in parameter list., Unexpected token ';', Unexpected end of script, Unexpected identifier 'b', Unexpected end of script — identical to what zig-js now produces, and JSC's .message carries no position either. e.line / e.column are populated on zig-js (1:5, 2:11, ...); JSC reports the outer script's position instead.

The decision I did not want to make for you

Either reading is defensible, and the second is a public-contract change, so I left it alone:

  1. The wrapper is still wanted — reapply the eval: / ShadowRealm.evaluate: prefix and at L:C suffix on the parser-error path as well, so the two paths agree again and the C API keeps appending sourceURL:line:column.
  2. The wrapper is gone on purpose — then the lexer path (eval: UnterminatedString at 2:2) is the odd one out and should also drop it, and the three tests need rewriting. Note this changes what JSEvaluateScript's exception stringifies to, which the C-API test pins deliberately; sourceURL, line, column and byteOffset stay available as properties either way.

Happy to land whichever you pick — the tests are the only thing standing between main and a green unit leg.

9 days ago

Landed in e00e753a (fix(errors): preserve syntax prose at embedding boundaries).

The legacy eval: / ShadowRealm.evaluate: / Function body: prefixes and at L:C suffixes are gone from the remaining lexer fallback path. Parser and lexer failures now share one prose boundary, while line, column, byteOffset, and C-API sourceURL remain non-enumerable structured properties. The C API now retains the parser diagnostic before the compact RunError crosses the embedding boundary instead of reconstructing <Zig tag>: <URL>:<line>:<column>.

Verification:

  • 244/244 standalone parser tests
  • 27/27 focused runtime cases, including the stack-exhaustion resource-error gate
  • public C-API probe: exact parser/lexer messages plus app.js, line 41, columns 11/2, and byte offsets 22/13
  • zig build c-api-audit: 117/117 public declarations complete and present
  • zig build test-c-api
  • exact-parent test262 comparison across string literals, comments, eval, Function, and ShadowRealm: 708 -> 708 passes, 0 failures, byte-identical transcripts, 0 flips

Sign in to comment on this issue.