diff --git a/Userland/Libraries/LibJS/AST.cpp b/Userland/Libraries/LibJS/AST.cpp index c1e7ecea43..411a578361 100644 --- a/Userland/Libraries/LibJS/AST.cpp +++ b/Userland/Libraries/LibJS/AST.cpp @@ -283,7 +283,7 @@ Value NewExpression::execute(Interpreter& interpreter, GlobalObject& global_obje return {}; auto& function = callee_value.as_function(); - return vm.construct(function, function, move(arg_list)); + return TRY_OR_DISCARD(construct(global_object, function, move(arg_list))); } void CallExpression::throw_type_error_for_callee(Interpreter& interpreter, GlobalObject& global_object, Value callee_value, StringView call_type) const @@ -372,11 +372,7 @@ Value SuperCall::execute(Interpreter& interpreter, GlobalObject& global_object) } // 6. Let result be ? Construct(func, argList, newTarget). - auto& function = new_target.as_function(); - - auto result = vm.construct(static_cast(*func), function, move(arg_list)); - if (vm.exception()) - return {}; + auto* result = TRY_OR_DISCARD(construct(global_object, static_cast(*func), move(arg_list), &new_target.as_function())); // 7. Let thisER be GetThisEnvironment(). auto& this_er = verify_cast(get_this_environment(interpreter.vm())); @@ -389,8 +385,7 @@ Value SuperCall::execute(Interpreter& interpreter, GlobalObject& global_object) [[maybe_unused]] auto& f = this_er.function_object(); // 11. Perform ? InitializeInstanceElements(result, F). - VERIFY(result.is_object()); - TRY_OR_DISCARD(vm.initialize_instance_elements(result.as_object(), f)); + TRY_OR_DISCARD(vm.initialize_instance_elements(*result, f)); // 12. Return result. return result; diff --git a/Userland/Libraries/LibJS/Bytecode/Op.cpp b/Userland/Libraries/LibJS/Bytecode/Op.cpp index 5710dd64d2..7a0600055e 100644 --- a/Userland/Libraries/LibJS/Bytecode/Op.cpp +++ b/Userland/Libraries/LibJS/Bytecode/Op.cpp @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include @@ -342,10 +343,14 @@ void Call::execute_impl(Bytecode::Interpreter& interpreter) const } if (m_type == CallType::Call) { auto return_value_or_error = interpreter.vm().call(function, this_value, move(argument_values)); - if (!return_value_or_error.is_error()) - return_value = return_value_or_error.release_value(); + if (return_value_or_error.is_error()) + return; + return_value = return_value_or_error.release_value(); } else { - return_value = interpreter.vm().construct(function, function, move(argument_values)); + auto return_value_or_error = construct(interpreter.global_object(), function, move(argument_values)); + if (return_value_or_error.is_error()) + return; + return_value = return_value_or_error.release_value(); } } diff --git a/Userland/Libraries/LibJS/Runtime/ArrayBufferPrototype.cpp b/Userland/Libraries/LibJS/Runtime/ArrayBufferPrototype.cpp index 4f6af6832c..dedbe5c045 100644 --- a/Userland/Libraries/LibJS/Runtime/ArrayBufferPrototype.cpp +++ b/Userland/Libraries/LibJS/Runtime/ArrayBufferPrototype.cpp @@ -68,15 +68,13 @@ JS_DEFINE_OLD_NATIVE_FUNCTION(ArrayBufferPrototype::slice) MarkedValueList arguments(vm.heap()); arguments.append(Value(new_length)); - auto new_array_buffer = vm.construct(*constructor, *constructor, move(arguments)); - if (vm.exception()) - return {}; + auto* new_array_buffer = TRY_OR_DISCARD(construct(global_object, *constructor, move(arguments))); - if (!new_array_buffer.is_object() || !is(new_array_buffer.as_object())) { + if (!is(new_array_buffer)) { vm.throw_exception(global_object, ErrorType::SpeciesConstructorDidNotCreate, "an ArrayBuffer"); return {}; } - auto* new_array_buffer_object = static_cast(&new_array_buffer.as_object()); + auto* new_array_buffer_object = static_cast(new_array_buffer); // FIXME: Check for shared buffer if (new_array_buffer_object->is_detached()) { diff --git a/Userland/Libraries/LibJS/Runtime/ArrayConstructor.cpp b/Userland/Libraries/LibJS/Runtime/ArrayConstructor.cpp index a608a8e53a..4c2d46f768 100644 --- a/Userland/Libraries/LibJS/Runtime/ArrayConstructor.cpp +++ b/Userland/Libraries/LibJS/Runtime/ArrayConstructor.cpp @@ -104,17 +104,13 @@ JS_DEFINE_OLD_NATIVE_FUNCTION(ArrayConstructor::from) auto items = vm.argument(0); auto using_iterator = TRY_OR_DISCARD(items.get_method(global_object, *vm.well_known_symbol_iterator())); if (using_iterator) { - Value array; - if (constructor.is_constructor()) { - array = vm.construct(constructor.as_function(), constructor.as_function(), {}); - if (vm.exception()) - return {}; - } else { + Object* array; + if (constructor.is_constructor()) + array = TRY_OR_DISCARD(JS::construct(global_object, constructor.as_function(), {})); + else array = MUST(Array::create(global_object, 0)); - } auto iterator = TRY_OR_DISCARD(get_iterator(global_object, items, IteratorHint::Sync, using_iterator)); - auto& array_object = array.as_object(); size_t k = 0; while (true) { @@ -125,7 +121,7 @@ JS_DEFINE_OLD_NATIVE_FUNCTION(ArrayConstructor::from) auto* next = TRY_OR_DISCARD(iterator_step(global_object, *iterator)); if (!next) { - TRY_OR_DISCARD(array_object.set(vm.names.length, Value(k), Object::ShouldThrowExceptions::Yes)); + TRY_OR_DISCARD(array->set(vm.names.length, Value(k), Object::ShouldThrowExceptions::Yes)); return array; } @@ -141,7 +137,7 @@ JS_DEFINE_OLD_NATIVE_FUNCTION(ArrayConstructor::from) mapped_value = next_value; } - auto result_or_error = array_object.create_data_property_or_throw(k, mapped_value); + auto result_or_error = array->create_data_property_or_throw(k, mapped_value); if (result_or_error.is_error()) return TRY_OR_DISCARD(iterator_close(*iterator, result_or_error.release_error())); @@ -153,19 +149,15 @@ JS_DEFINE_OLD_NATIVE_FUNCTION(ArrayConstructor::from) auto length = TRY_OR_DISCARD(length_of_array_like(global_object, *array_like)); - Value array; + Object* array; if (constructor.is_constructor()) { MarkedValueList arguments(vm.heap()); arguments.empend(length); - array = vm.construct(constructor.as_function(), constructor.as_function(), move(arguments)); - if (vm.exception()) - return {}; + array = TRY_OR_DISCARD(JS::construct(global_object, constructor.as_function(), move(arguments))); } else { array = TRY_OR_DISCARD(Array::create(global_object, length)); } - auto& array_object = array.as_object(); - for (size_t k = 0; k < length; ++k) { auto k_value = TRY_OR_DISCARD(array_like->get(k)); Value mapped_value; @@ -173,10 +165,10 @@ JS_DEFINE_OLD_NATIVE_FUNCTION(ArrayConstructor::from) mapped_value = TRY_OR_DISCARD(vm.call(*map_fn, this_arg, k_value, Value(k))); else mapped_value = k_value; - TRY_OR_DISCARD(array_object.create_data_property_or_throw(k, mapped_value)); + TRY_OR_DISCARD(array->create_data_property_or_throw(k, mapped_value)); } - TRY_OR_DISCARD(array_object.set(vm.names.length, Value(length), Object::ShouldThrowExceptions::Yes)); + TRY_OR_DISCARD(array->set(vm.names.length, Value(length), Object::ShouldThrowExceptions::Yes)); return array; } @@ -192,20 +184,17 @@ JS_DEFINE_OLD_NATIVE_FUNCTION(ArrayConstructor::is_array) JS_DEFINE_OLD_NATIVE_FUNCTION(ArrayConstructor::of) { auto this_value = vm.this_value(global_object); - Value array; + Object* array; if (this_value.is_constructor()) { MarkedValueList arguments(vm.heap()); arguments.empend(vm.argument_count()); - array = vm.construct(this_value.as_function(), this_value.as_function(), move(arguments)); - if (vm.exception()) - return {}; + array = TRY_OR_DISCARD(JS::construct(global_object, this_value.as_function(), move(arguments))); } else { array = TRY_OR_DISCARD(Array::create(global_object, vm.argument_count())); } - auto& array_object = array.as_object(); for (size_t k = 0; k < vm.argument_count(); ++k) - TRY_OR_DISCARD(array_object.create_data_property_or_throw(k, vm.argument(k))); - TRY_OR_DISCARD(array_object.set(vm.names.length, Value(vm.argument_count()), Object::ShouldThrowExceptions::Yes)); + TRY_OR_DISCARD(array->create_data_property_or_throw(k, vm.argument(k))); + TRY_OR_DISCARD(array->set(vm.names.length, Value(vm.argument_count()), Object::ShouldThrowExceptions::Yes)); return array; } diff --git a/Userland/Libraries/LibJS/Runtime/ArrayPrototype.cpp b/Userland/Libraries/LibJS/Runtime/ArrayPrototype.cpp index 2531a5d55d..d58cc6f38a 100644 --- a/Userland/Libraries/LibJS/Runtime/ArrayPrototype.cpp +++ b/Userland/Libraries/LibJS/Runtime/ArrayPrototype.cpp @@ -139,10 +139,7 @@ static Object* array_species_create(GlobalObject& global_object, Object& origina MarkedValueList arguments(vm.heap()); arguments.append(Value(length)); - auto result = vm.construct(constructor.as_function(), constructor.as_function(), move(arguments)); - if (vm.exception()) - return {}; - return &result.as_object(); + return TRY_OR_DISCARD(construct(global_object, constructor.as_function(), move(arguments))); } // 23.1.3.7 Array.prototype.filter ( callbackfn [ , thisArg ] ), https://tc39.es/ecma262/#sec-array.prototype.filter diff --git a/Userland/Libraries/LibJS/Runtime/PromiseReaction.cpp b/Userland/Libraries/LibJS/Runtime/PromiseReaction.cpp index c7fd18af34..8adfbd8c77 100644 --- a/Userland/Libraries/LibJS/Runtime/PromiseReaction.cpp +++ b/Userland/Libraries/LibJS/Runtime/PromiseReaction.cpp @@ -4,6 +4,7 @@ * SPDX-License-Identifier: BSD-2-Clause */ +#include #include #include #include @@ -45,15 +46,7 @@ PromiseCapability new_promise_capability(GlobalObject& global_object, Value cons MarkedValueList arguments(vm.heap()); arguments.append(executor); - auto promise = vm.construct(constructor.as_function(), constructor.as_function(), move(arguments)); - if (vm.exception()) - return {}; - - // I'm not sure if we could VERIFY(promise.is_object()) instead - the spec doesn't have this check... - if (!promise.is_object()) { - vm.throw_exception(global_object, ErrorType::NotAnObject, promise.to_string_without_side_effects()); - return {}; - } + auto* promise = TRY_OR_DISCARD(construct(global_object, constructor.as_function(), move(arguments))); if (!promise_capability_functions.resolve.is_function()) { vm.throw_exception(global_object, ErrorType::NotAFunction, promise_capability_functions.resolve.to_string_without_side_effects()); @@ -65,7 +58,7 @@ PromiseCapability new_promise_capability(GlobalObject& global_object, Value cons } return { - &promise.as_object(), + promise, &promise_capability_functions.resolve.as_function(), &promise_capability_functions.reject.as_function(), }; diff --git a/Userland/Libraries/LibJS/Runtime/ReflectObject.cpp b/Userland/Libraries/LibJS/Runtime/ReflectObject.cpp index b597067fa7..b763615224 100644 --- a/Userland/Libraries/LibJS/Runtime/ReflectObject.cpp +++ b/Userland/Libraries/LibJS/Runtime/ReflectObject.cpp @@ -95,7 +95,7 @@ JS_DEFINE_OLD_NATIVE_FUNCTION(ReflectObject::construct) auto args = TRY_OR_DISCARD(create_list_from_array_like(global_object, arguments_list)); // 5. Return ? Construct(target, args, newTarget). - return vm.construct(target.as_function(), new_target.as_function(), move(args)); + return TRY_OR_DISCARD(JS::construct(global_object, target.as_function(), move(args), &new_target.as_function())); } // 28.1.3 Reflect.defineProperty ( target, propertyKey, attributes ), https://tc39.es/ecma262/#sec-reflect.defineproperty diff --git a/Userland/Libraries/LibJS/Runtime/RegExpPrototype.cpp b/Userland/Libraries/LibJS/Runtime/RegExpPrototype.cpp index 4fbc0c3648..0bd8f3f177 100644 --- a/Userland/Libraries/LibJS/Runtime/RegExpPrototype.cpp +++ b/Userland/Libraries/LibJS/Runtime/RegExpPrototype.cpp @@ -422,10 +422,7 @@ JS_DEFINE_OLD_NATIVE_FUNCTION(RegExpPrototype::symbol_match_all) MarkedValueList arguments(vm.heap()); arguments.append(regexp_object); arguments.append(js_string(vm, move(flags))); - auto matcher_value = vm.construct(*constructor, *constructor, move(arguments)); - if (vm.exception()) - return {}; - auto* matcher = TRY_OR_DISCARD(matcher_value.to_object(global_object)); + auto* matcher = TRY_OR_DISCARD(construct(global_object, *constructor, move(arguments))); auto last_index_value = TRY_OR_DISCARD(regexp_object->get(vm.names.lastIndex)); auto last_index = TRY_OR_DISCARD(last_index_value.to_length(global_object)); @@ -589,10 +586,7 @@ JS_DEFINE_OLD_NATIVE_FUNCTION(RegExpPrototype::symbol_split) MarkedValueList arguments(vm.heap()); arguments.append(regexp_object); arguments.append(js_string(vm, move(new_flags))); - auto splitter_value = vm.construct(*constructor, *constructor, move(arguments)); - if (vm.exception()) - return {}; - auto* splitter = TRY_OR_DISCARD(splitter_value.to_object(global_object)); + auto* splitter = TRY_OR_DISCARD(construct(global_object, *constructor, move(arguments))); auto* array = MUST(Array::create(global_object, 0)); size_t array_length = 0; diff --git a/Userland/Libraries/LibJS/Runtime/Temporal/Calendar.cpp b/Userland/Libraries/LibJS/Runtime/Temporal/Calendar.cpp index 94fc8acc11..1ba7b47e17 100644 --- a/Userland/Libraries/LibJS/Runtime/Temporal/Calendar.cpp +++ b/Userland/Libraries/LibJS/Runtime/Temporal/Calendar.cpp @@ -71,10 +71,7 @@ ThrowCompletionOr get_builtin_calendar(GlobalObject& global_object, S // 2. Return ? Construct(%Temporal.Calendar%, « id »). MarkedValueList arguments(vm.heap()); arguments.append(js_string(vm, identifier)); - auto calendar = vm.construct(*global_object.temporal_calendar_constructor(), *global_object.temporal_calendar_constructor(), move(arguments)); - if (auto* exception = vm.exception()) - return throw_completion(exception->value()); - return static_cast(&calendar.as_object()); + return static_cast(TRY(construct(global_object, *global_object.temporal_calendar_constructor(), move(arguments)))); } // 12.1.4 GetISO8601Calendar ( ) diff --git a/Userland/Libraries/LibJS/Runtime/TypedArray.cpp b/Userland/Libraries/LibJS/Runtime/TypedArray.cpp index 9173bac418..3f0de1a103 100644 --- a/Userland/Libraries/LibJS/Runtime/TypedArray.cpp +++ b/Userland/Libraries/LibJS/Runtime/TypedArray.cpp @@ -342,14 +342,12 @@ ThrowCompletionOr typed_array_create(GlobalObject& global_objec if (!arguments.is_empty()) first_argument = arguments[0]; // 1. Let newTypedArray be ? Construct(constructor, argumentList). - auto new_typed_array = vm.construct(constructor, constructor, move(arguments)); - if (auto* exception = vm.exception()) - return throw_completion(exception->value()); + auto* new_typed_array = TRY(construct(global_object, constructor, move(arguments))); // 2. Perform ? ValidateTypedArray(newTypedArray). - if (!new_typed_array.is_object() || !new_typed_array.as_object().is_typed_array()) + if (!new_typed_array->is_typed_array()) return vm.throw_completion(global_object, ErrorType::NotAnObjectOfType, "TypedArray"); - auto& typed_array = static_cast(new_typed_array.as_object()); + auto& typed_array = *static_cast(new_typed_array); TRY(validate_typed_array(global_object, typed_array)); // 3. If argumentList is a List of a single Number, then diff --git a/Userland/Libraries/LibJS/Runtime/VM.cpp b/Userland/Libraries/LibJS/Runtime/VM.cpp index 62462c8ac1..f43485aa23 100644 --- a/Userland/Libraries/LibJS/Runtime/VM.cpp +++ b/Userland/Libraries/LibJS/Runtime/VM.cpp @@ -483,12 +483,6 @@ ThrowCompletionOr VM::initialize_instance_elements(Object& object, ECMAScr return {}; } -// NOTE: This is a leftover from the old world of vm.call() and vm.construct(). Replace all uses with plain construct() and remove this. -Value VM::construct(FunctionObject& function, FunctionObject& new_target, Optional arguments) -{ - return TRY_OR_DISCARD(JS::construct(function.global_object(), function, move(arguments), &new_target)); -} - void VM::throw_exception(Exception& exception) { set_exception(exception);