Parents: #359, #473
Related: #782, #783
Problem
Interpreter.applyBinary keeps both operands in raw Value locals while observable ToPrimitive coercion runs left-to-right. A user-defined left-side valueOf, toString, or Symbol.toPrimitive can enter baseline native code and consume a requested moving-GC safepoint before the right operand has been published in a precise root. The same pattern can leave the completed left primitive stale while coercing the right operand.
This was found during the #783 relocation audit. It is broader than String.prototype.concat and affects arithmetic, relational, bitwise, and loose-equality paths that perform user code during coercion.
Scope
- Publish both original operands before the first observable coercion.
- Replace each root slot with its completed primitive before coercing the next operand.
- Preserve exact ECMA-262 left-to-right ordering, abrupt completion, Symbol, BigInt, and string-concatenation behavior.
- Exercise a requested moving compaction from an earlier operand conversion while a later movable operand remains live.
- Cover tree-walker and VM-shaped entry paths where applicable.
No-workaround rules
- No disabling compaction, pinning cells, conservative native-stack dependency, source recognition, reordered coercion, or duplicated conversion.
- No stacks, queues, jobs, Promise or microtask, Worker lifecycle, or Map or Set iterator changes.
Acceptance
Completed integration
CI run 33113309062 completed successfully on main commit 8a1398ffc04e9e30987f968693667c7271ca3ce1, a descendant containing this implementation. All 53 executed jobs succeeded (unit and TSan-unit shards, Linux no-GIL TSan, functional/no-GIL corpus gates, fuzz profiles, ABI, Wasm, Test262 parallel, and docs); the scheduled-only nightly job was skipped. Together with the measured local evidence in the comments, this completes this issue's acceptance.
Parents: #359, #473
Related: #782, #783
Problem
Interpreter.applyBinary keeps both operands in raw Value locals while observable ToPrimitive coercion runs left-to-right. A user-defined left-side valueOf, toString, or Symbol.toPrimitive can enter baseline native code and consume a requested moving-GC safepoint before the right operand has been published in a precise root. The same pattern can leave the completed left primitive stale while coercing the right operand.
This was found during the #783 relocation audit. It is broader than String.prototype.concat and affects arithmetic, relational, bitwise, and loose-equality paths that perform user code during coercion.
Scope
No-workaround rules
Acceptance
Completed integration
CI run 33113309062 completed successfully on main commit
8a1398ffc04e9e30987f968693667c7271ca3ce1, a descendant containing this implementation. All 53 executed jobs succeeded (unit and TSan-unit shards, Linux no-GIL TSan, functional/no-GIL corpus gates, fuzz profiles, ABI, Wasm, Test262 parallel, and docs); the scheduled-only nightly job was skipped. Together with the measured local evidence in the comments, this completes this issue's acceptance.