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 functionJavaScriptCore has no such wording. Where it cannot name a callee it still
describes it, using the same subject renderer as is not a constructor:
| source | zig-js | JavaScriptCore |
|---|---|---|
var it = { [Symbol.iterator]() { return { next: 1 }; } }; [...it] | value is not a function | 1 is not a function |
var o = { m: 1 }; o.m`x` | value is not a function | 1 is not a function (near '...o.m`x`...') |
So two distinct things are missing, and they should not be conflated:
- the subject —
valueshould 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]]; (near '...')— the tagged-template form, which additionally needs the tagged template's own source span.#889added that span toast.Node.call;ast.Node.tagged_templatedoes not have one yet.
Required implementation
- Replace the
value is not a functionplaceholder inInterpreter.throwNotAFunction's no-site branch with the described subject.notAFunctionSubjectalready renders every value category; confirm against the oracle whether the no-site branch uses it ornotAConstructorSubject(they differ for Symbols and for objects) before choosing. - Retain a source span on
ast.Node.tagged_templatethe way#889did forast.Node.call, and emit JSC's(near '...')suffix for a tag that is not callable. The tagged-template path must reach both tiers, as#889did. - 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.zigbeside the#889test, 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.