1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-05-31 07:08:10 +00:00

LibJS/Bytecode: Check for lexical bindings only in current scope

BlockDeclarationInstantiation takes as input the new lexical
environment that was created and checks if there is a binding for the
current name only in this new scope.

This allows shadowing lexical variables and prevents us crashing due to
an already initialized lexical variable in this case:
```js
let x = 1;
{
    let x = 1;
}
```
This commit is contained in:
Luke Wilde 2022-07-17 19:09:19 +01:00 committed by Linus Groh
parent c55a4c7f30
commit 3a48c7fdaf
2 changed files with 11 additions and 2 deletions

View file

@ -45,7 +45,9 @@ Bytecode::CodeGenerationErrorOr<void> ScopeNode::generate_bytecode(Bytecode::Gen
auto is_constant_declaration = declaration.is_constant_declaration();
declaration.for_each_bound_name([&](auto const& name) {
auto index = generator.intern_identifier(name);
if (is_constant_declaration || !generator.has_binding(index)) {
// NOTE: BlockDeclarationInstantiation takes as input the new lexical environment that was created and checks if there is a binding for the current name only in this new scope.
// For example: `{ let a = 1; { let a = 2; } }`. The second `a` will shadow the first `a` instead of re-initializing or setting it.
if (is_constant_declaration || !generator.has_binding_in_current_scope(index)) {
generator.register_binding(index);
generator.emit<Bytecode::Op::CreateVariable>(index, Bytecode::Op::EnvironmentMode::Lexical, is_constant_declaration);
}