1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-02 20:22:13 +00:00

LibJS/JIT: Update "unwind context" stack in JIT code

Until now, the unwind context stack has not been maintained by jitted
code, which meant we were unable to support the `with` statement.
This is a first step towards supporting that by making jitted code
call out to C++ to update the unwind context stack when entering/leaving
unwind contexts.

We also introduce a new "Catch" bytecode instruction that moves the
current exception into the accumulator. It's always emitted at the start
of a "catch" block.
This commit is contained in:
Andreas Kling 2023-11-11 23:19:46 +01:00
parent 298dfa96a4
commit cfdb8a2756
7 changed files with 60 additions and 7 deletions

View file

@ -294,13 +294,7 @@ void Interpreter::run_bytecode()
VERIFY(unwind_context.executable == m_current_executable);
if (handler) {
VERIFY(!unwind_context.handler_called);
vm().running_execution_context().lexical_environment = unwind_context.lexical_environment;
m_current_block = handler;
unwind_context.handler_called = true;
accumulator = reg(Register::exception());
reg(Register::exception()) = {};
goto start;
}
if (finalizer) {
@ -439,6 +433,17 @@ void Interpreter::leave_unwind_context()
unwind_contexts().take_last();
}
void Interpreter::catch_exception()
{
accumulator() = reg(Register::exception());
reg(Register::exception()) = {};
auto& context = unwind_contexts().last();
VERIFY(!context.handler_called);
VERIFY(context.executable == &current_executable());
context.handler_called = true;
vm().running_execution_context().lexical_environment = context.lexical_environment;
}
ThrowCompletionOr<NonnullRefPtr<Bytecode::Executable>> compile(VM& vm, ASTNode const& node, FunctionKind kind, DeprecatedFlyString const& name)
{
auto executable_result = Bytecode::Generator::generate(node, kind);
@ -746,6 +751,12 @@ ThrowCompletionOr<void> EnterObjectEnvironment::execute_impl(Bytecode::Interpret
return {};
}
ThrowCompletionOr<void> Catch::execute_impl(Bytecode::Interpreter& interpreter) const
{
interpreter.catch_exception();
return {};
}
ThrowCompletionOr<void> CreateVariable::execute_impl(Bytecode::Interpreter& interpreter) const
{
auto const& name = interpreter.current_executable().get_identifier(m_identifier);
@ -1733,4 +1744,9 @@ DeprecatedString ImportCall::to_deprecated_string_impl(Bytecode::Executable cons
return DeprecatedString::formatted("ImportCall specifier:{} options:{}"sv, m_specifier, m_options);
}
DeprecatedString Catch::to_deprecated_string_impl(Bytecode::Executable const&) const
{
return "Catch"sv;
}
}