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

LibJS/Bytecode: Handle awkward initialization case for duplicate var

`var` declarations can have duplicates, but duplicate `let` or `const`
bindings are a syntax error.

Because of this, we can sink `let` and `const` directly into the
preferred_dst if available. This is not safe for `var` since the
preferred_dst may be used in the initializer.

This patch fixes the issue by simply skipping the preferred_dst
optimization for `var` declarations.
This commit is contained in:
Andreas Kling 2024-03-01 12:54:50 +01:00
parent 2bbdfe0fba
commit bc21ed151e
2 changed files with 23 additions and 3 deletions

View file

@ -1452,10 +1452,15 @@ Bytecode::CodeGenerationErrorOr<Optional<Bytecode::Operand>> VariableDeclaration
Bytecode::Generator::SourceLocationScope scope(generator, *this);
for (auto& declarator : m_declarations) {
// NOTE: `var` declarations can have duplicates, but duplicate `let` or `const` bindings are a syntax error.
// Because of this, we can sink `let` and `const` directly into the preferred_dst if available.
// This is not safe for `var` since the preferred_dst may be used in the initializer.
Optional<Bytecode::Operand> init_dst;
if (auto const* identifier = declarator->target().get_pointer<NonnullRefPtr<Identifier const>>()) {
if ((*identifier)->is_local()) {
init_dst = Bytecode::Operand(Bytecode::Operand::Type::Local, (*identifier)->local_variable_index());
if (declaration_kind() != DeclarationKind::Var) {
if (auto const* identifier = declarator->target().get_pointer<NonnullRefPtr<Identifier const>>()) {
if ((*identifier)->is_local()) {
init_dst = Bytecode::Operand(Bytecode::Operand::Type::Local, (*identifier)->local_variable_index());
}
}
}