diff --git a/Userland/Libraries/LibJS/Bytecode/CommonImplementations.cpp b/Userland/Libraries/LibJS/Bytecode/CommonImplementations.cpp index 9f36c1bf35..31c6c41207 100644 --- a/Userland/Libraries/LibJS/Bytecode/CommonImplementations.cpp +++ b/Userland/Libraries/LibJS/Bytecode/CommonImplementations.cpp @@ -279,7 +279,7 @@ ThrowCompletionOr put_by_property_key(VM& vm, Value base, Value this_value return {}; } -ThrowCompletionOr perform_call(Interpreter& interpreter, Value this_value, Op::CallType call_type, Value callee, MarkedVector argument_values) +ThrowCompletionOr perform_call(Interpreter& interpreter, Value this_value, Op::CallType call_type, Value callee, ReadonlySpan argument_values) { auto& vm = interpreter.vm(); auto& function = callee.as_function(); @@ -288,11 +288,11 @@ ThrowCompletionOr perform_call(Interpreter& interpreter, Value this_value if (callee == interpreter.realm().intrinsics().eval_function()) return_value = TRY(perform_eval(vm, !argument_values.is_empty() ? argument_values[0].value_or(JS::js_undefined()) : js_undefined(), vm.in_strict_mode() ? CallerMode::Strict : CallerMode::NonStrict, EvalMode::Direct)); else - return_value = TRY(JS::call(vm, function, this_value, move(argument_values))); + return_value = TRY(JS::call(vm, function, this_value, argument_values)); } else if (call_type == Op::CallType::Call) - return_value = TRY(JS::call(vm, function, this_value, move(argument_values))); + return_value = TRY(JS::call(vm, function, this_value, argument_values)); else - return_value = TRY(construct(vm, function, move(argument_values))); + return_value = TRY(construct(vm, function, argument_values)); return return_value; } @@ -633,7 +633,7 @@ ThrowCompletionOr> super_call_with_argument_array(VM& vm, V return vm.throw_completion(ErrorType::NotAConstructor, "Super constructor"); // 6. Let result be ? Construct(func, argList, newTarget). - auto result = TRY(construct(vm, static_cast(*func), move(arg_list), &new_target.as_function())); + auto result = TRY(construct(vm, static_cast(*func), arg_list.span(), &new_target.as_function())); // 7. Let thisER be GetThisEnvironment(). auto& this_environment = verify_cast(*get_this_environment(vm)); diff --git a/Userland/Libraries/LibJS/Bytecode/CommonImplementations.h b/Userland/Libraries/LibJS/Bytecode/CommonImplementations.h index 829a056388..1b683de5d6 100644 --- a/Userland/Libraries/LibJS/Bytecode/CommonImplementations.h +++ b/Userland/Libraries/LibJS/Bytecode/CommonImplementations.h @@ -17,7 +17,7 @@ ThrowCompletionOr get_by_id(VM&, DeprecatedFlyString const& property, Val ThrowCompletionOr get_by_value(VM&, Value base_value, Value property_key_value); ThrowCompletionOr get_global(Bytecode::Interpreter&, DeprecatedFlyString const& identifier, GlobalVariableCache&); ThrowCompletionOr put_by_property_key(VM&, Value base, Value this_value, Value value, PropertyKey name, Op::PropertyKind kind, PropertyLookupCache* = nullptr); -ThrowCompletionOr perform_call(Interpreter&, Value this_value, Op::CallType, Value callee, MarkedVector argument_values); +ThrowCompletionOr perform_call(Interpreter&, Value this_value, Op::CallType, Value callee, ReadonlySpan argument_values); ThrowCompletionOr throw_if_needed_for_call(Interpreter&, Value callee, Op::CallType, Optional const& expression_string); ThrowCompletionOr typeof_variable(VM&, DeprecatedFlyString const&); ThrowCompletionOr set_variable(VM&, DeprecatedFlyString const&, Value, Op::EnvironmentMode, Op::SetVariable::InitializationMode, EnvironmentVariableCache&); diff --git a/Userland/Libraries/LibJS/JIT/Compiler.cpp b/Userland/Libraries/LibJS/JIT/Compiler.cpp index d64ca47bfe..40d5bcc27d 100644 --- a/Userland/Libraries/LibJS/JIT/Compiler.cpp +++ b/Userland/Libraries/LibJS/JIT/Compiler.cpp @@ -2507,12 +2507,8 @@ static Value cxx_call(VM& vm, Value callee, u32 first_argument_index, u32 argume { TRY_OR_SET_EXCEPTION(throw_if_needed_for_call(vm.bytecode_interpreter(), callee, call_type, expression_string)); - MarkedVector argument_values(vm.heap()); - argument_values.ensure_capacity(argument_count); - for (u32 i = 0; i < argument_count; ++i) { - argument_values.unchecked_append(vm.bytecode_interpreter().reg(Bytecode::Register { first_argument_index + i })); - } - return TRY_OR_SET_EXCEPTION(perform_call(vm.bytecode_interpreter(), this_value, call_type, callee, move(argument_values))); + auto argument_values = vm.bytecode_interpreter().registers().slice(first_argument_index, argument_count); + return TRY_OR_SET_EXCEPTION(perform_call(vm.bytecode_interpreter(), this_value, call_type, callee, argument_values)); } Assembler::Reg Compiler::argument_register(u32 index) diff --git a/Userland/Libraries/LibJS/Runtime/AbstractOperations.cpp b/Userland/Libraries/LibJS/Runtime/AbstractOperations.cpp index a344f91bee..c40b551f65 100644 --- a/Userland/Libraries/LibJS/Runtime/AbstractOperations.cpp +++ b/Userland/Libraries/LibJS/Runtime/AbstractOperations.cpp @@ -47,46 +47,40 @@ ThrowCompletionOr require_object_coercible(VM& vm, Value value) } // 7.3.14 Call ( F, V [ , argumentsList ] ), https://tc39.es/ecma262/#sec-call -ThrowCompletionOr call_impl(VM& vm, Value function, Value this_value, Optional> arguments_list) +ThrowCompletionOr call_impl(VM& vm, Value function, Value this_value, ReadonlySpan arguments_list) { // 1. If argumentsList is not present, set argumentsList to a new empty List. - if (!arguments_list.has_value()) - arguments_list = MarkedVector { vm.heap() }; // 2. If IsCallable(F) is false, throw a TypeError exception. if (!function.is_function()) return vm.throw_completion(ErrorType::NotAFunction, function.to_string_without_side_effects()); // 3. Return ? F.[[Call]](V, argumentsList). - return function.as_function().internal_call(this_value, move(*arguments_list)); + return function.as_function().internal_call(this_value, arguments_list); } -ThrowCompletionOr call_impl(VM& vm, FunctionObject& function, Value this_value, Optional> arguments_list) +ThrowCompletionOr call_impl(VM&, FunctionObject& function, Value this_value, ReadonlySpan arguments_list) { // 1. If argumentsList is not present, set argumentsList to a new empty List. - if (!arguments_list.has_value()) - arguments_list = MarkedVector { vm.heap() }; // 2. If IsCallable(F) is false, throw a TypeError exception. // Note: Called with a FunctionObject ref // 3. Return ? F.[[Call]](V, argumentsList). - return function.internal_call(this_value, move(*arguments_list)); + return function.internal_call(this_value, arguments_list); } // 7.3.15 Construct ( F [ , argumentsList [ , newTarget ] ] ), https://tc39.es/ecma262/#sec-construct -ThrowCompletionOr> construct_impl(VM& vm, FunctionObject& function, Optional> arguments_list, FunctionObject* new_target) +ThrowCompletionOr> construct_impl(VM&, FunctionObject& function, ReadonlySpan arguments_list, FunctionObject* new_target) { // 1. If newTarget is not present, set newTarget to F. if (!new_target) new_target = &function; // 2. If argumentsList is not present, set argumentsList to a new empty List. - if (!arguments_list.has_value()) - arguments_list = MarkedVector { vm.heap() }; // 3. Return ? F.[[Construct]](argumentsList, newTarget). - return function.internal_construct(move(*arguments_list), *new_target); + return function.internal_construct(arguments_list, *new_target); } // 7.3.19 LengthOfArrayLike ( obj ), https://tc39.es/ecma262/#sec-lengthofarraylike diff --git a/Userland/Libraries/LibJS/Runtime/AbstractOperations.h b/Userland/Libraries/LibJS/Runtime/AbstractOperations.h index c9629e8c4e..6ef8f45c24 100644 --- a/Userland/Libraries/LibJS/Runtime/AbstractOperations.h +++ b/Userland/Libraries/LibJS/Runtime/AbstractOperations.h @@ -28,9 +28,9 @@ NonnullGCPtr get_this_environment(VM&); bool can_be_held_weakly(Value); Object* get_super_constructor(VM&); ThrowCompletionOr require_object_coercible(VM&, Value); -ThrowCompletionOr call_impl(VM&, Value function, Value this_value, Optional> = {}); -ThrowCompletionOr call_impl(VM&, FunctionObject& function, Value this_value, Optional> = {}); -ThrowCompletionOr> construct_impl(VM&, FunctionObject&, Optional> = {}, FunctionObject* new_target = nullptr); +ThrowCompletionOr call_impl(VM&, Value function, Value this_value, ReadonlySpan arguments = {}); +ThrowCompletionOr call_impl(VM&, FunctionObject& function, Value this_value, ReadonlySpan arguments = {}); +ThrowCompletionOr> construct_impl(VM&, FunctionObject&, ReadonlySpan arguments = {}, FunctionObject* new_target = nullptr); ThrowCompletionOr length_of_array_like(VM&, Object const&); ThrowCompletionOr> create_list_from_array_like(VM&, Value, Function(Value)> = {}); ThrowCompletionOr species_constructor(VM&, Object const&, FunctionObject& default_constructor); @@ -75,45 +75,45 @@ ThrowCompletionOr perform_eval(VM&, Value, CallerMode, EvalMode); ThrowCompletionOr eval_declaration_instantiation(VM& vm, Program const& program, Environment* variable_environment, Environment* lexical_environment, PrivateEnvironment* private_environment, bool strict); // 7.3.14 Call ( F, V [ , argumentsList ] ), https://tc39.es/ecma262/#sec-call -ALWAYS_INLINE ThrowCompletionOr call(VM& vm, Value function, Value this_value, MarkedVector arguments_list) +ALWAYS_INLINE ThrowCompletionOr call(VM& vm, Value function, Value this_value, ReadonlySpan arguments_list) { - return call_impl(vm, function, this_value, move(arguments_list)); + return call_impl(vm, function, this_value, arguments_list); } -ALWAYS_INLINE ThrowCompletionOr call(VM& vm, Value function, Value this_value, Optional> arguments_list) +ALWAYS_INLINE ThrowCompletionOr call(VM& vm, Value function, Value this_value, Span arguments_list) { - return call_impl(vm, function, this_value, move(arguments_list)); + return call_impl(vm, function, this_value, static_cast>(arguments_list)); } template ALWAYS_INLINE ThrowCompletionOr call(VM& vm, Value function, Value this_value, Args&&... args) { - if constexpr (sizeof...(Args) > 0) { - MarkedVector arguments_list { vm.heap() }; - (..., arguments_list.append(forward(args))); - return call_impl(vm, function, this_value, move(arguments_list)); + constexpr auto argument_count = sizeof...(Args); + if constexpr (argument_count > 0) { + AK::Array arguments { forward(args)... }; + return call_impl(vm, function, this_value, static_cast>(arguments.span())); } return call_impl(vm, function, this_value); } -ALWAYS_INLINE ThrowCompletionOr call(VM& vm, FunctionObject& function, Value this_value, MarkedVector arguments_list) +ALWAYS_INLINE ThrowCompletionOr call(VM& vm, FunctionObject& function, Value this_value, ReadonlySpan arguments_list) { - return call_impl(vm, function, this_value, move(arguments_list)); + return call_impl(vm, function, this_value, arguments_list); } -ALWAYS_INLINE ThrowCompletionOr call(VM& vm, FunctionObject& function, Value this_value, Optional> arguments_list) +ALWAYS_INLINE ThrowCompletionOr call(VM& vm, FunctionObject& function, Value this_value, Span arguments_list) { - return call_impl(vm, function, this_value, move(arguments_list)); + return call_impl(vm, function, this_value, static_cast>(arguments_list)); } template ALWAYS_INLINE ThrowCompletionOr call(VM& vm, FunctionObject& function, Value this_value, Args&&... args) { - if constexpr (sizeof...(Args) > 0) { - MarkedVector arguments_list { vm.heap() }; - (..., arguments_list.append(forward(args))); - return call_impl(vm, function, this_value, move(arguments_list)); + constexpr auto argument_count = sizeof...(Args); + if constexpr (argument_count > 0) { + AK::Array arguments { forward(args)... }; + return call_impl(vm, function, this_value, static_cast>(arguments.span())); } return call_impl(vm, function, this_value); @@ -123,23 +123,23 @@ ALWAYS_INLINE ThrowCompletionOr call(VM& vm, FunctionObject& function, Va template ALWAYS_INLINE ThrowCompletionOr> construct(VM& vm, FunctionObject& function, Args&&... args) { - if constexpr (sizeof...(Args) > 0) { - MarkedVector arguments_list { vm.heap() }; - (..., arguments_list.append(forward(args))); - return construct_impl(vm, function, move(arguments_list)); + constexpr auto argument_count = sizeof...(Args); + if constexpr (argument_count > 0) { + AK::Array arguments { forward(args)... }; + return construct_impl(vm, function, static_cast>(arguments.span())); } return construct_impl(vm, function); } -ALWAYS_INLINE ThrowCompletionOr> construct(VM& vm, FunctionObject& function, MarkedVector arguments_list, FunctionObject* new_target = nullptr) +ALWAYS_INLINE ThrowCompletionOr> construct(VM& vm, FunctionObject& function, ReadonlySpan arguments_list, FunctionObject* new_target = nullptr) { - return construct_impl(vm, function, move(arguments_list), new_target); + return construct_impl(vm, function, arguments_list, new_target); } -ALWAYS_INLINE ThrowCompletionOr> construct(VM& vm, FunctionObject& function, Optional> arguments_list, FunctionObject* new_target = nullptr) +ALWAYS_INLINE ThrowCompletionOr> construct(VM& vm, FunctionObject& function, Span arguments_list, FunctionObject* new_target = nullptr) { - return construct_impl(vm, function, move(arguments_list), new_target); + return construct_impl(vm, function, static_cast>(arguments_list), new_target); } // 10.1.13 OrdinaryCreateFromConstructor ( constructor, intrinsicDefaultProto [ , internalSlotsList ] ), https://tc39.es/ecma262/#sec-ordinarycreatefromconstructor diff --git a/Userland/Libraries/LibJS/Runtime/Array.cpp b/Userland/Libraries/LibJS/Runtime/Array.cpp index 2222935c4a..f17c7c83a8 100644 --- a/Userland/Libraries/LibJS/Runtime/Array.cpp +++ b/Userland/Libraries/LibJS/Runtime/Array.cpp @@ -63,6 +63,24 @@ NonnullGCPtr Array::create_from(Realm& realm, Vector const& elemen return array; } +NonnullGCPtr Array::create_from(Realm& realm, ReadonlySpan const& elements) +{ + // 1. Let array be ! ArrayCreate(0). + auto array = MUST(Array::create(realm, 0)); + + // 2. Let n be 0. + // 3. For each element e of elements, do + for (u32 n = 0; n < elements.size(); ++n) { + // a. Perform ! CreateDataPropertyOrThrow(array, ! ToString(𝔽(n)), e). + MUST(array->create_data_property_or_throw(n, elements[n])); + + // b. Set n to n + 1. + } + + // 4. Return array. + return array; +} + Array::Array(Object& prototype) : Object(ConstructWithPrototypeTag::Tag, prototype) { diff --git a/Userland/Libraries/LibJS/Runtime/Array.h b/Userland/Libraries/LibJS/Runtime/Array.h index 8197c489e7..d5f40d2a5b 100644 --- a/Userland/Libraries/LibJS/Runtime/Array.h +++ b/Userland/Libraries/LibJS/Runtime/Array.h @@ -26,6 +26,7 @@ class Array : public Object { public: static ThrowCompletionOr> create(Realm&, u64 length, Object* prototype = nullptr); static NonnullGCPtr create_from(Realm&, Vector const&); + static NonnullGCPtr create_from(Realm&, ReadonlySpan const&); // Non-standard but equivalent to CreateArrayFromList. template diff --git a/Userland/Libraries/LibJS/Runtime/BoundFunction.cpp b/Userland/Libraries/LibJS/Runtime/BoundFunction.cpp index 1628b4d0ae..8a10a55106 100644 --- a/Userland/Libraries/LibJS/Runtime/BoundFunction.cpp +++ b/Userland/Libraries/LibJS/Runtime/BoundFunction.cpp @@ -45,7 +45,7 @@ BoundFunction::BoundFunction(Realm& realm, FunctionObject& bound_target_function } // 10.4.1.1 [[Call]] ( thisArgument, argumentsList ), https://tc39.es/ecma262/#sec-bound-function-exotic-objects-call-thisargument-argumentslist -ThrowCompletionOr BoundFunction::internal_call([[maybe_unused]] Value this_argument, MarkedVector arguments_list) +ThrowCompletionOr BoundFunction::internal_call([[maybe_unused]] Value this_argument, ReadonlySpan arguments_list) { auto& vm = this->vm(); @@ -59,16 +59,17 @@ ThrowCompletionOr BoundFunction::internal_call([[maybe_unused]] Value thi auto& bound_args = m_bound_arguments; // 4. Let args be the list-concatenation of boundArgs and argumentsList. - auto args = MarkedVector { heap() }; + Vector args; + args.ensure_capacity(bound_args.size() + arguments_list.size()); args.extend(bound_args); - args.extend(move(arguments_list)); + args.append(arguments_list.data(), arguments_list.size()); // 5. Return ? Call(target, boundThis, args). - return call(vm, &target, bound_this, move(args)); + return call(vm, &target, bound_this, args.span()); } // 10.4.1.2 [[Construct]] ( argumentsList, newTarget ), https://tc39.es/ecma262/#sec-bound-function-exotic-objects-construct-argumentslist-newtarget -ThrowCompletionOr> BoundFunction::internal_construct(MarkedVector arguments_list, FunctionObject& new_target) +ThrowCompletionOr> BoundFunction::internal_construct(ReadonlySpan arguments_list, FunctionObject& new_target) { auto& vm = this->vm(); @@ -84,7 +85,7 @@ ThrowCompletionOr> BoundFunction::internal_construct(Marked // 4. Let args be the list-concatenation of boundArgs and argumentsList. auto args = MarkedVector { heap() }; args.extend(bound_args); - args.extend(move(arguments_list)); + args.append(arguments_list.data(), arguments_list.size()); // 5. If SameValue(F, newTarget) is true, set newTarget to target. auto* final_new_target = &new_target; @@ -92,7 +93,7 @@ ThrowCompletionOr> BoundFunction::internal_construct(Marked final_new_target = ⌖ // 6. Return ? Construct(target, args, newTarget). - return construct(vm, target, move(args), final_new_target); + return construct(vm, target, args.span(), final_new_target); } void BoundFunction::visit_edges(Visitor& visitor) diff --git a/Userland/Libraries/LibJS/Runtime/BoundFunction.h b/Userland/Libraries/LibJS/Runtime/BoundFunction.h index c85c6f1876..e5d4796f72 100644 --- a/Userland/Libraries/LibJS/Runtime/BoundFunction.h +++ b/Userland/Libraries/LibJS/Runtime/BoundFunction.h @@ -20,8 +20,8 @@ public: virtual ~BoundFunction() override = default; - virtual ThrowCompletionOr internal_call(Value this_argument, MarkedVector arguments_list) override; - virtual ThrowCompletionOr> internal_construct(MarkedVector arguments_list, FunctionObject& new_target) override; + virtual ThrowCompletionOr internal_call(Value this_argument, ReadonlySpan arguments_list) override; + virtual ThrowCompletionOr> internal_construct(ReadonlySpan arguments_list, FunctionObject& new_target) override; virtual DeprecatedFlyString const& name() const override { return m_name; } virtual bool is_strict_mode() const override { return m_bound_target_function->is_strict_mode(); } diff --git a/Userland/Libraries/LibJS/Runtime/ECMAScriptFunctionObject.cpp b/Userland/Libraries/LibJS/Runtime/ECMAScriptFunctionObject.cpp index 1161224a78..6b254fa34f 100644 --- a/Userland/Libraries/LibJS/Runtime/ECMAScriptFunctionObject.cpp +++ b/Userland/Libraries/LibJS/Runtime/ECMAScriptFunctionObject.cpp @@ -361,7 +361,7 @@ void ECMAScriptFunctionObject::initialize(Realm& realm) } // 10.2.1 [[Call]] ( thisArgument, argumentsList ), https://tc39.es/ecma262/#sec-ecmascript-function-objects-call-thisargument-argumentslist -ThrowCompletionOr ECMAScriptFunctionObject::internal_call(Value this_argument, MarkedVector arguments_list) +ThrowCompletionOr ECMAScriptFunctionObject::internal_call(Value this_argument, ReadonlySpan arguments_list) { auto& vm = this->vm(); @@ -373,7 +373,7 @@ ThrowCompletionOr ECMAScriptFunctionObject::internal_call(Value this_argu callee_context.local_variables.resize(m_local_variables_names.size()); // Non-standard - callee_context.arguments.extend(move(arguments_list)); + callee_context.arguments.append(arguments_list.data(), arguments_list.size()); callee_context.instruction_stream_iterator = vm.bytecode_interpreter().instruction_stream_iterator(); // 2. Let calleeContext be PrepareForOrdinaryCall(F, undefined). @@ -420,7 +420,7 @@ ThrowCompletionOr ECMAScriptFunctionObject::internal_call(Value this_argu } // 10.2.2 [[Construct]] ( argumentsList, newTarget ), https://tc39.es/ecma262/#sec-ecmascript-function-objects-construct-argumentslist-newtarget -ThrowCompletionOr> ECMAScriptFunctionObject::internal_construct(MarkedVector arguments_list, FunctionObject& new_target) +ThrowCompletionOr> ECMAScriptFunctionObject::internal_construct(ReadonlySpan arguments_list, FunctionObject& new_target) { auto& vm = this->vm(); @@ -443,7 +443,7 @@ ThrowCompletionOr> ECMAScriptFunctionObject::internal_const callee_context.local_variables.resize(m_local_variables_names.size()); // Non-standard - callee_context.arguments.extend(move(arguments_list)); + callee_context.arguments.append(arguments_list.data(), arguments_list.size()); callee_context.instruction_stream_iterator = vm.bytecode_interpreter().instruction_stream_iterator(); // 4. Let calleeContext be PrepareForOrdinaryCall(F, newTarget). diff --git a/Userland/Libraries/LibJS/Runtime/ECMAScriptFunctionObject.h b/Userland/Libraries/LibJS/Runtime/ECMAScriptFunctionObject.h index 21184d8e20..c61cac27d5 100644 --- a/Userland/Libraries/LibJS/Runtime/ECMAScriptFunctionObject.h +++ b/Userland/Libraries/LibJS/Runtime/ECMAScriptFunctionObject.h @@ -44,8 +44,8 @@ public: virtual void initialize(Realm&) override; virtual ~ECMAScriptFunctionObject() override = default; - virtual ThrowCompletionOr internal_call(Value this_argument, MarkedVector arguments_list) override; - virtual ThrowCompletionOr> internal_construct(MarkedVector arguments_list, FunctionObject& new_target) override; + virtual ThrowCompletionOr internal_call(Value this_argument, ReadonlySpan arguments_list) override; + virtual ThrowCompletionOr> internal_construct(ReadonlySpan arguments_list, FunctionObject& new_target) override; void make_method(Object& home_object); diff --git a/Userland/Libraries/LibJS/Runtime/FunctionObject.h b/Userland/Libraries/LibJS/Runtime/FunctionObject.h index baacfd006a..238be5c5de 100644 --- a/Userland/Libraries/LibJS/Runtime/FunctionObject.h +++ b/Userland/Libraries/LibJS/Runtime/FunctionObject.h @@ -23,8 +23,8 @@ public: // Table 7: Additional Essential Internal Methods of Function Objects, https://tc39.es/ecma262/#table-additional-essential-internal-methods-of-function-objects - virtual ThrowCompletionOr internal_call(Value this_argument, MarkedVector arguments_list) = 0; - virtual ThrowCompletionOr> internal_construct([[maybe_unused]] MarkedVector arguments_list, [[maybe_unused]] FunctionObject& new_target) { VERIFY_NOT_REACHED(); } + virtual ThrowCompletionOr internal_call(Value this_argument, ReadonlySpan arguments_list) = 0; + virtual ThrowCompletionOr> internal_construct([[maybe_unused]] ReadonlySpan arguments_list, [[maybe_unused]] FunctionObject& new_target) { VERIFY_NOT_REACHED(); } virtual DeprecatedFlyString const& name() const = 0; diff --git a/Userland/Libraries/LibJS/Runtime/FunctionPrototype.cpp b/Userland/Libraries/LibJS/Runtime/FunctionPrototype.cpp index f5d17a883e..6463d70059 100644 --- a/Userland/Libraries/LibJS/Runtime/FunctionPrototype.cpp +++ b/Userland/Libraries/LibJS/Runtime/FunctionPrototype.cpp @@ -40,7 +40,7 @@ void FunctionPrototype::initialize(Realm& realm) define_direct_property(vm.names.name, PrimitiveString::create(vm, String {}), Attribute::Configurable); } -ThrowCompletionOr FunctionPrototype::internal_call(Value, MarkedVector) +ThrowCompletionOr FunctionPrototype::internal_call(Value, ReadonlySpan) { // The Function prototype object: // - accepts any arguments and returns undefined when invoked. @@ -76,7 +76,7 @@ JS_DEFINE_NATIVE_FUNCTION(FunctionPrototype::apply) // FIXME: 5. Perform PrepareForTailCall(). // 6. Return ? Call(func, thisArg, argList). - return TRY(JS::call(vm, function, this_arg, move(arguments))); + return TRY(JS::call(vm, function, this_arg, arguments.span())); } // 20.2.3.2 Function.prototype.bind ( thisArg, ...args ), https://tc39.es/ecma262/#sec-function.prototype.bind @@ -130,14 +130,10 @@ JS_DEFINE_NATIVE_FUNCTION(FunctionPrototype::call) // FIXME: 3. Perform PrepareForTailCall(). auto this_arg = vm.argument(0); - MarkedVector arguments(vm.heap()); - if (vm.argument_count() > 1) { - for (size_t i = 1; i < vm.argument_count(); ++i) - arguments.append(vm.argument(i)); - } + auto args = vm.argument_count() > 1 ? vm.running_execution_context().arguments.span().slice(1) : ReadonlySpan {}; // 4. Return ? Call(func, thisArg, args). - return TRY(JS::call(vm, function, this_arg, move(arguments))); + return TRY(JS::call(vm, function, this_arg, args)); } // 20.2.3.5 Function.prototype.toString ( ), https://tc39.es/ecma262/#sec-function.prototype.tostring diff --git a/Userland/Libraries/LibJS/Runtime/FunctionPrototype.h b/Userland/Libraries/LibJS/Runtime/FunctionPrototype.h index ea1378b706..ccd8b97a52 100644 --- a/Userland/Libraries/LibJS/Runtime/FunctionPrototype.h +++ b/Userland/Libraries/LibJS/Runtime/FunctionPrototype.h @@ -18,7 +18,7 @@ public: virtual void initialize(Realm&) override; virtual ~FunctionPrototype() override = default; - virtual ThrowCompletionOr internal_call(Value this_argument, MarkedVector arguments_list) override; + virtual ThrowCompletionOr internal_call(Value this_argument, ReadonlySpan arguments_list) override; virtual DeprecatedFlyString const& name() const override { return m_name; } private: diff --git a/Userland/Libraries/LibJS/Runtime/JobCallback.cpp b/Userland/Libraries/LibJS/Runtime/JobCallback.cpp index fe3d030302..e0f06fd9d7 100644 --- a/Userland/Libraries/LibJS/Runtime/JobCallback.cpp +++ b/Userland/Libraries/LibJS/Runtime/JobCallback.cpp @@ -18,13 +18,13 @@ JobCallback make_job_callback(FunctionObject& callback) } // 9.5.3 HostCallJobCallback ( jobCallback, V, argumentsList ), https://tc39.es/ecma262/#sec-hostcalljobcallback -ThrowCompletionOr call_job_callback(VM& vm, JobCallback& job_callback, Value this_value, MarkedVector arguments_list) +ThrowCompletionOr call_job_callback(VM& vm, JobCallback& job_callback, Value this_value, ReadonlySpan arguments_list) { // 1. Assert: IsCallable(jobCallback.[[Callback]]) is true. VERIFY(!job_callback.callback.is_null()); // 2. Return ? Call(jobCallback.[[Callback]], V, argumentsList). - return call(vm, job_callback.callback.cell(), this_value, move(arguments_list)); + return call(vm, job_callback.callback.cell(), this_value, arguments_list); } } diff --git a/Userland/Libraries/LibJS/Runtime/JobCallback.h b/Userland/Libraries/LibJS/Runtime/JobCallback.h index 00904127d3..4ff01c0d0d 100644 --- a/Userland/Libraries/LibJS/Runtime/JobCallback.h +++ b/Userland/Libraries/LibJS/Runtime/JobCallback.h @@ -23,6 +23,6 @@ struct JobCallback { }; JobCallback make_job_callback(FunctionObject& callback); -ThrowCompletionOr call_job_callback(VM&, JobCallback&, Value this_value, MarkedVector arguments_list); +ThrowCompletionOr call_job_callback(VM&, JobCallback&, Value this_value, ReadonlySpan arguments_list); } diff --git a/Userland/Libraries/LibJS/Runtime/NativeFunction.cpp b/Userland/Libraries/LibJS/Runtime/NativeFunction.cpp index d43b1d57e8..c55655ff87 100644 --- a/Userland/Libraries/LibJS/Runtime/NativeFunction.cpp +++ b/Userland/Libraries/LibJS/Runtime/NativeFunction.cpp @@ -96,7 +96,7 @@ NativeFunction::NativeFunction(DeprecatedFlyString name, Object& prototype) // these good candidates for a bit of code duplication :^) // 10.3.1 [[Call]] ( thisArgument, argumentsList ), https://tc39.es/ecma262/#sec-built-in-function-objects-call-thisargument-argumentslist -ThrowCompletionOr NativeFunction::internal_call(Value this_argument, MarkedVector arguments_list) +ThrowCompletionOr NativeFunction::internal_call(Value this_argument, ReadonlySpan arguments_list) { auto& vm = this->vm(); @@ -132,7 +132,7 @@ ThrowCompletionOr NativeFunction::internal_call(Value this_argument, Mark // 8. Perform any necessary implementation-defined initialization of calleeContext. callee_context.this_value = this_argument; - callee_context.arguments.extend(move(arguments_list)); + callee_context.arguments.append(arguments_list.data(), arguments_list.size()); callee_context.instruction_stream_iterator = vm.bytecode_interpreter().instruction_stream_iterator(); callee_context.lexical_environment = caller_context.lexical_environment; @@ -160,7 +160,7 @@ ThrowCompletionOr NativeFunction::internal_call(Value this_argument, Mark } // 10.3.2 [[Construct]] ( argumentsList, newTarget ), https://tc39.es/ecma262/#sec-built-in-function-objects-construct-argumentslist-newtarget -ThrowCompletionOr> NativeFunction::internal_construct(MarkedVector arguments_list, FunctionObject& new_target) +ThrowCompletionOr> NativeFunction::internal_construct(ReadonlySpan arguments_list, FunctionObject& new_target) { auto& vm = this->vm(); @@ -195,7 +195,7 @@ ThrowCompletionOr> NativeFunction::internal_construct(Marke // Note: This is already the default value. // 8. Perform any necessary implementation-defined initialization of calleeContext. - callee_context.arguments.extend(move(arguments_list)); + callee_context.arguments.append(arguments_list.data(), arguments_list.size()); callee_context.instruction_stream_iterator = vm.bytecode_interpreter().instruction_stream_iterator(); callee_context.lexical_environment = caller_context.lexical_environment; diff --git a/Userland/Libraries/LibJS/Runtime/NativeFunction.h b/Userland/Libraries/LibJS/Runtime/NativeFunction.h index 08073904c7..67287ae0be 100644 --- a/Userland/Libraries/LibJS/Runtime/NativeFunction.h +++ b/Userland/Libraries/LibJS/Runtime/NativeFunction.h @@ -26,8 +26,8 @@ public: virtual ~NativeFunction() override = default; - virtual ThrowCompletionOr internal_call(Value this_argument, MarkedVector arguments_list) override; - virtual ThrowCompletionOr> internal_construct(MarkedVector arguments_list, FunctionObject& new_target) override; + virtual ThrowCompletionOr internal_call(Value this_argument, ReadonlySpan arguments_list) override; + virtual ThrowCompletionOr> internal_construct(ReadonlySpan arguments_list, FunctionObject& new_target) override; // Used for [[Call]] / [[Construct]]'s "...result of evaluating F in a manner that conforms to the specification of F". // Needs to be overridden by all NativeFunctions without an m_native_function. diff --git a/Userland/Libraries/LibJS/Runtime/PromiseJobs.cpp b/Userland/Libraries/LibJS/Runtime/PromiseJobs.cpp index dd32f6c5f3..59b3a0f9fb 100644 --- a/Userland/Libraries/LibJS/Runtime/PromiseJobs.cpp +++ b/Userland/Libraries/LibJS/Runtime/PromiseJobs.cpp @@ -52,9 +52,7 @@ static ThrowCompletionOr run_reaction_job(VM& vm, PromiseReaction& reacti // e. Else, let handlerResult be Completion(HostCallJobCallback(handler, undefined, « argument »)). else { dbgln_if(PROMISE_DEBUG, "run_reaction_job: Calling handler callback {} @ {} with argument {}", handler.value().callback.cell()->class_name(), handler.value().callback.cell(), argument); - MarkedVector arguments(vm.heap()); - arguments.append(argument); - handler_result = vm.host_call_job_callback(handler.value(), js_undefined(), move(arguments)); + handler_result = vm.host_call_job_callback(handler.value(), js_undefined(), ReadonlySpan { &argument, 1 }); } // f. If promiseCapability is undefined, then @@ -128,10 +126,10 @@ static ThrowCompletionOr run_resolve_thenable_job(VM& vm, Promise& promis // b. Let thenCallResult be Completion(HostCallJobCallback(then, thenable, « resolvingFunctions.[[Resolve]], resolvingFunctions.[[Reject]] »)). dbgln_if(PROMISE_DEBUG, "run_resolve_thenable_job: Calling then job callback for thenable {}", &thenable); - MarkedVector arguments(vm.heap()); - arguments.append(Value(resolve_function)); - arguments.append(Value(reject_function)); - auto then_call_result = vm.host_call_job_callback(then, thenable, move(arguments)); + AK::Array arguments; + arguments[0] = Value(resolve_function); + arguments[1] = Value(reject_function); + auto then_call_result = vm.host_call_job_callback(then, thenable, arguments.span()); // c. If thenCallResult is an abrupt completion, then if (then_call_result.is_error()) { diff --git a/Userland/Libraries/LibJS/Runtime/ProxyObject.cpp b/Userland/Libraries/LibJS/Runtime/ProxyObject.cpp index 3edfdbae38..3e14b17cbe 100644 --- a/Userland/Libraries/LibJS/Runtime/ProxyObject.cpp +++ b/Userland/Libraries/LibJS/Runtime/ProxyObject.cpp @@ -774,7 +774,7 @@ ThrowCompletionOr> ProxyObject::internal_own_property_keys() } // 10.5.12 [[Call]] ( thisArgument, argumentsList ), https://tc39.es/ecma262/#sec-proxy-object-internal-methods-and-internal-slots-call-thisargument-argumentslist -ThrowCompletionOr ProxyObject::internal_call(Value this_argument, MarkedVector arguments_list) +ThrowCompletionOr ProxyObject::internal_call(Value this_argument, ReadonlySpan arguments_list) { auto& vm = this->vm(); auto& realm = *vm.current_realm(); @@ -797,7 +797,7 @@ ThrowCompletionOr ProxyObject::internal_call(Value this_argument, MarkedV // 6. If trap is undefined, then if (!trap) { // a. Return ? Call(target, thisArgument, argumentsList). - return call(vm, m_target, this_argument, move(arguments_list)); + return call(vm, m_target, this_argument, arguments_list); } // 7. Let argArray be CreateArrayFromList(argumentsList). @@ -818,7 +818,7 @@ bool ProxyObject::has_constructor() const } // 10.5.13 [[Construct]] ( argumentsList, newTarget ), https://tc39.es/ecma262/#sec-proxy-object-internal-methods-and-internal-slots-construct-argumentslist-newtarget -ThrowCompletionOr> ProxyObject::internal_construct(MarkedVector arguments_list, FunctionObject& new_target) +ThrowCompletionOr> ProxyObject::internal_construct(ReadonlySpan arguments_list, FunctionObject& new_target) { auto& vm = this->vm(); auto& realm = *vm.current_realm(); @@ -842,7 +842,7 @@ ThrowCompletionOr> ProxyObject::internal_construct(MarkedVe // 7. If trap is undefined, then if (!trap) { // a. Return ? Construct(target, argumentsList, newTarget). - return construct(vm, static_cast(*m_target), move(arguments_list), &new_target); + return construct(vm, static_cast(*m_target), arguments_list, &new_target); } // 8. Let argArray be CreateArrayFromList(argumentsList). diff --git a/Userland/Libraries/LibJS/Runtime/ProxyObject.h b/Userland/Libraries/LibJS/Runtime/ProxyObject.h index c11b318a0d..462570eadb 100644 --- a/Userland/Libraries/LibJS/Runtime/ProxyObject.h +++ b/Userland/Libraries/LibJS/Runtime/ProxyObject.h @@ -43,8 +43,8 @@ public: virtual ThrowCompletionOr internal_set(PropertyKey const&, Value value, Value receiver, CacheablePropertyMetadata*) override; virtual ThrowCompletionOr internal_delete(PropertyKey const&) override; virtual ThrowCompletionOr> internal_own_property_keys() const override; - virtual ThrowCompletionOr internal_call(Value this_argument, MarkedVector arguments_list) override; - virtual ThrowCompletionOr> internal_construct(MarkedVector arguments_list, FunctionObject& new_target) override; + virtual ThrowCompletionOr internal_call(Value this_argument, ReadonlySpan arguments_list) override; + virtual ThrowCompletionOr> internal_construct(ReadonlySpan arguments_list, FunctionObject& new_target) override; private: ProxyObject(Object& target, Object& handler, Object& prototype); diff --git a/Userland/Libraries/LibJS/Runtime/ReflectObject.cpp b/Userland/Libraries/LibJS/Runtime/ReflectObject.cpp index 32a5b9d12e..a4571015df 100644 --- a/Userland/Libraries/LibJS/Runtime/ReflectObject.cpp +++ b/Userland/Libraries/LibJS/Runtime/ReflectObject.cpp @@ -61,7 +61,7 @@ JS_DEFINE_NATIVE_FUNCTION(ReflectObject::apply) // 3. Perform PrepareForTailCall(). // 4. Return ? Call(target, thisArgument, args). - return TRY(call(vm, target.as_function(), this_argument, move(args))); + return TRY(call(vm, target.as_function(), this_argument, args.span())); } // 28.1.2 Reflect.construct ( target, argumentsList [ , newTarget ] ), https://tc39.es/ecma262/#sec-reflect.construct @@ -86,7 +86,7 @@ JS_DEFINE_NATIVE_FUNCTION(ReflectObject::construct) auto args = TRY(create_list_from_array_like(vm, arguments_list)); // 5. Return ? Construct(target, args, newTarget). - return TRY(JS::construct(vm, target.as_function(), move(args), &new_target.as_function())); + return TRY(JS::construct(vm, target.as_function(), args.span(), &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 2101453784..096e1fb536 100644 --- a/Userland/Libraries/LibJS/Runtime/RegExpPrototype.cpp +++ b/Userland/Libraries/LibJS/Runtime/RegExpPrototype.cpp @@ -777,7 +777,7 @@ JS_DEFINE_NATIVE_FUNCTION(RegExpPrototype::symbol_replace) } // iii. Let replValue be ? Call(replaceValue, undefined, replacerArgs). - auto replace_result = TRY(call(vm, replace_value.as_function(), js_undefined(), move(replacer_args))); + auto replace_result = TRY(call(vm, replace_value.as_function(), js_undefined(), replacer_args.span())); // iv. Let replacement be ? ToString(replValue). replacement = TRY(replace_result.to_string(vm)); diff --git a/Userland/Libraries/LibJS/Runtime/TypedArray.cpp b/Userland/Libraries/LibJS/Runtime/TypedArray.cpp index e2c7ffe90a..ba5153d86a 100644 --- a/Userland/Libraries/LibJS/Runtime/TypedArray.cpp +++ b/Userland/Libraries/LibJS/Runtime/TypedArray.cpp @@ -322,7 +322,7 @@ ThrowCompletionOr typed_array_create(VM& vm, FunctionObject& co if (!arguments.is_empty()) first_argument = arguments[0]; // 1. Let newTypedArray be ? Construct(constructor, argumentList). - auto new_typed_array = TRY(construct(vm, constructor, move(arguments))); + auto new_typed_array = TRY(construct(vm, constructor, arguments.span())); // 2. Perform ? ValidateTypedArray(newTypedArray). if (!new_typed_array->is_typed_array()) diff --git a/Userland/Libraries/LibJS/Runtime/VM.cpp b/Userland/Libraries/LibJS/Runtime/VM.cpp index 24b1b4562c..f7401dc397 100644 --- a/Userland/Libraries/LibJS/Runtime/VM.cpp +++ b/Userland/Libraries/LibJS/Runtime/VM.cpp @@ -78,8 +78,8 @@ VM::VM(OwnPtr custom_data, ErrorMessages error_messages) promise_rejection_tracker(promise, operation); }; - host_call_job_callback = [this](JobCallback& job_callback, Value this_value, MarkedVector arguments) { - return call_job_callback(*this, job_callback, this_value, move(arguments)); + host_call_job_callback = [this](JobCallback& job_callback, Value this_value, ReadonlySpan arguments) { + return call_job_callback(*this, job_callback, this_value, arguments); }; host_enqueue_finalization_registry_cleanup_job = [this](FinalizationRegistry& finalization_registry) { diff --git a/Userland/Libraries/LibJS/Runtime/VM.h b/Userland/Libraries/LibJS/Runtime/VM.h index 78f0bad1bc..7b70537a30 100644 --- a/Userland/Libraries/LibJS/Runtime/VM.h +++ b/Userland/Libraries/LibJS/Runtime/VM.h @@ -243,7 +243,7 @@ public: void enable_default_host_import_module_dynamically_hook(); Function host_promise_rejection_tracker; - Function(JobCallback&, Value, MarkedVector)> host_call_job_callback; + Function(JobCallback&, Value, ReadonlySpan)> host_call_job_callback; Function host_enqueue_finalization_registry_cleanup_job; Function()>, Realm*)> host_enqueue_promise_job; Function host_make_job_callback; diff --git a/Userland/Libraries/LibJS/Runtime/Value.cpp b/Userland/Libraries/LibJS/Runtime/Value.cpp index 058e58af14..9198086a58 100644 --- a/Userland/Libraries/LibJS/Runtime/Value.cpp +++ b/Userland/Libraries/LibJS/Runtime/Value.cpp @@ -2505,7 +2505,10 @@ ThrowCompletionOr Value::invoke_internal(VM& vm, PropertyKey const& prope auto function = TRY(get(vm, property_key)); // 3. Return ? Call(func, V, argumentsList). - return call(vm, function, *this, move(arguments)); + ReadonlySpan argument_list; + if (arguments.has_value()) + argument_list = arguments.value().span(); + return call(vm, function, *this, argument_list); } } diff --git a/Userland/Libraries/LibJS/Runtime/WrappedFunction.cpp b/Userland/Libraries/LibJS/Runtime/WrappedFunction.cpp index 3a2ec747bc..d6fd64b6d2 100644 --- a/Userland/Libraries/LibJS/Runtime/WrappedFunction.cpp +++ b/Userland/Libraries/LibJS/Runtime/WrappedFunction.cpp @@ -54,7 +54,7 @@ void WrappedFunction::visit_edges(Visitor& visitor) } // 2.1 [[Call]] ( thisArgument, argumentsList ), https://tc39.es/proposal-shadowrealm/#sec-wrapped-function-exotic-objects-call-thisargument-argumentslist -ThrowCompletionOr WrappedFunction::internal_call(Value this_argument, MarkedVector arguments_list) +ThrowCompletionOr WrappedFunction::internal_call(Value this_argument, ReadonlySpan arguments_list) { auto& vm = this->vm(); @@ -82,7 +82,7 @@ ThrowCompletionOr WrappedFunction::internal_call(Value this_argument, Mar } // 2.2 OrdinaryWrappedFunctionCall ( F: a wrapped function exotic object, thisArgument: an ECMAScript language value, argumentsList: a List of ECMAScript language values, ), https://tc39.es/proposal-shadowrealm/#sec-ordinary-wrapped-function-call -ThrowCompletionOr ordinary_wrapped_function_call(WrappedFunction const& function, Value this_argument, MarkedVector const& arguments_list) +ThrowCompletionOr ordinary_wrapped_function_call(WrappedFunction const& function, Value this_argument, ReadonlySpan arguments_list) { auto& vm = function.vm(); @@ -118,7 +118,7 @@ ThrowCompletionOr ordinary_wrapped_function_call(WrappedFunction const& f auto wrapped_this_argument = TRY(get_wrapped_value(vm, *target_realm, this_argument)); // 9. Let result be the Completion Record of Call(target, wrappedThisArgument, wrappedArgs). - auto result = call(vm, &target, wrapped_this_argument, move(wrapped_args)); + auto result = call(vm, &target, wrapped_this_argument, wrapped_args.span()); // 10. If result.[[Type]] is normal or result.[[Type]] is return, then if (!result.is_throw_completion()) { diff --git a/Userland/Libraries/LibJS/Runtime/WrappedFunction.h b/Userland/Libraries/LibJS/Runtime/WrappedFunction.h index c7deb252f2..e884c515ca 100644 --- a/Userland/Libraries/LibJS/Runtime/WrappedFunction.h +++ b/Userland/Libraries/LibJS/Runtime/WrappedFunction.h @@ -20,7 +20,7 @@ public: virtual ~WrappedFunction() = default; - virtual ThrowCompletionOr internal_call(Value this_argument, MarkedVector arguments_list) override; + virtual ThrowCompletionOr internal_call(Value this_argument, ReadonlySpan arguments_list) override; // FIXME: Remove this (and stop inventing random internal slots that shouldn't exist, jeez) virtual DeprecatedFlyString const& name() const override { return m_wrapped_target_function->name(); } @@ -40,7 +40,7 @@ private: NonnullGCPtr m_realm; // [[Realm]] }; -ThrowCompletionOr ordinary_wrapped_function_call(WrappedFunction const&, Value this_argument, MarkedVector const& arguments_list); +ThrowCompletionOr ordinary_wrapped_function_call(WrappedFunction const&, Value this_argument, ReadonlySpan arguments_list); void prepare_for_wrapped_function_call(WrappedFunction const&, ExecutionContext& callee_context); }