diff --git a/Userland/Libraries/LibJS/Bytecode/Executable.h b/Userland/Libraries/LibJS/Bytecode/Executable.h index 01270a0f0b..6ba6a850b9 100644 --- a/Userland/Libraries/LibJS/Bytecode/Executable.h +++ b/Userland/Libraries/LibJS/Bytecode/Executable.h @@ -82,6 +82,9 @@ public: HashMap source_map; + Vector local_variable_names; + size_t local_index_base { 0 }; + ByteString const& get_string(StringTableIndex index) const { return string_table->get(index); } DeprecatedFlyString const& get_identifier(IdentifierTableIndex index) const { return identifier_table->get(index); } diff --git a/Userland/Libraries/LibJS/Bytecode/Generator.cpp b/Userland/Libraries/LibJS/Bytecode/Generator.cpp index b1a81aef2a..fa54cb6adf 100644 --- a/Userland/Libraries/LibJS/Bytecode/Generator.cpp +++ b/Userland/Libraries/LibJS/Bytecode/Generator.cpp @@ -199,7 +199,7 @@ CodeGenerationErrorOr Generator::emit_function_declaration_instantiation(E return {}; } -CodeGenerationErrorOr> Generator::compile(VM& vm, ASTNode const& node, FunctionKind enclosing_function_kind, GCPtr function, MustPropagateCompletion must_propagate_completion) +CodeGenerationErrorOr> Generator::compile(VM& vm, ASTNode const& node, FunctionKind enclosing_function_kind, GCPtr function, MustPropagateCompletion must_propagate_completion, Vector local_variable_names) { Generator generator(vm, function, must_propagate_completion); @@ -451,6 +451,8 @@ CodeGenerationErrorOr> Generator::compile(VM& vm, ASTNo executable->exception_handlers = move(linked_exception_handlers); executable->basic_block_start_offsets = move(basic_block_start_offsets); executable->source_map = move(source_map); + executable->local_variable_names = move(local_variable_names); + executable->local_index_base = number_of_registers + number_of_constants; generator.m_finished = true; @@ -459,12 +461,15 @@ CodeGenerationErrorOr> Generator::compile(VM& vm, ASTNo CodeGenerationErrorOr> Generator::generate_from_ast_node(VM& vm, ASTNode const& node, FunctionKind enclosing_function_kind) { - return compile(vm, node, enclosing_function_kind, {}); + Vector local_variable_names; + if (is(node)) + local_variable_names = static_cast(node).local_variables_names(); + return compile(vm, node, enclosing_function_kind, {}, MustPropagateCompletion::Yes, move(local_variable_names)); } CodeGenerationErrorOr> Generator::generate_from_function(VM& vm, ECMAScriptFunctionObject const& function) { - return compile(vm, function.ecmascript_code(), function.kind(), &function, MustPropagateCompletion::No); + return compile(vm, function.ecmascript_code(), function.kind(), &function, MustPropagateCompletion::No, function.local_variables_names()); } void Generator::grow(size_t additional_size) diff --git a/Userland/Libraries/LibJS/Bytecode/Generator.h b/Userland/Libraries/LibJS/Bytecode/Generator.h index 255ed214cc..139ae51791 100644 --- a/Userland/Libraries/LibJS/Bytecode/Generator.h +++ b/Userland/Libraries/LibJS/Bytecode/Generator.h @@ -343,7 +343,7 @@ public: private: VM& m_vm; - static CodeGenerationErrorOr> compile(VM&, ASTNode const&, FunctionKind, GCPtr, MustPropagateCompletion = MustPropagateCompletion::Yes); + static CodeGenerationErrorOr> compile(VM&, ASTNode const&, FunctionKind, GCPtr, MustPropagateCompletion, Vector local_variable_names); enum class JumpType { Continue, diff --git a/Userland/Libraries/LibJS/Bytecode/Interpreter.cpp b/Userland/Libraries/LibJS/Bytecode/Interpreter.cpp index deb01be7c7..16a1eb3131 100644 --- a/Userland/Libraries/LibJS/Bytecode/Interpreter.cpp +++ b/Userland/Libraries/LibJS/Bytecode/Interpreter.cpp @@ -53,8 +53,7 @@ static ByteString format_operand(StringView name, Operand operand, Bytecode::Exe } break; case Operand::Type::Local: - // FIXME: Show local name. - builder.appendff("\033[34mloc{}\033[0m", operand.index()); + builder.appendff("\033[34m{}~{}\033[0m", executable.local_variable_names[operand.index() - executable.local_index_base], operand.index() - executable.local_index_base); break; case Operand::Type::Constant: { builder.append("\033[36m"sv); @@ -708,9 +707,9 @@ Interpreter::ResultAndReturnRegister Interpreter::run_executable(Executable& exe VERIFY(!vm().execution_context_stack().is_empty()); auto& running_execution_context = vm().running_execution_context(); - u32 registers_and_contants_count = executable.number_of_registers + executable.constants.size(); - if (running_execution_context.registers_and_constants_and_locals.size() < registers_and_contants_count) - running_execution_context.registers_and_constants_and_locals.resize(registers_and_contants_count); + u32 registers_and_constants_and_locals_count = executable.number_of_registers + executable.constants.size() + executable.local_variable_names.size(); + if (running_execution_context.registers_and_constants_and_locals.size() < registers_and_constants_and_locals_count) + running_execution_context.registers_and_constants_and_locals.resize(registers_and_constants_and_locals_count); TemporaryChange restore_running_execution_context { m_running_execution_context, &running_execution_context }; TemporaryChange restore_arguments { m_arguments, running_execution_context.arguments.span() };