/src/serenity/Userland/Libraries/LibJS/Runtime/AbstractOperations.h
Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | * Copyright (c) 2020-2023, Linus Groh <linusg@serenityos.org> |
3 | | * |
4 | | * SPDX-License-Identifier: BSD-2-Clause |
5 | | */ |
6 | | |
7 | | #pragma once |
8 | | |
9 | | #include <AK/Concepts.h> |
10 | | #include <AK/Forward.h> |
11 | | #include <LibCrypto/Forward.h> |
12 | | #include <LibJS/Forward.h> |
13 | | #include <LibJS/Heap/MarkedVector.h> |
14 | | #include <LibJS/Runtime/CanonicalIndex.h> |
15 | | #include <LibJS/Runtime/FunctionObject.h> |
16 | | #include <LibJS/Runtime/GlobalObject.h> |
17 | | #include <LibJS/Runtime/Iterator.h> |
18 | | #include <LibJS/Runtime/KeyedCollections.h> |
19 | | #include <LibJS/Runtime/PrivateEnvironment.h> |
20 | | #include <LibJS/Runtime/VM.h> |
21 | | #include <LibJS/Runtime/Value.h> |
22 | | |
23 | | namespace JS { |
24 | | |
25 | | NonnullGCPtr<DeclarativeEnvironment> new_declarative_environment(Environment&); |
26 | | NonnullGCPtr<ObjectEnvironment> new_object_environment(Object&, bool is_with_environment, Environment*); |
27 | | NonnullGCPtr<FunctionEnvironment> new_function_environment(ECMAScriptFunctionObject&, Object* new_target); |
28 | | NonnullGCPtr<PrivateEnvironment> new_private_environment(VM& vm, PrivateEnvironment* outer); |
29 | | NonnullGCPtr<Environment> get_this_environment(VM&); |
30 | | bool can_be_held_weakly(Value); |
31 | | Object* get_super_constructor(VM&); |
32 | | ThrowCompletionOr<Value> require_object_coercible(VM&, Value); |
33 | | ThrowCompletionOr<Value> call_impl(VM&, Value function, Value this_value, ReadonlySpan<Value> arguments = {}); |
34 | | ThrowCompletionOr<Value> call_impl(VM&, FunctionObject& function, Value this_value, ReadonlySpan<Value> arguments = {}); |
35 | | ThrowCompletionOr<NonnullGCPtr<Object>> construct_impl(VM&, FunctionObject&, ReadonlySpan<Value> arguments = {}, FunctionObject* new_target = nullptr); |
36 | | ThrowCompletionOr<size_t> length_of_array_like(VM&, Object const&); |
37 | | ThrowCompletionOr<MarkedVector<Value>> create_list_from_array_like(VM&, Value, Function<ThrowCompletionOr<void>(Value)> = {}); |
38 | | ThrowCompletionOr<FunctionObject*> species_constructor(VM&, Object const&, FunctionObject& default_constructor); |
39 | | ThrowCompletionOr<Realm*> get_function_realm(VM&, FunctionObject const&); |
40 | | ThrowCompletionOr<void> initialize_bound_name(VM&, DeprecatedFlyString const&, Value, Environment*); |
41 | | bool is_compatible_property_descriptor(bool extensible, PropertyDescriptor const&, Optional<PropertyDescriptor> const& current); |
42 | | bool validate_and_apply_property_descriptor(Object*, PropertyKey const&, bool extensible, PropertyDescriptor const&, Optional<PropertyDescriptor> const& current); |
43 | | ThrowCompletionOr<Object*> get_prototype_from_constructor(VM&, FunctionObject const& constructor, NonnullGCPtr<Object> (Intrinsics::*intrinsic_default_prototype)()); |
44 | | Object* create_unmapped_arguments_object(VM&, ReadonlySpan<Value> arguments); |
45 | | Object* create_mapped_arguments_object(VM&, FunctionObject&, Vector<FunctionParameter> const&, ReadonlySpan<Value> arguments, Environment&); |
46 | | |
47 | | struct DisposableResource { |
48 | | Value resource_value; |
49 | | NonnullGCPtr<FunctionObject> dispose_method; |
50 | | }; |
51 | | ThrowCompletionOr<void> add_disposable_resource(VM&, Vector<DisposableResource>& disposable, Value, Environment::InitializeBindingHint, FunctionObject* = nullptr); |
52 | | ThrowCompletionOr<DisposableResource> create_disposable_resource(VM&, Value, Environment::InitializeBindingHint, FunctionObject* method = nullptr); |
53 | | ThrowCompletionOr<GCPtr<FunctionObject>> get_dispose_method(VM&, Value, Environment::InitializeBindingHint); |
54 | | Completion dispose(VM& vm, Value, NonnullGCPtr<FunctionObject> method); |
55 | | Completion dispose_resources(VM& vm, Vector<DisposableResource> const& disposable, Completion completion); |
56 | | Completion dispose_resources(VM& vm, GCPtr<DeclarativeEnvironment> disposable, Completion completion); |
57 | | |
58 | | ThrowCompletionOr<Value> perform_import_call(VM&, Value specifier, Value options_value); |
59 | | |
60 | | enum class CanonicalIndexMode { |
61 | | DetectNumericRoundtrip, |
62 | | IgnoreNumericRoundtrip, |
63 | | }; |
64 | | [[nodiscard]] CanonicalIndex canonical_numeric_index_string(PropertyKey const&, CanonicalIndexMode needs_numeric); |
65 | | ThrowCompletionOr<String> get_substitution(VM&, Utf16View const& matched, Utf16View const& str, size_t position, Span<Value> captures, Value named_captures, Value replacement); |
66 | | |
67 | | enum class CallerMode { |
68 | | Strict, |
69 | | NonStrict |
70 | | }; |
71 | | |
72 | | ThrowCompletionOr<Value> perform_eval(VM&, Value, CallerMode, EvalMode); |
73 | | |
74 | | ThrowCompletionOr<void> eval_declaration_instantiation(VM& vm, Program const& program, Environment* variable_environment, Environment* lexical_environment, PrivateEnvironment* private_environment, bool strict); |
75 | | |
76 | | // 7.3.14 Call ( F, V [ , argumentsList ] ), https://tc39.es/ecma262/#sec-call |
77 | | ALWAYS_INLINE ThrowCompletionOr<Value> call(VM& vm, Value function, Value this_value, ReadonlySpan<Value> arguments_list) |
78 | 0 | { |
79 | 0 | return call_impl(vm, function, this_value, arguments_list); |
80 | 0 | } |
81 | | |
82 | | ALWAYS_INLINE ThrowCompletionOr<Value> call(VM& vm, Value function, Value this_value, Span<Value> arguments_list) |
83 | 0 | { |
84 | 0 | return call_impl(vm, function, this_value, static_cast<ReadonlySpan<Value>>(arguments_list)); |
85 | 0 | } |
86 | | |
87 | | template<typename... Args> |
88 | | ALWAYS_INLINE ThrowCompletionOr<Value> call(VM& vm, Value function, Value this_value, Args&&... args) |
89 | 0 | { |
90 | 0 | constexpr auto argument_count = sizeof...(Args); |
91 | 0 | if constexpr (argument_count > 0) { |
92 | 0 | AK::Array<Value, argument_count> arguments { forward<Args>(args)... }; |
93 | 0 | return call_impl(vm, function, this_value, static_cast<ReadonlySpan<Value>>(arguments.span())); |
94 | 0 | } |
95 | | |
96 | 0 | return call_impl(vm, function, this_value); |
97 | 0 | } Unexecuted instantiation: JS::ThrowCompletionOr<JS::Value> JS::call<>(JS::VM&, JS::Value, JS::Value) Unexecuted instantiation: JS::ThrowCompletionOr<JS::Value> JS::call<JS::Value&, JS::Value&>(JS::VM&, JS::Value, JS::Value, JS::Value&, JS::Value&) Unexecuted instantiation: JS::ThrowCompletionOr<JS::Value> JS::call<JS::Value>(JS::VM&, JS::Value, JS::Value, JS::Value&&) Unexecuted instantiation: JS::ThrowCompletionOr<JS::Value> JS::call<JS::Value&, JS::Value>(JS::VM&, JS::Value, JS::Value, JS::Value&, JS::Value&&) Unexecuted instantiation: JS::ThrowCompletionOr<JS::Value> JS::call<JS::Value&>(JS::VM&, JS::Value, JS::Value, JS::Value&) Unexecuted instantiation: JS::ThrowCompletionOr<JS::Value> JS::call<JS::NonnullGCPtr<JS::Object>&, JS::Value&, JS::NonnullGCPtr<JS::Array>&>(JS::VM&, JS::Value, JS::Value, JS::NonnullGCPtr<JS::Object>&, JS::Value&, JS::NonnullGCPtr<JS::Array>&) Unexecuted instantiation: JS::ThrowCompletionOr<JS::Value> JS::call<JS::NonnullGCPtr<JS::Object>&, JS::NonnullGCPtr<JS::Array>&, JS::FunctionObject*>(JS::VM&, JS::Value, JS::Value, JS::NonnullGCPtr<JS::Object>&, JS::NonnullGCPtr<JS::Array>&, JS::FunctionObject*&&) Unexecuted instantiation: JS::ThrowCompletionOr<JS::Value> JS::call<JS::Object*, JS::Object*>(JS::VM&, JS::Value, JS::Value, JS::Object*&&, JS::Object*&&) Unexecuted instantiation: JS::ThrowCompletionOr<JS::Value> JS::call<JS::Value&, JS::Temporal::Duration*, JS::Value>(JS::VM&, JS::Value, JS::Value, JS::Value&, JS::Temporal::Duration*&&, JS::Value&&) |
98 | | |
99 | | ALWAYS_INLINE ThrowCompletionOr<Value> call(VM& vm, FunctionObject& function, Value this_value, ReadonlySpan<Value> arguments_list) |
100 | 0 | { |
101 | 0 | return call_impl(vm, function, this_value, arguments_list); |
102 | 0 | } |
103 | | |
104 | | ALWAYS_INLINE ThrowCompletionOr<Value> call(VM& vm, FunctionObject& function, Value this_value, Span<Value> arguments_list) |
105 | 0 | { |
106 | 0 | return call_impl(vm, function, this_value, static_cast<ReadonlySpan<Value>>(arguments_list)); |
107 | 0 | } |
108 | | |
109 | | template<typename... Args> |
110 | | ALWAYS_INLINE ThrowCompletionOr<Value> call(VM& vm, FunctionObject& function, Value this_value, Args&&... args) |
111 | 0 | { |
112 | 0 | constexpr auto argument_count = sizeof...(Args); |
113 | 0 | if constexpr (argument_count > 0) { |
114 | 0 | AK::Array<Value, argument_count> arguments { forward<Args>(args)... }; |
115 | 0 | return call_impl(vm, function, this_value, static_cast<ReadonlySpan<Value>>(arguments.span())); |
116 | 0 | } |
117 | | |
118 | 0 | return call_impl(vm, function, this_value); |
119 | 0 | } Unexecuted instantiation: JS::ThrowCompletionOr<JS::Value> JS::call<>(JS::VM&, JS::FunctionObject&, JS::Value) Unexecuted instantiation: JS::ThrowCompletionOr<JS::Value> JS::call<JS::Value&>(JS::VM&, JS::FunctionObject&, JS::Value, JS::Value&) Unexecuted instantiation: JS::ThrowCompletionOr<JS::Value> JS::call<JS::NonnullGCPtr<JS::TypeError>&>(JS::VM&, JS::FunctionObject&, JS::Value, JS::NonnullGCPtr<JS::TypeError>&) Unexecuted instantiation: JS::ThrowCompletionOr<JS::Value> JS::call<JS::Object* const&>(JS::VM&, JS::FunctionObject&, JS::Value, JS::Object* const&) Unexecuted instantiation: JS::ThrowCompletionOr<JS::Value> JS::call<JS::Value>(JS::VM&, JS::FunctionObject&, JS::Value, JS::Value&&) Unexecuted instantiation: JS::ThrowCompletionOr<JS::Value> JS::call<JS::Value&, JS::Value, JS::Object*>(JS::VM&, JS::FunctionObject&, JS::Value, JS::Value&, JS::Value&&, JS::Object*&&) Unexecuted instantiation: JS::ThrowCompletionOr<JS::Value> JS::call<JS::Value&, JS::Value, JS::NonnullGCPtr<JS::Object>&>(JS::VM&, JS::FunctionObject&, JS::Value, JS::Value&, JS::Value&&, JS::NonnullGCPtr<JS::Object>&) Unexecuted instantiation: JS::ThrowCompletionOr<JS::Value> JS::call<JS::Value&, JS::Value&, JS::Value, JS::NonnullGCPtr<JS::Object>&>(JS::VM&, JS::FunctionObject&, JS::Value, JS::Value&, JS::Value&, JS::Value&&, JS::NonnullGCPtr<JS::Object>&) Unexecuted instantiation: JS::ThrowCompletionOr<JS::Value> JS::call<JS::GCPtr<JS::Object>&>(JS::VM&, JS::FunctionObject&, JS::Value, JS::GCPtr<JS::Object>&) Unexecuted instantiation: JS::ThrowCompletionOr<JS::Value> JS::call<JS::NonnullGCPtr<JS::Object>&>(JS::VM&, JS::FunctionObject&, JS::Value, JS::NonnullGCPtr<JS::Object>&) Unexecuted instantiation: JS::ThrowCompletionOr<JS::Value> JS::call<JS::Value, JS::Value>(JS::VM&, JS::FunctionObject&, JS::Value, JS::Value&&, JS::Value&&) Unexecuted instantiation: JS::ThrowCompletionOr<JS::Value> JS::call<JS::Value&, JS::Value>(JS::VM&, JS::FunctionObject&, JS::Value, JS::Value&, JS::Value&&) Unexecuted instantiation: JS::ThrowCompletionOr<JS::Value> JS::call<JS::Value&, JS::Value&, JS::Value>(JS::VM&, JS::FunctionObject&, JS::Value, JS::Value&, JS::Value&, JS::Value&&) Unexecuted instantiation: JS::ThrowCompletionOr<JS::Value> JS::call<JS::NonnullGCPtr<JS::PrimitiveString> >(JS::VM&, JS::FunctionObject&, JS::Value, JS::NonnullGCPtr<JS::PrimitiveString>&&) Unexecuted instantiation: JS::ThrowCompletionOr<JS::Value> JS::call<JS::NonnullGCPtr<JS::PrimitiveString>, JS::Value&>(JS::VM&, JS::FunctionObject&, JS::Value, JS::NonnullGCPtr<JS::PrimitiveString>&&, JS::Value&) Unexecuted instantiation: JS::ThrowCompletionOr<JS::Value> JS::call<JS::Value&, JS::Value&>(JS::VM&, JS::FunctionObject&, JS::Value, JS::Value&, JS::Value&) Unexecuted instantiation: JS::ThrowCompletionOr<JS::Value> JS::call<JS::Value&, JS::Value&, JS::NonnullGCPtr<JS::Map>&>(JS::VM&, JS::FunctionObject&, JS::Value, JS::Value&, JS::Value&, JS::NonnullGCPtr<JS::Map>&) Unexecuted instantiation: JS::ThrowCompletionOr<JS::Value> JS::call<JS::NonnullGCPtr<JS::Array>&>(JS::VM&, JS::FunctionObject&, JS::Value, JS::NonnullGCPtr<JS::Array>&) Unexecuted instantiation: JS::ThrowCompletionOr<JS::Value> JS::call<JS::NonnullGCPtr<JS::FunctionObject>&, JS::NonnullGCPtr<JS::FunctionObject>&>(JS::VM&, JS::FunctionObject&, JS::Value, JS::NonnullGCPtr<JS::FunctionObject>&, JS::NonnullGCPtr<JS::FunctionObject>&) Unexecuted instantiation: JS::ThrowCompletionOr<JS::Value> JS::call<JS::Value const&>(JS::VM&, JS::FunctionObject&, JS::Value, JS::Value const&) Unexecuted instantiation: JS::ThrowCompletionOr<JS::Value> JS::call<JS::NonnullGCPtr<JS::AggregateError>&>(JS::VM&, JS::FunctionObject&, JS::Value, JS::NonnullGCPtr<JS::AggregateError>&) Unexecuted instantiation: JS::ThrowCompletionOr<JS::Value> JS::call<JS::NonnullGCPtr<JS::Object> const&>(JS::VM&, JS::FunctionObject&, JS::Value, JS::NonnullGCPtr<JS::Object> const&) Unexecuted instantiation: JS::ThrowCompletionOr<JS::Value> JS::call<JS::NonnullGCPtr<JS::Object>&, JS::Object*&>(JS::VM&, JS::FunctionObject&, JS::Value, JS::NonnullGCPtr<JS::Object>&, JS::Object*&) Unexecuted instantiation: JS::ThrowCompletionOr<JS::Value> JS::call<JS::NonnullGCPtr<JS::Object> const&, JS::Value>(JS::VM&, JS::FunctionObject&, JS::Value, JS::NonnullGCPtr<JS::Object> const&, JS::Value&&) Unexecuted instantiation: JS::ThrowCompletionOr<JS::Value> JS::call<JS::NonnullGCPtr<JS::Object>&, JS::Value, JS::Value&>(JS::VM&, JS::FunctionObject&, JS::Value, JS::NonnullGCPtr<JS::Object>&, JS::Value&&, JS::Value&) Unexecuted instantiation: JS::ThrowCompletionOr<JS::Value> JS::call<JS::NonnullGCPtr<JS::Object> const&, JS::Value, JS::Value&>(JS::VM&, JS::FunctionObject&, JS::Value, JS::NonnullGCPtr<JS::Object> const&, JS::Value&&, JS::Value&) Unexecuted instantiation: JS::ThrowCompletionOr<JS::Value> JS::call<JS::NonnullGCPtr<JS::Object>&, JS::Value, JS::Value&, JS::Value&>(JS::VM&, JS::FunctionObject&, JS::Value, JS::NonnullGCPtr<JS::Object>&, JS::Value&&, JS::Value&, JS::Value&) Unexecuted instantiation: JS::ThrowCompletionOr<JS::Value> JS::call<JS::NonnullGCPtr<JS::Object>&, JS::Value>(JS::VM&, JS::FunctionObject&, JS::Value, JS::NonnullGCPtr<JS::Object>&, JS::Value&&) Unexecuted instantiation: JS::ThrowCompletionOr<JS::Value> JS::call<JS::Value&, JS::Value&, JS::NonnullGCPtr<JS::Set>&>(JS::VM&, JS::FunctionObject&, JS::Value, JS::Value&, JS::Value&, JS::NonnullGCPtr<JS::Set>&) Unexecuted instantiation: JS::ThrowCompletionOr<JS::Value> JS::call<JS::NonnullGCPtr<JS::PrimitiveString>, JS::Value, JS::NonnullGCPtr<JS::PrimitiveString> >(JS::VM&, JS::FunctionObject&, JS::Value, JS::NonnullGCPtr<JS::PrimitiveString>&&, JS::Value&&, JS::NonnullGCPtr<JS::PrimitiveString>&&) Unexecuted instantiation: JS::ThrowCompletionOr<JS::Value> JS::call<JS::Value&, JS::Value, JS::TypedArrayBase const*>(JS::VM&, JS::FunctionObject&, JS::Value, JS::Value&, JS::Value&&, JS::TypedArrayBase const*&&) Unexecuted instantiation: JS::ThrowCompletionOr<JS::Value> JS::call<JS::Value&, JS::Value, JS::TypedArrayBase*&>(JS::VM&, JS::FunctionObject&, JS::Value, JS::Value&, JS::Value&&, JS::TypedArrayBase*&) Unexecuted instantiation: JS::ThrowCompletionOr<JS::Value> JS::call<JS::Value&, JS::Value&, JS::Value, JS::TypedArrayBase*&>(JS::VM&, JS::FunctionObject&, JS::Value, JS::Value&, JS::Value&, JS::Value&&, JS::TypedArrayBase*&) Unexecuted instantiation: JS::ThrowCompletionOr<JS::Value> JS::call<JS::Value&, JS::Value&, Web::CSS::FontFaceSet*&>(JS::VM&, JS::FunctionObject&, JS::Value, JS::Value&, JS::Value&, Web::CSS::FontFaceSet*&) Unexecuted instantiation: JS::ThrowCompletionOr<JS::Value> JS::call<JS::Value&, JS::Value&, JS::Value&>(JS::VM&, JS::FunctionObject&, JS::Value, JS::Value&, JS::Value&, JS::Value&) |
120 | | |
121 | | // 7.3.15 Construct ( F [ , argumentsList [ , newTarget ] ] ), https://tc39.es/ecma262/#sec-construct |
122 | | template<typename... Args> |
123 | | ALWAYS_INLINE ThrowCompletionOr<NonnullGCPtr<Object>> construct(VM& vm, FunctionObject& function, Args&&... args) |
124 | 0 | { |
125 | 0 | constexpr auto argument_count = sizeof...(Args); |
126 | 0 | if constexpr (argument_count > 0) { |
127 | 0 | AK::Array<Value, argument_count> arguments { forward<Args>(args)... }; |
128 | 0 | return construct_impl(vm, function, static_cast<ReadonlySpan<Value>>(arguments.span())); |
129 | 0 | } |
130 | | |
131 | 0 | return construct_impl(vm, function); |
132 | 0 | } Unexecuted instantiation: JS::ThrowCompletionOr<JS::NonnullGCPtr<JS::Object> > JS::construct<JS::Value>(JS::VM&, JS::FunctionObject&, JS::Value&&) Unexecuted instantiation: JS::ThrowCompletionOr<JS::NonnullGCPtr<JS::Object> > JS::construct<>(JS::VM&, JS::FunctionObject&) Unexecuted instantiation: JS::ThrowCompletionOr<JS::NonnullGCPtr<JS::Object> > JS::construct<JS::Value&, JS::Value&>(JS::VM&, JS::FunctionObject&, JS::Value&, JS::Value&) Unexecuted instantiation: JS::ThrowCompletionOr<JS::NonnullGCPtr<JS::Object> > JS::construct<JS::NonnullGCPtr<JS::PrimitiveString>, JS::NonnullGCPtr<JS::Object>&>(JS::VM&, JS::FunctionObject&, JS::NonnullGCPtr<JS::PrimitiveString>&&, JS::NonnullGCPtr<JS::Object>&) Unexecuted instantiation: JS::ThrowCompletionOr<JS::NonnullGCPtr<JS::Object> > JS::construct<JS::NonnullGCPtr<JS::PrimitiveString> >(JS::VM&, JS::FunctionObject&, JS::NonnullGCPtr<JS::PrimitiveString>&&) Unexecuted instantiation: JS::ThrowCompletionOr<JS::NonnullGCPtr<JS::Object> > JS::construct<JS::NonnullGCPtr<JS::NativeFunction>&>(JS::VM&, JS::FunctionObject&, JS::NonnullGCPtr<JS::NativeFunction>&) Unexecuted instantiation: JS::ThrowCompletionOr<JS::NonnullGCPtr<JS::Object> > JS::construct<JS::NonnullGCPtr<JS::Object>&, JS::NonnullGCPtr<JS::PrimitiveString> >(JS::VM&, JS::FunctionObject&, JS::NonnullGCPtr<JS::Object>&, JS::NonnullGCPtr<JS::PrimitiveString>&&) Unexecuted instantiation: JS::ThrowCompletionOr<JS::NonnullGCPtr<JS::Object> > JS::construct<JS::Value, JS::Value>(JS::VM&, JS::FunctionObject&, JS::Value&&, JS::Value&&) Unexecuted instantiation: JS::ThrowCompletionOr<JS::NonnullGCPtr<JS::Object> > JS::construct<JS::NonnullGCPtr<JS::ArrayBuffer>&, JS::Value, JS::Value>(JS::VM&, JS::FunctionObject&, JS::NonnullGCPtr<JS::ArrayBuffer>&, JS::Value&&, JS::Value&&) Unexecuted instantiation: JS::ThrowCompletionOr<JS::NonnullGCPtr<JS::Object> > JS::construct<JS::NonnullGCPtr<JS::ArrayBuffer> const&, JS::Value, JS::Value>(JS::VM&, JS::FunctionObject&, JS::NonnullGCPtr<JS::ArrayBuffer> const&, JS::Value&&, JS::Value&&) Unexecuted instantiation: JS::ThrowCompletionOr<JS::NonnullGCPtr<JS::Object> > JS::construct<JS::ArrayBuffer*&>(JS::VM&, JS::FunctionObject&, JS::ArrayBuffer*&) |
133 | | |
134 | | ALWAYS_INLINE ThrowCompletionOr<NonnullGCPtr<Object>> construct(VM& vm, FunctionObject& function, ReadonlySpan<Value> arguments_list, FunctionObject* new_target = nullptr) |
135 | 0 | { |
136 | 0 | return construct_impl(vm, function, arguments_list, new_target); |
137 | 0 | } |
138 | | |
139 | | ALWAYS_INLINE ThrowCompletionOr<NonnullGCPtr<Object>> construct(VM& vm, FunctionObject& function, Span<Value> arguments_list, FunctionObject* new_target = nullptr) |
140 | 0 | { |
141 | 0 | return construct_impl(vm, function, static_cast<ReadonlySpan<Value>>(arguments_list), new_target); |
142 | 0 | } |
143 | | |
144 | | // 10.1.13 OrdinaryCreateFromConstructor ( constructor, intrinsicDefaultProto [ , internalSlotsList ] ), https://tc39.es/ecma262/#sec-ordinarycreatefromconstructor |
145 | | template<typename T, typename... Args> |
146 | | ThrowCompletionOr<NonnullGCPtr<T>> ordinary_create_from_constructor(VM& vm, FunctionObject const& constructor, NonnullGCPtr<Object> (Intrinsics::*intrinsic_default_prototype)(), Args&&... args) |
147 | 0 | { |
148 | 0 | auto& realm = *vm.current_realm(); |
149 | 0 | auto* prototype = TRY(get_prototype_from_constructor(vm, constructor, intrinsic_default_prototype)); |
150 | 0 | return realm.heap().allocate<T>(realm, forward<Args>(args)..., *prototype); |
151 | 0 | } Unexecuted instantiation: JS::ThrowCompletionOr<JS::NonnullGCPtr<JS::Object> > JS::ordinary_create_from_constructor<JS::Object, JS::Object::ConstructWithPrototypeTag>(JS::VM&, JS::FunctionObject const&, JS::NonnullGCPtr<JS::Object> (JS::Intrinsics::*)(), JS::Object::ConstructWithPrototypeTag&&) Unexecuted instantiation: JS::ThrowCompletionOr<JS::NonnullGCPtr<JS::Error> > JS::ordinary_create_from_constructor<JS::Error>(JS::VM&, JS::FunctionObject const&, JS::NonnullGCPtr<JS::Object> (JS::Intrinsics::*)()) Unexecuted instantiation: JS::ThrowCompletionOr<JS::NonnullGCPtr<JS::EvalError> > JS::ordinary_create_from_constructor<JS::EvalError>(JS::VM&, JS::FunctionObject const&, JS::NonnullGCPtr<JS::Object> (JS::Intrinsics::*)()) Unexecuted instantiation: JS::ThrowCompletionOr<JS::NonnullGCPtr<JS::InternalError> > JS::ordinary_create_from_constructor<JS::InternalError>(JS::VM&, JS::FunctionObject const&, JS::NonnullGCPtr<JS::Object> (JS::Intrinsics::*)()) Unexecuted instantiation: JS::ThrowCompletionOr<JS::NonnullGCPtr<JS::RangeError> > JS::ordinary_create_from_constructor<JS::RangeError>(JS::VM&, JS::FunctionObject const&, JS::NonnullGCPtr<JS::Object> (JS::Intrinsics::*)()) Unexecuted instantiation: JS::ThrowCompletionOr<JS::NonnullGCPtr<JS::ReferenceError> > JS::ordinary_create_from_constructor<JS::ReferenceError>(JS::VM&, JS::FunctionObject const&, JS::NonnullGCPtr<JS::Object> (JS::Intrinsics::*)()) Unexecuted instantiation: JS::ThrowCompletionOr<JS::NonnullGCPtr<JS::SyntaxError> > JS::ordinary_create_from_constructor<JS::SyntaxError>(JS::VM&, JS::FunctionObject const&, JS::NonnullGCPtr<JS::Object> (JS::Intrinsics::*)()) Unexecuted instantiation: JS::ThrowCompletionOr<JS::NonnullGCPtr<JS::TypeError> > JS::ordinary_create_from_constructor<JS::TypeError>(JS::VM&, JS::FunctionObject const&, JS::NonnullGCPtr<JS::Object> (JS::Intrinsics::*)()) Unexecuted instantiation: JS::ThrowCompletionOr<JS::NonnullGCPtr<JS::URIError> > JS::ordinary_create_from_constructor<JS::URIError>(JS::VM&, JS::FunctionObject const&, JS::NonnullGCPtr<JS::Object> (JS::Intrinsics::*)()) Unexecuted instantiation: JS::ThrowCompletionOr<JS::NonnullGCPtr<JS::AggregateError> > JS::ordinary_create_from_constructor<JS::AggregateError>(JS::VM&, JS::FunctionObject const&, JS::NonnullGCPtr<JS::Object> (JS::Intrinsics::*)()) Unexecuted instantiation: JS::ThrowCompletionOr<JS::NonnullGCPtr<JS::ArrayBuffer> > JS::ordinary_create_from_constructor<JS::ArrayBuffer, decltype(nullptr)>(JS::VM&, JS::FunctionObject const&, JS::NonnullGCPtr<JS::Object> (JS::Intrinsics::*)(), decltype(nullptr)&&) Unexecuted instantiation: JS::ThrowCompletionOr<JS::NonnullGCPtr<JS::BooleanObject> > JS::ordinary_create_from_constructor<JS::BooleanObject, bool&>(JS::VM&, JS::FunctionObject const&, JS::NonnullGCPtr<JS::Object> (JS::Intrinsics::*)(), bool&) Unexecuted instantiation: JS::ThrowCompletionOr<JS::NonnullGCPtr<JS::DataView> > JS::ordinary_create_from_constructor<JS::DataView, JS::ArrayBuffer*, JS::ByteLength, unsigned long&>(JS::VM&, JS::FunctionObject const&, JS::NonnullGCPtr<JS::Object> (JS::Intrinsics::*)(), JS::ArrayBuffer*&&, JS::ByteLength&&, unsigned long&) Unexecuted instantiation: JS::ThrowCompletionOr<JS::NonnullGCPtr<JS::Intl::DateTimeFormat> > JS::ordinary_create_from_constructor<JS::Intl::DateTimeFormat>(JS::VM&, JS::FunctionObject const&, JS::NonnullGCPtr<JS::Object> (JS::Intrinsics::*)()) Unexecuted instantiation: JS::ThrowCompletionOr<JS::NonnullGCPtr<JS::Date> > JS::ordinary_create_from_constructor<JS::Date, double&>(JS::VM&, JS::FunctionObject const&, JS::NonnullGCPtr<JS::Object> (JS::Intrinsics::*)(), double&) Unexecuted instantiation: JS::ThrowCompletionOr<JS::NonnullGCPtr<JS::DisposableStack> > JS::ordinary_create_from_constructor<JS::DisposableStack, AK::Vector<JS::DisposableResource, 0ul>&>(JS::VM&, JS::FunctionObject const&, JS::NonnullGCPtr<JS::Object> (JS::Intrinsics::*)(), AK::Vector<JS::DisposableResource, 0ul>&) Unexecuted instantiation: JS::ThrowCompletionOr<JS::NonnullGCPtr<JS::DisposableStack> > JS::ordinary_create_from_constructor<JS::DisposableStack, AK::Vector<JS::DisposableResource, 0ul> >(JS::VM&, JS::FunctionObject const&, JS::NonnullGCPtr<JS::Object> (JS::Intrinsics::*)(), AK::Vector<JS::DisposableResource, 0ul>&&) Unexecuted instantiation: JS::ThrowCompletionOr<JS::NonnullGCPtr<JS::FinalizationRegistry> > JS::ordinary_create_from_constructor<JS::FinalizationRegistry, JS::Realm&, JS::NonnullGCPtr<JS::JobCallback> >(JS::VM&, JS::FunctionObject const&, JS::NonnullGCPtr<JS::Object> (JS::Intrinsics::*)(), JS::Realm&, JS::NonnullGCPtr<JS::JobCallback>&&) Unexecuted instantiation: JS::ThrowCompletionOr<JS::NonnullGCPtr<JS::Intl::Collator> > JS::ordinary_create_from_constructor<JS::Intl::Collator>(JS::VM&, JS::FunctionObject const&, JS::NonnullGCPtr<JS::Object> (JS::Intrinsics::*)()) Unexecuted instantiation: JS::ThrowCompletionOr<JS::NonnullGCPtr<JS::Intl::DisplayNames> > JS::ordinary_create_from_constructor<JS::Intl::DisplayNames>(JS::VM&, JS::FunctionObject const&, JS::NonnullGCPtr<JS::Object> (JS::Intrinsics::*)()) Unexecuted instantiation: JS::ThrowCompletionOr<JS::NonnullGCPtr<JS::Intl::DurationFormat> > JS::ordinary_create_from_constructor<JS::Intl::DurationFormat>(JS::VM&, JS::FunctionObject const&, JS::NonnullGCPtr<JS::Object> (JS::Intrinsics::*)()) Unexecuted instantiation: JS::ThrowCompletionOr<JS::NonnullGCPtr<JS::Intl::ListFormat> > JS::ordinary_create_from_constructor<JS::Intl::ListFormat>(JS::VM&, JS::FunctionObject const&, JS::NonnullGCPtr<JS::Object> (JS::Intrinsics::*)()) Unexecuted instantiation: JS::ThrowCompletionOr<JS::NonnullGCPtr<JS::Intl::Locale> > JS::ordinary_create_from_constructor<JS::Intl::Locale>(JS::VM&, JS::FunctionObject const&, JS::NonnullGCPtr<JS::Object> (JS::Intrinsics::*)()) Unexecuted instantiation: JS::ThrowCompletionOr<JS::NonnullGCPtr<JS::Intl::NumberFormat> > JS::ordinary_create_from_constructor<JS::Intl::NumberFormat>(JS::VM&, JS::FunctionObject const&, JS::NonnullGCPtr<JS::Object> (JS::Intrinsics::*)()) Unexecuted instantiation: JS::ThrowCompletionOr<JS::NonnullGCPtr<JS::Intl::PluralRules> > JS::ordinary_create_from_constructor<JS::Intl::PluralRules>(JS::VM&, JS::FunctionObject const&, JS::NonnullGCPtr<JS::Object> (JS::Intrinsics::*)()) Unexecuted instantiation: JS::ThrowCompletionOr<JS::NonnullGCPtr<JS::Intl::RelativeTimeFormat> > JS::ordinary_create_from_constructor<JS::Intl::RelativeTimeFormat>(JS::VM&, JS::FunctionObject const&, JS::NonnullGCPtr<JS::Object> (JS::Intrinsics::*)()) Unexecuted instantiation: JS::ThrowCompletionOr<JS::NonnullGCPtr<JS::Intl::Segmenter> > JS::ordinary_create_from_constructor<JS::Intl::Segmenter>(JS::VM&, JS::FunctionObject const&, JS::NonnullGCPtr<JS::Object> (JS::Intrinsics::*)()) Unexecuted instantiation: JS::ThrowCompletionOr<JS::NonnullGCPtr<JS::Iterator> > JS::ordinary_create_from_constructor<JS::Iterator>(JS::VM&, JS::FunctionObject const&, JS::NonnullGCPtr<JS::Object> (JS::Intrinsics::*)()) Unexecuted instantiation: JS::ThrowCompletionOr<JS::NonnullGCPtr<JS::Map> > JS::ordinary_create_from_constructor<JS::Map>(JS::VM&, JS::FunctionObject const&, JS::NonnullGCPtr<JS::Object> (JS::Intrinsics::*)()) Unexecuted instantiation: JS::ThrowCompletionOr<JS::NonnullGCPtr<JS::NumberObject> > JS::ordinary_create_from_constructor<JS::NumberObject, double>(JS::VM&, JS::FunctionObject const&, JS::NonnullGCPtr<JS::Object> (JS::Intrinsics::*)(), double&&) Unexecuted instantiation: JS::ThrowCompletionOr<JS::NonnullGCPtr<JS::Promise> > JS::ordinary_create_from_constructor<JS::Promise>(JS::VM&, JS::FunctionObject const&, JS::NonnullGCPtr<JS::Object> (JS::Intrinsics::*)()) Unexecuted instantiation: JS::ThrowCompletionOr<JS::NonnullGCPtr<JS::RegExpObject> > JS::ordinary_create_from_constructor<JS::RegExpObject>(JS::VM&, JS::FunctionObject const&, JS::NonnullGCPtr<JS::Object> (JS::Intrinsics::*)()) Unexecuted instantiation: JS::ThrowCompletionOr<JS::NonnullGCPtr<JS::Set> > JS::ordinary_create_from_constructor<JS::Set>(JS::VM&, JS::FunctionObject const&, JS::NonnullGCPtr<JS::Object> (JS::Intrinsics::*)()) Unexecuted instantiation: JS::ThrowCompletionOr<JS::NonnullGCPtr<JS::ShadowRealm> > JS::ordinary_create_from_constructor<JS::ShadowRealm>(JS::VM&, JS::FunctionObject const&, JS::NonnullGCPtr<JS::Object> (JS::Intrinsics::*)()) Unexecuted instantiation: JS::ThrowCompletionOr<JS::NonnullGCPtr<JS::SuppressedError> > JS::ordinary_create_from_constructor<JS::SuppressedError>(JS::VM&, JS::FunctionObject const&, JS::NonnullGCPtr<JS::Object> (JS::Intrinsics::*)()) Unexecuted instantiation: JS::ThrowCompletionOr<JS::NonnullGCPtr<JS::Temporal::Calendar> > JS::ordinary_create_from_constructor<JS::Temporal::Calendar, AK::String>(JS::VM&, JS::FunctionObject const&, JS::NonnullGCPtr<JS::Object> (JS::Intrinsics::*)(), AK::String&&) Unexecuted instantiation: JS::ThrowCompletionOr<JS::NonnullGCPtr<JS::Temporal::Duration> > JS::ordinary_create_from_constructor<JS::Temporal::Duration, double&, double&, double&, double&, double&, double&, double&, double&, double&, double&>(JS::VM&, JS::FunctionObject const&, JS::NonnullGCPtr<JS::Object> (JS::Intrinsics::*)(), double&, double&, double&, double&, double&, double&, double&, double&, double&, double&) Unexecuted instantiation: JS::ThrowCompletionOr<JS::NonnullGCPtr<JS::Temporal::Instant> > JS::ordinary_create_from_constructor<JS::Temporal::Instant, JS::BigInt const&>(JS::VM&, JS::FunctionObject const&, JS::NonnullGCPtr<JS::Object> (JS::Intrinsics::*)(), JS::BigInt const&) Unexecuted instantiation: JS::ThrowCompletionOr<JS::NonnullGCPtr<JS::Temporal::PlainDate> > JS::ordinary_create_from_constructor<JS::Temporal::PlainDate, int&, unsigned char&, unsigned char&, JS::Object&>(JS::VM&, JS::FunctionObject const&, JS::NonnullGCPtr<JS::Object> (JS::Intrinsics::*)(), int&, unsigned char&, unsigned char&, JS::Object&) Unexecuted instantiation: JS::ThrowCompletionOr<JS::NonnullGCPtr<JS::Temporal::PlainDateTime> > JS::ordinary_create_from_constructor<JS::Temporal::PlainDateTime, int&, unsigned char&, unsigned char&, unsigned char&, unsigned char&, unsigned char&, unsigned short&, unsigned short&, unsigned short&, JS::Object&>(JS::VM&, JS::FunctionObject const&, JS::NonnullGCPtr<JS::Object> (JS::Intrinsics::*)(), int&, unsigned char&, unsigned char&, unsigned char&, unsigned char&, unsigned char&, unsigned short&, unsigned short&, unsigned short&, JS::Object&) Unexecuted instantiation: JS::ThrowCompletionOr<JS::NonnullGCPtr<JS::Temporal::PlainMonthDay> > JS::ordinary_create_from_constructor<JS::Temporal::PlainMonthDay, unsigned char&, unsigned char&, int&, JS::Object&>(JS::VM&, JS::FunctionObject const&, JS::NonnullGCPtr<JS::Object> (JS::Intrinsics::*)(), unsigned char&, unsigned char&, int&, JS::Object&) Unexecuted instantiation: JS::ThrowCompletionOr<JS::NonnullGCPtr<JS::Temporal::PlainTime> > JS::ordinary_create_from_constructor<JS::Temporal::PlainTime, unsigned char&, unsigned char&, unsigned char&, unsigned short&, unsigned short&, unsigned short&, JS::Temporal::Calendar&>(JS::VM&, JS::FunctionObject const&, JS::NonnullGCPtr<JS::Object> (JS::Intrinsics::*)(), unsigned char&, unsigned char&, unsigned char&, unsigned short&, unsigned short&, unsigned short&, JS::Temporal::Calendar&) Unexecuted instantiation: JS::ThrowCompletionOr<JS::NonnullGCPtr<JS::Temporal::PlainYearMonth> > JS::ordinary_create_from_constructor<JS::Temporal::PlainYearMonth, int&, unsigned char&, unsigned char&, JS::Object&>(JS::VM&, JS::FunctionObject const&, JS::NonnullGCPtr<JS::Object> (JS::Intrinsics::*)(), int&, unsigned char&, unsigned char&, JS::Object&) Unexecuted instantiation: JS::ThrowCompletionOr<JS::NonnullGCPtr<JS::Temporal::TimeZone> > JS::ordinary_create_from_constructor<JS::Temporal::TimeZone>(JS::VM&, JS::FunctionObject const&, JS::NonnullGCPtr<JS::Object> (JS::Intrinsics::*)()) Unexecuted instantiation: JS::ThrowCompletionOr<JS::NonnullGCPtr<JS::Temporal::ZonedDateTime> > JS::ordinary_create_from_constructor<JS::Temporal::ZonedDateTime, JS::BigInt const&, JS::Object&, JS::Object&>(JS::VM&, JS::FunctionObject const&, JS::NonnullGCPtr<JS::Object> (JS::Intrinsics::*)(), JS::BigInt const&, JS::Object&, JS::Object&) Unexecuted instantiation: JS::ThrowCompletionOr<JS::NonnullGCPtr<JS::WeakMap> > JS::ordinary_create_from_constructor<JS::WeakMap>(JS::VM&, JS::FunctionObject const&, JS::NonnullGCPtr<JS::Object> (JS::Intrinsics::*)()) Unexecuted instantiation: JS::ThrowCompletionOr<JS::NonnullGCPtr<JS::WeakRef> > JS::ordinary_create_from_constructor<JS::WeakRef, JS::Object&>(JS::VM&, JS::FunctionObject const&, JS::NonnullGCPtr<JS::Object> (JS::Intrinsics::*)(), JS::Object&) Unexecuted instantiation: JS::ThrowCompletionOr<JS::NonnullGCPtr<JS::WeakRef> > JS::ordinary_create_from_constructor<JS::WeakRef, JS::Symbol&>(JS::VM&, JS::FunctionObject const&, JS::NonnullGCPtr<JS::Object> (JS::Intrinsics::*)(), JS::Symbol&) Unexecuted instantiation: JS::ThrowCompletionOr<JS::NonnullGCPtr<JS::WeakSet> > JS::ordinary_create_from_constructor<JS::WeakSet>(JS::VM&, JS::FunctionObject const&, JS::NonnullGCPtr<JS::Object> (JS::Intrinsics::*)()) |
152 | | |
153 | | // 14.1 MergeLists ( a, b ), https://tc39.es/proposal-temporal/#sec-temporal-mergelists |
154 | | template<typename T> |
155 | | Vector<T> merge_lists(Vector<T> const& a, Vector<T> const& b) |
156 | 0 | { |
157 | | // 1. Let merged be a new empty List. |
158 | 0 | Vector<T> merged; |
159 | | |
160 | | // 2. For each element element of a, do |
161 | 0 | for (auto const& element : a) { |
162 | | // a. If merged does not contain element, then |
163 | 0 | if (!merged.contains_slow(element)) { |
164 | | // i. Append element to merged. |
165 | 0 | merged.append(element); |
166 | 0 | } |
167 | 0 | } |
168 | | |
169 | | // 3. For each element element of b, do |
170 | 0 | for (auto const& element : b) { |
171 | | // a. If merged does not contain element, then |
172 | 0 | if (!merged.contains_slow(element)) { |
173 | | // i. Append element to merged. |
174 | 0 | merged.append(element); |
175 | 0 | } |
176 | 0 | } |
177 | | |
178 | | // 4. Return merged. |
179 | 0 | return merged; |
180 | 0 | } |
181 | | |
182 | | // 7.3.35 AddValueToKeyedGroup ( groups, key, value ), https://tc39.es/ecma262/#sec-add-value-to-keyed-group |
183 | | template<typename GroupsType, typename KeyType> |
184 | | void add_value_to_keyed_group(VM& vm, GroupsType& groups, KeyType key, Value value) |
185 | 0 | { |
186 | | // 1. For each Record { [[Key]], [[Elements]] } g of groups, do |
187 | | // a. If SameValue(g.[[Key]], key) is true, then |
188 | | // NOTE: This is performed in KeyedGroupTraits::equals for groupToMap and Traits<JS::PropertyKey>::equals for group. |
189 | 0 | auto existing_elements_iterator = groups.find(key); |
190 | 0 | if (existing_elements_iterator != groups.end()) { |
191 | | // i. Assert: exactly one element of groups meets this criteria. |
192 | | // NOTE: This is done on insertion into the hash map, as only `set` tells us if we overrode an entry. |
193 | | |
194 | | // ii. Append value as the last element of g.[[Elements]]. |
195 | 0 | existing_elements_iterator->value.append(value); |
196 | | |
197 | | // iii. Return unused. |
198 | 0 | return; |
199 | 0 | } |
200 | | |
201 | | // 2. Let group be the Record { [[Key]]: key, [[Elements]]: « value » }. |
202 | 0 | MarkedVector<Value> new_elements { vm.heap() }; |
203 | 0 | new_elements.append(value); |
204 | | |
205 | | // 3. Append group as the last element of groups. |
206 | 0 | auto result = groups.set(key, move(new_elements)); |
207 | 0 | VERIFY(result == AK::HashSetResult::InsertedNewEntry); |
208 | | |
209 | | // 4. Return unused. |
210 | 0 | } Unexecuted instantiation: MapConstructor.cpp:void JS::add_value_to_keyed_group<AK::HashMap<JS::Handle<JS::Value>, JS::MarkedVector<JS::Value, 0ul>, JS::MapConstructor::group_by(JS::VM&)::KeyedGroupTraits, AK::Traits<JS::MarkedVector<JS::Value, 0ul> >, true>, JS::Handle<JS::Value> >(JS::VM&, AK::HashMap<JS::Handle<JS::Value>, JS::MarkedVector<JS::Value, 0ul>, JS::MapConstructor::group_by(JS::VM&)::KeyedGroupTraits, AK::Traits<JS::MarkedVector<JS::Value, 0ul> >, true>&, JS::Handle<JS::Value>, JS::Value) Unexecuted instantiation: void JS::add_value_to_keyed_group<AK::HashMap<JS::PropertyKey, JS::MarkedVector<JS::Value, 0ul>, AK::Traits<JS::PropertyKey>, AK::Traits<JS::MarkedVector<JS::Value, 0ul> >, true>, JS::PropertyKey>(JS::VM&, AK::HashMap<JS::PropertyKey, JS::MarkedVector<JS::Value, 0ul>, AK::Traits<JS::PropertyKey>, AK::Traits<JS::MarkedVector<JS::Value, 0ul> >, true>&, JS::PropertyKey, JS::Value) |
211 | | |
212 | | // 7.3.36 GroupBy ( items, callbackfn, keyCoercion ), https://tc39.es/ecma262/#sec-groupby |
213 | | template<typename GroupsType, typename KeyType> |
214 | | ThrowCompletionOr<GroupsType> group_by(VM& vm, Value items, Value callback_function) |
215 | 0 | { |
216 | | // 1. Perform ? RequireObjectCoercible(items). |
217 | 0 | TRY(require_object_coercible(vm, items)); |
218 | | |
219 | | // 2. If IsCallable(callbackfn) is false, throw a TypeError exception. |
220 | 0 | if (!callback_function.is_function()) |
221 | 0 | return vm.throw_completion<TypeError>(ErrorType::NotAFunction, callback_function.to_string_without_side_effects()); |
222 | | |
223 | | // 3. Let groups be a new empty List. |
224 | 0 | GroupsType groups; |
225 | | |
226 | | // 4. Let iteratorRecord be ? GetIterator(items, sync). |
227 | 0 | auto iterator_record = TRY(get_iterator(vm, items, IteratorHint::Sync)); |
228 | | |
229 | | // 5. Let k be 0. |
230 | 0 | u64 k = 0; |
231 | | |
232 | | // 6. Repeat, |
233 | 0 | while (true) { |
234 | | // a. If k ≥ 2^53 - 1, then |
235 | 0 | if (k >= MAX_ARRAY_LIKE_INDEX) { |
236 | | // i. Let error be ThrowCompletion(a newly created TypeError object). |
237 | 0 | auto error = vm.throw_completion<TypeError>(ErrorType::ArrayMaxSize); |
238 | | |
239 | | // ii. Return ? IteratorClose(iteratorRecord, error). |
240 | 0 | return iterator_close(vm, iterator_record, move(error)); |
241 | 0 | } |
242 | | |
243 | | // b. Let next be ? IteratorStepValue(iteratorRecord). |
244 | 0 | auto next = TRY(iterator_step_value(vm, iterator_record)); |
245 | | |
246 | | // c. If next is DONE, then |
247 | 0 | if (!next.has_value()) { |
248 | | // i. Return groups. |
249 | 0 | return ThrowCompletionOr<GroupsType> { move(groups) }; |
250 | 0 | } |
251 | | |
252 | | // d. Let value be next. |
253 | 0 | auto value = next.release_value(); |
254 | | |
255 | | // e. Let key be Completion(Call(callbackfn, undefined, « value, 𝔽(k) »)). |
256 | 0 | auto key = call(vm, callback_function, js_undefined(), value, Value(k)); |
257 | | |
258 | | // f. IfAbruptCloseIterator(key, iteratorRecord). |
259 | 0 | if (key.is_error()) |
260 | 0 | return Completion { *TRY(iterator_close(vm, iterator_record, key.release_error())) }; |
261 | | |
262 | | // g. If keyCoercion is property, then |
263 | 0 | if constexpr (IsSame<KeyType, PropertyKey>) { |
264 | | // i. Set key to Completion(ToPropertyKey(key)). |
265 | 0 | auto property_key = key.value().to_property_key(vm); |
266 | | |
267 | | // ii. IfAbruptCloseIterator(key, iteratorRecord). |
268 | 0 | if (property_key.is_error()) |
269 | 0 | return Completion { *TRY(iterator_close(vm, iterator_record, property_key.release_error())) }; |
270 | | |
271 | 0 | add_value_to_keyed_group(vm, groups, property_key.release_value(), value); |
272 | | } |
273 | | // h. Else, |
274 | 0 | else { |
275 | | // i. Assert: keyCoercion is zero. |
276 | 0 | static_assert(IsSame<KeyType, void>); |
277 | | |
278 | | // ii. Set key to CanonicalizeKeyedCollectionKey(key). |
279 | 0 | key = canonicalize_keyed_collection_key(key.value()); |
280 | |
|
281 | 0 | add_value_to_keyed_group(vm, groups, make_handle(key.release_value()), value); |
282 | 0 | } |
283 | | |
284 | | // i. Perform AddValueToKeyedGroup(groups, key, value). |
285 | | // NOTE: This is dependent on the `key_coercion` template parameter and thus done separately in the branches above. |
286 | | |
287 | | // j. Set k to k + 1. |
288 | 0 | ++k; |
289 | 0 | } |
290 | 0 | } Unexecuted instantiation: MapConstructor.cpp:JS::ThrowCompletionOr<AK::HashMap<JS::Handle<JS::Value>, JS::MarkedVector<JS::Value, 0ul>, JS::MapConstructor::group_by(JS::VM&)::KeyedGroupTraits, AK::Traits<JS::MarkedVector<JS::Value, 0ul> >, true> > JS::group_by<AK::HashMap<JS::Handle<JS::Value>, JS::MarkedVector<JS::Value, 0ul>, JS::MapConstructor::group_by(JS::VM&)::KeyedGroupTraits, AK::Traits<JS::MarkedVector<JS::Value, 0ul> >, true>, void>(JS::VM&, JS::Value, JS::Value) Unexecuted instantiation: JS::ThrowCompletionOr<AK::HashMap<JS::PropertyKey, JS::MarkedVector<JS::Value, 0ul>, AK::Traits<JS::PropertyKey>, AK::Traits<JS::MarkedVector<JS::Value, 0ul> >, true> > JS::group_by<AK::HashMap<JS::PropertyKey, JS::MarkedVector<JS::Value, 0ul>, AK::Traits<JS::PropertyKey>, AK::Traits<JS::MarkedVector<JS::Value, 0ul> >, true>, JS::PropertyKey>(JS::VM&, JS::Value, JS::Value) |
291 | | |
292 | | // x modulo y, https://tc39.es/ecma262/#eqn-modulo |
293 | | template<Arithmetic T, Arithmetic U> |
294 | | auto modulo(T x, U y) |
295 | 0 | { |
296 | | // The notation “x modulo y” (y must be finite and non-zero) computes a value k of the same sign as y (or zero) such that abs(k) < abs(y) and x - k = q × y for some integer q. |
297 | 0 | VERIFY(y != 0); |
298 | 0 | if constexpr (IsFloatingPoint<T> || IsFloatingPoint<U>) { |
299 | | if constexpr (IsFloatingPoint<U>) |
300 | 0 | VERIFY(isfinite(y)); |
301 | 0 | auto r = fmod(x, y); |
302 | 0 | return r < 0 ? r + y : r; |
303 | 0 | } else { |
304 | 0 | return ((x % y) + y) % y; |
305 | 0 | } |
306 | 0 | } Unexecuted instantiation: _ZN2JS6moduloITkN2AK8Concepts10ArithmeticEdTkNS2_10ArithmeticEiEEDaT_T0_ Unexecuted instantiation: _ZN2JS6moduloITkN2AK8Concepts10ArithmeticEdTkNS2_10ArithmeticEdEEDaT_T0_ Unexecuted instantiation: _ZN2JS6moduloITkN2AK8Concepts10ArithmeticEmTkNS2_10ArithmeticEmEEDaT_T0_ Unexecuted instantiation: _ZN2JS6moduloITkN2AK8Concepts10ArithmeticEmTkNS2_10ArithmeticEjEEDaT_T0_ |
307 | | |
308 | | auto modulo(Crypto::BigInteger auto const& x, Crypto::BigInteger auto const& y) |
309 | 0 | { |
310 | 0 | VERIFY(!y.is_zero()); |
311 | 0 | auto result = x.divided_by(y).remainder; |
312 | 0 | if (result.is_negative()) |
313 | 0 | result = result.plus(y); |
314 | 0 | return result; |
315 | 0 | } Unexecuted instantiation: _ZN2JS6moduloITkN6Crypto10BigIntegerENS1_16SignedBigIntegerETkNS1_10BigIntegerES2_EEDaRKT_RKT0_ Unexecuted instantiation: _ZN2JS6moduloITkN6Crypto10BigIntegerENS1_16SignedBigIntegerETkNS1_10BigIntegerENS1_18UnsignedBigIntegerEEEDaRKT_RKT0_ |
316 | | |
317 | | // remainder(x, y), https://tc39.es/proposal-temporal/#eqn-remainder |
318 | | template<Arithmetic T, Arithmetic U> |
319 | | auto remainder(T x, U y) |
320 | | { |
321 | | // The mathematical function remainder(x, y) produces the mathematical value whose sign is the sign of x and whose magnitude is abs(x) modulo y. |
322 | | VERIFY(y != 0); |
323 | | if constexpr (IsFloatingPoint<T> || IsFloatingPoint<U>) { |
324 | | if constexpr (IsFloatingPoint<U>) |
325 | | VERIFY(isfinite(y)); |
326 | | return fmod(x, y); |
327 | | } else { |
328 | | return x % y; |
329 | | } |
330 | | } |
331 | | |
332 | | auto remainder(Crypto::BigInteger auto const& x, Crypto::BigInteger auto const& y) |
333 | 0 | { |
334 | 0 | VERIFY(!y.is_zero()); |
335 | 0 | return x.divided_by(y).remainder; |
336 | 0 | } |
337 | | |
338 | | } |