ReviewOS

zig-utils/zig-js

Compiler: lower super method calls in tail position

#710
Closed chris opened this 8 days ago ·
8 days ago

Parents: #465, #498 Related: #709, #491

Problem

The bytecode compiler lowers non-tail named/computed super calls, but compileTailCall rejects every super callee. Because class methods are strict, an ordinary return super.method(args) enters the proper-tail-call path and falls back even though tail_call_with_this already supports the exact callee/receiver contract. Generator super calls with spread also reach the generic receiver-less spread path rather than the existing call_with_this_spread operation.

Scope

  • Lower fixed-argument named/computed super calls in strict tail position with the current this receiver.
  • Share one super-call lowering between tail and non-tail paths so GetThisBinding, computed key/ToPropertyKey, getter, arguments, and call remain exactly ordered.
  • Lower non-tail generator super calls with spread through the receiver-aware spread operation.
  • Preserve home-object lookup, inherited getter receiver, abrupt completion, recursion, suspension in computed keys/arguments, and proper-tail-call frame reuse.
  • Keep tail spread explicitly unsupported until a receiver-aware tail-spread operation exists.

No-workaround rules

  • No receiver-less call, repeated key/getter, AST rewrite, tree-walker callback, disabled PTC, source-shape exception, new global/shared scratch, or new runtime primitive.
  • No stacks, queues, jobs, Promise/microtask, Worker, or Map/Set iterator changes.

Acceptance

  • Named/computed fixed-argument super calls compile in strict tail position; non-tail generator super spread uses the exact receiver.
  • Exact witnesses cover receiver identity, key/getter/argument/call and abrupt order, recursion, suspension, spread, and emitted tail opcode identity.
  • Forced tree-walker and compiled-bytecode behavior matches; unsupported tail spread retains a causal admission barrier.
  • Focused compiler/frontend, full units, applicable TSan, and exact relevant Test262 before → after accounting pass with zero regressions.
  • Parent/related issues and landing commit are cross-linked with quantified evidence.

Result

Landed in e818a068.

  • Shared one receiver-aware lowering for normal and tail super calls; computed keys resolve after GetThisBinding and before inherited getters/arguments/call.
  • Fixed-argument tail calls emit tail_call_with_this; generator spread emits call_with_this_spread; receiver-aware tail spread remains causally unsupported.
  • Exact Test262: super expressions 94/94 → 94/94; class super statements 8/8 → 8/8; total 102/102 → 102/102, 0 flips, 0 regressions, byte-identical diagnostics.
  • Validation: 2 focused units, forced tree-walker/compiled-bytecode differential, 2 focused TSan units, 12 frontend tests, and full units at 1,814 passed / 1 skipped / 0 failed / 0 leaked.
8 days ago

Implemented and pushed directly to main in e818a068. Exact Test262 remained 102/102 before and after with byte-identical diagnostics (0 flips, 0 regressions); full units passed 1,814 with 1 platform skip and no failures or leaks.

8 days ago

Related #711 landed in d1c8251b — feat(compiler): lower spread calls and constructors (#711): ordinary program/plain/generator/async spread calls and constructors now use the existing variadic bytecode family with exact receiver and evaluation ordering. Exact call/new/super Test262 remained 245/245 with byte-identical diagnostics and 0 regressions.

Sign in to comment on this issue.