LibJS: Convert standalone construct() to NonnullGCPtr
This commit is contained in:
parent
6ae79a84df
commit
bd40464195
Notes:
sideshowbarker
2024-07-17 20:19:08 +09:00
Author: https://github.com/linusg Commit: https://github.com/SerenityOS/serenity/commit/bd40464195 Pull-request: https://github.com/SerenityOS/serenity/pull/16498 Reviewed-by: https://github.com/trflynn89 ✅
17 changed files with 35 additions and 35 deletions
|
@ -510,7 +510,7 @@ Completion SuperCall::execute(Interpreter& interpreter) const
|
|||
return vm.throw_completion<TypeError>(ErrorType::NotAConstructor, "Super constructor");
|
||||
|
||||
// 6. Let result be ? Construct(func, argList, newTarget).
|
||||
auto* result = TRY(construct(vm, static_cast<FunctionObject&>(*func), move(arg_list), &new_target.as_function()));
|
||||
auto result = TRY(construct(vm, 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(vm));
|
||||
|
|
|
@ -679,7 +679,7 @@ ThrowCompletionOr<void> SuperCall::execute_impl(Bytecode::Interpreter& interpret
|
|||
return vm.throw_completion<TypeError>(ErrorType::NotAConstructor, "Super constructor");
|
||||
|
||||
// 6. Let result be ? Construct(func, argList, newTarget).
|
||||
auto* result = TRY(construct(vm, static_cast<FunctionObject&>(*func), move(arg_list), &new_target.as_function()));
|
||||
auto result = TRY(construct(vm, static_cast<FunctionObject&>(*func), move(arg_list), &new_target.as_function()));
|
||||
|
||||
// 7. Let thisER be GetThisEnvironment().
|
||||
auto& this_environment = verify_cast<FunctionEnvironment>(get_this_environment(vm));
|
||||
|
|
|
@ -71,7 +71,7 @@ ThrowCompletionOr<Value> call_impl(VM& vm, FunctionObject& function, Value this_
|
|||
}
|
||||
|
||||
// 7.3.15 Construct ( F [ , argumentsList [ , newTarget ] ] ), https://tc39.es/ecma262/#sec-construct
|
||||
ThrowCompletionOr<Object*> construct_impl(VM& vm, FunctionObject& function, Optional<MarkedVector<Value>> arguments_list, FunctionObject* new_target)
|
||||
ThrowCompletionOr<NonnullGCPtr<Object>> construct_impl(VM& vm, FunctionObject& function, Optional<MarkedVector<Value>> arguments_list, FunctionObject* new_target)
|
||||
{
|
||||
// 1. If newTarget is not present, set newTarget to F.
|
||||
if (!new_target)
|
||||
|
@ -82,7 +82,7 @@ ThrowCompletionOr<Object*> construct_impl(VM& vm, FunctionObject& function, Opti
|
|||
arguments_list = MarkedVector<Value> { vm.heap() };
|
||||
|
||||
// 3. Return ? F.[[Construct]](argumentsList, newTarget).
|
||||
return TRY(function.internal_construct(move(*arguments_list), *new_target)).ptr();
|
||||
return function.internal_construct(move(*arguments_list), *new_target);
|
||||
}
|
||||
|
||||
// 7.3.19 LengthOfArrayLike ( obj ), https://tc39.es/ecma262/#sec-lengthofarraylike
|
||||
|
|
|
@ -30,7 +30,7 @@ ThrowCompletionOr<Reference> make_super_property_reference(VM&, Value actual_thi
|
|||
ThrowCompletionOr<Value> require_object_coercible(VM&, Value);
|
||||
ThrowCompletionOr<Value> call_impl(VM&, Value function, Value this_value, Optional<MarkedVector<Value>> = {});
|
||||
ThrowCompletionOr<Value> call_impl(VM&, FunctionObject& function, Value this_value, Optional<MarkedVector<Value>> = {});
|
||||
ThrowCompletionOr<Object*> construct_impl(VM&, FunctionObject&, Optional<MarkedVector<Value>> = {}, FunctionObject* new_target = nullptr);
|
||||
ThrowCompletionOr<NonnullGCPtr<Object>> construct_impl(VM&, FunctionObject&, Optional<MarkedVector<Value>> = {}, FunctionObject* new_target = nullptr);
|
||||
ThrowCompletionOr<size_t> length_of_array_like(VM&, Object const&);
|
||||
ThrowCompletionOr<MarkedVector<Value>> create_list_from_array_like(VM&, Value, Function<ThrowCompletionOr<void>(Value)> = {});
|
||||
ThrowCompletionOr<FunctionObject*> species_constructor(VM&, Object const&, FunctionObject& default_constructor);
|
||||
|
@ -108,7 +108,7 @@ ALWAYS_INLINE ThrowCompletionOr<Value> call(VM& vm, FunctionObject& function, Va
|
|||
|
||||
// 7.3.15 Construct ( F [ , argumentsList [ , newTarget ] ] ), https://tc39.es/ecma262/#sec-construct
|
||||
template<typename... Args>
|
||||
ALWAYS_INLINE ThrowCompletionOr<Object*> construct(VM& vm, FunctionObject& function, Args&&... args)
|
||||
ALWAYS_INLINE ThrowCompletionOr<NonnullGCPtr<Object>> construct(VM& vm, FunctionObject& function, Args&&... args)
|
||||
{
|
||||
if constexpr (sizeof...(Args) > 0) {
|
||||
MarkedVector<Value> arguments_list { vm.heap() };
|
||||
|
@ -119,12 +119,12 @@ ALWAYS_INLINE ThrowCompletionOr<Object*> construct(VM& vm, FunctionObject& funct
|
|||
return construct_impl(vm, function);
|
||||
}
|
||||
|
||||
ALWAYS_INLINE ThrowCompletionOr<Object*> construct(VM& vm, FunctionObject& function, MarkedVector<Value> arguments_list, FunctionObject* new_target = nullptr)
|
||||
ALWAYS_INLINE ThrowCompletionOr<NonnullGCPtr<Object>> construct(VM& vm, FunctionObject& function, MarkedVector<Value> arguments_list, FunctionObject* new_target = nullptr)
|
||||
{
|
||||
return construct_impl(vm, function, move(arguments_list), new_target);
|
||||
}
|
||||
|
||||
ALWAYS_INLINE ThrowCompletionOr<Object*> construct(VM& vm, FunctionObject& function, Optional<MarkedVector<Value>> arguments_list, FunctionObject* new_target = nullptr)
|
||||
ALWAYS_INLINE ThrowCompletionOr<NonnullGCPtr<Object>> construct(VM& vm, FunctionObject& function, Optional<MarkedVector<Value>> arguments_list, FunctionObject* new_target = nullptr)
|
||||
{
|
||||
return construct_impl(vm, function, move(arguments_list), new_target);
|
||||
}
|
||||
|
|
|
@ -85,12 +85,12 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayBufferPrototype::slice)
|
|||
auto* constructor = TRY(species_constructor(vm, *array_buffer_object, *realm.intrinsics().array_buffer_constructor()));
|
||||
|
||||
// 16. Let new be ? Construct(ctor, « 𝔽(newLen) »).
|
||||
auto* new_array_buffer = TRY(construct(vm, *constructor, Value(new_length)));
|
||||
auto new_array_buffer = TRY(construct(vm, *constructor, Value(new_length)));
|
||||
|
||||
// 17. Perform ? RequireInternalSlot(new, [[ArrayBufferData]]).
|
||||
if (!is<ArrayBuffer>(new_array_buffer))
|
||||
if (!is<ArrayBuffer>(new_array_buffer.ptr()))
|
||||
return vm.throw_completion<TypeError>(ErrorType::SpeciesConstructorDidNotCreate, "an ArrayBuffer");
|
||||
auto* new_array_buffer_object = static_cast<ArrayBuffer*>(new_array_buffer);
|
||||
auto* new_array_buffer_object = static_cast<ArrayBuffer*>(new_array_buffer.ptr());
|
||||
|
||||
// 18. If IsSharedArrayBuffer(new) is true, throw a TypeError exception.
|
||||
// FIXME: Check for shared buffer
|
||||
|
|
|
@ -145,7 +145,7 @@ static ThrowCompletionOr<Object*> array_species_create(VM& vm, Object& original_
|
|||
if (!constructor.is_constructor())
|
||||
return vm.throw_completion<TypeError>(ErrorType::NotAConstructor, constructor.to_string_without_side_effects());
|
||||
|
||||
return TRY(construct(vm, constructor.as_function(), Value(length)));
|
||||
return TRY(construct(vm, constructor.as_function(), Value(length))).ptr();
|
||||
}
|
||||
|
||||
// 23.1.3.1 Array.prototype.at ( index ), https://tc39.es/ecma262/#sec-array.prototype.at
|
||||
|
|
|
@ -71,7 +71,7 @@ JS_DEFINE_NATIVE_FUNCTION(BigIntPrototype::to_locale_string)
|
|||
auto* bigint = TRY(this_bigint_value(vm, vm.this_value()));
|
||||
|
||||
// 2. Let numberFormat be ? Construct(%NumberFormat%, « locales, options »).
|
||||
auto* number_format = static_cast<Intl::NumberFormat*>(TRY(construct(vm, *realm.intrinsics().intl_number_format_constructor(), locales, options)));
|
||||
auto* number_format = static_cast<Intl::NumberFormat*>(TRY(construct(vm, *realm.intrinsics().intl_number_format_constructor(), locales, options)).ptr());
|
||||
|
||||
// 3. Return ? FormatNumeric(numberFormat, x).
|
||||
auto formatted = Intl::format_numeric(vm, *number_format, Value(bigint));
|
||||
|
|
|
@ -90,7 +90,7 @@ ThrowCompletionOr<NonnullGCPtr<Object>> BoundFunction::internal_construct(Marked
|
|||
final_new_target = ⌖
|
||||
|
||||
// 6. Return ? Construct(target, args, newTarget).
|
||||
return *TRY(construct(vm, target, move(args), final_new_target));
|
||||
return construct(vm, target, move(args), final_new_target);
|
||||
}
|
||||
|
||||
void BoundFunction::visit_edges(Visitor& visitor)
|
||||
|
|
|
@ -986,8 +986,8 @@ JS_DEFINE_NATIVE_FUNCTION(DatePrototype::to_json)
|
|||
static ThrowCompletionOr<Intl::DateTimeFormat*> construct_date_time_format(VM& vm, Value locales, Value options)
|
||||
{
|
||||
auto& realm = *vm.current_realm();
|
||||
auto* date_time_format = TRY(construct(vm, *realm.intrinsics().intl_date_time_format_constructor(), locales, options));
|
||||
return static_cast<Intl::DateTimeFormat*>(date_time_format);
|
||||
auto date_time_format = TRY(construct(vm, *realm.intrinsics().intl_date_time_format_constructor(), locales, options));
|
||||
return static_cast<Intl::DateTimeFormat*>(date_time_format.ptr());
|
||||
}
|
||||
|
||||
// 21.4.4.38 Date.prototype.toLocaleDateString ( [ reserved1 [ , reserved2 ] ] ), https://tc39.es/ecma262/#sec-date.prototype.tolocaledatestring
|
||||
|
|
|
@ -548,8 +548,8 @@ ThrowCompletionOr<Vector<PatternPartition>> format_date_time_pattern(VM& vm, Dat
|
|||
auto const& data_locale = date_time_format.data_locale();
|
||||
|
||||
auto construct_number_format = [&](auto& options) -> ThrowCompletionOr<NumberFormat*> {
|
||||
auto* number_format = TRY(construct(vm, *realm.intrinsics().intl_number_format_constructor(), PrimitiveString::create(vm, locale), options));
|
||||
return static_cast<NumberFormat*>(number_format);
|
||||
auto number_format = TRY(construct(vm, *realm.intrinsics().intl_number_format_constructor(), PrimitiveString::create(vm, locale), options));
|
||||
return static_cast<NumberFormat*>(number_format.ptr());
|
||||
};
|
||||
|
||||
// 4. Let nfOptions be OrdinaryObjectCreate(null).
|
||||
|
|
|
@ -437,7 +437,7 @@ Vector<PatternPartition> partition_duration_format_pattern(VM& vm, DurationForma
|
|||
// i. If style is "2-digit" or "numeric", then
|
||||
if (style == DurationFormat::ValueStyle::TwoDigit || style == DurationFormat::ValueStyle::Numeric) {
|
||||
// 1. Let nf be ! Construct(%NumberFormat%, « durationFormat.[[Locale]], nfOpts »).
|
||||
auto* number_format = static_cast<NumberFormat*>(MUST(construct(vm, *realm.intrinsics().intl_number_format_constructor(), PrimitiveString::create(vm, duration_format.locale()), number_format_options)));
|
||||
auto* number_format = static_cast<NumberFormat*>(MUST(construct(vm, *realm.intrinsics().intl_number_format_constructor(), PrimitiveString::create(vm, duration_format.locale()), number_format_options)).ptr());
|
||||
|
||||
// 2. Let dataLocale be durationFormat.[[DataLocale]].
|
||||
auto const& data_locale = duration_format.data_locale();
|
||||
|
@ -501,7 +501,7 @@ Vector<PatternPartition> partition_duration_format_pattern(VM& vm, DurationForma
|
|||
MUST(number_format_options->create_data_property_or_throw(vm.names.unitDisplay, PrimitiveString::create(vm, unicode_style)));
|
||||
|
||||
// 4. Let nf be ! Construct(%NumberFormat%, « durationFormat.[[Locale]], nfOpts »).
|
||||
auto* number_format = static_cast<NumberFormat*>(MUST(construct(vm, *realm.intrinsics().intl_number_format_constructor(), PrimitiveString::create(vm, duration_format.locale()), number_format_options)));
|
||||
auto* number_format = static_cast<NumberFormat*>(MUST(construct(vm, *realm.intrinsics().intl_number_format_constructor(), PrimitiveString::create(vm, duration_format.locale()), number_format_options)).ptr());
|
||||
|
||||
// 5. Let parts be ! PartitionNumberPattern(nf, 𝔽(value)).
|
||||
auto parts = partition_number_pattern(vm, *number_format, MathematicalValue(value));
|
||||
|
@ -542,7 +542,7 @@ Vector<PatternPartition> partition_duration_format_pattern(VM& vm, DurationForma
|
|||
MUST(list_format_options->create_data_property_or_throw(vm.names.style, PrimitiveString::create(vm, unicode_list_style)));
|
||||
|
||||
// 9. Let lf be ! Construct(%ListFormat%, « durationFormat.[[Locale]], lfOpts »).
|
||||
auto* list_format = static_cast<ListFormat*>(MUST(construct(vm, *realm.intrinsics().intl_list_format_constructor(), PrimitiveString::create(vm, duration_format.locale()), list_format_options)));
|
||||
auto* list_format = static_cast<ListFormat*>(MUST(construct(vm, *realm.intrinsics().intl_list_format_constructor(), PrimitiveString::create(vm, duration_format.locale()), list_format_options)).ptr());
|
||||
|
||||
// FIXME: CreatePartsFromList expects a list of strings and creates a list of Pattern Partition records, but we already created a list of Pattern Partition records
|
||||
// so we try to hack something together from it that looks mostly right
|
||||
|
|
|
@ -138,12 +138,12 @@ ThrowCompletionOr<RelativeTimeFormat*> initialize_relative_time_format(VM& vm, R
|
|||
relative_time_format.set_numeric(numeric.as_string().deprecated_string());
|
||||
|
||||
// 19. Let relativeTimeFormat.[[NumberFormat]] be ! Construct(%NumberFormat%, « locale »).
|
||||
auto* number_format = MUST(construct(vm, *realm.intrinsics().intl_number_format_constructor(), PrimitiveString::create(vm, locale)));
|
||||
relative_time_format.set_number_format(static_cast<NumberFormat*>(number_format));
|
||||
auto number_format = MUST(construct(vm, *realm.intrinsics().intl_number_format_constructor(), PrimitiveString::create(vm, locale)));
|
||||
relative_time_format.set_number_format(static_cast<NumberFormat*>(number_format.ptr()));
|
||||
|
||||
// 20. Let relativeTimeFormat.[[PluralRules]] be ! Construct(%PluralRules%, « locale »).
|
||||
auto* plural_rules = MUST(construct(vm, *realm.intrinsics().intl_plural_rules_constructor(), PrimitiveString::create(vm, locale)));
|
||||
relative_time_format.set_plural_rules(static_cast<PluralRules*>(plural_rules));
|
||||
auto plural_rules = MUST(construct(vm, *realm.intrinsics().intl_plural_rules_constructor(), PrimitiveString::create(vm, locale)));
|
||||
relative_time_format.set_plural_rules(static_cast<PluralRules*>(plural_rules.ptr()));
|
||||
|
||||
// 21. Return relativeTimeFormat.
|
||||
return &relative_time_format;
|
||||
|
|
|
@ -284,7 +284,7 @@ JS_DEFINE_NATIVE_FUNCTION(NumberPrototype::to_locale_string)
|
|||
auto number_value = TRY(this_number_value(vm, vm.this_value()));
|
||||
|
||||
// 2. Let numberFormat be ? Construct(%NumberFormat%, « locales, options »).
|
||||
auto* number_format = static_cast<Intl::NumberFormat*>(TRY(construct(vm, *realm.intrinsics().intl_number_format_constructor(), locales, options)));
|
||||
auto* number_format = static_cast<Intl::NumberFormat*>(TRY(construct(vm, *realm.intrinsics().intl_number_format_constructor(), locales, options)).ptr());
|
||||
|
||||
// 3. Return ? FormatNumeric(numberFormat, x).
|
||||
// Note: Our implementation of FormatNumeric does not throw.
|
||||
|
|
|
@ -808,7 +808,7 @@ ThrowCompletionOr<NonnullGCPtr<Object>> ProxyObject::internal_construct(MarkedVe
|
|||
// 7. If trap is undefined, then
|
||||
if (!trap) {
|
||||
// a. Return ? Construct(target, argumentsList, newTarget).
|
||||
return *TRY(construct(vm, static_cast<FunctionObject&>(m_target), move(arguments_list), &new_target));
|
||||
return construct(vm, static_cast<FunctionObject&>(m_target), move(arguments_list), &new_target);
|
||||
}
|
||||
|
||||
// 8. Let argArray be CreateArrayFromList(argumentsList).
|
||||
|
|
|
@ -620,7 +620,7 @@ JS_DEFINE_NATIVE_FUNCTION(RegExpPrototype::symbol_match_all)
|
|||
bool full_unicode = flags.contains('u') || flags.contains('v');
|
||||
|
||||
// 6. Let matcher be ? Construct(C, « R, flags »).
|
||||
auto* matcher = TRY(construct(vm, *constructor, regexp_object, PrimitiveString::create(vm, move(flags))));
|
||||
auto matcher = TRY(construct(vm, *constructor, regexp_object, PrimitiveString::create(vm, move(flags))));
|
||||
|
||||
// 7. Let lastIndex be ? ToLength(? Get(R, "lastIndex")).
|
||||
auto last_index_value = TRY(regexp_object->get(vm.names.lastIndex));
|
||||
|
@ -630,7 +630,7 @@ JS_DEFINE_NATIVE_FUNCTION(RegExpPrototype::symbol_match_all)
|
|||
TRY(matcher->set(vm.names.lastIndex, Value(last_index), Object::ShouldThrowExceptions::Yes));
|
||||
|
||||
// 13. Return CreateRegExpStringIterator(matcher, S, global, fullUnicode).
|
||||
return RegExpStringIterator::create(realm, *matcher, move(string), global, full_unicode);
|
||||
return RegExpStringIterator::create(realm, matcher, move(string), global, full_unicode);
|
||||
}
|
||||
|
||||
// 22.2.5.11 RegExp.prototype [ @@replace ] ( string, replaceValue ), https://tc39.es/ecma262/#sec-regexp.prototype-@@replace
|
||||
|
@ -923,7 +923,7 @@ JS_DEFINE_NATIVE_FUNCTION(RegExpPrototype::symbol_split)
|
|||
auto new_flags = flags.find('y').has_value() ? move(flags) : DeprecatedString::formatted("{}y", flags);
|
||||
|
||||
// 10. Let splitter be ? Construct(C, « rx, newFlags »).
|
||||
auto* splitter = TRY(construct(vm, *constructor, regexp_object, PrimitiveString::create(vm, move(new_flags))));
|
||||
auto splitter = TRY(construct(vm, *constructor, regexp_object, PrimitiveString::create(vm, move(new_flags))));
|
||||
|
||||
// 11. Let A be ! ArrayCreate(0).
|
||||
auto array = MUST(Array::create(realm, 0));
|
||||
|
@ -944,7 +944,7 @@ JS_DEFINE_NATIVE_FUNCTION(RegExpPrototype::symbol_split)
|
|||
// 16. If size is 0, then
|
||||
if (string.is_empty()) {
|
||||
// a. Let z be ? RegExpExec(splitter, S).
|
||||
auto result = TRY(regexp_exec(vm, *splitter, string));
|
||||
auto result = TRY(regexp_exec(vm, splitter, string));
|
||||
|
||||
// b. If z is not null, return A.
|
||||
if (!result.is_null())
|
||||
|
@ -969,7 +969,7 @@ JS_DEFINE_NATIVE_FUNCTION(RegExpPrototype::symbol_split)
|
|||
TRY(splitter->set(vm.names.lastIndex, Value(next_search_from), Object::ShouldThrowExceptions::Yes));
|
||||
|
||||
// b. Let z be ? RegExpExec(splitter, S).
|
||||
auto result = TRY(regexp_exec(vm, *splitter, string));
|
||||
auto result = TRY(regexp_exec(vm, splitter, string));
|
||||
|
||||
// c. If z is null, set q to AdvanceStringIndex(S, q, unicodeMatching).
|
||||
if (result.is_null()) {
|
||||
|
|
|
@ -432,7 +432,7 @@ JS_DEFINE_NATIVE_FUNCTION(StringPrototype::locale_compare)
|
|||
auto that_value = TRY(vm.argument(0).to_string(vm));
|
||||
|
||||
// 4. Let collator be ? Construct(%Collator%, « locales, options »).
|
||||
auto* collator = TRY(construct(vm, *realm.intrinsics().intl_collator_constructor(), vm.argument(1), vm.argument(2)));
|
||||
auto collator = TRY(construct(vm, *realm.intrinsics().intl_collator_constructor(), vm.argument(1), vm.argument(2)));
|
||||
|
||||
// 5. Return CompareStrings(collator, S, thatValue).
|
||||
return Intl::compare_strings(static_cast<Intl::Collator&>(*collator), Utf8View(string), Utf8View(that_value));
|
||||
|
|
|
@ -321,12 +321,12 @@ ThrowCompletionOr<TypedArrayBase*> 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, move(arguments)));
|
||||
|
||||
// 2. Perform ? ValidateTypedArray(newTypedArray).
|
||||
if (!new_typed_array->is_typed_array())
|
||||
return vm.throw_completion<TypeError>(ErrorType::NotAnObjectOfType, "TypedArray");
|
||||
auto& typed_array = *static_cast<TypedArrayBase*>(new_typed_array);
|
||||
auto& typed_array = *static_cast<TypedArrayBase*>(new_typed_array.ptr());
|
||||
TRY(validate_typed_array(vm, typed_array));
|
||||
|
||||
// 3. If argumentList is a List of a single Number, then
|
||||
|
|
Loading…
Add table
Reference in a new issue