Bladeren bron

LibJS: Add support for running test-js with the bytecode interpreter

This obviously won't actually successfully run the test suite until
more of the AST expressions used by the test suite are supported.
Gunnar Beutner 4 jaren geleden
bovenliggende
commit
a612c22278

+ 37 - 2
Userland/Libraries/LibTest/JavaScriptTestRunner.h

@@ -19,6 +19,7 @@
 #include <LibCore/ArgsParser.h>
 #include <LibCore/DirIterator.h>
 #include <LibCore/File.h>
+#include <LibJS/Bytecode/Interpreter.h>
 #include <LibJS/Interpreter.h>
 #include <LibJS/Lexer.h>
 #include <LibJS/Parser.h>
@@ -104,6 +105,8 @@ static consteval size_t __testjs_last() { return (AK::Detail::IntegralConstant<s
 static constexpr auto TOP_LEVEL_TEST_NAME = "__$$TOP_LEVEL$$__";
 extern RefPtr<JS::VM> g_vm;
 extern bool g_collect_on_every_allocation;
+extern bool g_run_bytecode;
+extern bool g_dump_bytecode;
 extern String g_currently_running_test;
 extern String g_test_glob;
 struct FunctionWithLength {
@@ -385,12 +388,44 @@ inline JSFileResult TestRunner::run_file_test(const String& test_path)
         m_test_program = result.value();
     }
 
-    interpreter->run(interpreter->global_object(), *m_test_program);
+    if (g_run_bytecode) {
+        auto unit = JS::Bytecode::Generator::generate(*m_test_program);
+        if (g_dump_bytecode) {
+            for (auto& block : unit.basic_blocks)
+                block.dump(unit);
+            if (!unit.string_table->is_empty()) {
+                outln();
+                unit.string_table->dump();
+            }
+        }
+
+        JS::Bytecode::Interpreter bytecode_interpreter(interpreter->global_object());
+        bytecode_interpreter.run(unit);
+    } else {
+        interpreter->run(interpreter->global_object(), *m_test_program);
+    }
+
+    VERIFY(!g_vm->exception());
 
     auto file_program = parse_file(test_path);
     if (file_program.is_error())
         return { test_path, file_program.error() };
-    interpreter->run(interpreter->global_object(), *file_program.value());
+    if (g_run_bytecode) {
+        auto unit = JS::Bytecode::Generator::generate(*file_program.value());
+        if (g_dump_bytecode) {
+            for (auto& block : unit.basic_blocks)
+                block.dump(unit);
+            if (!unit.string_table->is_empty()) {
+                outln();
+                unit.string_table->dump();
+            }
+        }
+
+        JS::Bytecode::Interpreter bytecode_interpreter(interpreter->global_object());
+        bytecode_interpreter.run(unit);
+    } else {
+        interpreter->run(interpreter->global_object(), *file_program.value());
+    }
 
     if (g_vm->exception())
         g_vm->clear_exception();

+ 9 - 0
Userland/Libraries/LibTest/JavaScriptTestRunnerMain.cpp

@@ -14,6 +14,8 @@ namespace Test::JS {
 
 RefPtr<::JS::VM> g_vm;
 bool g_collect_on_every_allocation = false;
+bool g_run_bytecode = false;
+bool g_dump_bytecode = false;
 String g_currently_running_test;
 String g_test_glob;
 HashMap<String, FunctionWithLength> s_exposed_global_functions;
@@ -103,6 +105,8 @@ int main(int argc, char** argv)
     });
     args_parser.add_option(print_json, "Show results as JSON", "json", 'j');
     args_parser.add_option(g_collect_on_every_allocation, "Collect garbage after every allocation", "collect-often", 'g');
+    args_parser.add_option(g_run_bytecode, "Use the bytecode interpreter", "run-bytecode", 'b');
+    args_parser.add_option(g_dump_bytecode, "Dump the bytecode", "dump-bytecode", 'd');
     args_parser.add_option(g_test_glob, "Only run tests matching the given glob", "filter", 'f', "glob");
     for (auto& entry : g_extra_args)
         args_parser.add_option(*entry.key, entry.value.get<0>().characters(), entry.value.get<1>().characters(), entry.value.get<2>());
@@ -116,6 +120,11 @@ int main(int argc, char** argv)
         AK::set_debug_enabled(false);
     }
 
+    if (g_dump_bytecode && !g_run_bytecode) {
+        warnln("--dump-bytecode can only be used when --run-bytecode is specified.");
+        return 1;
+    }
+
     String test_root;
 
     if (specified_test_root) {