Browse Source

LibJS: Add Bytecode::Executable::dump()

Let's have a helper for producing a consistent executable dump instead
of repeating the logic in multiple places.
Andreas Kling 3 năm trước cách đây
mục cha
commit
da77e2aa4f

+ 21 - 0
Userland/Libraries/LibJS/Bytecode/Executable.cpp

@@ -0,0 +1,21 @@
+/*
+ * Copyright (c) 2021, Andreas Kling <kling@serenityos.org>
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+
+#include <LibJS/Bytecode/Executable.h>
+
+namespace JS::Bytecode {
+
+void Executable::dump() const
+{
+    for (auto& block : basic_blocks)
+        block.dump(*this);
+    if (!string_table->is_empty()) {
+        outln();
+        string_table->dump();
+    }
+}
+
+}

+ 25 - 0
Userland/Libraries/LibJS/Bytecode/Executable.h

@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2021, Andreas Kling <kling@serenityos.org>
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+
+#pragma once
+
+#include <AK/NonnullOwnPtrVector.h>
+#include <LibJS/Bytecode/BasicBlock.h>
+#include <LibJS/Bytecode/StringTable.h>
+
+namespace JS::Bytecode {
+
+struct Executable {
+    NonnullOwnPtrVector<BasicBlock> basic_blocks;
+    NonnullOwnPtr<StringTable> string_table;
+    size_t number_of_registers { 0 };
+
+    String const& get_string(StringTableIndex index) const { return string_table->get(index); }
+
+    void dump() const;
+};
+
+}

+ 1 - 8
Userland/Libraries/LibJS/Bytecode/Generator.h

@@ -10,6 +10,7 @@
 #include <AK/OwnPtr.h>
 #include <AK/SinglyLinkedList.h>
 #include <LibJS/Bytecode/BasicBlock.h>
+#include <LibJS/Bytecode/Executable.h>
 #include <LibJS/Bytecode/Label.h>
 #include <LibJS/Bytecode/Op.h>
 #include <LibJS/Bytecode/Register.h>
@@ -18,14 +19,6 @@
 
 namespace JS::Bytecode {
 
-struct Executable {
-    NonnullOwnPtrVector<BasicBlock> basic_blocks;
-    NonnullOwnPtr<StringTable> string_table;
-    size_t number_of_registers { 0 };
-
-    String const& get_string(StringTableIndex index) const { return string_table->get(index); }
-};
-
 class Generator {
 public:
     static Executable generate(ASTNode const&, bool is_in_generator_function = false);

+ 1 - 0
Userland/Libraries/LibJS/CMakeLists.txt

@@ -2,6 +2,7 @@ set(SOURCES
     AST.cpp
     Bytecode/ASTCodegen.cpp
     Bytecode/BasicBlock.cpp
+    Bytecode/Executable.cpp
     Bytecode/Generator.cpp
     Bytecode/Instruction.cpp
     Bytecode/Interpreter.cpp

+ 8 - 22
Userland/Libraries/LibTest/JavaScriptTestRunner.h

@@ -337,18 +337,11 @@ inline JSFileResult TestRunner::run_file_test(const String& test_path)
     }
 
     if (g_run_bytecode) {
-        auto unit = JS::Bytecode::Generator::generate(m_test_script->parse_node());
-        if (g_dump_bytecode) {
-            for (auto& block : unit.basic_blocks)
-                block.dump(unit);
-            if (!unit.string_table->is_empty()) {
-                outln();
-                unit.string_table->dump();
-            }
-        }
-
+        auto executable = JS::Bytecode::Generator::generate(m_test_script->parse_node());
+        if (g_dump_bytecode)
+            executable.dump();
         JS::Bytecode::Interpreter bytecode_interpreter(interpreter->global_object(), interpreter->realm());
-        bytecode_interpreter.run(unit);
+        bytecode_interpreter.run(executable);
     } else {
         interpreter->run(interpreter->global_object(), m_test_script->parse_node());
     }
@@ -359,18 +352,11 @@ inline JSFileResult TestRunner::run_file_test(const String& test_path)
     if (file_script.is_error())
         return { test_path, file_script.error() };
     if (g_run_bytecode) {
-        auto unit = JS::Bytecode::Generator::generate(file_script.value()->parse_node());
-        if (g_dump_bytecode) {
-            for (auto& block : unit.basic_blocks)
-                block.dump(unit);
-            if (!unit.string_table->is_empty()) {
-                outln();
-                unit.string_table->dump();
-            }
-        }
-
+        auto executable = JS::Bytecode::Generator::generate(file_script.value()->parse_node());
+        if (g_dump_bytecode)
+            executable.dump();
         JS::Bytecode::Interpreter bytecode_interpreter(interpreter->global_object(), interpreter->realm());
-        bytecode_interpreter.run(unit);
+        bytecode_interpreter.run(executable);
     } else {
         interpreter->run(interpreter->global_object(), file_script.value()->parse_node());
     }