ReviewOS

zig-utils/zig-js

Compiler: lower sloppy mapped arguments into VM frames

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

Parents: #465, #498 Related: #728, #493

Problem

#728 gives strict ordinary functions an activation-local unmapped arguments object, but the compiler still rejects every sloppy ordinary function that owns arguments. Sloppy simple-parameter functions require the arguments exotic object's live [[ParameterMap]]: indexed reads/writes alias parameter bindings, duplicate formals map only their last occurrence, and delete or descriptor changes can sever an individual alias. The current parameter map targets Environment bindings only and therefore cannot safely address VM frame slots.

This keeps a common no-JIT function surface on the tree walker and hides a separate duplicate-formal frame-layout hazard behind the broad admission barrier.

Scope

  • Add explicit bytecode metadata for a sloppy ordinary function's mapped-arguments owner and its exact formal-slot mapping.
  • Materialize the arguments exotic object during FunctionDeclarationInstantiation and let its parameter map address heap activation slots with the same synchronization protocol as escaped upvalues.
  • Preserve both directions of aliasing, duplicate-formal right-to-left selection, missing/extra arguments, callee, length, @@iterator, delete, DefineProperty value updates, writable-to-false severing, accessor conversion, and per-index severing.
  • Keep escaped mapped slots alive and precisely traced/relocated without retaining or scanning unrelated completed activations.
  • Preserve nested-arrow ownership, nested ordinary shadowing, recursion, constructors, methods, tail calls, debugger views, OOM rollback, activation recycling, and direct-eval barriers.
  • Keep strict and sloppy non-simple-parameter arguments objects unmapped, using the #728 path where already eligible.
  • Reject baseline/optimizing native entry until their activation inputs and mapped-slot invalidation are represented exactly.

No-workaround rules

  • No Environment-backed tree-walker fallback presented as VM support, source rewriting, stale argument snapshots, global activation-reuse disablement, broad frame pinning, unsafe raw slot access, process-global state, benchmark recognizer, or semantic exclusions.
  • No changes to stacks, queues, jobs, Promise, microtasks, Worker lifecycle, or Map/Set iterators.

Acceptance

  • Forced tree-walker and required-bytecode witnesses match for bidirectional aliases, duplicate formals, missing/extra arguments, escaped objects, nested arrows, recursion, methods/constructors, abrupt completion, and tail calls.
  • Delete and every relevant DefineProperty transition preserve exact mapped-arguments severing and descriptor semantics.
  • Moving/concurrent GC precisely traces and relocates live mapped slots; completed non-escaping calls still reuse bounded activation storage.
  • No-GIL/TSan witnesses prove mapped-index and parameter access is engine-race-free under publication.
  • Focused compiler/VM/frontend tests, full units, relevant Test262 arguments/function/class subtrees, and tier differentials pass with exact before-to-after accounting.
  • #465/#498/#728 are cross-linked and the remaining direct-eval/non-simple admission boundaries stay explicit.
9 days ago

Landed 26b8c248 on main.

Implemented object-owned atomic mapped-parameter cells, dedicated local/upvalue bytecodes, exact duplicate-formal and missing/extra argument layouts, descriptor/delete severing, debugger synchronization, bounded activation recycling, and precise concurrent/moving-GC tracing and relocation. Automatic VM admission now accepts sloppy mapped owners; direct eval, non-simple parameters, legacy caller reflection, and baseline/optimizing native entry remain explicit fail-closed boundaries.

Validation:

  • full units: 1,859 passed, 1 skipped, 0 failed, 0 leaked
  • full TSan units: 1,858 passed, 2 skipped, 0 failed, 0 leaked
  • focused frontend: 14/14; focused VM: 4/4
  • Test262 arguments-object: 263 -> 263 pass, 0 fail; mapped: 43 -> 43 pass; flips 0, regressions 0
  • candidate Test262: for-of 751/751, function expressions 264/264, function statements 451/451, class arguments 2/2
9 days ago

Non-simple own-arguments defaults are now covered by #740 in feat(compiler): lower invocation defaults (#740). They remain unmapped and are admitted only when no formal owns the arguments name; #729’s sloppy simple mapped-cell contract is unchanged.

Sign in to comment on this issue.