From 9430bbcc627048ee3a3eb051561739415c247f81 Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Mon, 26 Jun 2023 21:34:08 +0200 Subject: [PATCH] LibJS/Bytecode: Propagate FunctionDeclarationInstantiation exceptions If an exception is thrown by FunctionDeclarationInstantiation for an async or async-generator function, we still need to return a promise. We can't just throw the exception. 81 new passes on test262. :^) --- .../LibJS/Runtime/ECMAScriptFunctionObject.cpp | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/Userland/Libraries/LibJS/Runtime/ECMAScriptFunctionObject.cpp b/Userland/Libraries/LibJS/Runtime/ECMAScriptFunctionObject.cpp index f1f3c6e114..b5a08d9bd0 100644 --- a/Userland/Libraries/LibJS/Runtime/ECMAScriptFunctionObject.cpp +++ b/Userland/Libraries/LibJS/Runtime/ECMAScriptFunctionObject.cpp @@ -861,10 +861,22 @@ Completion ECMAScriptFunctionObject::ordinary_call_evaluate_body() } } - TRY(function_declaration_instantiation(nullptr)); + auto declaration_result = function_declaration_instantiation(nullptr); - if (!m_bytecode_executable) { + if (m_kind == FunctionKind::Normal || m_kind == FunctionKind::Generator) { + if (declaration_result.is_error()) + return declaration_result.release_error(); + } + + if (!m_bytecode_executable) m_bytecode_executable = TRY(Bytecode::compile(vm, *m_ecmascript_code, m_kind, m_name)); + + if (m_kind == FunctionKind::Async || m_kind == FunctionKind::AsyncGenerator) { + if (declaration_result.is_throw_completion()) { + auto promise_capability = MUST(new_promise_capability(vm, realm.intrinsics().promise_constructor())); + MUST(call(vm, *promise_capability->reject(), js_undefined(), *declaration_result.throw_completion().value())); + return Completion { Completion::Type::Return, promise_capability->promise(), {} }; + } } auto result_and_frame = bytecode_interpreter->run_and_return_frame(realm, *m_bytecode_executable, nullptr);