diff --git a/Userland/Libraries/LibJS/AST.cpp b/Userland/Libraries/LibJS/AST.cpp index 5a64f2977a..d0d5ad88a4 100644 --- a/Userland/Libraries/LibJS/AST.cpp +++ b/Userland/Libraries/LibJS/AST.cpp @@ -243,7 +243,7 @@ Value CallExpression::execute(Interpreter& interpreter, GlobalObject& global_obj && callee_reference.name().as_string() == vm.names.eval.as_string()) { auto script_value = arg_list.size() == 0 ? js_undefined() : arg_list[0]; - return perform_eval(script_value, global_object, vm.in_strict_mode() ? CallerMode::Strict : CallerMode::NonStrict, EvalMode::Direct); + return TRY_OR_DISCARD(perform_eval(script_value, global_object, vm.in_strict_mode() ? CallerMode::Strict : CallerMode::NonStrict, EvalMode::Direct)); } return vm.call(function, this_value, move(arg_list)); diff --git a/Userland/Libraries/LibJS/Runtime/AbstractOperations.cpp b/Userland/Libraries/LibJS/Runtime/AbstractOperations.cpp index 2fca5dc5da..4cd9deb70c 100644 --- a/Userland/Libraries/LibJS/Runtime/AbstractOperations.cpp +++ b/Userland/Libraries/LibJS/Runtime/AbstractOperations.cpp @@ -407,7 +407,7 @@ ThrowCompletionOr make_super_property_reference(GlobalObject& global_ } // 19.2.1.1 PerformEval ( x, callerRealm, strictCaller, direct ), https://tc39.es/ecma262/#sec-performeval -Value perform_eval(Value x, GlobalObject& caller_realm, CallerMode strict_caller, EvalMode direct) +ThrowCompletionOr perform_eval(Value x, GlobalObject& caller_realm, CallerMode strict_caller, EvalMode direct) { VERIFY(direct == EvalMode::Direct || strict_caller == CallerMode::NonStrict); if (!x.is_string()) @@ -420,17 +420,23 @@ Value perform_eval(Value x, GlobalObject& caller_realm, CallerMode strict_caller if (parser.has_errors()) { auto& error = parser.errors()[0]; - vm.throw_exception(caller_realm, error.to_string()); - return {}; + return vm.throw_completion(caller_realm, error.to_string()); } auto& interpreter = vm.interpreter(); - if (direct == EvalMode::Direct) - return interpreter.execute_statement(caller_realm, program).value_or(js_undefined()); + if (direct == EvalMode::Direct) { + auto result = interpreter.execute_statement(caller_realm, program).value_or(js_undefined()); + if (auto* exception = vm.exception()) + return throw_completion(exception->value()); + return result; + } TemporaryChange scope_change(vm.running_execution_context().lexical_environment, static_cast(&interpreter.realm().global_environment())); TemporaryChange scope_change_strict(vm.running_execution_context().is_strict_mode, strict_caller == CallerMode::Strict); - return interpreter.execute_statement(caller_realm, program).value_or(js_undefined()); + auto result = interpreter.execute_statement(caller_realm, program).value_or(js_undefined()); + if (auto* exception = vm.exception()) + return throw_completion(exception->value()); + return result; } // 10.4.4.6 CreateUnmappedArgumentsObject ( argumentsList ), https://tc39.es/ecma262/#sec-createunmappedargumentsobject diff --git a/Userland/Libraries/LibJS/Runtime/AbstractOperations.h b/Userland/Libraries/LibJS/Runtime/AbstractOperations.h index d588e31f68..2b2b9b755a 100644 --- a/Userland/Libraries/LibJS/Runtime/AbstractOperations.h +++ b/Userland/Libraries/LibJS/Runtime/AbstractOperations.h @@ -40,7 +40,7 @@ enum class EvalMode { Direct, Indirect }; -Value perform_eval(Value, GlobalObject&, CallerMode, EvalMode); +ThrowCompletionOr perform_eval(Value, GlobalObject&, CallerMode, EvalMode); // 10.1.13 OrdinaryCreateFromConstructor ( constructor, intrinsicDefaultProto [ , internalSlotsList ] ), https://tc39.es/ecma262/#sec-ordinarycreatefromconstructor template diff --git a/Userland/Libraries/LibJS/Runtime/GlobalObject.cpp b/Userland/Libraries/LibJS/Runtime/GlobalObject.cpp index d47f1c5445..504f5f3615 100644 --- a/Userland/Libraries/LibJS/Runtime/GlobalObject.cpp +++ b/Userland/Libraries/LibJS/Runtime/GlobalObject.cpp @@ -430,7 +430,7 @@ JS_DEFINE_NATIVE_FUNCTION(GlobalObject::parse_int) // 19.2.1 eval ( x ), https://tc39.es/ecma262/#sec-eval-x JS_DEFINE_NATIVE_FUNCTION(GlobalObject::eval) { - return perform_eval(vm.argument(0), global_object, CallerMode::NonStrict, EvalMode::Indirect); + return TRY_OR_DISCARD(perform_eval(vm.argument(0), global_object, CallerMode::NonStrict, EvalMode::Indirect)); } // 19.2.6.1.1 Encode ( string, unescapedSet ), https://tc39.es/ecma262/#sec-encode