From 776e5d38cd69d4e7bb84fec83994cb6e324a5b0e Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Thu, 13 Jun 2024 21:19:06 +0200 Subject: [PATCH] LibJS/Bytecode: Display local variable names in bytecode dumps Instead of displaying locals as "locN", we now show them as "name~N". This makes it a lot easier to follow bytecode dumps, especially in longer functions. Note that we keep displaying the local index, to avoid confusion in case there are multiple separate locals with the same name in one executable. (cherry picked from commit 0aa8cb7dac60c88eac3bb7674e3fe575cf1da60b) --- Userland/Libraries/LibJS/Bytecode/Executable.h | 3 +++ Userland/Libraries/LibJS/Bytecode/Generator.cpp | 11 ++++++++--- Userland/Libraries/LibJS/Bytecode/Generator.h | 2 +- Userland/Libraries/LibJS/Bytecode/Interpreter.cpp | 9 ++++----- 4 files changed, 16 insertions(+), 9 deletions(-) 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() };