Skip to content

Instantly share code, notes, and snippets.

@xeioex
Created March 5, 2026 07:28
Show Gist options
  • Select an option

  • Save xeioex/0398c2e41ef64fa8486690b8e54911d1 to your computer and use it in GitHub Desktop.

Select an option

Save xeioex/0398c2e41ef64fa8486690b8e54911d1 to your computer and use it in GitHub Desktop.

parser_refactor_method_frame vs master — Summary

Why

Spec compliance: ECMAScript requires arguments (including their side effects) to be evaluated before the callee's callability is checked. The old call lowering created the frame first, which threw non-callable errors before argument side effects ran.

Enable await in call arguments and tagged templates: The old frame-first design made it impossible to suspend on await during argument evaluation because the frame was already half-constructed. The parser rejected both as a workaround.

Preserve this for grouped optional calls: (o?.m)() resolved the callee through the optional chain but dispatched via plain FUNCTION_CALL, losing the receiver.

Behavioral changes

  • Arguments with side effects are now fully evaluated before non-callable errors are thrown.
  • Constructor arguments are evaluated before checking whether the callee is constructable.
  • Error messages change from (intermediate value)["x"] is not a function to type is not a function (e.g., "number is not a function").
  • Backtraces no longer show native frames when arguments throw before reaching the native function.
  • await in call arguments and tagged templates is now allowed.
  • (o?.m)() correctly preserves the receiver.

Examples

// Call ordering — previously threw before evaluating foo()
var fooCalled = false;
function foo() { fooCalled = true; }
var o = {};
try { o.bar(foo()) } catch (e) {}
fooCalled  // true (was false)

// Await in call arguments — previously SyntaxError
async function f() {
    return ({
        g(v) { return v; }
    }).g(await Promise.resolve(2));
}

// Grouped optional chain this — previously TypeError
var o = {x: 5, m: function() { return this.x }};
(o?.m)()  // 5 (was TypeError: cannot get property "x" of undefined)

Test262: +12 tests passed (14457 → 14469)

  • language/expressions/call/11.2.3-3_{1,2,4,6,7} — call argument ordering
  • language/expressions/new/ctorExpr-isCtor-after-args-eval{,-fn-wrapup} — constructor ordering
  • language/expressions/await/await-{awaits-thenables,monkey-patched-promise} — await in args
  • language/expressions/optional-chaining/{member-expression-async-literal,optional-chain-async-*-square-brackets} — await + optional chain
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment