ReviewOS

zig-utils/zig-js

Compiler: lower member compound assignment references

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

Parents: #465, #498 Depends on: #706 for top-level program expressions Related: #705, #491

Problem

The bytecode compiler lowered identifier compound assignment but rejected ordinary member targets. obj.x += rhs, obj[key] **= rhs, and the bitwise/shift forms therefore fell back even though #705 provided an activation-safe one-reference contract for function bytecode.

Program-mode bytecode still lacks activation-local scratch, and super writes still need receiver-aware lowering. Those boundaries remain explicit rather than using shared names or repeated evaluation.

Scope

  • Lower ordinary named and computed member targets for arithmetic, exponentiation, bitwise, and shift compound assignments in plain, generator, and async function activations.
  • Reuse one resolved base/key and one observable ToPropertyKey across GetValue and PutValue.
  • Preserve left-to-right coercion, getter/proxy read, RHS suspension, binary Number/BigInt semantics, setter/proxy write, strict errors, and assignment result.
  • Keep top-level program and super-property targets causally unsupported behind #706 and the receiver-aware super-write boundary.

No-workaround rules

  • No repeated base/key/coercion, eager RHS, skipped accessors/proxies, raw numeric shortcut, AST rewrite, tree-walker callback, hidden global scratch, or GIL-only serialization.

Acceptance

  • Named/computed member compound operators compile across plain, generator, and async admission; program mode retains a causal #706 rejection.
  • Exact witnesses cover base/key/get/RHS/binary/set order, Number/BigInt/coercion, Symbol keys where legal, recursion, proxies/accessors, strict failures, and abrupt completion.
  • Generator resume and async settlement preserve the resolved reference and pre-suspension old value.
  • Forced tree-walker and required-bytecode function differentials match; program and super targets retain causal barriers.
  • Focused compiler/frontend, full units, applicable TSan, and exact relevant Test262 before → after accounting pass with no regressions.
  • Parent/dependency issues and the landing commit are cross-linked with quantified evidence.

Result

Landed in feat(compiler): lower member compound assignments (#707).

  • All 12 compound operators lower for ordinary named/computed members in plain, generator, and async activations.
  • The resolved base/key uses activation-local state; the VM operand stack preserves the old value across RHS suspension; no shared program scratch or repeated reference evaluation was introduced.
  • Exact Test262 test/language/expressions/compound-assignment: 0 fail, 454 pass before → 0 fail, 454 pass after; diagnostics are byte-identical, so flips 0 and regressions 0.
  • Focused semantic/admission/inventory/async witnesses: 10/10 passed. Focused TSan compound-assignment set: 6/6 passed. Frontend: 12/12 passed.
  • Full units: 1,805 passed, 1 skipped, 0 failed, 0 leaked across all 1,806 linked tests.
9 days ago

#708 reused the activation-local member Reference contract introduced here for prefix/postfix updates in 1f925020. It adds no stack/runtime primitive and preserves the same recursion/suspension guarantees; exact update-expression Test262 remained 142/142 with 0 regressions.

Sign in to comment on this issue.