From ddce5e03c21bae4c628d46b37938c9f511c1f435 Mon Sep 17 00:00:00 2001 From: Simon Wanner Date: Sun, 29 Oct 2023 02:24:51 +0200 Subject: [PATCH] LibJS/JIT: Clear unwind context handler on usage This clears the handler pointer of the current unwind context before jumping to it. This is necessary to not loop infinitely when an exception is thrown from the handler. In that case control flow should go to the finalizer instead. This mirrors how unwind_context.handler_called is used in the Bytecode::Interpreter. `try { throw 1 } catch (e) { throw 2 } finally {}` now runs without looping infinitely in the catch block. --- Userland/Libraries/LibJS/JIT/Compiler.cpp | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/Userland/Libraries/LibJS/JIT/Compiler.cpp b/Userland/Libraries/LibJS/JIT/Compiler.cpp index 10a9507982..c22c3eb43b 100644 --- a/Userland/Libraries/LibJS/JIT/Compiler.cpp +++ b/Userland/Libraries/LibJS/JIT/Compiler.cpp @@ -346,10 +346,6 @@ void Compiler::handle_exception() handle_exception.link(m_assembler); // if (unwind_context.handler) { - // accumulator = exception; - // exception = Value(); - // goto handler; - // } Assembler::Label no_handler {}; m_assembler.mov( Assembler::Operand::Register(GPR0), @@ -358,13 +354,24 @@ void Compiler::handle_exception() Assembler::Operand::Register(GPR0), Assembler::Operand::Imm(0), no_handler); + // accumulator = exception; load_vm_register(GPR1, Bytecode::Register::exception()); store_vm_register(Bytecode::Register::accumulator(), GPR1); + // exception = Value(); m_assembler.mov( Assembler::Operand::Register(GPR1), Assembler::Operand::Imm(Value().encoded())); store_vm_register(Bytecode::Register::exception(), GPR1); + // unwind_context.handler = nullptr; + m_assembler.mov( + Assembler::Operand::Register(GPR1), + Assembler::Operand::Imm(0)); + m_assembler.mov( + Assembler::Operand::Mem64BaseAndOffset(UNWIND_CONTEXT_BASE, 8), + Assembler::Operand::Register(GPR1)); + // goto handler; m_assembler.jump(Assembler::Operand::Register(GPR0)); + // } // no_handler: no_handler.link(m_assembler);