mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-10-05 07:39:16 +00:00
LibJS: Save and restore exceptions on yields in finalizers
Also removes a bunch of related old FIXMEs.
This commit is contained in:
parent
8d3eb937c8
commit
af94e4c05d
Notes:
sideshowbarker
2024-07-16 23:05:02 +09:00
Author: https://github.com/Hendiadyoin1
Commit: af94e4c05d
Pull-request: https://github.com/SerenityOS/serenity/pull/24244
4 changed files with 41 additions and 10 deletions
|
@ -1782,6 +1782,12 @@ static void generate_yield(Bytecode::Generator& generator,
|
|||
|
||||
Bytecode::CodeGenerationErrorOr<Optional<Bytecode::Operand>> YieldExpression::generate_bytecode(Bytecode::Generator& generator, [[maybe_unused]] Optional<Bytecode::Operand> preferred_dst) const
|
||||
{
|
||||
// Note: We need to catch any scheduled exceptions and reschedule them on re-entry
|
||||
// as the act of yielding would otherwise clear them out
|
||||
// This only applies when we are in a finalizer
|
||||
bool is_in_finalizer = generator.is_in_finalizer();
|
||||
Optional<Bytecode::Register> saved_exception;
|
||||
|
||||
Bytecode::Generator::SourceLocationScope scope(generator, *this);
|
||||
VERIFY(generator.is_in_generator_function());
|
||||
|
||||
|
@ -1890,6 +1896,11 @@ Bytecode::CodeGenerationErrorOr<Optional<Bytecode::Operand>> YieldExpression::ge
|
|||
auto current_value = Bytecode::Operand(generator.allocate_register());
|
||||
generator.emit_iterator_value(current_value, inner_result);
|
||||
|
||||
if (is_in_finalizer) {
|
||||
saved_exception = generator.allocate_register();
|
||||
generator.emit<Bytecode::Op::Mov>(Bytecode::Operand(*saved_exception), Bytecode::Operand(Bytecode::Register::exception()));
|
||||
}
|
||||
|
||||
generate_yield(generator,
|
||||
Bytecode::Label { continuation_block },
|
||||
current_value,
|
||||
|
@ -2077,6 +2088,10 @@ Bytecode::CodeGenerationErrorOr<Optional<Bytecode::Operand>> YieldExpression::ge
|
|||
generate_yield(generator, Bytecode::Label { continuation_block }, received, received_completion, received_completion_type, received_completion_value, type_identifier, value_identifier, AwaitBeforeYield::No);
|
||||
|
||||
generator.switch_to_basic_block(continuation_block);
|
||||
|
||||
if (is_in_finalizer)
|
||||
generator.emit<Bytecode::Op::Mov>(Bytecode::Operand(Bytecode::Register::exception()), Bytecode::Operand(*saved_exception));
|
||||
|
||||
generator.emit<Bytecode::Op::Mov>(received_completion, Bytecode::Operand(Bytecode::Register(0)));
|
||||
get_received_completion_type_and_value(generator, received_completion, received_completion_type, received_completion_value, type_identifier, value_identifier);
|
||||
generator.emit<Bytecode::Op::Jump>(Bytecode::Label { loop_block });
|
||||
|
@ -2092,8 +2107,18 @@ Bytecode::CodeGenerationErrorOr<Optional<Bytecode::Operand>> YieldExpression::ge
|
|||
argument = generator.add_constant(js_undefined());
|
||||
|
||||
auto& continuation_block = generator.make_block();
|
||||
|
||||
if (is_in_finalizer) {
|
||||
saved_exception = generator.allocate_register();
|
||||
generator.emit<Bytecode::Op::Mov>(Bytecode::Operand(*saved_exception), Bytecode::Operand(Bytecode::Register::exception()));
|
||||
}
|
||||
|
||||
generate_yield(generator, Bytecode::Label { continuation_block }, *argument, received_completion, received_completion_type, received_completion_value, type_identifier, value_identifier, AwaitBeforeYield::Yes);
|
||||
generator.switch_to_basic_block(continuation_block);
|
||||
|
||||
if (is_in_finalizer)
|
||||
generator.emit<Bytecode::Op::Mov>(Bytecode::Operand(Bytecode::Register::exception()), Bytecode::Operand(*saved_exception));
|
||||
|
||||
generator.emit<Bytecode::Op::Mov>(received_completion, Bytecode::Operand(Bytecode::Register(0)));
|
||||
get_received_completion_type_and_value(generator, received_completion, received_completion_type, received_completion_value, type_identifier, value_identifier);
|
||||
|
||||
|
@ -2190,9 +2215,6 @@ Bytecode::CodeGenerationErrorOr<Optional<Bytecode::Operand>> IfStatement::genera
|
|||
Bytecode::CodeGenerationErrorOr<Optional<Bytecode::Operand>> ContinueStatement::generate_bytecode(Bytecode::Generator& generator, [[maybe_unused]] Optional<Bytecode::Operand> preferred_dst) const
|
||||
{
|
||||
Bytecode::Generator::SourceLocationScope scope(generator, *this);
|
||||
// FIXME: Handle finally blocks in a graceful manner
|
||||
// We need to execute the finally block, but tell it to resume
|
||||
// execution at the designated block
|
||||
if (!m_target_label.has_value()) {
|
||||
generator.generate_continue();
|
||||
return Optional<Bytecode::Operand> {};
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue