mirror of
https://github.com/RGBCube/serenity
synced 2025-06-28 21:02:07 +00:00
LibJS: Don't enter finally blocks upon yield
in bytecode mode
This commit is contained in:
parent
088dc1b24b
commit
1f6a0ef6e0
1 changed files with 9 additions and 1 deletions
|
@ -75,8 +75,10 @@ Interpreter::ValueAndFrame Interpreter::run_and_return_frame(Executable const& e
|
|||
Bytecode::InstructionStreamIterator pc(m_current_block->instruction_stream());
|
||||
TemporaryChange temp_change { m_pc, &pc };
|
||||
|
||||
// FIXME: This is getting kinda spaghetti-y
|
||||
bool will_jump = false;
|
||||
bool will_return = false;
|
||||
bool will_yield = false;
|
||||
while (!pc.at_end()) {
|
||||
auto& instruction = *pc;
|
||||
auto ran_or_error = instruction.execute(*this);
|
||||
|
@ -113,6 +115,12 @@ Interpreter::ValueAndFrame Interpreter::run_and_return_frame(Executable const& e
|
|||
}
|
||||
if (!m_return_value.is_empty()) {
|
||||
will_return = true;
|
||||
// Note: A `yield` statement will not go through a finally statement,
|
||||
// hence we need to set a flag to not do so,
|
||||
// but we generate a Yield Operation in the case of returns in
|
||||
// generators as well, so we need to check if it will actually
|
||||
// continue or is a `return` in disguise
|
||||
will_yield = instruction.type() == Instruction::Type::Yield && static_cast<Op::Yield const&>(instruction).continuation().has_value();
|
||||
break;
|
||||
}
|
||||
++pc;
|
||||
|
@ -121,7 +129,7 @@ Interpreter::ValueAndFrame Interpreter::run_and_return_frame(Executable const& e
|
|||
if (will_jump)
|
||||
continue;
|
||||
|
||||
if (!unwind_contexts().is_empty()) {
|
||||
if (!unwind_contexts().is_empty() && !will_yield) {
|
||||
auto& unwind_context = unwind_contexts().last();
|
||||
if (unwind_context.executable == m_current_executable && unwind_context.finalizer) {
|
||||
m_saved_return_value = make_handle(m_return_value);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue