1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-25 18:37:35 +00:00

LibJS/Bytecode: Leave GlobalDeclarationInstantiation in C++

Don't try to implement this AO in bytecode. Instead, the bytecode
Interpreter class now has a run() API with the same inputs as the AST
interpreter. It sets up the necessary environments etc, including
invoking the GlobalDeclarationInstantiation AO.
This commit is contained in:
Andreas Kling 2023-06-15 12:36:57 +02:00
parent 32d9c8e3ca
commit d063f35afd
12 changed files with 172 additions and 284 deletions

View file

@ -22,7 +22,7 @@
#define EXPECT_NO_EXCEPTION(executable) \
auto executable = MUST(JS::Bytecode::Generator::generate(program)); \
auto result = bytecode_interpreter.run(*executable); \
auto result = bytecode_interpreter.run(*script); \
if (result.is_error()) { \
FAIL("unexpected exception"); \
dbgln("Error: {}", MUST(result.throw_completion().value()->to_deprecated_string(vm))); \
@ -113,11 +113,8 @@ TEST_CASE(loading_multiple_files)
auto test_file_script = MUST(JS::Script::parse(
"if (f() !== 'hello') throw new Exception('failed'); "sv, ast_interpreter->realm()));
auto const& test_file_program = test_file_script->parse_node();
auto executable = MUST(JS::Bytecode::Generator::generate(test_file_program));
// TODO: This could be TRY_OR_FAIL(), if someone implements Formatter<JS::Completion>.
MUST(bytecode_interpreter.run(*executable));
MUST(bytecode_interpreter.run(test_file_script));
}
}

View file

@ -79,35 +79,10 @@ static Result<ScriptOrModuleProgram, TestError> parse_program(JS::Realm& realm,
template<typename InterpreterT>
static Result<void, TestError> run_program(InterpreterT& interpreter, ScriptOrModuleProgram& program)
{
auto result = JS::ThrowCompletionOr<JS::Value> { JS::js_undefined() };
if constexpr (IsSame<InterpreterT, JS::Interpreter>) {
result = program.visit(
[&](auto& visitor) {
return interpreter.run(*visitor);
});
} else {
auto program_node = program.visit(
[](auto& visitor) -> NonnullRefPtr<JS::Program const> {
return visitor->parse_node();
});
auto& vm = interpreter.vm();
if (auto unit_result = JS::Bytecode::Generator::generate(program_node); unit_result.is_error()) {
if (auto error_string = unit_result.error().to_string(); error_string.is_error())
result = vm.template throw_completion<JS::InternalError>(vm.error_message(JS::VM::ErrorMessage::OutOfMemory));
else if (error_string = String::formatted("TODO({})", error_string.value()); error_string.is_error())
result = vm.template throw_completion<JS::InternalError>(vm.error_message(JS::VM::ErrorMessage::OutOfMemory));
else
result = JS::throw_completion(JS::InternalError::create(interpreter.realm(), error_string.release_value()));
} else {
auto unit = unit_result.release_value();
auto optimization_level = s_enable_bytecode_optimizations ? JS::Bytecode::Interpreter::OptimizationLevel::Optimize : JS::Bytecode::Interpreter::OptimizationLevel::Default;
auto& passes = JS::Bytecode::Interpreter::optimization_pipeline(optimization_level);
passes.perform(*unit);
result = interpreter.run(*unit);
}
}
auto result = program.visit(
[&](auto& visitor) {
return interpreter.run(*visitor);
});
if (result.is_error()) {
auto error_value = *result.throw_completion().value();