ReviewOS

zig-utils/zig-js

Errors: append JavaScriptCore's "(evaluating '...')" to construction and member diagnostics

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

Parent: #459 Related: #889, #891

Problem

JavaScriptCore ends most of its runtime TypeErrors with the source text of the expression being evaluated. zig-js matches the leading clause on these families but stops there:

sourcezig-jsJavaScriptCore
var o = {}; o.m.n()undefined is not an objectundefined is not an object (evaluating 'o.m.n')
var g = 1; new g()1 is not a constructor1 is not a constructor (evaluating 'new g()')
var g = {}; new g.m()undefined is not a constructorundefined is not a constructor (evaluating 'new g.m()')

A 41-case JSC differential over call and construction shapes matches 39/41; the two misses are exactly the new form above. On the is not an object family every leading clause already matches, so the suffix is all that is left.

Why it is now tractable

The blocker was recorded as "ast.Node has no spans". #889 showed that framing was too pessimistic: the parser retains the whole source buffer for the life of the parse and already slices it for Function.prototype.toString, so retaining a node's own span is the established pattern rather than new machinery. #889 did exactly this for ast.Node.call at no size cost — the union is sized by class_expr (72 bytes) and the enlarged call payload is 56.

ast.Node.new_expr (24 bytes) and ast.Node.member (40) have the same headroom.

Required implementation

  • Retain the construction's source span on ast.Node.new_expr, and emit JSC's (evaluating '<source>') suffix from the is not a constructor throw sites in interpreter.zig (notAConstructorSubject's five callers).
  • Retain the member expression's span on ast.Node.member, and emit the same suffix from notAnObjectMessage's callers. Note JSC prints the member expression there (o.m.n), not the enclosing call.
  • Both must reach the bytecode tier too. #889 added bc.Chunk.call_sites plus Chunk.callSiteAt for exactly this; the construction and member opcodes need the same treatment, or the tiers disagree on text under a corpus that never asserts it.
  • Gate it beside the #889 test in src/context.zig, asserting identical text on the tree-walker and inside a generator body (which only the VM can run).

Sign in to comment on this issue.