1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-05-30 21:58:10 +00:00

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.
This commit is contained in:
Gunnar Beutner 2021-06-12 05:49:25 +02:00 committed by Andreas Kling
parent 6a78b44c22
commit a612c22278
2 changed files with 46 additions and 2 deletions

View file

@ -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();
}
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() };
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();

View file

@ -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) {