diff --git a/Userland/Libraries/LibJS/Bytecode/Interpreter.cpp b/Userland/Libraries/LibJS/Bytecode/Interpreter.cpp index db0755acc5..234b5537c9 100644 --- a/Userland/Libraries/LibJS/Bytecode/Interpreter.cpp +++ b/Userland/Libraries/LibJS/Bytecode/Interpreter.cpp @@ -39,7 +39,7 @@ Interpreter::~Interpreter() s_current = nullptr; } -Value Interpreter::run(Executable const& executable, BasicBlock const* entry_point) +Interpreter::ValueAndFrame Interpreter::run_and_return_frame(Executable const& executable, BasicBlock const* entry_point) { dbgln_if(JS_BYTECODE_DEBUG, "Bytecode::Interpreter will run unit {:p}", &executable); @@ -62,14 +62,16 @@ Value Interpreter::run(Executable const& executable, BasicBlock const* entry_poi } auto block = entry_point ?: &executable.basic_blocks.first(); - if (m_manually_entered_frames) { - VERIFY(registers().size() >= executable.number_of_registers); + if (!m_manually_entered_frames.is_empty() && m_manually_entered_frames.last()) { + m_register_windows.append(make(m_register_windows.last())); } else { m_register_windows.append(make()); - registers().resize(executable.number_of_registers); - registers()[Register::global_object_index] = Value(&global_object()); } + registers().resize(executable.number_of_registers); + registers()[Register::global_object_index] = Value(&global_object()); + m_manually_entered_frames.append(false); + for (;;) { Bytecode::InstructionStreamIterator pc(block->instruction_stream()); bool will_jump = false; @@ -138,8 +140,11 @@ Value Interpreter::run(Executable const& executable, BasicBlock const* entry_poi vm().set_last_value(Badge {}, accumulator()); - if (!m_manually_entered_frames) - m_register_windows.take_last(); + OwnPtr frame; + if (!m_manually_entered_frames.last()) { + frame = m_register_windows.take_last(); + m_manually_entered_frames.take_last(); + } auto return_value = m_return_value.value_or(js_undefined()); m_return_value = {}; @@ -153,7 +158,7 @@ Value Interpreter::run(Executable const& executable, BasicBlock const* entry_poi vm().finish_execution_generation(); - return return_value; + return { return_value, move(frame) }; } void Interpreter::enter_unwind_context(Optional