ReviewOS

zig-utils/zig-js

Compiler: lower parameter-local calls in VM frames

#744
Closed chris opened this 9 days ago ·
9 days ago

Parents: #465, #498 Depends on: #743 Related: #739, #740, #741, #742

Problem

#743 permits exact public property reads rooted in invocation context or strictly earlier formals, including getters that can already reenter JavaScript. Calling a proven earlier callable, or a public method read from a proven receiver, still rejects the enclosing plain function even though the VM already owns canonical callability checks, receiver binding, argument order, Proxy [[Call]], abrupt completion, activation nesting, and GC roots.

Scope

  • Admit non-optional, non-spread calls when the callee and every argument recursively satisfy the parameter-safe grammar.
  • Preserve this = undefined for value calls and the exact base receiver for named/computed member calls.
  • Preserve callee/property lookup before arguments, left-to-right arguments, one call, Proxy apply behavior, non-callable errors, provided-value bypass, recursion/reentrancy, moving GC, and OOM propagation.
  • Permit nested safe calls and composition through existing value/property expression nodes while retaining immutable metadata, debugger/step/watchdog accounting, shared-chunk no-GIL execution, and exact activation restoration.

Syntactically direct eval, optional calls/chains, spread arguments, private or super calls, tagged templates, construction, writes/assignment/update/delete, unresolved outer/body bindings, import/suspension, literal allocation, nested-pattern expressions, and rest mixtures remain barriers.

No-workaround rules

  • No eager invocation, cached result, duplicated callee/getter/argument effect, receiver substitution, skipped callability check, source rewriting, permissive call arm, tree-walker callback, hidden native tier, or benchmark-only path.
  • No stacks, queues, jobs, Promise, microtask, Worker lifecycle, or Map/Set iterator changes.

Acceptance

  • Exhaustive admission tests accept only recursively safe value/member calls and reject direct-eval/optional/spread/private/super/new/outer forms.
  • Forced tree-walker and required bytecode agree on value and named/computed method calls, receiver identity, callee-before-arguments order, Proxy apply, non-callable/throwing calls, provided bypass, methods/arrows/base constructors, and recursion/reentrancy.
  • Moving-GC, allocation-failure restoration, shared no-GIL, and TSan witnesses preserve one-shot effects and activation state.
  • Full units, focused compiler/frontend/VM, threadfuzz, and exact nonzero relevant Test262 accounting pass with zero regressions.
  • A conventional commit lands directly on main and cross-links #465, #498, #743, #742, #739, #740, and #741.

Landed

402e805a — feat(compiler): lower parameter call defaults (#744)

9 days ago

Landed on main in 402e805a.

The compiler now admits non-optional, non-spread calls only when the callee and every argument recursively satisfy the proven parameter-safe grammar. Execution stays on canonical call/call_with_this, preserving callee/property lookup, receiver identity, arguments, Proxy apply, callability errors, throws, activation nesting, GC, and OOM exactly once. Direct eval, optional/spread/private/super calls, construction, writes, and unresolved names remain fail-closed.

Validation on the landed tree:

  • Test262: 10296 -> 10296, byte-identical diagnostics across seven function/class boundaries; 0 gains, 0 regressions.
  • Final full units: 1,888 passed, 1 skipped, 0 failed, 0 leaked across 1,889 tests.
  • Focused compiler, three-mode semantic, shared no-GIL, and nested-call allocation-failure tests passed normally and under TSan; frontend 23/23.
  • Seeded threadfuzz: 400/0 in default and TSan builds.

One intermediate full run let the existing parallel_js: optimized reads race delete redefine and prototype replacement reader observe zero loop iterations because its writer set stop first. No stale value or engine error occurred. I did not modify that Thread surface; three isolated reruns exercised it successfully and the final complete suite was green.

The acceptance checklist is complete. Crosslinks: #465, #498, #743, #742, #739, #740, #741.

9 days ago

Follow-up #745 landed on main as feat(compiler): lower parameter construction defaults (#745). It composes the parameter-safe value/property/call grammar into canonical non-spread new_call lowering, remains fail-closed for unsupported forms, and records 10,296 -> 10,296 exact relevant Test262 cases with 0 flips. Derived and field-initializing constructor activations are separated into #746.

Sign in to comment on this issue.