Browse Source

LibJS: Remove vm.construct and it's usages

Idan Horowitz 3 years ago
parent
commit
e26d9f419b

+ 3 - 8
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<FunctionObject&>(*func), function, move(arg_list));
-    if (vm.exception())
-        return {};
+    auto* result = TRY_OR_DISCARD(construct(global_object, static_cast<FunctionObject&>(*func), move(arg_list), &new_target.as_function()));
 
     // 7. Let thisER be GetThisEnvironment().
     auto& this_er = verify_cast<FunctionEnvironment>(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;

+ 8 - 3
Userland/Libraries/LibJS/Bytecode/Op.cpp

@@ -9,6 +9,7 @@
 #include <AK/HashTable.h>
 #include <LibJS/Bytecode/Interpreter.h>
 #include <LibJS/Bytecode/Op.h>
+#include <LibJS/Runtime/AbstractOperations.h>
 #include <LibJS/Runtime/Array.h>
 #include <LibJS/Runtime/BigInt.h>
 #include <LibJS/Runtime/DeclarativeEnvironment.h>
@@ -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();
         }
     }
 

+ 3 - 5
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<ArrayBuffer>(new_array_buffer.as_object())) {
+    if (!is<ArrayBuffer>(new_array_buffer)) {
         vm.throw_exception<TypeError>(global_object, ErrorType::SpeciesConstructorDidNotCreate, "an ArrayBuffer");
         return {};
     }
-    auto* new_array_buffer_object = static_cast<ArrayBuffer*>(&new_array_buffer.as_object());
+    auto* new_array_buffer_object = static_cast<ArrayBuffer*>(new_array_buffer);
 
     // FIXME: Check for shared buffer
     if (new_array_buffer_object->is_detached()) {

+ 14 - 25
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;
 }
 

+ 1 - 4
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

+ 3 - 10
Userland/Libraries/LibJS/Runtime/PromiseReaction.cpp

@@ -4,6 +4,7 @@
  * SPDX-License-Identifier: BSD-2-Clause
  */
 
+#include <LibJS/Runtime/AbstractOperations.h>
 #include <LibJS/Runtime/Error.h>
 #include <LibJS/Runtime/MarkedValueList.h>
 #include <LibJS/Runtime/NativeFunction.h>
@@ -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<TypeError>(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<TypeError>(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(),
     };

+ 1 - 1
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

+ 2 - 8
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;
 

+ 1 - 4
Userland/Libraries/LibJS/Runtime/Temporal/Calendar.cpp

@@ -71,10 +71,7 @@ ThrowCompletionOr<Calendar*> 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*>(&calendar.as_object());
+    return static_cast<Calendar*>(TRY(construct(global_object, *global_object.temporal_calendar_constructor(), move(arguments))));
 }
 
 // 12.1.4 GetISO8601Calendar ( )

+ 3 - 5
Userland/Libraries/LibJS/Runtime/TypedArray.cpp

@@ -342,14 +342,12 @@ ThrowCompletionOr<TypedArrayBase*> 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<TypeError>(global_object, ErrorType::NotAnObjectOfType, "TypedArray");
-    auto& typed_array = static_cast<TypedArrayBase&>(new_typed_array.as_object());
+    auto& typed_array = *static_cast<TypedArrayBase*>(new_typed_array);
     TRY(validate_typed_array(global_object, typed_array));
 
     // 3. If argumentList is a List of a single Number, then

+ 0 - 6
Userland/Libraries/LibJS/Runtime/VM.cpp

@@ -483,12 +483,6 @@ ThrowCompletionOr<void> 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<MarkedValueList> arguments)
-{
-    return TRY_OR_DISCARD(JS::construct(function.global_object(), function, move(arguments), &new_target));
-}
-
 void VM::throw_exception(Exception& exception)
 {
     set_exception(exception);