mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-07-12 03:51:52 +00:00
LibJS: Preserve information about local variables declaration kind
This is required for upcoming change where we want to emit ThrowIfTDZ for assignment expressions only for lexical declarations.
This commit is contained in:
parent
2774068ca0
commit
db480b1f0c
Notes:
github-actions[bot]
2025-05-06 10:07:32 +00:00
Author: https://github.com/kalenikaliaksandr
Commit: db480b1f0c
Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/4616
Reviewed-by: https://github.com/awesomekling
11 changed files with 83 additions and 40 deletions
|
@ -17,6 +17,7 @@
|
|||
#include <LibJS/Bytecode/StringTable.h>
|
||||
#include <LibJS/Forward.h>
|
||||
#include <LibJS/Heap/Cell.h>
|
||||
#include <LibJS/LocalVariable.h>
|
||||
#include <LibJS/Runtime/EnvironmentCoordinate.h>
|
||||
#include <LibJS/SourceRange.h>
|
||||
|
||||
|
@ -85,7 +86,7 @@ public:
|
|||
|
||||
HashMap<size_t, SourceRecord> source_map;
|
||||
|
||||
Vector<FlyString> local_variable_names;
|
||||
Vector<LocalVariable> local_variable_names;
|
||||
size_t local_index_base { 0 };
|
||||
size_t argument_index_base { 0 };
|
||||
|
||||
|
|
|
@ -56,7 +56,7 @@ CodeGenerationErrorOr<void> Generator::emit_function_declaration_instantiation(E
|
|||
|
||||
if (function.shared_data().m_arguments_object_needed) {
|
||||
Optional<Operand> dst;
|
||||
auto local_var_index = function.shared_data().m_local_variables_names.find_first_index("arguments"_fly_string);
|
||||
auto local_var_index = function.shared_data().m_local_variables_names.find_first_index_if([](auto const& local) { return local.declaration_kind == LocalVariable::DeclarationKind::ArgumentsObject; });
|
||||
if (local_var_index.has_value())
|
||||
dst = local(Identifier::Local::variable(local_var_index.value()));
|
||||
|
||||
|
@ -215,9 +215,10 @@ CodeGenerationErrorOr<void> Generator::emit_function_declaration_instantiation(E
|
|||
return {};
|
||||
}
|
||||
|
||||
CodeGenerationErrorOr<GC::Ref<Executable>> Generator::compile(VM& vm, ASTNode const& node, FunctionKind enclosing_function_kind, GC::Ptr<ECMAScriptFunctionObject const> function, MustPropagateCompletion must_propagate_completion, Vector<FlyString> local_variable_names)
|
||||
CodeGenerationErrorOr<GC::Ref<Executable>> Generator::compile(VM& vm, ASTNode const& node, FunctionKind enclosing_function_kind, GC::Ptr<ECMAScriptFunctionObject const> function, MustPropagateCompletion must_propagate_completion, Vector<LocalVariable> local_variable_names)
|
||||
{
|
||||
Generator generator(vm, function, must_propagate_completion);
|
||||
generator.m_local_variables = local_variable_names;
|
||||
|
||||
generator.switch_to_basic_block(generator.make_block());
|
||||
SourceLocationScope scope(generator, node);
|
||||
|
@ -483,7 +484,7 @@ CodeGenerationErrorOr<GC::Ref<Executable>> Generator::compile(VM& vm, ASTNode co
|
|||
|
||||
CodeGenerationErrorOr<GC::Ref<Executable>> Generator::generate_from_ast_node(VM& vm, ASTNode const& node, FunctionKind enclosing_function_kind)
|
||||
{
|
||||
Vector<FlyString> local_variable_names;
|
||||
Vector<LocalVariable> local_variable_names;
|
||||
if (is<ScopeNode>(node))
|
||||
local_variable_names = static_cast<ScopeNode const&>(node).local_variables_names();
|
||||
return compile(vm, node, enclosing_function_kind, {}, MustPropagateCompletion::Yes, move(local_variable_names));
|
||||
|
@ -1211,6 +1212,13 @@ void Generator::set_local_initialized(Identifier::Local const& local)
|
|||
}
|
||||
}
|
||||
|
||||
bool Generator::is_local_lexically_declared(Identifier::Local const& local) const
|
||||
{
|
||||
if (local.is_argument())
|
||||
return false;
|
||||
return m_local_variables[local.index].declaration_kind == LocalVariable::DeclarationKind::LetOrConst;
|
||||
}
|
||||
|
||||
ScopedOperand Generator::get_this(Optional<ScopedOperand> preferred_dst)
|
||||
{
|
||||
if (m_current_basic_block->has_resolved_this())
|
||||
|
|
|
@ -53,6 +53,7 @@ public:
|
|||
void set_local_initialized(Identifier::Local const&);
|
||||
[[nodiscard]] bool is_local_initialized(u32 local_index) const;
|
||||
[[nodiscard]] bool is_local_initialized(Identifier::Local const&) const;
|
||||
[[nodiscard]] bool is_local_lexically_declared(Identifier::Local const& local) const;
|
||||
|
||||
class SourceLocationScope {
|
||||
public:
|
||||
|
@ -358,7 +359,7 @@ public:
|
|||
private:
|
||||
VM& m_vm;
|
||||
|
||||
static CodeGenerationErrorOr<GC::Ref<Executable>> compile(VM&, ASTNode const&, FunctionKind, GC::Ptr<ECMAScriptFunctionObject const>, MustPropagateCompletion, Vector<FlyString> local_variable_names);
|
||||
static CodeGenerationErrorOr<GC::Ref<Executable>> compile(VM&, ASTNode const&, FunctionKind, GC::Ptr<ECMAScriptFunctionObject const>, MustPropagateCompletion, Vector<LocalVariable> local_variable_names);
|
||||
|
||||
enum class JumpType {
|
||||
Continue,
|
||||
|
@ -413,6 +414,7 @@ private:
|
|||
|
||||
HashTable<u32> m_initialized_locals;
|
||||
HashTable<u32> m_initialized_arguments;
|
||||
Vector<LocalVariable> m_local_variables;
|
||||
|
||||
bool m_finished { false };
|
||||
bool m_must_propagate_completion { true };
|
||||
|
|
|
@ -83,7 +83,7 @@ static ByteString format_operand(StringView name, Operand operand, Bytecode::Exe
|
|||
}
|
||||
break;
|
||||
case Operand::Type::Local:
|
||||
builder.appendff("\033[34m{}~{}\033[0m", executable.local_variable_names[operand.index() - executable.local_index_base], operand.index() - executable.local_index_base);
|
||||
builder.appendff("\033[34m{}~{}\033[0m", executable.local_variable_names[operand.index() - executable.local_index_base].name, operand.index() - executable.local_index_base);
|
||||
break;
|
||||
case Operand::Type::Argument:
|
||||
builder.appendff("\033[34marg{}\033[0m", operand.index() - executable.argument_index_base);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue