From 2372584b189bd00d2d538a9d25f2f572a70da77e Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Mon, 20 Nov 2023 00:26:25 +0100 Subject: [PATCH] LibJS/JIT: Continue to outer `finally` before returning Fixes #21854 --- Userland/Libraries/LibJS/JIT/Compiler.cpp | 11 ++++++++--- .../Libraries/LibJS/Tests/try-return-finally.js | 15 +++++++++++++++ 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/Userland/Libraries/LibJS/JIT/Compiler.cpp b/Userland/Libraries/LibJS/JIT/Compiler.cpp index 9b461f92c6..b26efd471e 100644 --- a/Userland/Libraries/LibJS/JIT/Compiler.cpp +++ b/Userland/Libraries/LibJS/JIT/Compiler.cpp @@ -2899,9 +2899,14 @@ void Compiler::compile_continue_pending_unwind(Bytecode::Op::ContinuePendingUnwi Assembler::Operand::Register(GPR1), label_for(op.resume_target().block())); - // finish the pending return from the try block - store_vm_register(Bytecode::Register::return_value(), GPR0); - jump_to_exit(); + if (auto const* finalizer = m_current_block->finalizer()) { + // The current block has its own finalizer, we have to jump there instead of returning. + m_assembler.jump(label_for(*finalizer)); + } else { + // finish the pending return from the try block + store_vm_register(Bytecode::Register::return_value(), GPR0); + jump_to_exit(); + } } static void cxx_create_lexical_environment(VM& vm) diff --git a/Userland/Libraries/LibJS/Tests/try-return-finally.js b/Userland/Libraries/LibJS/Tests/try-return-finally.js index b134fc88ef..f0fb85dccd 100644 --- a/Userland/Libraries/LibJS/Tests/try-return-finally.js +++ b/Userland/Libraries/LibJS/Tests/try-return-finally.js @@ -9,3 +9,18 @@ test("return from try followed by finally with function call inside", () => { expect(value).toBe(1); }); + +test("return from outer finally with nested unwind contexts", () => { + let value = (() => { + try { + try { + return 1; + } finally { + } + } finally { + return 2; + } + })(); + + expect(value).toBe(2); +});