ReviewOS

zig-utils/zig-js

Errors: describe the value in "is not a function" where no CallExpression owns the call

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

Parent: #459 Related: #889, #890

Problem

#889 gives every CallExpression JavaScriptCore's exact is not a function text. The remaining [[Call]]s — the ones no CallExpression owns — still emit a literal placeholder that JSC never produces:

TypeError: value is not a function

JavaScriptCore has no such wording. Where it cannot name a callee it still describes it, using the same subject renderer as is not a constructor:

sourcezig-jsJavaScriptCore
var it = { [Symbol.iterator]() { return { next: 1 }; } }; [...it]value is not a function1 is not a function
var o = { m: 1 }; o.m`x` value is not a function1 is not a function (near '...o.m`x`...')

So two distinct things are missing, and they should not be conflated:

  1. the subject — value should be the described value (1, undefined, "s", an instance of Object, …). This is the whole fix for the iterator protocol and every other internal [[Call]];
  2. (near '...') — the tagged-template form, which additionally needs the tagged template's own source span. #889 added that span to ast.Node.call; ast.Node.tagged_template does not have one yet.

Required implementation

  • Replace the value is not a function placeholder in Interpreter.throwNotAFunction's no-site branch with the described subject. notAFunctionSubject already renders every value category; confirm against the oracle whether the no-site branch uses it or notAConstructorSubject (they differ for Symbols and for objects) before choosing.
  • Retain a source span on ast.Node.tagged_template the way #889 did for ast.Node.call, and emit JSC's (near '...') suffix for a tag that is not callable. The tagged-template path must reach both tiers, as #889 did.
  • Sweep for callers that would change wording, and check each against the oracle rather than assuming: some already have their own exact JSC message (Array.prototype.forEach callback must be a function, 'get' property of a Proxy's handler should be callable) and must not be touched.
  • Gate it in src/context.zig beside the #889 test, which currently asserts the placeholder for exactly these two paths and will need updating.

Method

The differential harness is documented in docs/conformance.md's neighbourhood and in the #889 work: build a CASES array, run it through ~/Code/Home/lang/zig-out/bin/home-tool run (a real JSC backend — node gives V8, the wrong target) and through zig-out/bin/test262 --eval, then diff. Re-run each case inside a generator body to hold the bytecode tier to the same text.

Sign in to comment on this issue.