LibJS: Copy base object of LHS of assignment to preserve eval order
Some checks are pending
CI / macOS, arm64, Sanitizer, Clang (push) Waiting to run
CI / Linux, x86_64, Fuzzers, Clang (push) Waiting to run
CI / Linux, x86_64, Sanitizer, GNU (push) Waiting to run
CI / Linux, x86_64, Sanitizer, Clang (push) Waiting to run
Package the js repl as a binary artifact / Linux, arm64 (push) Waiting to run
Package the js repl as a binary artifact / macOS, arm64 (push) Waiting to run
Package the js repl as a binary artifact / Linux, x86_64 (push) Waiting to run
Run test262 and test-wasm / run_and_update_results (push) Waiting to run
Lint Code / lint (push) Waiting to run
Label PRs with merge conflicts / auto-labeler (push) Waiting to run
Push notes / build (push) Waiting to run

Previously, the given test would create an object with the test
property that pointed to itself.

This is because `temp = temp.test || {}` overwrote the `temp` local
register, and `temp.test = temp` used the new object instead of the
original one it fetched.

Allows https://www.yorkshiretea.co.uk/ to load, which was failing in
Gsap library initialization.
This commit is contained in:
Luke Wilde 2025-09-01 15:38:42 +01:00 committed by Luke Wilde
commit 18c0739bbb
Notes: github-actions[bot] 2025-09-02 12:01:01 +00:00
2 changed files with 14 additions and 1 deletions

View file

@ -568,7 +568,8 @@ Bytecode::CodeGenerationErrorOr<Optional<ScopedOperand>> AssignmentExpression::g
lhs_is_super_expression = is<SuperExpression>(expression.object());
if (!lhs_is_super_expression) {
base = TRY(expression.object().generate_bytecode(generator)).value();
auto generated_base = TRY(expression.object().generate_bytecode(generator)).value();
base = generator.copy_if_needed_to_preserve_evaluation_order(generated_base);
} else {
// https://tc39.es/ecma262/#sec-super-keyword-runtime-semantics-evaluation
// 1. Let env be GetThisEnvironment().

View file

@ -19,3 +19,15 @@ test("Binary assignment should always evaluate LHS first", () => {
go(a);
expect(a).toEqual([3, 2]);
});
test("Base object of lhs of assignment is copied to preserve evaluation order", () => {
let topLevel = {};
function go() {
let temp = topLevel;
temp.test = temp = temp.test || {};
}
go();
expect(topLevel.test).not.toBeUndefined();
expect(topLevel.test).toEqual({});
});