mirror of
https://github.com/RGBCube/serenity
synced 2025-05-31 10:58:12 +00:00
LibJS: Fix that constant declaration in for loop was mutable in body
This commit is contained in:
parent
714f0c3dce
commit
8319d7ac06
3 changed files with 34 additions and 4 deletions
|
@ -921,12 +921,22 @@ struct ForInOfHeadState {
|
||||||
else {
|
else {
|
||||||
VERIFY(expression_lhs && is<VariableDeclaration>(*expression_lhs));
|
VERIFY(expression_lhs && is<VariableDeclaration>(*expression_lhs));
|
||||||
iteration_environment = new_declarative_environment(*interpreter.lexical_environment());
|
iteration_environment = new_declarative_environment(*interpreter.lexical_environment());
|
||||||
|
|
||||||
auto& for_declaration = static_cast<VariableDeclaration const&>(*expression_lhs);
|
auto& for_declaration = static_cast<VariableDeclaration const&>(*expression_lhs);
|
||||||
|
|
||||||
|
// 14.7.5.4 Runtime Semantics: ForDeclarationBindingInstantiation, https://tc39.es/ecma262/#sec-runtime-semantics-fordeclarationbindinginstantiation
|
||||||
|
// 1. For each element name of the BoundNames of ForBinding, do
|
||||||
for_declaration.for_each_bound_name([&](auto const& name) {
|
for_declaration.for_each_bound_name([&](auto const& name) {
|
||||||
if (for_declaration.declaration_kind() == DeclarationKind::Const)
|
// a. If IsConstantDeclaration of LetOrConst is true, then
|
||||||
MUST(iteration_environment->create_immutable_binding(vm, name, false));
|
if (for_declaration.is_constant_declaration()) {
|
||||||
else
|
// i. Perform ! environment.CreateImmutableBinding(name, true).
|
||||||
MUST(iteration_environment->create_mutable_binding(vm, name, true));
|
MUST(iteration_environment->create_immutable_binding(vm, name, true));
|
||||||
|
}
|
||||||
|
// b. Else,
|
||||||
|
else {
|
||||||
|
// i. Perform ! environment.CreateMutableBinding(name, false).
|
||||||
|
MUST(iteration_environment->create_mutable_binding(vm, name, false));
|
||||||
|
}
|
||||||
});
|
});
|
||||||
interpreter.vm().running_execution_context().lexical_environment = iteration_environment;
|
interpreter.vm().running_execution_context().lexical_environment = iteration_environment;
|
||||||
|
|
||||||
|
|
|
@ -98,6 +98,16 @@ describe("special left hand sides", () => {
|
||||||
eval("for (f() in [0]) { expect().fail() }");
|
eval("for (f() in [0]) { expect().fail() }");
|
||||||
}).toThrowWithMessage(ReferenceError, "Invalid left-hand side in assignment");
|
}).toThrowWithMessage(ReferenceError, "Invalid left-hand side in assignment");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test("Cannot change constant declaration in body", () => {
|
||||||
|
const vals = [];
|
||||||
|
for (const v in [1, 2]) {
|
||||||
|
expect(() => v++).toThrowWithMessage(TypeError, "Invalid assignment to const variable");
|
||||||
|
vals.push(v);
|
||||||
|
}
|
||||||
|
|
||||||
|
expect(vals).toEqual(["0", "1"]);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
test("remove properties while iterating", () => {
|
test("remove properties while iterating", () => {
|
||||||
|
|
|
@ -142,4 +142,14 @@ describe("special left hand sides", () => {
|
||||||
eval("for (f() of [0]) { expect().fail() }");
|
eval("for (f() of [0]) { expect().fail() }");
|
||||||
}).toThrowWithMessage(ReferenceError, "Invalid left-hand side in assignment");
|
}).toThrowWithMessage(ReferenceError, "Invalid left-hand side in assignment");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test("Cannot change constant declaration in body", () => {
|
||||||
|
const vals = [];
|
||||||
|
for (const v of [1, 2]) {
|
||||||
|
expect(() => v++).toThrowWithMessage(TypeError, "Invalid assignment to const variable");
|
||||||
|
vals.push(v);
|
||||||
|
}
|
||||||
|
|
||||||
|
expect(vals).toEqual([1, 2]);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue