Parents: #465, #498 Depends on: #706 for top-level program expressions Related: #707, #491
Problem
The bytecode compiler lowers identifier ++/-- but rejects ordinary member targets. obj.x++, --obj[key], and suspendable computed forms therefore fall back even though #707 now provides an activation-safe one-reference contract for function bytecode.
Program-mode bytecode still lacks activation-local scratch, and super writes need receiver-aware lowering. Those boundaries must remain explicit.
Scope
- Lower ordinary named and computed member prefix/postfix increment and decrement in plain, generator, and async function activations.
- Resolve the base/key and observable ToPropertyKey once, perform GetValue and ToNumeric once, and PutValue on the same reference.
- Preserve Number/BigInt behavior, prefix-new versus postfix-old results, coercion/getter/setter/proxy order, strict errors, abrupt completion, recursion, and suspension while resolving computed keys.
- Keep top-level program and super-property targets causally unsupported behind #706 and receiver-aware super writes.
No-workaround rules
- No repeated base/key/coercion,
old + 1substitution, AST rewrite, tree-walker callback, shared/global scratch, GIL-only serialization, skipped proxies/accessors, or changed stack/runtime primitive.
Acceptance
- Named/computed prefix/postfix updates compile across plain, generator, and async admission; program mode retains a causal #706 rejection.
- Exact witnesses cover one-shot base/key/get/ToNumeric/set order, Number/BigInt/string coercion, Symbol keys, recursion, proxies/accessors, strict failures, and abrupt completion.
- Generator/async suspension while resolving a computed key preserves the exact base; prefix/postfix results remain exact.
- Forced tree-walker and required-bytecode differentials match; program and super barriers stay causal.
- Focused compiler/frontend, full units, applicable TSan, and exact relevant Test262 before → after accounting pass with no regressions.
- Parent/dependency issues and landing commit are cross-linked with quantified evidence.
Result
Landed in feat(compiler): lower member update expressions (#708).
- Ordinary named/computed
++/--now uses one activation-local Reference across plain, generator, and async bytecode, including suspension during computed-key resolution. - The tree-walker now captures named member bases once too, and the VM
to_numericoperation returns the required Number/BigInt postfix value instead of preserving a string primitive. - Test262 before → after: postfix increment 38/38 → 38/38, postfix decrement 37/37 → 37/37, prefix increment 33/33 → 33/33, prefix decrement 34/34 → 34/34; total 142/142 → 142/142, flips 0, regressions 0.
- Validation: member-update units 3/3; ToNumeric/native optimizer units 7/7; admission/barrier/inventory/async-template units 8/8; TSan member-update units 3/3; focused frontend 12/12; full units 1,808 passed, 1 skipped, 0 failed, 0 leaked.
- Program mode remains causally rejected behind #706; super remains behind receiver-aware write lowering.