LibJS: Restore scheduled jumps in catch blocks without finalizers

This commit is contained in:
Hendiadyoin1 2024-04-11 11:07:35 +02:00 committed by Andreas Kling
parent 301a1fc763
commit b4b9c4b383
Notes: sideshowbarker 2024-07-17 03:18:29 +09:00
5 changed files with 32 additions and 1 deletions

View File

@ -2461,8 +2461,10 @@ Bytecode::CodeGenerationErrorOr<Optional<Bytecode::Operand>> TryStatement::gener
auto caught_value = Bytecode::Operand { generator.allocate_register() };
generator.emit<Bytecode::Op::Catch>(caught_value);
if (!m_finalizer)
if (!m_finalizer) {
generator.emit<Bytecode::Op::LeaveUnwindContext>();
generator.emit<Bytecode::Op::RestoreScheduledJump>();
}
// OPTIMIZATION: We avoid creating a lexical environment if the catch clause has no parameter.
bool did_create_variable_scope_for_catch_clause = false;

View File

@ -98,6 +98,7 @@
O(PutPrivateById) \
O(ResolveThisBinding) \
O(ResolveSuperBase) \
O(RestoreScheduledJump) \
O(Return) \
O(RightShift) \
O(ScheduleJump) \

View File

@ -537,6 +537,11 @@ void Interpreter::catch_exception(Operand dst)
vm().running_execution_context().lexical_environment = context.lexical_environment;
}
void Interpreter::restore_scheduled_jump()
{
m_scheduled_jump = call_frame().previously_scheduled_jumps.take_last();
}
void Interpreter::enter_object_environment(Object& object)
{
auto& running_execution_context = vm().running_execution_context();
@ -1020,6 +1025,12 @@ ThrowCompletionOr<void> Catch::execute_impl(Bytecode::Interpreter& interpreter)
return {};
}
ThrowCompletionOr<void> RestoreScheduledJump::execute_impl(Bytecode::Interpreter& interpreter) const
{
interpreter.restore_scheduled_jump();
return {};
}
ThrowCompletionOr<void> CreateVariable::execute_impl(Bytecode::Interpreter& interpreter) const
{
auto const& name = interpreter.current_executable().get_identifier(m_identifier);
@ -2231,6 +2242,11 @@ ByteString Catch::to_byte_string_impl(Bytecode::Executable const& executable) co
format_operand("dst"sv, m_dst, executable));
}
ByteString RestoreScheduledJump::to_byte_string_impl(Bytecode::Executable const&) const
{
return ByteString::formatted("RestoreScheduledJump");
}
ByteString GetObjectFromIteratorRecord::to_byte_string_impl(Bytecode::Executable const& executable) const
{
return ByteString::formatted("GetObjectFromIteratorRecord {}, {}",

View File

@ -68,6 +68,7 @@ public:
void enter_unwind_context();
void leave_unwind_context();
void catch_exception(Operand dst);
void restore_scheduled_jump();
void enter_object_environment(Object&);

View File

@ -452,6 +452,17 @@ private:
Operand m_dst;
};
class RestoreScheduledJump final : public Instruction {
public:
explicit RestoreScheduledJump()
: Instruction(Type::RestoreScheduledJump, sizeof(*this))
{
}
ThrowCompletionOr<void> execute_impl(Bytecode::Interpreter&) const;
ByteString to_byte_string_impl(Bytecode::Executable const&) const;
};
class CreateVariable final : public Instruction {
public:
explicit CreateVariable(IdentifierTableIndex identifier, EnvironmentMode mode, bool is_immutable, bool is_global = false, bool is_strict = false)