From f75d78f56a907d4b3641dacd7461c2827c31ec86 Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Sun, 24 Oct 2021 14:33:56 +0200 Subject: [PATCH] LibJS: Include executable name in bytecode dumps --- Userland/Libraries/LibJS/Bytecode/Executable.cpp | 1 + Userland/Libraries/LibJS/Bytecode/Executable.h | 2 ++ Userland/Libraries/LibJS/Bytecode/Generator.cpp | 2 +- .../LibJS/Runtime/ECMAScriptFunctionObject.cpp | 5 +++-- Userland/Libraries/LibTest/JavaScriptTestRunner.h | 2 ++ Userland/Utilities/js.cpp | 10 +++++++--- 6 files changed, 16 insertions(+), 6 deletions(-) diff --git a/Userland/Libraries/LibJS/Bytecode/Executable.cpp b/Userland/Libraries/LibJS/Bytecode/Executable.cpp index caa34ba450..d2bd4423cc 100644 --- a/Userland/Libraries/LibJS/Bytecode/Executable.cpp +++ b/Userland/Libraries/LibJS/Bytecode/Executable.cpp @@ -10,6 +10,7 @@ namespace JS::Bytecode { void Executable::dump() const { + dbgln("\033[33;1mJS::Bytecode::Executable\033[0m ({})", name); for (auto& block : basic_blocks) block.dump(*this); if (!string_table->is_empty()) { diff --git a/Userland/Libraries/LibJS/Bytecode/Executable.h b/Userland/Libraries/LibJS/Bytecode/Executable.h index 7b20e8004d..c861222d52 100644 --- a/Userland/Libraries/LibJS/Bytecode/Executable.h +++ b/Userland/Libraries/LibJS/Bytecode/Executable.h @@ -6,6 +6,7 @@ #pragma once +#include #include #include #include @@ -13,6 +14,7 @@ namespace JS::Bytecode { struct Executable { + FlyString name; NonnullOwnPtrVector basic_blocks; NonnullOwnPtr string_table; size_t number_of_registers { 0 }; diff --git a/Userland/Libraries/LibJS/Bytecode/Generator.cpp b/Userland/Libraries/LibJS/Bytecode/Generator.cpp index c01e47e937..7cf0718996 100644 --- a/Userland/Libraries/LibJS/Bytecode/Generator.cpp +++ b/Userland/Libraries/LibJS/Bytecode/Generator.cpp @@ -44,7 +44,7 @@ Executable Generator::generate(ASTNode const& node, bool is_in_generator_functio generator.emit(nullptr); } } - return { move(generator.m_root_basic_blocks), move(generator.m_string_table), generator.m_next_register }; + return { {}, move(generator.m_root_basic_blocks), move(generator.m_string_table), generator.m_next_register }; } void Generator::grow(size_t additional_size) diff --git a/Userland/Libraries/LibJS/Runtime/ECMAScriptFunctionObject.cpp b/Userland/Libraries/LibJS/Runtime/ECMAScriptFunctionObject.cpp index b06b2235bc..accd057046 100644 --- a/Userland/Libraries/LibJS/Runtime/ECMAScriptFunctionObject.cpp +++ b/Userland/Libraries/LibJS/Runtime/ECMAScriptFunctionObject.cpp @@ -678,14 +678,15 @@ Completion ECMAScriptFunctionObject::ordinary_call_evaluate_body() TRY(function_declaration_instantiation(nullptr)); if (!m_bytecode_executable.has_value()) { m_bytecode_executable = Bytecode::Generator::generate(m_ecmascript_code, m_kind == FunctionKind::Generator); + m_bytecode_executable->name = m_name; auto& passes = JS::Bytecode::Interpreter::optimization_pipeline(); passes.perform(*m_bytecode_executable); if constexpr (JS_BYTECODE_DEBUG) { dbgln("Optimisation passes took {}us", passes.elapsed()); dbgln("Compiled Bytecode::Block for function '{}':", m_name); - for (auto& block : m_bytecode_executable->basic_blocks) - block.dump(*m_bytecode_executable); } + if (JS::Bytecode::g_dump_bytecode) + m_bytecode_executable->dump(); } auto result = bytecode_interpreter->run(*m_bytecode_executable); if (auto* exception = vm.exception()) diff --git a/Userland/Libraries/LibTest/JavaScriptTestRunner.h b/Userland/Libraries/LibTest/JavaScriptTestRunner.h index 436c327d48..231986f847 100644 --- a/Userland/Libraries/LibTest/JavaScriptTestRunner.h +++ b/Userland/Libraries/LibTest/JavaScriptTestRunner.h @@ -337,6 +337,7 @@ inline JSFileResult TestRunner::run_file_test(const String& test_path) if (g_run_bytecode) { auto executable = JS::Bytecode::Generator::generate(m_test_script->parse_node()); + executable.name = test_path; if (JS::Bytecode::g_dump_bytecode) executable.dump(); JS::Bytecode::Interpreter bytecode_interpreter(interpreter->global_object(), interpreter->realm()); @@ -352,6 +353,7 @@ inline JSFileResult TestRunner::run_file_test(const String& test_path) return { test_path, file_script.error() }; if (g_run_bytecode) { auto executable = JS::Bytecode::Generator::generate(file_script.value()->parse_node()); + executable.name = test_path; if (JS::Bytecode::g_dump_bytecode) executable.dump(); JS::Bytecode::Interpreter bytecode_interpreter(interpreter->global_object(), interpreter->realm()); diff --git a/Userland/Utilities/js.cpp b/Userland/Utilities/js.cpp index 18acb52f92..2df4b1b24a 100644 --- a/Userland/Utilities/js.cpp +++ b/Userland/Utilities/js.cpp @@ -807,7 +807,7 @@ static bool write_to_file(String const& path) return true; } -static bool parse_and_run(JS::Interpreter& interpreter, StringView const& source) +static bool parse_and_run(JS::Interpreter& interpreter, StringView source, StringView source_name) { auto program_type = s_as_module ? JS::Program::Type::Module : JS::Program::Type::Script; auto parser = JS::Parser(JS::Lexer(source), program_type); @@ -825,6 +825,7 @@ static bool parse_and_run(JS::Interpreter& interpreter, StringView const& source } else { if (JS::Bytecode::g_dump_bytecode || s_run_bytecode) { auto executable = JS::Bytecode::Generator::generate(*program); + executable.name = source_name; if (s_opt_bytecode) { auto& passes = JS::Bytecode::Interpreter::optimization_pipeline(); passes.perform(executable); @@ -1006,7 +1007,7 @@ static void repl(JS::Interpreter& interpreter) if (piece.is_empty()) continue; repl_statements.append(piece); - parse_and_run(interpreter, piece); + parse_and_run(interpreter, piece, "REPL"); } } @@ -1400,7 +1401,10 @@ int main(int argc, char** argv) builder.append(source); } - if (!parse_and_run(*interpreter, builder.to_string())) + StringBuilder source_name_builder; + source_name_builder.join(", ", script_paths); + + if (!parse_and_run(*interpreter, builder.string_view(), source_name_builder.string_view())) return 1; }