mirror of
https://github.com/RGBCube/serenity
synced 2025-05-31 18:18:12 +00:00
LibJS: Remove GlobalObject from VM::throw_completion()
This is a continuation of the previous five commits. A first big step into the direction of no longer having to pass a realm (or currently, a global object) trough layers upon layers of AOs! Unlike the create() APIs we can safely assume that this is only ever called when a running execution context and therefore current realm exists. If not, you can always manually allocate the Error and put it in a Completion :^) In the spec, throw exceptions implicitly use the current realm's intrinsics as well: https://tc39.es/ecma262/#sec-throw-an-exception
This commit is contained in:
parent
5398dcc55e
commit
f3117d46dc
165 changed files with 892 additions and 900 deletions
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2020-2021, Andreas Kling <kling@serenityos.org>
|
* Copyright (c) 2020-2021, Andreas Kling <kling@serenityos.org>
|
||||||
* Copyright (c) 2021, Linus Groh <linusg@serenityos.org>
|
* Copyright (c) 2021-2022, Linus Groh <linusg@serenityos.org>
|
||||||
* Copyright (c) 2021, Luke Wilde <lukew@serenityos.org>
|
* Copyright (c) 2021, Luke Wilde <lukew@serenityos.org>
|
||||||
* Copyright (c) 2022, Ali Mohammad Pur <mpfard@serenityos.org>
|
* Copyright (c) 2022, Ali Mohammad Pur <mpfard@serenityos.org>
|
||||||
*
|
*
|
||||||
|
@ -356,7 +356,7 @@ static void generate_to_cpp(SourceGenerator& generator, ParameterType& parameter
|
||||||
RefPtr<@cpp_type@> @cpp_name@;
|
RefPtr<@cpp_type@> @cpp_name@;
|
||||||
if (!@js_name@@js_suffix@.is_nullish()) {
|
if (!@js_name@@js_suffix@.is_nullish()) {
|
||||||
if (!@js_name@@js_suffix@.is_object())
|
if (!@js_name@@js_suffix@.is_object())
|
||||||
return vm.throw_completion<JS::TypeError>(global_object, JS::ErrorType::NotAnObject, @js_name@@js_suffix@.to_string_without_side_effects());
|
return vm.throw_completion<JS::TypeError>(JS::ErrorType::NotAnObject, @js_name@@js_suffix@.to_string_without_side_effects());
|
||||||
|
|
||||||
CallbackType callback_type(JS::make_handle(&@js_name@@js_suffix@.as_object()), HTML::incumbent_settings_object());
|
CallbackType callback_type(JS::make_handle(&@js_name@@js_suffix@.as_object()), HTML::incumbent_settings_object());
|
||||||
@cpp_name@ = adopt_ref(*new @cpp_type@(move(callback_type)));
|
@cpp_name@ = adopt_ref(*new @cpp_type@(move(callback_type)));
|
||||||
|
@ -365,7 +365,7 @@ static void generate_to_cpp(SourceGenerator& generator, ParameterType& parameter
|
||||||
} else {
|
} else {
|
||||||
scoped_generator.append(R"~~~(
|
scoped_generator.append(R"~~~(
|
||||||
if (!@js_name@@js_suffix@.is_object())
|
if (!@js_name@@js_suffix@.is_object())
|
||||||
return vm.throw_completion<JS::TypeError>(global_object, JS::ErrorType::NotAnObject, @js_name@@js_suffix@.to_string_without_side_effects());
|
return vm.throw_completion<JS::TypeError>(JS::ErrorType::NotAnObject, @js_name@@js_suffix@.to_string_without_side_effects());
|
||||||
|
|
||||||
CallbackType callback_type(JS::make_handle(&@js_name@@js_suffix@.as_object()), HTML::incumbent_settings_object());
|
CallbackType callback_type(JS::make_handle(&@js_name@@js_suffix@.as_object()), HTML::incumbent_settings_object());
|
||||||
auto @cpp_name@ = adopt_ref(*new @cpp_type@(move(callback_type)));
|
auto @cpp_name@ = adopt_ref(*new @cpp_type@(move(callback_type)));
|
||||||
|
@ -376,7 +376,7 @@ static void generate_to_cpp(SourceGenerator& generator, ParameterType& parameter
|
||||||
if (!optional) {
|
if (!optional) {
|
||||||
scoped_generator.append(R"~~~(
|
scoped_generator.append(R"~~~(
|
||||||
if (!@js_name@@js_suffix@.is_object() || !is<@wrapper_name@>(@js_name@@js_suffix@.as_object()))
|
if (!@js_name@@js_suffix@.is_object() || !is<@wrapper_name@>(@js_name@@js_suffix@.as_object()))
|
||||||
return vm.throw_completion<JS::TypeError>(global_object, JS::ErrorType::NotAnObjectOfType, "@parameter.type.name@");
|
return vm.throw_completion<JS::TypeError>(JS::ErrorType::NotAnObjectOfType, "@parameter.type.name@");
|
||||||
|
|
||||||
auto& @cpp_name@ = static_cast<@wrapper_name@&>(@js_name@@js_suffix@.as_object()).impl();
|
auto& @cpp_name@ = static_cast<@wrapper_name@&>(@js_name@@js_suffix@.as_object()).impl();
|
||||||
)~~~");
|
)~~~");
|
||||||
|
@ -385,7 +385,7 @@ static void generate_to_cpp(SourceGenerator& generator, ParameterType& parameter
|
||||||
Optional<NonnullRefPtr<@parameter.type.name@>> @cpp_name@;
|
Optional<NonnullRefPtr<@parameter.type.name@>> @cpp_name@;
|
||||||
if (!@js_name@@js_suffix@.is_undefined()) {
|
if (!@js_name@@js_suffix@.is_undefined()) {
|
||||||
if (!@js_name@@js_suffix@.is_object() || !is<@wrapper_name@>(@js_name@@js_suffix@.as_object()))
|
if (!@js_name@@js_suffix@.is_object() || !is<@wrapper_name@>(@js_name@@js_suffix@.as_object()))
|
||||||
return vm.throw_completion<JS::TypeError>(global_object, JS::ErrorType::NotAnObjectOfType, "@parameter.type.name@");
|
return vm.throw_completion<JS::TypeError>(JS::ErrorType::NotAnObjectOfType, "@parameter.type.name@");
|
||||||
|
|
||||||
@cpp_name@ = static_cast<@wrapper_name@&>(@js_name@@js_suffix@.as_object()).impl();
|
@cpp_name@ = static_cast<@wrapper_name@&>(@js_name@@js_suffix@.as_object()).impl();
|
||||||
}
|
}
|
||||||
|
@ -396,7 +396,7 @@ static void generate_to_cpp(SourceGenerator& generator, ParameterType& parameter
|
||||||
@parameter.type.name@* @cpp_name@ = nullptr;
|
@parameter.type.name@* @cpp_name@ = nullptr;
|
||||||
if (!@js_name@@js_suffix@.is_nullish()) {
|
if (!@js_name@@js_suffix@.is_nullish()) {
|
||||||
if (!@js_name@@js_suffix@.is_object() || !is<@wrapper_name@>(@js_name@@js_suffix@.as_object()))
|
if (!@js_name@@js_suffix@.is_object() || !is<@wrapper_name@>(@js_name@@js_suffix@.as_object()))
|
||||||
return vm.throw_completion<JS::TypeError>(global_object, JS::ErrorType::NotAnObjectOfType, "@parameter.type.name@");
|
return vm.throw_completion<JS::TypeError>(JS::ErrorType::NotAnObjectOfType, "@parameter.type.name@");
|
||||||
|
|
||||||
@cpp_name@ = &static_cast<@wrapper_name@&>(@js_name@@js_suffix@.as_object()).impl();
|
@cpp_name@ = &static_cast<@wrapper_name@&>(@js_name@@js_suffix@.as_object()).impl();
|
||||||
}
|
}
|
||||||
|
@ -566,7 +566,7 @@ static void generate_to_cpp(SourceGenerator& generator, ParameterType& parameter
|
||||||
} else if (parameter.type->name == "BufferSource") {
|
} else if (parameter.type->name == "BufferSource") {
|
||||||
scoped_generator.append(R"~~~(
|
scoped_generator.append(R"~~~(
|
||||||
if (!@js_name@@js_suffix@.is_object() || !(is<JS::TypedArrayBase>(@js_name@@js_suffix@.as_object()) || is<JS::ArrayBuffer>(@js_name@@js_suffix@.as_object()) || is<JS::DataView>(@js_name@@js_suffix@.as_object())))
|
if (!@js_name@@js_suffix@.is_object() || !(is<JS::TypedArrayBase>(@js_name@@js_suffix@.as_object()) || is<JS::ArrayBuffer>(@js_name@@js_suffix@.as_object()) || is<JS::DataView>(@js_name@@js_suffix@.as_object())))
|
||||||
return vm.throw_completion<JS::TypeError>(global_object, JS::ErrorType::NotAnObjectOfType, "@parameter.type.name@");
|
return vm.throw_completion<JS::TypeError>(JS::ErrorType::NotAnObjectOfType, "@parameter.type.name@");
|
||||||
|
|
||||||
// TODO: Should we make this a Variant?
|
// TODO: Should we make this a Variant?
|
||||||
auto @cpp_name@ = JS::make_handle(&@js_name@@js_suffix@.as_object());
|
auto @cpp_name@ = JS::make_handle(&@js_name@@js_suffix@.as_object());
|
||||||
|
@ -642,7 +642,7 @@ static void generate_to_cpp(SourceGenerator& generator, ParameterType& parameter
|
||||||
if constexpr (!IsSame<Attribute, RemoveConst<ParameterType>>) {
|
if constexpr (!IsSame<Attribute, RemoveConst<ParameterType>>) {
|
||||||
enum_generator.append(R"~~~(
|
enum_generator.append(R"~~~(
|
||||||
@else@
|
@else@
|
||||||
return vm.throw_completion<JS::TypeError>(global_object, JS::ErrorType::InvalidEnumerationValue, @js_name.as_string@, "@parameter.type.name@");
|
return vm.throw_completion<JS::TypeError>(JS::ErrorType::InvalidEnumerationValue, @js_name.as_string@, "@parameter.type.name@");
|
||||||
)~~~");
|
)~~~");
|
||||||
} else {
|
} else {
|
||||||
enum_generator.append(R"~~~(
|
enum_generator.append(R"~~~(
|
||||||
|
@ -662,7 +662,7 @@ static void generate_to_cpp(SourceGenerator& generator, ParameterType& parameter
|
||||||
auto dictionary_generator = scoped_generator.fork();
|
auto dictionary_generator = scoped_generator.fork();
|
||||||
dictionary_generator.append(R"~~~(
|
dictionary_generator.append(R"~~~(
|
||||||
if (!@js_name@@js_suffix@.is_nullish() && !@js_name@@js_suffix@.is_object())
|
if (!@js_name@@js_suffix@.is_nullish() && !@js_name@@js_suffix@.is_object())
|
||||||
return vm.throw_completion<JS::TypeError>(global_object, JS::ErrorType::NotAnObjectOfType, "@parameter.type.name@");
|
return vm.throw_completion<JS::TypeError>(JS::ErrorType::NotAnObjectOfType, "@parameter.type.name@");
|
||||||
|
|
||||||
@parameter.type.name@ @cpp_name@ {};
|
@parameter.type.name@ @cpp_name@ {};
|
||||||
)~~~");
|
)~~~");
|
||||||
|
@ -683,7 +683,7 @@ static void generate_to_cpp(SourceGenerator& generator, ParameterType& parameter
|
||||||
if (member.required) {
|
if (member.required) {
|
||||||
dictionary_generator.append(R"~~~(
|
dictionary_generator.append(R"~~~(
|
||||||
if (@member_name@.is_undefined())
|
if (@member_name@.is_undefined())
|
||||||
return vm.throw_completion<JS::TypeError>(global_object, JS::ErrorType::MissingRequiredProperty, "@member_key@");
|
return vm.throw_completion<JS::TypeError>(JS::ErrorType::MissingRequiredProperty, "@member_key@");
|
||||||
)~~~");
|
)~~~");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -710,7 +710,7 @@ static void generate_to_cpp(SourceGenerator& generator, ParameterType& parameter
|
||||||
if (!callback_function.is_legacy_treat_non_object_as_null) {
|
if (!callback_function.is_legacy_treat_non_object_as_null) {
|
||||||
callback_function_generator.append(R"~~~(
|
callback_function_generator.append(R"~~~(
|
||||||
if (!@js_name@@js_suffix@.is_function())
|
if (!@js_name@@js_suffix@.is_function())
|
||||||
return vm.throw_completion<JS::TypeError>(global_object, JS::ErrorType::NotAFunction, @js_name@@js_suffix@.to_string_without_side_effects());
|
return vm.throw_completion<JS::TypeError>(JS::ErrorType::NotAFunction, @js_name@@js_suffix@.to_string_without_side_effects());
|
||||||
)~~~");
|
)~~~");
|
||||||
}
|
}
|
||||||
// 2. Return the IDL callback function type value that represents a reference to the same object that V represents, with the incumbent settings object as the callback context.
|
// 2. Return the IDL callback function type value that represents a reference to the same object that V represents, with the incumbent settings object as the callback context.
|
||||||
|
@ -775,11 +775,11 @@ static void generate_to_cpp(SourceGenerator& generator, ParameterType& parameter
|
||||||
|
|
||||||
sequence_generator.append(R"~~~(
|
sequence_generator.append(R"~~~(
|
||||||
if (!@js_name@@js_suffix@.is_object())
|
if (!@js_name@@js_suffix@.is_object())
|
||||||
return vm.throw_completion<JS::TypeError>(global_object, JS::ErrorType::NotAnObject, @js_name@@js_suffix@.to_string_without_side_effects());
|
return vm.throw_completion<JS::TypeError>(JS::ErrorType::NotAnObject, @js_name@@js_suffix@.to_string_without_side_effects());
|
||||||
|
|
||||||
auto* iterator_method@recursion_depth@ = TRY(@js_name@@js_suffix@.get_method(global_object, *vm.well_known_symbol_iterator()));
|
auto* iterator_method@recursion_depth@ = TRY(@js_name@@js_suffix@.get_method(global_object, *vm.well_known_symbol_iterator()));
|
||||||
if (!iterator_method@recursion_depth@)
|
if (!iterator_method@recursion_depth@)
|
||||||
return vm.throw_completion<JS::TypeError>(global_object, JS::ErrorType::NotIterable, @js_name@@js_suffix@.to_string_without_side_effects());
|
return vm.throw_completion<JS::TypeError>(JS::ErrorType::NotIterable, @js_name@@js_suffix@.to_string_without_side_effects());
|
||||||
)~~~");
|
)~~~");
|
||||||
|
|
||||||
parameterized_type.generate_sequence_from_iterable(sequence_generator, String::formatted("{}{}", acceptable_cpp_name, optional ? "_non_optional" : ""), String::formatted("{}{}", js_name, js_suffix), String::formatted("iterator_method{}", recursion_depth), interface, recursion_depth + 1);
|
parameterized_type.generate_sequence_from_iterable(sequence_generator, String::formatted("{}{}", acceptable_cpp_name, optional ? "_non_optional" : ""), String::formatted("{}{}", js_name, js_suffix), String::formatted("iterator_method{}", recursion_depth), interface, recursion_depth + 1);
|
||||||
|
@ -824,7 +824,7 @@ static void generate_to_cpp(SourceGenerator& generator, ParameterType& parameter
|
||||||
if (recursion_depth == 0) {
|
if (recursion_depth == 0) {
|
||||||
record_generator.append(R"~~~(
|
record_generator.append(R"~~~(
|
||||||
if (!@js_name@@js_suffix@.is_object())
|
if (!@js_name@@js_suffix@.is_object())
|
||||||
return vm.throw_completion<JS::TypeError>(global_object, JS::ErrorType::NotAnObject, @js_name@@js_suffix@.to_string_without_side_effects());
|
return vm.throw_completion<JS::TypeError>(JS::ErrorType::NotAnObject, @js_name@@js_suffix@.to_string_without_side_effects());
|
||||||
|
|
||||||
auto& @js_name@@js_suffix@_object = @js_name@@js_suffix@.as_object();
|
auto& @js_name@@js_suffix@_object = @js_name@@js_suffix@.as_object();
|
||||||
)~~~");
|
)~~~");
|
||||||
|
@ -1234,7 +1234,7 @@ static void generate_to_cpp(SourceGenerator& generator, ParameterType& parameter
|
||||||
// 19. Throw a TypeError.
|
// 19. Throw a TypeError.
|
||||||
// FIXME: Replace the error message with something more descriptive.
|
// FIXME: Replace the error message with something more descriptive.
|
||||||
union_generator.append(R"~~~(
|
union_generator.append(R"~~~(
|
||||||
return vm.throw_completion<JS::TypeError>(global_object, "No union types matched");
|
return vm.throw_completion<JS::TypeError>("No union types matched");
|
||||||
)~~~");
|
)~~~");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1310,7 +1310,7 @@ static void generate_argument_count_check(SourceGenerator& generator, String con
|
||||||
|
|
||||||
argument_count_check_generator.append(R"~~~(
|
argument_count_check_generator.append(R"~~~(
|
||||||
if (vm.argument_count() < @function.nargs@)
|
if (vm.argument_count() < @function.nargs@)
|
||||||
return vm.throw_completion<JS::TypeError>(global_object, @.bad_arg_count@, "@function.name@"@.arg_count_suffix@);
|
return vm.throw_completion<JS::TypeError>(@.bad_arg_count@, "@function.name@"@.arg_count_suffix@);
|
||||||
)~~~");
|
)~~~");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1803,7 +1803,7 @@ JS_DEFINE_NATIVE_FUNCTION(@class_name@::@function.name:snakecase@)
|
||||||
}
|
}
|
||||||
|
|
||||||
function_generator.append(R"~~~(
|
function_generator.append(R"~~~(
|
||||||
return vm.throw_completion<JS::TypeError>(global_object, JS::ErrorType::OverloadResolutionFailed);
|
return vm.throw_completion<JS::TypeError>(JS::ErrorType::OverloadResolutionFailed);
|
||||||
}
|
}
|
||||||
)~~~");
|
)~~~");
|
||||||
}
|
}
|
||||||
|
@ -2944,7 +2944,7 @@ namespace Web::Bindings {
|
||||||
|
|
||||||
JS::ThrowCompletionOr<JS::Value> @constructor_class@::call()
|
JS::ThrowCompletionOr<JS::Value> @constructor_class@::call()
|
||||||
{
|
{
|
||||||
return vm().throw_completion<JS::TypeError>(global_object(), JS::ErrorType::ConstructorWithoutNew, "@name@");
|
return vm().throw_completion<JS::TypeError>(JS::ErrorType::ConstructorWithoutNew, "@name@");
|
||||||
}
|
}
|
||||||
|
|
||||||
JS::ThrowCompletionOr<JS::Object*> @constructor_class@::construct(FunctionObject&)
|
JS::ThrowCompletionOr<JS::Object*> @constructor_class@::construct(FunctionObject&)
|
||||||
|
@ -2955,7 +2955,7 @@ JS::ThrowCompletionOr<JS::Object*> @constructor_class@::construct(FunctionObject
|
||||||
// No constructor
|
// No constructor
|
||||||
generator.set("constructor.length", "0");
|
generator.set("constructor.length", "0");
|
||||||
generator.append(R"~~~(
|
generator.append(R"~~~(
|
||||||
return vm().throw_completion<JS::TypeError>(global_object(), JS::ErrorType::NotAConstructor, "@name@");
|
return vm().throw_completion<JS::TypeError>(JS::ErrorType::NotAConstructor, "@name@");
|
||||||
)~~~");
|
)~~~");
|
||||||
} else if (interface.constructors.size() == 1) {
|
} else if (interface.constructors.size() == 1) {
|
||||||
// Single constructor
|
// Single constructor
|
||||||
|
@ -3386,7 +3386,7 @@ static JS::ThrowCompletionOr<@fully_qualified_name@*> impl_from(JS::VM& vm, JS::
|
||||||
|
|
||||||
generator.append(R"~~~(
|
generator.append(R"~~~(
|
||||||
if (!is<@wrapper_class@>(this_object))
|
if (!is<@wrapper_class@>(this_object))
|
||||||
return vm.throw_completion<JS::TypeError>(global_object, JS::ErrorType::NotAnObjectOfType, "@fully_qualified_name@");
|
return vm.throw_completion<JS::TypeError>(JS::ErrorType::NotAnObjectOfType, "@fully_qualified_name@");
|
||||||
|
|
||||||
return &static_cast<@wrapper_class@*>(this_object)->impl();
|
return &static_cast<@wrapper_class@*>(this_object)->impl();
|
||||||
}
|
}
|
||||||
|
@ -3538,7 +3538,7 @@ JS_DEFINE_NATIVE_FUNCTION(@prototype_class@::for_each)
|
||||||
|
|
||||||
auto callback = vm.argument(0);
|
auto callback = vm.argument(0);
|
||||||
if (!callback.is_function())
|
if (!callback.is_function())
|
||||||
return vm.throw_completion<JS::TypeError>(global_object, JS::ErrorType::NotAFunction, callback.to_string_without_side_effects());
|
return vm.throw_completion<JS::TypeError>(JS::ErrorType::NotAFunction, callback.to_string_without_side_effects());
|
||||||
|
|
||||||
auto this_value = vm.this_value(global_object);
|
auto this_value = vm.this_value(global_object);
|
||||||
TRY(impl->for_each([&](auto key, auto value) -> JS::ThrowCompletionOr<void> {
|
TRY(impl->for_each([&](auto key, auto value) -> JS::ThrowCompletionOr<void> {
|
||||||
|
@ -3809,7 +3809,7 @@ static JS::ThrowCompletionOr<@fully_qualified_name@*> impl_from(JS::VM& vm, JS::
|
||||||
{
|
{
|
||||||
auto* this_object = TRY(vm.this_value(global_object).to_object(global_object));
|
auto* this_object = TRY(vm.this_value(global_object).to_object(global_object));
|
||||||
if (!is<@wrapper_class@>(this_object))
|
if (!is<@wrapper_class@>(this_object))
|
||||||
return vm.throw_completion<JS::TypeError>(global_object, JS::ErrorType::NotAnObjectOfType, "@fully_qualified_name@");
|
return vm.throw_completion<JS::TypeError>(JS::ErrorType::NotAnObjectOfType, "@fully_qualified_name@");
|
||||||
return &static_cast<@wrapper_class@*>(this_object)->impl();
|
return &static_cast<@wrapper_class@*>(this_object)->impl();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -35,7 +35,7 @@ TESTJS_GLOBAL_FUNCTION(get_weak_set_size, getWeakSetSize)
|
||||||
{
|
{
|
||||||
auto* object = TRY(vm.argument(0).to_object(global_object));
|
auto* object = TRY(vm.argument(0).to_object(global_object));
|
||||||
if (!is<JS::WeakSet>(object))
|
if (!is<JS::WeakSet>(object))
|
||||||
return vm.throw_completion<JS::TypeError>(global_object, JS::ErrorType::NotAnObjectOfType, "WeakSet");
|
return vm.throw_completion<JS::TypeError>(JS::ErrorType::NotAnObjectOfType, "WeakSet");
|
||||||
auto* weak_set = static_cast<JS::WeakSet*>(object);
|
auto* weak_set = static_cast<JS::WeakSet*>(object);
|
||||||
return JS::Value(weak_set->values().size());
|
return JS::Value(weak_set->values().size());
|
||||||
}
|
}
|
||||||
|
@ -44,7 +44,7 @@ TESTJS_GLOBAL_FUNCTION(get_weak_map_size, getWeakMapSize)
|
||||||
{
|
{
|
||||||
auto* object = TRY(vm.argument(0).to_object(global_object));
|
auto* object = TRY(vm.argument(0).to_object(global_object));
|
||||||
if (!is<JS::WeakMap>(object))
|
if (!is<JS::WeakMap>(object))
|
||||||
return vm.throw_completion<JS::TypeError>(global_object, JS::ErrorType::NotAnObjectOfType, "WeakMap");
|
return vm.throw_completion<JS::TypeError>(JS::ErrorType::NotAnObjectOfType, "WeakMap");
|
||||||
auto* weak_map = static_cast<JS::WeakMap*>(object);
|
auto* weak_map = static_cast<JS::WeakMap*>(object);
|
||||||
return JS::Value(weak_map->values().size());
|
return JS::Value(weak_map->values().size());
|
||||||
}
|
}
|
||||||
|
@ -53,7 +53,7 @@ TESTJS_GLOBAL_FUNCTION(mark_as_garbage, markAsGarbage)
|
||||||
{
|
{
|
||||||
auto argument = vm.argument(0);
|
auto argument = vm.argument(0);
|
||||||
if (!argument.is_string())
|
if (!argument.is_string())
|
||||||
return vm.throw_completion<JS::TypeError>(global_object, JS::ErrorType::NotAString, argument.to_string_without_side_effects());
|
return vm.throw_completion<JS::TypeError>(JS::ErrorType::NotAString, argument.to_string_without_side_effects());
|
||||||
|
|
||||||
auto& variable_name = argument.as_string();
|
auto& variable_name = argument.as_string();
|
||||||
|
|
||||||
|
@ -62,14 +62,14 @@ TESTJS_GLOBAL_FUNCTION(mark_as_garbage, markAsGarbage)
|
||||||
return execution_context->lexical_environment != nullptr;
|
return execution_context->lexical_environment != nullptr;
|
||||||
});
|
});
|
||||||
if (!outer_environment.has_value())
|
if (!outer_environment.has_value())
|
||||||
return vm.throw_completion<JS::ReferenceError>(global_object, JS::ErrorType::UnknownIdentifier, variable_name.string());
|
return vm.throw_completion<JS::ReferenceError>(JS::ErrorType::UnknownIdentifier, variable_name.string());
|
||||||
|
|
||||||
auto reference = TRY(vm.resolve_binding(variable_name.string(), outer_environment.value()->lexical_environment));
|
auto reference = TRY(vm.resolve_binding(variable_name.string(), outer_environment.value()->lexical_environment));
|
||||||
|
|
||||||
auto value = TRY(reference.get_value(global_object));
|
auto value = TRY(reference.get_value(global_object));
|
||||||
|
|
||||||
if (!can_be_held_weakly(value))
|
if (!can_be_held_weakly(value))
|
||||||
return vm.throw_completion<JS::TypeError>(global_object, JS::ErrorType::CannotBeHeldWeakly, String::formatted("Variable with name {}", variable_name.string()));
|
return vm.throw_completion<JS::TypeError>(JS::ErrorType::CannotBeHeldWeakly, String::formatted("Variable with name {}", variable_name.string()));
|
||||||
|
|
||||||
vm.heap().uproot_cell(&value.as_cell());
|
vm.heap().uproot_cell(&value.as_cell());
|
||||||
TRY(reference.delete_(global_object));
|
TRY(reference.delete_(global_object));
|
||||||
|
@ -81,7 +81,7 @@ TESTJS_GLOBAL_FUNCTION(detach_array_buffer, detachArrayBuffer)
|
||||||
{
|
{
|
||||||
auto array_buffer = vm.argument(0);
|
auto array_buffer = vm.argument(0);
|
||||||
if (!array_buffer.is_object() || !is<JS::ArrayBuffer>(array_buffer.as_object()))
|
if (!array_buffer.is_object() || !is<JS::ArrayBuffer>(array_buffer.as_object()))
|
||||||
return vm.throw_completion<JS::TypeError>(global_object, JS::ErrorType::NotAnObjectOfType, "ArrayBuffer");
|
return vm.throw_completion<JS::TypeError>(JS::ErrorType::NotAnObjectOfType, "ArrayBuffer");
|
||||||
|
|
||||||
auto& array_buffer_object = static_cast<JS::ArrayBuffer&>(array_buffer.as_object());
|
auto& array_buffer_object = static_cast<JS::ArrayBuffer&>(array_buffer.as_object());
|
||||||
TRY(JS::detach_array_buffer(global_object, array_buffer_object, vm.argument(1)));
|
TRY(JS::detach_array_buffer(global_object, array_buffer_object, vm.argument(1)));
|
||||||
|
|
|
@ -18,17 +18,17 @@ TESTJS_GLOBAL_FUNCTION(read_binary_wasm_file, readBinaryWasmFile)
|
||||||
auto filename = TRY(vm.argument(0).to_string(global_object));
|
auto filename = TRY(vm.argument(0).to_string(global_object));
|
||||||
auto file = Core::Stream::File::open(filename, Core::Stream::OpenMode::Read);
|
auto file = Core::Stream::File::open(filename, Core::Stream::OpenMode::Read);
|
||||||
if (file.is_error())
|
if (file.is_error())
|
||||||
return vm.throw_completion<JS::TypeError>(global_object, strerror(file.error().code()));
|
return vm.throw_completion<JS::TypeError>(strerror(file.error().code()));
|
||||||
|
|
||||||
auto file_size = file.value()->size();
|
auto file_size = file.value()->size();
|
||||||
if (file_size.is_error())
|
if (file_size.is_error())
|
||||||
return vm.throw_completion<JS::TypeError>(global_object, strerror(file_size.error().code()));
|
return vm.throw_completion<JS::TypeError>(strerror(file_size.error().code()));
|
||||||
|
|
||||||
auto* array = TRY(JS::Uint8Array::create(realm, file_size.value()));
|
auto* array = TRY(JS::Uint8Array::create(realm, file_size.value()));
|
||||||
|
|
||||||
auto read = file.value()->read(array->data());
|
auto read = file.value()->read(array->data());
|
||||||
if (read.is_error())
|
if (read.is_error())
|
||||||
return vm.throw_completion<JS::TypeError>(global_object, strerror(read.error().code()));
|
return vm.throw_completion<JS::TypeError>(strerror(read.error().code()));
|
||||||
|
|
||||||
return JS::Value(array);
|
return JS::Value(array);
|
||||||
}
|
}
|
||||||
|
@ -57,10 +57,10 @@ public:
|
||||||
linker.link(spec_test_namespace());
|
linker.link(spec_test_namespace());
|
||||||
auto link_result = linker.finish();
|
auto link_result = linker.finish();
|
||||||
if (link_result.is_error())
|
if (link_result.is_error())
|
||||||
return vm.throw_completion<JS::TypeError>(realm.global_object(), "Link failed");
|
return vm.throw_completion<JS::TypeError>("Link failed");
|
||||||
auto result = machine().instantiate(*instance->m_module, link_result.release_value());
|
auto result = machine().instantiate(*instance->m_module, link_result.release_value());
|
||||||
if (result.is_error())
|
if (result.is_error())
|
||||||
return vm.throw_completion<JS::TypeError>(realm.global_object(), result.release_error().error);
|
return vm.throw_completion<JS::TypeError>(result.release_error().error);
|
||||||
instance->m_module_instance = result.release_value();
|
instance->m_module_instance = result.release_value();
|
||||||
return instance;
|
return instance;
|
||||||
}
|
}
|
||||||
|
@ -103,7 +103,7 @@ TESTJS_GLOBAL_FUNCTION(parse_webassembly_module, parseWebAssemblyModule)
|
||||||
auto& realm = *global_object.associated_realm();
|
auto& realm = *global_object.associated_realm();
|
||||||
auto* object = TRY(vm.argument(0).to_object(global_object));
|
auto* object = TRY(vm.argument(0).to_object(global_object));
|
||||||
if (!is<JS::Uint8Array>(object))
|
if (!is<JS::Uint8Array>(object))
|
||||||
return vm.throw_completion<JS::TypeError>(global_object, "Expected a Uint8Array argument to parse_webassembly_module");
|
return vm.throw_completion<JS::TypeError>("Expected a Uint8Array argument to parse_webassembly_module");
|
||||||
auto& array = static_cast<JS::Uint8Array&>(*object);
|
auto& array = static_cast<JS::Uint8Array&>(*object);
|
||||||
InputMemoryStream stream { array.data() };
|
InputMemoryStream stream { array.data() };
|
||||||
ScopeGuard handle_stream_error {
|
ScopeGuard handle_stream_error {
|
||||||
|
@ -113,10 +113,10 @@ TESTJS_GLOBAL_FUNCTION(parse_webassembly_module, parseWebAssemblyModule)
|
||||||
};
|
};
|
||||||
auto result = Wasm::Module::parse(stream);
|
auto result = Wasm::Module::parse(stream);
|
||||||
if (result.is_error())
|
if (result.is_error())
|
||||||
return vm.throw_completion<JS::SyntaxError>(global_object, Wasm::parse_error_to_string(result.error()));
|
return vm.throw_completion<JS::SyntaxError>(Wasm::parse_error_to_string(result.error()));
|
||||||
|
|
||||||
if (stream.handle_any_error())
|
if (stream.handle_any_error())
|
||||||
return vm.throw_completion<JS::SyntaxError>(global_object, "Binary stream contained errors");
|
return vm.throw_completion<JS::SyntaxError>("Binary stream contained errors");
|
||||||
|
|
||||||
HashMap<Wasm::Linker::Name, Wasm::ExternValue> imports;
|
HashMap<Wasm::Linker::Name, Wasm::ExternValue> imports;
|
||||||
auto import_value = vm.argument(1);
|
auto import_value = vm.argument(1);
|
||||||
|
@ -141,11 +141,11 @@ TESTJS_GLOBAL_FUNCTION(compare_typed_arrays, compareTypedArrays)
|
||||||
{
|
{
|
||||||
auto* lhs = TRY(vm.argument(0).to_object(global_object));
|
auto* lhs = TRY(vm.argument(0).to_object(global_object));
|
||||||
if (!is<JS::TypedArrayBase>(lhs))
|
if (!is<JS::TypedArrayBase>(lhs))
|
||||||
return vm.throw_completion<JS::TypeError>(global_object, "Expected a TypedArray");
|
return vm.throw_completion<JS::TypeError>("Expected a TypedArray");
|
||||||
auto& lhs_array = static_cast<JS::TypedArrayBase&>(*lhs);
|
auto& lhs_array = static_cast<JS::TypedArrayBase&>(*lhs);
|
||||||
auto* rhs = TRY(vm.argument(1).to_object(global_object));
|
auto* rhs = TRY(vm.argument(1).to_object(global_object));
|
||||||
if (!is<JS::TypedArrayBase>(rhs))
|
if (!is<JS::TypedArrayBase>(rhs))
|
||||||
return vm.throw_completion<JS::TypeError>(global_object, "Expected a TypedArray");
|
return vm.throw_completion<JS::TypeError>("Expected a TypedArray");
|
||||||
auto& rhs_array = static_cast<JS::TypedArrayBase&>(*rhs);
|
auto& rhs_array = static_cast<JS::TypedArrayBase&>(*rhs);
|
||||||
return JS::Value(lhs_array.viewed_array_buffer()->buffer() == rhs_array.viewed_array_buffer()->buffer());
|
return JS::Value(lhs_array.viewed_array_buffer()->buffer() == rhs_array.viewed_array_buffer()->buffer());
|
||||||
}
|
}
|
||||||
|
@ -163,7 +163,7 @@ JS_DEFINE_NATIVE_FUNCTION(WebAssemblyModule::get_export)
|
||||||
auto this_value = vm.this_value(global_object);
|
auto this_value = vm.this_value(global_object);
|
||||||
auto* object = TRY(this_value.to_object(global_object));
|
auto* object = TRY(this_value.to_object(global_object));
|
||||||
if (!is<WebAssemblyModule>(object))
|
if (!is<WebAssemblyModule>(object))
|
||||||
return vm.throw_completion<JS::TypeError>(global_object, "Not a WebAssemblyModule");
|
return vm.throw_completion<JS::TypeError>("Not a WebAssemblyModule");
|
||||||
auto instance = static_cast<WebAssemblyModule*>(object);
|
auto instance = static_cast<WebAssemblyModule*>(object);
|
||||||
for (auto& entry : instance->module_instance().exports()) {
|
for (auto& entry : instance->module_instance().exports()) {
|
||||||
if (entry.name() == name) {
|
if (entry.name() == name) {
|
||||||
|
@ -181,10 +181,10 @@ JS_DEFINE_NATIVE_FUNCTION(WebAssemblyModule::get_export)
|
||||||
[&](const auto& ref) -> JS::Value { return JS::Value(static_cast<double>(ref.address.value())); });
|
[&](const auto& ref) -> JS::Value { return JS::Value(static_cast<double>(ref.address.value())); });
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
return vm.throw_completion<JS::TypeError>(global_object, String::formatted("'{}' does not refer to a function or a global", name));
|
return vm.throw_completion<JS::TypeError>(String::formatted("'{}' does not refer to a function or a global", name));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return vm.throw_completion<JS::TypeError>(global_object, String::formatted("'{}' could not be found", name));
|
return vm.throw_completion<JS::TypeError>(String::formatted("'{}' could not be found", name));
|
||||||
}
|
}
|
||||||
|
|
||||||
JS_DEFINE_NATIVE_FUNCTION(WebAssemblyModule::wasm_invoke)
|
JS_DEFINE_NATIVE_FUNCTION(WebAssemblyModule::wasm_invoke)
|
||||||
|
@ -193,16 +193,16 @@ JS_DEFINE_NATIVE_FUNCTION(WebAssemblyModule::wasm_invoke)
|
||||||
Wasm::FunctionAddress function_address { address };
|
Wasm::FunctionAddress function_address { address };
|
||||||
auto function_instance = WebAssemblyModule::machine().store().get(function_address);
|
auto function_instance = WebAssemblyModule::machine().store().get(function_address);
|
||||||
if (!function_instance)
|
if (!function_instance)
|
||||||
return vm.throw_completion<JS::TypeError>(global_object, "Invalid function address");
|
return vm.throw_completion<JS::TypeError>("Invalid function address");
|
||||||
|
|
||||||
Wasm::FunctionType const* type { nullptr };
|
Wasm::FunctionType const* type { nullptr };
|
||||||
function_instance->visit([&](auto& value) { type = &value.type(); });
|
function_instance->visit([&](auto& value) { type = &value.type(); });
|
||||||
if (!type)
|
if (!type)
|
||||||
return vm.throw_completion<JS::TypeError>(global_object, "Invalid function found at given address");
|
return vm.throw_completion<JS::TypeError>("Invalid function found at given address");
|
||||||
|
|
||||||
Vector<Wasm::Value> arguments;
|
Vector<Wasm::Value> arguments;
|
||||||
if (type->parameters().size() + 1 > vm.argument_count())
|
if (type->parameters().size() + 1 > vm.argument_count())
|
||||||
return vm.throw_completion<JS::TypeError>(global_object, String::formatted("Expected {} arguments for call, but found {}", type->parameters().size() + 1, vm.argument_count()));
|
return vm.throw_completion<JS::TypeError>(String::formatted("Expected {} arguments for call, but found {}", type->parameters().size() + 1, vm.argument_count()));
|
||||||
size_t index = 1;
|
size_t index = 1;
|
||||||
for (auto& param : type->parameters()) {
|
for (auto& param : type->parameters()) {
|
||||||
auto argument = vm.argument(index++);
|
auto argument = vm.argument(index++);
|
||||||
|
@ -244,7 +244,7 @@ JS_DEFINE_NATIVE_FUNCTION(WebAssemblyModule::wasm_invoke)
|
||||||
|
|
||||||
auto result = WebAssemblyModule::machine().invoke(function_address, arguments);
|
auto result = WebAssemblyModule::machine().invoke(function_address, arguments);
|
||||||
if (result.is_trap())
|
if (result.is_trap())
|
||||||
return vm.throw_completion<JS::TypeError>(global_object, String::formatted("Execution trapped: {}", result.trap().reason));
|
return vm.throw_completion<JS::TypeError>(String::formatted("Execution trapped: {}", result.trap().reason));
|
||||||
|
|
||||||
if (result.values().is_empty())
|
if (result.values().is_empty())
|
||||||
return JS::js_null();
|
return JS::js_null();
|
||||||
|
|
|
@ -174,7 +174,7 @@ JS_DEFINE_NATIVE_FUNCTION(SheetGlobalObject::get_name)
|
||||||
auto* this_object = TRY(vm.this_value(global_object).to_object(global_object));
|
auto* this_object = TRY(vm.this_value(global_object).to_object(global_object));
|
||||||
|
|
||||||
if (!is<SheetGlobalObject>(this_object))
|
if (!is<SheetGlobalObject>(this_object))
|
||||||
return vm.throw_completion<JS::TypeError>(global_object, JS::ErrorType::NotAnObjectOfType, "SheetGlobalObject");
|
return vm.throw_completion<JS::TypeError>(JS::ErrorType::NotAnObjectOfType, "SheetGlobalObject");
|
||||||
|
|
||||||
auto sheet_object = static_cast<SheetGlobalObject*>(this_object);
|
auto sheet_object = static_cast<SheetGlobalObject*>(this_object);
|
||||||
return JS::js_string(global_object.heap(), sheet_object->m_sheet.name());
|
return JS::js_string(global_object.heap(), sheet_object->m_sheet.name());
|
||||||
|
@ -185,19 +185,19 @@ JS_DEFINE_NATIVE_FUNCTION(SheetGlobalObject::get_real_cell_contents)
|
||||||
auto* this_object = TRY(vm.this_value(global_object).to_object(global_object));
|
auto* this_object = TRY(vm.this_value(global_object).to_object(global_object));
|
||||||
|
|
||||||
if (!is<SheetGlobalObject>(this_object))
|
if (!is<SheetGlobalObject>(this_object))
|
||||||
return vm.throw_completion<JS::TypeError>(global_object, JS::ErrorType::NotAnObjectOfType, "SheetGlobalObject");
|
return vm.throw_completion<JS::TypeError>(JS::ErrorType::NotAnObjectOfType, "SheetGlobalObject");
|
||||||
|
|
||||||
auto sheet_object = static_cast<SheetGlobalObject*>(this_object);
|
auto sheet_object = static_cast<SheetGlobalObject*>(this_object);
|
||||||
|
|
||||||
if (vm.argument_count() != 1)
|
if (vm.argument_count() != 1)
|
||||||
return vm.throw_completion<JS::TypeError>(global_object, "Expected exactly one argument to get_real_cell_contents()");
|
return vm.throw_completion<JS::TypeError>("Expected exactly one argument to get_real_cell_contents()");
|
||||||
|
|
||||||
auto name_value = vm.argument(0);
|
auto name_value = vm.argument(0);
|
||||||
if (!name_value.is_string())
|
if (!name_value.is_string())
|
||||||
return vm.throw_completion<JS::TypeError>(global_object, "Expected a String argument to get_real_cell_contents()");
|
return vm.throw_completion<JS::TypeError>("Expected a String argument to get_real_cell_contents()");
|
||||||
auto position = sheet_object->m_sheet.parse_cell_name(name_value.as_string().string());
|
auto position = sheet_object->m_sheet.parse_cell_name(name_value.as_string().string());
|
||||||
if (!position.has_value())
|
if (!position.has_value())
|
||||||
return vm.throw_completion<JS::TypeError>(global_object, "Invalid cell name");
|
return vm.throw_completion<JS::TypeError>("Invalid cell name");
|
||||||
|
|
||||||
auto const* cell = sheet_object->m_sheet.at(position.value());
|
auto const* cell = sheet_object->m_sheet.at(position.value());
|
||||||
if (!cell)
|
if (!cell)
|
||||||
|
@ -214,23 +214,23 @@ JS_DEFINE_NATIVE_FUNCTION(SheetGlobalObject::set_real_cell_contents)
|
||||||
auto* this_object = TRY(vm.this_value(global_object).to_object(global_object));
|
auto* this_object = TRY(vm.this_value(global_object).to_object(global_object));
|
||||||
|
|
||||||
if (!is<SheetGlobalObject>(this_object))
|
if (!is<SheetGlobalObject>(this_object))
|
||||||
return vm.throw_completion<JS::TypeError>(global_object, JS::ErrorType::NotAnObjectOfType, "SheetGlobalObject");
|
return vm.throw_completion<JS::TypeError>(JS::ErrorType::NotAnObjectOfType, "SheetGlobalObject");
|
||||||
|
|
||||||
auto sheet_object = static_cast<SheetGlobalObject*>(this_object);
|
auto sheet_object = static_cast<SheetGlobalObject*>(this_object);
|
||||||
|
|
||||||
if (vm.argument_count() != 2)
|
if (vm.argument_count() != 2)
|
||||||
return vm.throw_completion<JS::TypeError>(global_object, "Expected exactly two arguments to set_real_cell_contents()");
|
return vm.throw_completion<JS::TypeError>("Expected exactly two arguments to set_real_cell_contents()");
|
||||||
|
|
||||||
auto name_value = vm.argument(0);
|
auto name_value = vm.argument(0);
|
||||||
if (!name_value.is_string())
|
if (!name_value.is_string())
|
||||||
return vm.throw_completion<JS::TypeError>(global_object, "Expected the first argument of set_real_cell_contents() to be a String");
|
return vm.throw_completion<JS::TypeError>("Expected the first argument of set_real_cell_contents() to be a String");
|
||||||
auto position = sheet_object->m_sheet.parse_cell_name(name_value.as_string().string());
|
auto position = sheet_object->m_sheet.parse_cell_name(name_value.as_string().string());
|
||||||
if (!position.has_value())
|
if (!position.has_value())
|
||||||
return vm.throw_completion<JS::TypeError>(global_object, "Invalid cell name");
|
return vm.throw_completion<JS::TypeError>("Invalid cell name");
|
||||||
|
|
||||||
auto new_contents_value = vm.argument(1);
|
auto new_contents_value = vm.argument(1);
|
||||||
if (!new_contents_value.is_string())
|
if (!new_contents_value.is_string())
|
||||||
return vm.throw_completion<JS::TypeError>(global_object, "Expected the second argument of set_real_cell_contents() to be a String");
|
return vm.throw_completion<JS::TypeError>("Expected the second argument of set_real_cell_contents() to be a String");
|
||||||
|
|
||||||
auto& cell = sheet_object->m_sheet.ensure(position.value());
|
auto& cell = sheet_object->m_sheet.ensure(position.value());
|
||||||
auto& new_contents = new_contents_value.as_string().string();
|
auto& new_contents = new_contents_value.as_string().string();
|
||||||
|
@ -245,15 +245,15 @@ JS_DEFINE_NATIVE_FUNCTION(SheetGlobalObject::parse_cell_name)
|
||||||
auto* this_object = TRY(vm.this_value(global_object).to_object(global_object));
|
auto* this_object = TRY(vm.this_value(global_object).to_object(global_object));
|
||||||
|
|
||||||
if (!is<SheetGlobalObject>(this_object))
|
if (!is<SheetGlobalObject>(this_object))
|
||||||
return vm.throw_completion<JS::TypeError>(global_object, JS::ErrorType::NotAnObjectOfType, "SheetGlobalObject");
|
return vm.throw_completion<JS::TypeError>(JS::ErrorType::NotAnObjectOfType, "SheetGlobalObject");
|
||||||
|
|
||||||
auto sheet_object = static_cast<SheetGlobalObject*>(this_object);
|
auto sheet_object = static_cast<SheetGlobalObject*>(this_object);
|
||||||
|
|
||||||
if (vm.argument_count() != 1)
|
if (vm.argument_count() != 1)
|
||||||
return vm.throw_completion<JS::TypeError>(global_object, "Expected exactly one argument to parse_cell_name()");
|
return vm.throw_completion<JS::TypeError>("Expected exactly one argument to parse_cell_name()");
|
||||||
auto name_value = vm.argument(0);
|
auto name_value = vm.argument(0);
|
||||||
if (!name_value.is_string())
|
if (!name_value.is_string())
|
||||||
return vm.throw_completion<JS::TypeError>(global_object, "Expected a String argument to parse_cell_name()");
|
return vm.throw_completion<JS::TypeError>("Expected a String argument to parse_cell_name()");
|
||||||
auto position = sheet_object->m_sheet.parse_cell_name(name_value.as_string().string());
|
auto position = sheet_object->m_sheet.parse_cell_name(name_value.as_string().string());
|
||||||
if (!position.has_value())
|
if (!position.has_value())
|
||||||
return JS::js_undefined();
|
return JS::js_undefined();
|
||||||
|
@ -270,12 +270,12 @@ JS_DEFINE_NATIVE_FUNCTION(SheetGlobalObject::current_cell_position)
|
||||||
auto& realm = *global_object.associated_realm();
|
auto& realm = *global_object.associated_realm();
|
||||||
|
|
||||||
if (vm.argument_count() != 0)
|
if (vm.argument_count() != 0)
|
||||||
return vm.throw_completion<JS::TypeError>(global_object, "Expected no arguments to current_cell_position()");
|
return vm.throw_completion<JS::TypeError>("Expected no arguments to current_cell_position()");
|
||||||
|
|
||||||
auto* this_object = TRY(vm.this_value(global_object).to_object(global_object));
|
auto* this_object = TRY(vm.this_value(global_object).to_object(global_object));
|
||||||
|
|
||||||
if (!is<SheetGlobalObject>(this_object))
|
if (!is<SheetGlobalObject>(this_object))
|
||||||
return vm.throw_completion<JS::TypeError>(global_object, JS::ErrorType::NotAnObjectOfType, "SheetGlobalObject");
|
return vm.throw_completion<JS::TypeError>(JS::ErrorType::NotAnObjectOfType, "SheetGlobalObject");
|
||||||
|
|
||||||
auto sheet_object = static_cast<SheetGlobalObject*>(this_object);
|
auto sheet_object = static_cast<SheetGlobalObject*>(this_object);
|
||||||
auto* current_cell = sheet_object->m_sheet.current_evaluated_cell();
|
auto* current_cell = sheet_object->m_sheet.current_evaluated_cell();
|
||||||
|
@ -294,24 +294,24 @@ JS_DEFINE_NATIVE_FUNCTION(SheetGlobalObject::current_cell_position)
|
||||||
JS_DEFINE_NATIVE_FUNCTION(SheetGlobalObject::column_index)
|
JS_DEFINE_NATIVE_FUNCTION(SheetGlobalObject::column_index)
|
||||||
{
|
{
|
||||||
if (vm.argument_count() != 1)
|
if (vm.argument_count() != 1)
|
||||||
return vm.throw_completion<JS::TypeError>(global_object, "Expected exactly one argument to column_index()");
|
return vm.throw_completion<JS::TypeError>("Expected exactly one argument to column_index()");
|
||||||
|
|
||||||
auto column_name = vm.argument(0);
|
auto column_name = vm.argument(0);
|
||||||
if (!column_name.is_string())
|
if (!column_name.is_string())
|
||||||
return vm.throw_completion<JS::TypeError>(global_object, JS::ErrorType::NotAnObjectOfType, "String");
|
return vm.throw_completion<JS::TypeError>(JS::ErrorType::NotAnObjectOfType, "String");
|
||||||
|
|
||||||
auto& column_name_str = column_name.as_string().string();
|
auto& column_name_str = column_name.as_string().string();
|
||||||
|
|
||||||
auto* this_object = TRY(vm.this_value(global_object).to_object(global_object));
|
auto* this_object = TRY(vm.this_value(global_object).to_object(global_object));
|
||||||
|
|
||||||
if (!is<SheetGlobalObject>(this_object))
|
if (!is<SheetGlobalObject>(this_object))
|
||||||
return vm.throw_completion<JS::TypeError>(global_object, JS::ErrorType::NotAnObjectOfType, "SheetGlobalObject");
|
return vm.throw_completion<JS::TypeError>(JS::ErrorType::NotAnObjectOfType, "SheetGlobalObject");
|
||||||
|
|
||||||
auto sheet_object = static_cast<SheetGlobalObject*>(this_object);
|
auto sheet_object = static_cast<SheetGlobalObject*>(this_object);
|
||||||
auto& sheet = sheet_object->m_sheet;
|
auto& sheet = sheet_object->m_sheet;
|
||||||
auto column_index = sheet.column_index(column_name_str);
|
auto column_index = sheet.column_index(column_name_str);
|
||||||
if (!column_index.has_value())
|
if (!column_index.has_value())
|
||||||
return vm.throw_completion<JS::TypeError>(global_object, String::formatted("'{}' is not a valid column", column_name_str));
|
return vm.throw_completion<JS::TypeError>(String::formatted("'{}' is not a valid column", column_name_str));
|
||||||
|
|
||||||
return JS::Value((i32)column_index.value());
|
return JS::Value((i32)column_index.value());
|
||||||
}
|
}
|
||||||
|
@ -319,11 +319,11 @@ JS_DEFINE_NATIVE_FUNCTION(SheetGlobalObject::column_index)
|
||||||
JS_DEFINE_NATIVE_FUNCTION(SheetGlobalObject::column_arithmetic)
|
JS_DEFINE_NATIVE_FUNCTION(SheetGlobalObject::column_arithmetic)
|
||||||
{
|
{
|
||||||
if (vm.argument_count() != 2)
|
if (vm.argument_count() != 2)
|
||||||
return vm.throw_completion<JS::TypeError>(global_object, "Expected exactly two arguments to column_arithmetic()");
|
return vm.throw_completion<JS::TypeError>("Expected exactly two arguments to column_arithmetic()");
|
||||||
|
|
||||||
auto column_name = vm.argument(0);
|
auto column_name = vm.argument(0);
|
||||||
if (!column_name.is_string())
|
if (!column_name.is_string())
|
||||||
return vm.throw_completion<JS::TypeError>(global_object, JS::ErrorType::NotAnObjectOfType, "String");
|
return vm.throw_completion<JS::TypeError>(JS::ErrorType::NotAnObjectOfType, "String");
|
||||||
|
|
||||||
auto& column_name_str = column_name.as_string().string();
|
auto& column_name_str = column_name.as_string().string();
|
||||||
|
|
||||||
|
@ -333,13 +333,13 @@ JS_DEFINE_NATIVE_FUNCTION(SheetGlobalObject::column_arithmetic)
|
||||||
auto* this_object = TRY(vm.this_value(global_object).to_object(global_object));
|
auto* this_object = TRY(vm.this_value(global_object).to_object(global_object));
|
||||||
|
|
||||||
if (!is<SheetGlobalObject>(this_object))
|
if (!is<SheetGlobalObject>(this_object))
|
||||||
return vm.throw_completion<JS::TypeError>(global_object, JS::ErrorType::NotAnObjectOfType, "SheetGlobalObject");
|
return vm.throw_completion<JS::TypeError>(JS::ErrorType::NotAnObjectOfType, "SheetGlobalObject");
|
||||||
|
|
||||||
auto sheet_object = static_cast<SheetGlobalObject*>(this_object);
|
auto sheet_object = static_cast<SheetGlobalObject*>(this_object);
|
||||||
auto& sheet = sheet_object->m_sheet;
|
auto& sheet = sheet_object->m_sheet;
|
||||||
auto new_column = sheet.column_arithmetic(column_name_str, offset_number);
|
auto new_column = sheet.column_arithmetic(column_name_str, offset_number);
|
||||||
if (!new_column.has_value())
|
if (!new_column.has_value())
|
||||||
return vm.throw_completion<JS::TypeError>(global_object, String::formatted("'{}' is not a valid column", column_name_str));
|
return vm.throw_completion<JS::TypeError>(String::formatted("'{}' is not a valid column", column_name_str));
|
||||||
|
|
||||||
return JS::js_string(vm, new_column.release_value());
|
return JS::js_string(vm, new_column.release_value());
|
||||||
}
|
}
|
||||||
|
@ -347,23 +347,23 @@ JS_DEFINE_NATIVE_FUNCTION(SheetGlobalObject::column_arithmetic)
|
||||||
JS_DEFINE_NATIVE_FUNCTION(SheetGlobalObject::get_column_bound)
|
JS_DEFINE_NATIVE_FUNCTION(SheetGlobalObject::get_column_bound)
|
||||||
{
|
{
|
||||||
if (vm.argument_count() != 1)
|
if (vm.argument_count() != 1)
|
||||||
return vm.throw_completion<JS::TypeError>(global_object, "Expected exactly one argument to get_column_bound()");
|
return vm.throw_completion<JS::TypeError>("Expected exactly one argument to get_column_bound()");
|
||||||
|
|
||||||
auto column_name = vm.argument(0);
|
auto column_name = vm.argument(0);
|
||||||
if (!column_name.is_string())
|
if (!column_name.is_string())
|
||||||
return vm.throw_completion<JS::TypeError>(global_object, JS::ErrorType::NotAnObjectOfType, "String");
|
return vm.throw_completion<JS::TypeError>(JS::ErrorType::NotAnObjectOfType, "String");
|
||||||
|
|
||||||
auto& column_name_str = column_name.as_string().string();
|
auto& column_name_str = column_name.as_string().string();
|
||||||
auto* this_object = TRY(vm.this_value(global_object).to_object(global_object));
|
auto* this_object = TRY(vm.this_value(global_object).to_object(global_object));
|
||||||
|
|
||||||
if (!is<SheetGlobalObject>(this_object))
|
if (!is<SheetGlobalObject>(this_object))
|
||||||
return vm.throw_completion<JS::TypeError>(global_object, JS::ErrorType::NotAnObjectOfType, "SheetGlobalObject");
|
return vm.throw_completion<JS::TypeError>(JS::ErrorType::NotAnObjectOfType, "SheetGlobalObject");
|
||||||
|
|
||||||
auto sheet_object = static_cast<SheetGlobalObject*>(this_object);
|
auto sheet_object = static_cast<SheetGlobalObject*>(this_object);
|
||||||
auto& sheet = sheet_object->m_sheet;
|
auto& sheet = sheet_object->m_sheet;
|
||||||
auto maybe_column_index = sheet.column_index(column_name_str);
|
auto maybe_column_index = sheet.column_index(column_name_str);
|
||||||
if (!maybe_column_index.has_value())
|
if (!maybe_column_index.has_value())
|
||||||
return vm.throw_completion<JS::TypeError>(global_object, String::formatted("'{}' is not a valid column", column_name_str));
|
return vm.throw_completion<JS::TypeError>(String::formatted("'{}' is not a valid column", column_name_str));
|
||||||
|
|
||||||
auto bounds = sheet.written_data_bounds(*maybe_column_index);
|
auto bounds = sheet.written_data_bounds(*maybe_column_index);
|
||||||
return JS::Value(bounds.row);
|
return JS::Value(bounds.row);
|
||||||
|
@ -391,15 +391,15 @@ void WorkbookObject::visit_edges(Visitor& visitor)
|
||||||
JS_DEFINE_NATIVE_FUNCTION(WorkbookObject::sheet)
|
JS_DEFINE_NATIVE_FUNCTION(WorkbookObject::sheet)
|
||||||
{
|
{
|
||||||
if (vm.argument_count() != 1)
|
if (vm.argument_count() != 1)
|
||||||
return vm.throw_completion<JS::TypeError>(global_object, "Expected exactly one argument to sheet()");
|
return vm.throw_completion<JS::TypeError>("Expected exactly one argument to sheet()");
|
||||||
auto name_value = vm.argument(0);
|
auto name_value = vm.argument(0);
|
||||||
if (!name_value.is_string() && !name_value.is_number())
|
if (!name_value.is_string() && !name_value.is_number())
|
||||||
return vm.throw_completion<JS::TypeError>(global_object, "Expected a String or Number argument to sheet()");
|
return vm.throw_completion<JS::TypeError>("Expected a String or Number argument to sheet()");
|
||||||
|
|
||||||
auto* this_object = TRY(vm.this_value(global_object).to_object(global_object));
|
auto* this_object = TRY(vm.this_value(global_object).to_object(global_object));
|
||||||
|
|
||||||
if (!is<WorkbookObject>(this_object))
|
if (!is<WorkbookObject>(this_object))
|
||||||
return vm.throw_completion<JS::TypeError>(global_object, JS::ErrorType::NotAnObjectOfType, "WorkbookObject");
|
return vm.throw_completion<JS::TypeError>(JS::ErrorType::NotAnObjectOfType, "WorkbookObject");
|
||||||
|
|
||||||
auto& workbook = static_cast<WorkbookObject*>(this_object)->m_workbook;
|
auto& workbook = static_cast<WorkbookObject*>(this_object)->m_workbook;
|
||||||
|
|
||||||
|
|
|
@ -172,7 +172,7 @@ JS::ThrowCompletionOr<JS::Value> Sheet::evaluate(StringView source, Cell* on_beh
|
||||||
name);
|
name);
|
||||||
|
|
||||||
if (script_or_error.is_error())
|
if (script_or_error.is_error())
|
||||||
return interpreter().vm().throw_completion<JS::SyntaxError>(interpreter().global_object(), script_or_error.error().first().to_string());
|
return interpreter().vm().throw_completion<JS::SyntaxError>(script_or_error.error().first().to_string());
|
||||||
|
|
||||||
return interpreter().run(script_or_error.value());
|
return interpreter().run(script_or_error.value());
|
||||||
}
|
}
|
||||||
|
|
|
@ -407,7 +407,6 @@ Completion NewExpression::execute(Interpreter& interpreter) const
|
||||||
|
|
||||||
Completion CallExpression::throw_type_error_for_callee(Interpreter& interpreter, Value callee_value, StringView call_type) const
|
Completion CallExpression::throw_type_error_for_callee(Interpreter& interpreter, Value callee_value, StringView call_type) const
|
||||||
{
|
{
|
||||||
auto& global_object = interpreter.global_object();
|
|
||||||
auto& vm = interpreter.vm();
|
auto& vm = interpreter.vm();
|
||||||
|
|
||||||
if (is<Identifier>(*m_callee) || is<MemberExpression>(*m_callee)) {
|
if (is<Identifier>(*m_callee) || is<MemberExpression>(*m_callee)) {
|
||||||
|
@ -417,9 +416,9 @@ Completion CallExpression::throw_type_error_for_callee(Interpreter& interpreter,
|
||||||
} else {
|
} else {
|
||||||
expression_string = static_cast<MemberExpression const&>(*m_callee).to_string_approximation();
|
expression_string = static_cast<MemberExpression const&>(*m_callee).to_string_approximation();
|
||||||
}
|
}
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::IsNotAEvaluatedFrom, callee_value.to_string_without_side_effects(), call_type, expression_string);
|
return vm.throw_completion<TypeError>(ErrorType::IsNotAEvaluatedFrom, callee_value.to_string_without_side_effects(), call_type, expression_string);
|
||||||
} else {
|
} else {
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::IsNotA, callee_value.to_string_without_side_effects(), call_type);
|
return vm.throw_completion<TypeError>(ErrorType::IsNotA, callee_value.to_string_without_side_effects(), call_type);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -494,7 +493,7 @@ Completion SuperCall::execute(Interpreter& interpreter) const
|
||||||
|
|
||||||
// 5. If IsConstructor(func) is false, throw a TypeError exception.
|
// 5. If IsConstructor(func) is false, throw a TypeError exception.
|
||||||
if (!func || !Value(func).is_constructor())
|
if (!func || !Value(func).is_constructor())
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::NotAConstructor, "Super constructor");
|
return vm.throw_completion<TypeError>(ErrorType::NotAConstructor, "Super constructor");
|
||||||
|
|
||||||
// 6. Let result be ? Construct(func, argList, newTarget).
|
// 6. Let result be ? Construct(func, argList, newTarget).
|
||||||
auto* result = TRY(construct(global_object, static_cast<FunctionObject&>(*func), move(arg_list), &new_target.as_function()));
|
auto* result = TRY(construct(global_object, static_cast<FunctionObject&>(*func), move(arg_list), &new_target.as_function()));
|
||||||
|
@ -1201,7 +1200,7 @@ Completion ForAwaitOfStatement::loop_evaluation(Interpreter& interpreter, Vector
|
||||||
|
|
||||||
// c. If Type(nextResult) is not Object, throw a TypeError exception.
|
// c. If Type(nextResult) is not Object, throw a TypeError exception.
|
||||||
if (!next_result.is_object())
|
if (!next_result.is_object())
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::IterableNextBadReturn);
|
return vm.throw_completion<TypeError>(ErrorType::IterableNextBadReturn);
|
||||||
|
|
||||||
// d. Let done be ? IteratorComplete(nextResult).
|
// d. Let done be ? IteratorComplete(nextResult).
|
||||||
auto done = TRY(iterator_complete(global_object, next_result.as_object()));
|
auto done = TRY(iterator_complete(global_object, next_result.as_object()));
|
||||||
|
@ -1260,7 +1259,7 @@ Completion BinaryExpression::execute(Interpreter& interpreter) const
|
||||||
|
|
||||||
auto rhs_result = TRY(m_rhs->execute(interpreter)).release_value();
|
auto rhs_result = TRY(m_rhs->execute(interpreter)).release_value();
|
||||||
if (!rhs_result.is_object())
|
if (!rhs_result.is_object())
|
||||||
return interpreter.vm().throw_completion<TypeError>(global_object, ErrorType::InOperatorWithObject);
|
return interpreter.vm().throw_completion<TypeError>(ErrorType::InOperatorWithObject);
|
||||||
auto* private_environment = interpreter.vm().running_execution_context().private_environment;
|
auto* private_environment = interpreter.vm().running_execution_context().private_environment;
|
||||||
VERIFY(private_environment);
|
VERIFY(private_environment);
|
||||||
auto private_name = private_environment->resolve_private_identifier(private_identifier);
|
auto private_name = private_environment->resolve_private_identifier(private_identifier);
|
||||||
|
@ -1856,11 +1855,11 @@ ThrowCompletionOr<ECMAScriptFunctionObject*> ClassExpression::class_definition_e
|
||||||
if (super_class.is_null()) {
|
if (super_class.is_null()) {
|
||||||
proto_parent = nullptr;
|
proto_parent = nullptr;
|
||||||
} else if (!super_class.is_constructor()) {
|
} else if (!super_class.is_constructor()) {
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::ClassExtendsValueNotAConstructorOrNull, super_class.to_string_without_side_effects());
|
return vm.throw_completion<TypeError>(ErrorType::ClassExtendsValueNotAConstructorOrNull, super_class.to_string_without_side_effects());
|
||||||
} else {
|
} else {
|
||||||
auto super_class_prototype = TRY(super_class.get(global_object, vm.names.prototype));
|
auto super_class_prototype = TRY(super_class.get(global_object, vm.names.prototype));
|
||||||
if (!super_class_prototype.is_null() && !super_class_prototype.is_object())
|
if (!super_class_prototype.is_null() && !super_class_prototype.is_object())
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::ClassExtendsValueInvalidPrototype, super_class_prototype.to_string_without_side_effects());
|
return vm.throw_completion<TypeError>(ErrorType::ClassExtendsValueInvalidPrototype, super_class_prototype.to_string_without_side_effects());
|
||||||
|
|
||||||
if (super_class_prototype.is_null())
|
if (super_class_prototype.is_null())
|
||||||
proto_parent = nullptr;
|
proto_parent = nullptr;
|
||||||
|
@ -4555,18 +4554,18 @@ ThrowCompletionOr<void> Program::global_declaration_instantiation(Interpreter& i
|
||||||
TRY(for_each_lexically_declared_name([&](FlyString const& name) -> ThrowCompletionOr<void> {
|
TRY(for_each_lexically_declared_name([&](FlyString const& name) -> ThrowCompletionOr<void> {
|
||||||
// a. If env.HasVarDeclaration(name) is true, throw a SyntaxError exception.
|
// a. If env.HasVarDeclaration(name) is true, throw a SyntaxError exception.
|
||||||
if (global_environment.has_var_declaration(name))
|
if (global_environment.has_var_declaration(name))
|
||||||
return interpreter.vm().throw_completion<SyntaxError>(global_object, ErrorType::TopLevelVariableAlreadyDeclared, name);
|
return interpreter.vm().throw_completion<SyntaxError>(ErrorType::TopLevelVariableAlreadyDeclared, name);
|
||||||
|
|
||||||
// b. If env.HasLexicalDeclaration(name) is true, throw a SyntaxError exception.
|
// b. If env.HasLexicalDeclaration(name) is true, throw a SyntaxError exception.
|
||||||
if (global_environment.has_lexical_declaration(name))
|
if (global_environment.has_lexical_declaration(name))
|
||||||
return interpreter.vm().throw_completion<SyntaxError>(global_object, ErrorType::TopLevelVariableAlreadyDeclared, name);
|
return interpreter.vm().throw_completion<SyntaxError>(ErrorType::TopLevelVariableAlreadyDeclared, name);
|
||||||
|
|
||||||
// c. Let hasRestrictedGlobal be ? env.HasRestrictedGlobalProperty(name).
|
// c. Let hasRestrictedGlobal be ? env.HasRestrictedGlobalProperty(name).
|
||||||
auto has_restricted_global = TRY(global_environment.has_restricted_global_property(name));
|
auto has_restricted_global = TRY(global_environment.has_restricted_global_property(name));
|
||||||
|
|
||||||
// d. If hasRestrictedGlobal is true, throw a SyntaxError exception.
|
// d. If hasRestrictedGlobal is true, throw a SyntaxError exception.
|
||||||
if (has_restricted_global)
|
if (has_restricted_global)
|
||||||
return interpreter.vm().throw_completion<SyntaxError>(global_object, ErrorType::RestrictedGlobalProperty, name);
|
return interpreter.vm().throw_completion<SyntaxError>(ErrorType::RestrictedGlobalProperty, name);
|
||||||
|
|
||||||
return {};
|
return {};
|
||||||
}));
|
}));
|
||||||
|
@ -4575,7 +4574,7 @@ ThrowCompletionOr<void> Program::global_declaration_instantiation(Interpreter& i
|
||||||
TRY(for_each_var_declared_name([&](auto const& name) -> ThrowCompletionOr<void> {
|
TRY(for_each_var_declared_name([&](auto const& name) -> ThrowCompletionOr<void> {
|
||||||
// a. If env.HasLexicalDeclaration(name) is true, throw a SyntaxError exception.
|
// a. If env.HasLexicalDeclaration(name) is true, throw a SyntaxError exception.
|
||||||
if (global_environment.has_lexical_declaration(name))
|
if (global_environment.has_lexical_declaration(name))
|
||||||
return interpreter.vm().throw_completion<SyntaxError>(global_object, ErrorType::TopLevelVariableAlreadyDeclared, name);
|
return interpreter.vm().throw_completion<SyntaxError>(ErrorType::TopLevelVariableAlreadyDeclared, name);
|
||||||
|
|
||||||
return {};
|
return {};
|
||||||
}));
|
}));
|
||||||
|
@ -4607,7 +4606,7 @@ ThrowCompletionOr<void> Program::global_declaration_instantiation(Interpreter& i
|
||||||
|
|
||||||
// 2. If fnDefinable is false, throw a TypeError exception.
|
// 2. If fnDefinable is false, throw a TypeError exception.
|
||||||
if (!function_definable)
|
if (!function_definable)
|
||||||
return interpreter.vm().throw_completion<TypeError>(global_object, ErrorType::CannotDeclareGlobalFunction, function.name());
|
return interpreter.vm().throw_completion<TypeError>(ErrorType::CannotDeclareGlobalFunction, function.name());
|
||||||
|
|
||||||
// 3. Append fn to declaredFunctionNames.
|
// 3. Append fn to declaredFunctionNames.
|
||||||
// Note: Already done in step iv. above.
|
// Note: Already done in step iv. above.
|
||||||
|
@ -4636,7 +4635,7 @@ ThrowCompletionOr<void> Program::global_declaration_instantiation(Interpreter& i
|
||||||
|
|
||||||
// b. If vnDefinable is false, throw a TypeError exception.
|
// b. If vnDefinable is false, throw a TypeError exception.
|
||||||
if (!var_definable)
|
if (!var_definable)
|
||||||
return interpreter.vm().throw_completion<TypeError>(global_object, ErrorType::CannotDeclareGlobalVariable, name);
|
return interpreter.vm().throw_completion<TypeError>(ErrorType::CannotDeclareGlobalVariable, name);
|
||||||
|
|
||||||
// c. If vn is not an element of declaredVarNames, then
|
// c. If vn is not an element of declaredVarNames, then
|
||||||
// i. Append vn to declaredVarNames.
|
// i. Append vn to declaredVarNames.
|
||||||
|
|
|
@ -69,7 +69,7 @@ static ThrowCompletionOr<void> put_by_property_key(Object* object, Value value,
|
||||||
case PropertyKind::KeyValue: {
|
case PropertyKind::KeyValue: {
|
||||||
bool succeeded = TRY(object->internal_set(name, interpreter.accumulator(), object));
|
bool succeeded = TRY(object->internal_set(name, interpreter.accumulator(), object));
|
||||||
if (!succeeded && interpreter.vm().in_strict_mode())
|
if (!succeeded && interpreter.vm().in_strict_mode())
|
||||||
return interpreter.vm().throw_completion<TypeError>(interpreter.global_object(), ErrorType::ReferenceNullishSetProperty, name, interpreter.accumulator().to_string_without_side_effects());
|
return interpreter.vm().throw_completion<TypeError>(ErrorType::ReferenceNullishSetProperty, name, interpreter.accumulator().to_string_without_side_effects());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case PropertyKind::Spread:
|
case PropertyKind::Spread:
|
||||||
|
@ -346,7 +346,7 @@ ThrowCompletionOr<void> CreateVariable::execute_impl(Bytecode::Interpreter& inte
|
||||||
// Note: This is papering over an issue where "FunctionDeclarationInstantiation" creates these bindings for us.
|
// Note: This is papering over an issue where "FunctionDeclarationInstantiation" creates these bindings for us.
|
||||||
// Instead of crashing in there, we'll just raise an exception here.
|
// Instead of crashing in there, we'll just raise an exception here.
|
||||||
if (TRY(vm.lexical_environment()->has_binding(name)))
|
if (TRY(vm.lexical_environment()->has_binding(name)))
|
||||||
return vm.throw_completion<InternalError>(interpreter.global_object(), String::formatted("Lexical environment already has binding '{}'", name));
|
return vm.throw_completion<InternalError>(String::formatted("Lexical environment already has binding '{}'", name));
|
||||||
|
|
||||||
if (m_is_immutable)
|
if (m_is_immutable)
|
||||||
vm.lexical_environment()->create_immutable_binding(interpreter.global_object(), name, vm.in_strict_mode());
|
vm.lexical_environment()->create_immutable_binding(interpreter.global_object(), name, vm.in_strict_mode());
|
||||||
|
@ -481,10 +481,10 @@ ThrowCompletionOr<void> Call::execute_impl(Bytecode::Interpreter& interpreter) c
|
||||||
auto callee = interpreter.reg(m_callee);
|
auto callee = interpreter.reg(m_callee);
|
||||||
|
|
||||||
if (m_type == CallType::Call && !callee.is_function())
|
if (m_type == CallType::Call && !callee.is_function())
|
||||||
return interpreter.vm().throw_completion<TypeError>(interpreter.global_object(), ErrorType::IsNotA, callee.to_string_without_side_effects(), "function"sv);
|
return interpreter.vm().throw_completion<TypeError>(ErrorType::IsNotA, callee.to_string_without_side_effects(), "function"sv);
|
||||||
|
|
||||||
if (m_type == CallType::Construct && !callee.is_constructor())
|
if (m_type == CallType::Construct && !callee.is_constructor())
|
||||||
return interpreter.vm().throw_completion<TypeError>(interpreter.global_object(), ErrorType::IsNotA, callee.to_string_without_side_effects(), "constructor"sv);
|
return interpreter.vm().throw_completion<TypeError>(ErrorType::IsNotA, callee.to_string_without_side_effects(), "constructor"sv);
|
||||||
|
|
||||||
auto& function = callee.as_function();
|
auto& function = callee.as_function();
|
||||||
|
|
||||||
|
@ -699,7 +699,7 @@ ThrowCompletionOr<void> GetObjectPropertyIterator::execute_impl(Bytecode::Interp
|
||||||
auto& realm = *global_object.associated_realm();
|
auto& realm = *global_object.associated_realm();
|
||||||
auto iterated_object_value = vm.this_value(global_object);
|
auto iterated_object_value = vm.this_value(global_object);
|
||||||
if (!iterated_object_value.is_object())
|
if (!iterated_object_value.is_object())
|
||||||
return vm.throw_completion<InternalError>(global_object, "Invalid state for GetObjectPropertyIterator.next");
|
return vm.throw_completion<InternalError>("Invalid state for GetObjectPropertyIterator.next");
|
||||||
|
|
||||||
auto& iterated_object = iterated_object_value.as_object();
|
auto& iterated_object = iterated_object_value.as_object();
|
||||||
auto* result_object = Object::create(realm, nullptr);
|
auto* result_object = Object::create(realm, nullptr);
|
||||||
|
|
|
@ -71,7 +71,7 @@ JS_DEFINE_NATIVE_FUNCTION($262Object::detach_array_buffer)
|
||||||
{
|
{
|
||||||
auto array_buffer = vm.argument(0);
|
auto array_buffer = vm.argument(0);
|
||||||
if (!array_buffer.is_object() || !is<ArrayBuffer>(array_buffer.as_object()))
|
if (!array_buffer.is_object() || !is<ArrayBuffer>(array_buffer.as_object()))
|
||||||
return vm.throw_completion<TypeError>(global_object);
|
return vm.throw_completion<TypeError>();
|
||||||
|
|
||||||
auto& array_buffer_object = static_cast<ArrayBuffer&>(array_buffer.as_object());
|
auto& array_buffer_object = static_cast<ArrayBuffer&>(array_buffer.as_object());
|
||||||
TRY(JS::detach_array_buffer(global_object, array_buffer_object, vm.argument(1)));
|
TRY(JS::detach_array_buffer(global_object, array_buffer_object, vm.argument(1)));
|
||||||
|
@ -83,7 +83,7 @@ JS_DEFINE_NATIVE_FUNCTION($262Object::eval_script)
|
||||||
auto source = TRY(vm.argument(0).to_string(global_object));
|
auto source = TRY(vm.argument(0).to_string(global_object));
|
||||||
auto script_or_error = Script::parse(source, *vm.current_realm());
|
auto script_or_error = Script::parse(source, *vm.current_realm());
|
||||||
if (script_or_error.is_error())
|
if (script_or_error.is_error())
|
||||||
return vm.throw_completion<SyntaxError>(global_object, script_or_error.error()[0].to_string());
|
return vm.throw_completion<SyntaxError>(script_or_error.error()[0].to_string());
|
||||||
TRY(vm.interpreter().run(script_or_error.value()));
|
TRY(vm.interpreter().run(script_or_error.value()));
|
||||||
return js_undefined();
|
return js_undefined();
|
||||||
}
|
}
|
||||||
|
|
|
@ -349,11 +349,4 @@ void Heap::uproot_cell(Cell* cell)
|
||||||
m_uprooted_cells.append(cell);
|
m_uprooted_cells.append(cell);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Temporary helper function as we can't pass a realm directly until Heap::allocate<T>() and VM::throw_completion<T>() receive one.
|
|
||||||
// Heap.h and VM.h only have a forward declaration of the GlobalObject, so no inlined member access possible.
|
|
||||||
Realm& realm_from_global_object(GlobalObject& global_object)
|
|
||||||
{
|
|
||||||
return *global_object.associated_realm();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,8 +25,6 @@
|
||||||
|
|
||||||
namespace JS {
|
namespace JS {
|
||||||
|
|
||||||
Realm& realm_from_global_object(GlobalObject&);
|
|
||||||
|
|
||||||
class Heap {
|
class Heap {
|
||||||
AK_MAKE_NONCOPYABLE(Heap);
|
AK_MAKE_NONCOPYABLE(Heap);
|
||||||
AK_MAKE_NONMOVABLE(Heap);
|
AK_MAKE_NONMOVABLE(Heap);
|
||||||
|
|
|
@ -38,7 +38,7 @@ ThrowCompletionOr<Value> require_object_coercible(GlobalObject& global_object, V
|
||||||
{
|
{
|
||||||
auto& vm = global_object.vm();
|
auto& vm = global_object.vm();
|
||||||
if (value.is_nullish())
|
if (value.is_nullish())
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::NotObjectCoercible, value.to_string_without_side_effects());
|
return vm.throw_completion<TypeError>(ErrorType::NotObjectCoercible, value.to_string_without_side_effects());
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -53,7 +53,7 @@ ThrowCompletionOr<Value> call_impl(GlobalObject& global_object, Value function,
|
||||||
|
|
||||||
// 2. If IsCallable(F) is false, throw a TypeError exception.
|
// 2. If IsCallable(F) is false, throw a TypeError exception.
|
||||||
if (!function.is_function())
|
if (!function.is_function())
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::NotAFunction, function.to_string_without_side_effects());
|
return vm.throw_completion<TypeError>(ErrorType::NotAFunction, function.to_string_without_side_effects());
|
||||||
|
|
||||||
// 3. Return ? F.[[Call]](V, argumentsList).
|
// 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, move(*arguments_list));
|
||||||
|
@ -105,7 +105,7 @@ ThrowCompletionOr<MarkedVector<Value>> create_list_from_array_like(GlobalObject&
|
||||||
|
|
||||||
// 2. If Type(obj) is not Object, throw a TypeError exception.
|
// 2. If Type(obj) is not Object, throw a TypeError exception.
|
||||||
if (!value.is_object())
|
if (!value.is_object())
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::NotAnObject, value.to_string_without_side_effects());
|
return vm.throw_completion<TypeError>(ErrorType::NotAnObject, value.to_string_without_side_effects());
|
||||||
|
|
||||||
auto& array_like = value.as_object();
|
auto& array_like = value.as_object();
|
||||||
|
|
||||||
|
@ -151,7 +151,7 @@ ThrowCompletionOr<FunctionObject*> species_constructor(GlobalObject& global_obje
|
||||||
|
|
||||||
// 3. If Type(C) is not Object, throw a TypeError exception.
|
// 3. If Type(C) is not Object, throw a TypeError exception.
|
||||||
if (!constructor.is_object())
|
if (!constructor.is_object())
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::NotAConstructor, constructor.to_string_without_side_effects());
|
return vm.throw_completion<TypeError>(ErrorType::NotAConstructor, constructor.to_string_without_side_effects());
|
||||||
|
|
||||||
// 4. Let S be ? Get(C, @@species).
|
// 4. Let S be ? Get(C, @@species).
|
||||||
auto species = TRY(constructor.as_object().get(*vm.well_known_symbol_species()));
|
auto species = TRY(constructor.as_object().get(*vm.well_known_symbol_species()));
|
||||||
|
@ -165,7 +165,7 @@ ThrowCompletionOr<FunctionObject*> species_constructor(GlobalObject& global_obje
|
||||||
return &species.as_function();
|
return &species.as_function();
|
||||||
|
|
||||||
// 7. Throw a TypeError exception.
|
// 7. Throw a TypeError exception.
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::NotAConstructor, species.to_string_without_side_effects());
|
return vm.throw_completion<TypeError>(ErrorType::NotAConstructor, species.to_string_without_side_effects());
|
||||||
}
|
}
|
||||||
|
|
||||||
// 7.3.25 GetFunctionRealm ( obj ), https://tc39.es/ecma262/#sec-getfunctionrealm
|
// 7.3.25 GetFunctionRealm ( obj ), https://tc39.es/ecma262/#sec-getfunctionrealm
|
||||||
|
@ -196,7 +196,7 @@ ThrowCompletionOr<Realm*> get_function_realm(GlobalObject& global_object, Functi
|
||||||
|
|
||||||
// a. If obj.[[ProxyHandler]] is null, throw a TypeError exception.
|
// a. If obj.[[ProxyHandler]] is null, throw a TypeError exception.
|
||||||
if (proxy.is_revoked())
|
if (proxy.is_revoked())
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::ProxyRevoked);
|
return vm.throw_completion<TypeError>(ErrorType::ProxyRevoked);
|
||||||
|
|
||||||
// b. Let proxyTarget be obj.[[ProxyTarget]].
|
// b. Let proxyTarget be obj.[[ProxyTarget]].
|
||||||
auto& proxy_target = proxy.target();
|
auto& proxy_target = proxy.target();
|
||||||
|
@ -595,7 +595,7 @@ ThrowCompletionOr<Value> perform_eval(GlobalObject& global_object, Value x, Call
|
||||||
// b. If script is a List of errors, throw a SyntaxError exception.
|
// b. If script is a List of errors, throw a SyntaxError exception.
|
||||||
if (parser.has_errors()) {
|
if (parser.has_errors()) {
|
||||||
auto& error = parser.errors()[0];
|
auto& error = parser.errors()[0];
|
||||||
return vm.throw_completion<SyntaxError>(global_object, error.to_string());
|
return vm.throw_completion<SyntaxError>(error.to_string());
|
||||||
}
|
}
|
||||||
|
|
||||||
bool strict_eval = false;
|
bool strict_eval = false;
|
||||||
|
@ -697,7 +697,7 @@ ThrowCompletionOr<Value> perform_eval(GlobalObject& global_object, Value x, Call
|
||||||
if (auto* bytecode_interpreter = Bytecode::Interpreter::current()) {
|
if (auto* bytecode_interpreter = Bytecode::Interpreter::current()) {
|
||||||
auto executable_result = Bytecode::Generator::generate(program);
|
auto executable_result = Bytecode::Generator::generate(program);
|
||||||
if (executable_result.is_error())
|
if (executable_result.is_error())
|
||||||
return vm.throw_completion<InternalError>(bytecode_interpreter->global_object(), ErrorType::NotImplemented, executable_result.error().to_string());
|
return vm.throw_completion<InternalError>(ErrorType::NotImplemented, executable_result.error().to_string());
|
||||||
|
|
||||||
auto executable = executable_result.release_value();
|
auto executable = executable_result.release_value();
|
||||||
executable->name = "eval"sv;
|
executable->name = "eval"sv;
|
||||||
|
@ -739,7 +739,7 @@ ThrowCompletionOr<void> eval_declaration_instantiation(VM& vm, GlobalObject& glo
|
||||||
TRY(program.for_each_var_declared_name([&](auto const& name) -> ThrowCompletionOr<void> {
|
TRY(program.for_each_var_declared_name([&](auto const& name) -> ThrowCompletionOr<void> {
|
||||||
// 1. If varEnv.HasLexicalDeclaration(name) is true, throw a SyntaxError exception.
|
// 1. If varEnv.HasLexicalDeclaration(name) is true, throw a SyntaxError exception.
|
||||||
if (global_var_environment->has_lexical_declaration(name))
|
if (global_var_environment->has_lexical_declaration(name))
|
||||||
return vm.throw_completion<SyntaxError>(global_object, ErrorType::TopLevelVariableAlreadyDeclared, name);
|
return vm.throw_completion<SyntaxError>(ErrorType::TopLevelVariableAlreadyDeclared, name);
|
||||||
|
|
||||||
// 2. NOTE: eval will not create a global var declaration that would be shadowed by a global lexical declaration.
|
// 2. NOTE: eval will not create a global var declaration that would be shadowed by a global lexical declaration.
|
||||||
return {};
|
return {};
|
||||||
|
@ -760,7 +760,7 @@ ThrowCompletionOr<void> eval_declaration_instantiation(VM& vm, GlobalObject& glo
|
||||||
// a. If ! thisEnv.HasBinding(name) is true, then
|
// a. If ! thisEnv.HasBinding(name) is true, then
|
||||||
if (MUST(this_environment->has_binding(name))) {
|
if (MUST(this_environment->has_binding(name))) {
|
||||||
// i. Throw a SyntaxError exception.
|
// i. Throw a SyntaxError exception.
|
||||||
return vm.throw_completion<SyntaxError>(global_object, ErrorType::TopLevelVariableAlreadyDeclared, name);
|
return vm.throw_completion<SyntaxError>(ErrorType::TopLevelVariableAlreadyDeclared, name);
|
||||||
|
|
||||||
// FIXME: ii. NOTE: Annex B.3.4 defines alternate semantics for the above step.
|
// FIXME: ii. NOTE: Annex B.3.4 defines alternate semantics for the above step.
|
||||||
// In particular it only throw the syntax error if it is not an environment from a catchclause.
|
// In particular it only throw the syntax error if it is not an environment from a catchclause.
|
||||||
|
@ -811,7 +811,7 @@ ThrowCompletionOr<void> eval_declaration_instantiation(VM& vm, GlobalObject& glo
|
||||||
|
|
||||||
// b. If fnDefinable is false, throw a TypeError exception.
|
// b. If fnDefinable is false, throw a TypeError exception.
|
||||||
if (!function_definable)
|
if (!function_definable)
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::CannotDeclareGlobalFunction, function.name());
|
return vm.throw_completion<TypeError>(ErrorType::CannotDeclareGlobalFunction, function.name());
|
||||||
}
|
}
|
||||||
|
|
||||||
// 2. Append fn to declaredFunctionNames.
|
// 2. Append fn to declaredFunctionNames.
|
||||||
|
@ -937,7 +937,7 @@ ThrowCompletionOr<void> eval_declaration_instantiation(VM& vm, GlobalObject& glo
|
||||||
|
|
||||||
// ii. If vnDefinable is false, throw a TypeError exception.
|
// ii. If vnDefinable is false, throw a TypeError exception.
|
||||||
if (!variable_definable)
|
if (!variable_definable)
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::CannotDeclareGlobalVariable, name);
|
return vm.throw_completion<TypeError>(ErrorType::CannotDeclareGlobalVariable, name);
|
||||||
}
|
}
|
||||||
|
|
||||||
// b. If vn is not an element of declaredVarNames, then
|
// b. If vn is not an element of declaredVarNames, then
|
||||||
|
|
|
@ -23,7 +23,7 @@ ThrowCompletionOr<Array*> Array::create(Realm& realm, u64 length, Object* protot
|
||||||
|
|
||||||
// 1. If length > 2^32 - 1, throw a RangeError exception.
|
// 1. If length > 2^32 - 1, throw a RangeError exception.
|
||||||
if (length > NumericLimits<u32>::max())
|
if (length > NumericLimits<u32>::max())
|
||||||
return vm.throw_completion<RangeError>(realm.global_object(), ErrorType::InvalidLength, "array");
|
return vm.throw_completion<RangeError>(ErrorType::InvalidLength, "array");
|
||||||
|
|
||||||
// 2. If proto is not present, set proto to %Array.prototype%.
|
// 2. If proto is not present, set proto to %Array.prototype%.
|
||||||
if (!prototype)
|
if (!prototype)
|
||||||
|
@ -84,7 +84,7 @@ ThrowCompletionOr<bool> Array::set_length(PropertyDescriptor const& property_des
|
||||||
auto number_length = TRY(property_descriptor.value->to_number(global_object));
|
auto number_length = TRY(property_descriptor.value->to_number(global_object));
|
||||||
// 5. If newLen is not the same value as numberLen, throw a RangeError exception.
|
// 5. If newLen is not the same value as numberLen, throw a RangeError exception.
|
||||||
if (new_length != number_length.as_double())
|
if (new_length != number_length.as_double())
|
||||||
return vm.throw_completion<RangeError>(global_object, ErrorType::InvalidLength, "array");
|
return vm.throw_completion<RangeError>(ErrorType::InvalidLength, "array");
|
||||||
}
|
}
|
||||||
|
|
||||||
// 6. Set newLenDesc.[[Value]] to newLen.
|
// 6. Set newLenDesc.[[Value]] to newLen.
|
||||||
|
|
|
@ -15,7 +15,7 @@ ThrowCompletionOr<ArrayBuffer*> ArrayBuffer::create(Realm& realm, size_t byte_le
|
||||||
{
|
{
|
||||||
auto buffer = ByteBuffer::create_zeroed(byte_length);
|
auto buffer = ByteBuffer::create_zeroed(byte_length);
|
||||||
if (buffer.is_error())
|
if (buffer.is_error())
|
||||||
return realm.vm().throw_completion<RangeError>(realm.global_object(), ErrorType::NotEnoughMemoryToAllocate, byte_length);
|
return realm.vm().throw_completion<RangeError>(ErrorType::NotEnoughMemoryToAllocate, byte_length);
|
||||||
|
|
||||||
return realm.heap().allocate<ArrayBuffer>(realm, buffer.release_value(), *realm.global_object().array_buffer_prototype());
|
return realm.heap().allocate<ArrayBuffer>(realm, buffer.release_value(), *realm.global_object().array_buffer_prototype());
|
||||||
}
|
}
|
||||||
|
@ -59,7 +59,7 @@ ThrowCompletionOr<ArrayBuffer*> allocate_array_buffer(GlobalObject& global_objec
|
||||||
// 2. Let block be ? CreateByteDataBlock(byteLength).
|
// 2. Let block be ? CreateByteDataBlock(byteLength).
|
||||||
auto block = ByteBuffer::create_zeroed(byte_length);
|
auto block = ByteBuffer::create_zeroed(byte_length);
|
||||||
if (block.is_error())
|
if (block.is_error())
|
||||||
return global_object.vm().throw_completion<RangeError>(global_object, ErrorType::NotEnoughMemoryToAllocate, byte_length);
|
return global_object.vm().throw_completion<RangeError>(ErrorType::NotEnoughMemoryToAllocate, byte_length);
|
||||||
|
|
||||||
// 3. Set obj.[[ArrayBufferData]] to block.
|
// 3. Set obj.[[ArrayBufferData]] to block.
|
||||||
obj->set_buffer(block.release_value());
|
obj->set_buffer(block.release_value());
|
||||||
|
@ -84,7 +84,7 @@ ThrowCompletionOr<void> detach_array_buffer(GlobalObject& global_object, ArrayBu
|
||||||
|
|
||||||
// 3. If SameValue(arrayBuffer.[[ArrayBufferDetachKey]], key) is false, throw a TypeError exception.
|
// 3. If SameValue(arrayBuffer.[[ArrayBufferDetachKey]], key) is false, throw a TypeError exception.
|
||||||
if (!same_value(array_buffer.detach_key(), *key))
|
if (!same_value(array_buffer.detach_key(), *key))
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::DetachKeyMismatch, *key, array_buffer.detach_key());
|
return vm.throw_completion<TypeError>(ErrorType::DetachKeyMismatch, *key, array_buffer.detach_key());
|
||||||
|
|
||||||
// 4. Set arrayBuffer.[[ArrayBufferData]] to null.
|
// 4. Set arrayBuffer.[[ArrayBufferData]] to null.
|
||||||
// 5. Set arrayBuffer.[[ArrayBufferByteLength]] to 0.
|
// 5. Set arrayBuffer.[[ArrayBufferByteLength]] to 0.
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2020, Linus Groh <linusg@serenityos.org>
|
* Copyright (c) 2020-2022, Linus Groh <linusg@serenityos.org>
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: BSD-2-Clause
|
* SPDX-License-Identifier: BSD-2-Clause
|
||||||
*/
|
*/
|
||||||
|
@ -39,7 +39,7 @@ void ArrayBufferConstructor::initialize(Realm& realm)
|
||||||
ThrowCompletionOr<Value> ArrayBufferConstructor::call()
|
ThrowCompletionOr<Value> ArrayBufferConstructor::call()
|
||||||
{
|
{
|
||||||
auto& vm = this->vm();
|
auto& vm = this->vm();
|
||||||
return vm.throw_completion<TypeError>(global_object(), ErrorType::ConstructorWithoutNew, vm.names.ArrayBuffer);
|
return vm.throw_completion<TypeError>(ErrorType::ConstructorWithoutNew, vm.names.ArrayBuffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 25.1.3.1 ArrayBuffer ( length ), https://tc39.es/ecma262/#sec-arraybuffer-length
|
// 25.1.3.1 ArrayBuffer ( length ), https://tc39.es/ecma262/#sec-arraybuffer-length
|
||||||
|
@ -52,7 +52,7 @@ ThrowCompletionOr<Object*> ArrayBufferConstructor::construct(FunctionObject& new
|
||||||
auto error = byte_length_or_error.release_error();
|
auto error = byte_length_or_error.release_error();
|
||||||
if (error.value()->is_object() && is<RangeError>(error.value()->as_object())) {
|
if (error.value()->is_object() && is<RangeError>(error.value()->as_object())) {
|
||||||
// Re-throw more specific RangeError
|
// Re-throw more specific RangeError
|
||||||
return vm.throw_completion<RangeError>(global_object(), ErrorType::InvalidLength, "array buffer");
|
return vm.throw_completion<RangeError>(ErrorType::InvalidLength, "array buffer");
|
||||||
}
|
}
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2020, Linus Groh <linusg@serenityos.org>
|
* Copyright (c) 2020-2022, Linus Groh <linusg@serenityos.org>
|
||||||
* Copyright (c) 2021-2022, Jamie Mansfield <jmansfield@cadixdev.org>
|
* Copyright (c) 2021-2022, Jamie Mansfield <jmansfield@cadixdev.org>
|
||||||
* Copyright (c) 2021, Idan Horowitz <idan.horowitz@serenityos.org>
|
* Copyright (c) 2021, Idan Horowitz <idan.horowitz@serenityos.org>
|
||||||
*
|
*
|
||||||
|
@ -43,7 +43,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayBufferPrototype::slice)
|
||||||
|
|
||||||
// 4. If IsDetachedBuffer(O) is true, throw a TypeError exception.
|
// 4. If IsDetachedBuffer(O) is true, throw a TypeError exception.
|
||||||
if (array_buffer_object->is_detached())
|
if (array_buffer_object->is_detached())
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::DetachedArrayBuffer);
|
return vm.throw_completion<TypeError>(ErrorType::DetachedArrayBuffer);
|
||||||
|
|
||||||
// 5. Let len be O.[[ArrayBufferByteLength]].
|
// 5. Let len be O.[[ArrayBufferByteLength]].
|
||||||
auto length = array_buffer_object->byte_length();
|
auto length = array_buffer_object->byte_length();
|
||||||
|
@ -87,7 +87,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayBufferPrototype::slice)
|
||||||
|
|
||||||
// 17. Perform ? RequireInternalSlot(new, [[ArrayBufferData]]).
|
// 17. Perform ? RequireInternalSlot(new, [[ArrayBufferData]]).
|
||||||
if (!is<ArrayBuffer>(new_array_buffer))
|
if (!is<ArrayBuffer>(new_array_buffer))
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::SpeciesConstructorDidNotCreate, "an ArrayBuffer");
|
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);
|
||||||
|
|
||||||
// 18. If IsSharedArrayBuffer(new) is true, throw a TypeError exception.
|
// 18. If IsSharedArrayBuffer(new) is true, throw a TypeError exception.
|
||||||
|
@ -95,20 +95,20 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayBufferPrototype::slice)
|
||||||
|
|
||||||
// 19. If IsDetachedBuffer(new) is true, throw a TypeError exception.
|
// 19. If IsDetachedBuffer(new) is true, throw a TypeError exception.
|
||||||
if (new_array_buffer_object->is_detached())
|
if (new_array_buffer_object->is_detached())
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::SpeciesConstructorReturned, "a detached ArrayBuffer");
|
return vm.throw_completion<TypeError>(ErrorType::SpeciesConstructorReturned, "a detached ArrayBuffer");
|
||||||
|
|
||||||
// 20. If SameValue(new, O) is true, throw a TypeError exception.
|
// 20. If SameValue(new, O) is true, throw a TypeError exception.
|
||||||
if (same_value(new_array_buffer_object, array_buffer_object))
|
if (same_value(new_array_buffer_object, array_buffer_object))
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::SpeciesConstructorReturned, "same ArrayBuffer instance");
|
return vm.throw_completion<TypeError>(ErrorType::SpeciesConstructorReturned, "same ArrayBuffer instance");
|
||||||
|
|
||||||
// 21. If new.[[ArrayBufferByteLength]] < newLen, throw a TypeError exception.
|
// 21. If new.[[ArrayBufferByteLength]] < newLen, throw a TypeError exception.
|
||||||
if (new_array_buffer_object->byte_length() < new_length)
|
if (new_array_buffer_object->byte_length() < new_length)
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::SpeciesConstructorReturned, "an ArrayBuffer smaller than requested");
|
return vm.throw_completion<TypeError>(ErrorType::SpeciesConstructorReturned, "an ArrayBuffer smaller than requested");
|
||||||
|
|
||||||
// 22. NOTE: Side-effects of the above steps may have detached O.
|
// 22. NOTE: Side-effects of the above steps may have detached O.
|
||||||
// 23. If IsDetachedBuffer(O) is true, throw a TypeError exception.
|
// 23. If IsDetachedBuffer(O) is true, throw a TypeError exception.
|
||||||
if (array_buffer_object->is_detached())
|
if (array_buffer_object->is_detached())
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::DetachedArrayBuffer);
|
return vm.throw_completion<TypeError>(ErrorType::DetachedArrayBuffer);
|
||||||
|
|
||||||
// 24. Let fromBuf be O.[[ArrayBufferData]].
|
// 24. Let fromBuf be O.[[ArrayBufferData]].
|
||||||
// 25. Let toBuf be new.[[ArrayBufferData]].
|
// 25. Let toBuf be new.[[ArrayBufferData]].
|
||||||
|
|
|
@ -68,7 +68,7 @@ ThrowCompletionOr<Object*> ArrayConstructor::construct(FunctionObject& new_targe
|
||||||
} else {
|
} else {
|
||||||
int_length = MUST(length.to_u32(global_object));
|
int_length = MUST(length.to_u32(global_object));
|
||||||
if (int_length != length.as_double())
|
if (int_length != length.as_double())
|
||||||
return vm.throw_completion<RangeError>(global_object, ErrorType::InvalidLength, "array");
|
return vm.throw_completion<RangeError>(ErrorType::InvalidLength, "array");
|
||||||
}
|
}
|
||||||
TRY(array->set(vm.names.length, Value(int_length), Object::ShouldThrowExceptions::Yes));
|
TRY(array->set(vm.names.length, Value(int_length), Object::ShouldThrowExceptions::Yes));
|
||||||
return array;
|
return array;
|
||||||
|
@ -92,7 +92,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayConstructor::from)
|
||||||
if (!vm.argument(1).is_undefined()) {
|
if (!vm.argument(1).is_undefined()) {
|
||||||
auto callback = vm.argument(1);
|
auto callback = vm.argument(1);
|
||||||
if (!callback.is_function())
|
if (!callback.is_function())
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::NotAFunction, callback.to_string_without_side_effects());
|
return vm.throw_completion<TypeError>(ErrorType::NotAFunction, callback.to_string_without_side_effects());
|
||||||
map_fn = &callback.as_function();
|
map_fn = &callback.as_function();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -112,7 +112,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayConstructor::from)
|
||||||
size_t k = 0;
|
size_t k = 0;
|
||||||
while (true) {
|
while (true) {
|
||||||
if (k >= MAX_ARRAY_LIKE_INDEX) {
|
if (k >= MAX_ARRAY_LIKE_INDEX) {
|
||||||
auto error = vm.throw_completion<TypeError>(global_object, ErrorType::ArrayMaxSize);
|
auto error = vm.throw_completion<TypeError>(ErrorType::ArrayMaxSize);
|
||||||
return TRY(iterator_close(global_object, iterator, move(error)));
|
return TRY(iterator_close(global_object, iterator, move(error)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -52,7 +52,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayIteratorPrototype::next)
|
||||||
auto& typed_array = static_cast<TypedArrayBase&>(array);
|
auto& typed_array = static_cast<TypedArrayBase&>(array);
|
||||||
|
|
||||||
if (typed_array.viewed_array_buffer()->is_detached())
|
if (typed_array.viewed_array_buffer()->is_detached())
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::DetachedArrayBuffer);
|
return vm.throw_completion<TypeError>(ErrorType::DetachedArrayBuffer);
|
||||||
|
|
||||||
length = typed_array.array_length();
|
length = typed_array.array_length();
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -144,7 +144,7 @@ static ThrowCompletionOr<Object*> array_species_create(GlobalObject& global_obje
|
||||||
return TRY(Array::create(realm, length));
|
return TRY(Array::create(realm, length));
|
||||||
|
|
||||||
if (!constructor.is_constructor())
|
if (!constructor.is_constructor())
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::NotAConstructor, constructor.to_string_without_side_effects());
|
return vm.throw_completion<TypeError>(ErrorType::NotAConstructor, constructor.to_string_without_side_effects());
|
||||||
|
|
||||||
return TRY(construct(global_object, constructor.as_function(), Value(length)));
|
return TRY(construct(global_object, constructor.as_function(), Value(length)));
|
||||||
}
|
}
|
||||||
|
@ -199,7 +199,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::concat)
|
||||||
auto length = TRY(length_of_array_like(global_object, obj));
|
auto length = TRY(length_of_array_like(global_object, obj));
|
||||||
|
|
||||||
if (n + length > MAX_ARRAY_LIKE_INDEX)
|
if (n + length > MAX_ARRAY_LIKE_INDEX)
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::ArrayMaxSize);
|
return vm.throw_completion<TypeError>(ErrorType::ArrayMaxSize);
|
||||||
while (k < length) {
|
while (k < length) {
|
||||||
auto k_exists = TRY(obj.has_property(k));
|
auto k_exists = TRY(obj.has_property(k));
|
||||||
if (k_exists) {
|
if (k_exists) {
|
||||||
|
@ -211,7 +211,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::concat)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (n >= MAX_ARRAY_LIKE_INDEX)
|
if (n >= MAX_ARRAY_LIKE_INDEX)
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::ArrayMaxSize);
|
return vm.throw_completion<TypeError>(ErrorType::ArrayMaxSize);
|
||||||
TRY(new_array->create_data_property_or_throw(n, arg));
|
TRY(new_array->create_data_property_or_throw(n, arg));
|
||||||
++n;
|
++n;
|
||||||
}
|
}
|
||||||
|
@ -317,7 +317,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::every)
|
||||||
|
|
||||||
// 3. If IsCallable(callbackfn) is false, throw a TypeError exception.
|
// 3. If IsCallable(callbackfn) is false, throw a TypeError exception.
|
||||||
if (!callback_function.is_function())
|
if (!callback_function.is_function())
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::NotAFunction, callback_function.to_string_without_side_effects());
|
return vm.throw_completion<TypeError>(ErrorType::NotAFunction, callback_function.to_string_without_side_effects());
|
||||||
|
|
||||||
// 4. Let k be 0.
|
// 4. Let k be 0.
|
||||||
// 5. Repeat, while k < len,
|
// 5. Repeat, while k < len,
|
||||||
|
@ -403,7 +403,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::filter)
|
||||||
|
|
||||||
// 3. If IsCallable(callbackfn) is false, throw a TypeError exception.
|
// 3. If IsCallable(callbackfn) is false, throw a TypeError exception.
|
||||||
if (!callback_function.is_function())
|
if (!callback_function.is_function())
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::NotAFunction, callback_function.to_string_without_side_effects());
|
return vm.throw_completion<TypeError>(ErrorType::NotAFunction, callback_function.to_string_without_side_effects());
|
||||||
|
|
||||||
// 4. Let A be ? ArraySpeciesCreate(O, 0).
|
// 4. Let A be ? ArraySpeciesCreate(O, 0).
|
||||||
auto* array = TRY(array_species_create(global_object, *object, 0));
|
auto* array = TRY(array_species_create(global_object, *object, 0));
|
||||||
|
@ -461,7 +461,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::find)
|
||||||
|
|
||||||
// 3. If IsCallable(predicate) is false, throw a TypeError exception.
|
// 3. If IsCallable(predicate) is false, throw a TypeError exception.
|
||||||
if (!predicate.is_function())
|
if (!predicate.is_function())
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::NotAFunction, predicate.to_string_without_side_effects());
|
return vm.throw_completion<TypeError>(ErrorType::NotAFunction, predicate.to_string_without_side_effects());
|
||||||
|
|
||||||
// 4. Let k be 0.
|
// 4. Let k be 0.
|
||||||
// 5. Repeat, while k < len,
|
// 5. Repeat, while k < len,
|
||||||
|
@ -500,7 +500,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::find_index)
|
||||||
|
|
||||||
// 3. If IsCallable(predicate) is false, throw a TypeError exception.
|
// 3. If IsCallable(predicate) is false, throw a TypeError exception.
|
||||||
if (!predicate.is_function())
|
if (!predicate.is_function())
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::NotAFunction, predicate.to_string_without_side_effects());
|
return vm.throw_completion<TypeError>(ErrorType::NotAFunction, predicate.to_string_without_side_effects());
|
||||||
|
|
||||||
// 4. Let k be 0.
|
// 4. Let k be 0.
|
||||||
// 5. Repeat, while k < len,
|
// 5. Repeat, while k < len,
|
||||||
|
@ -539,7 +539,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::find_last)
|
||||||
|
|
||||||
// 3. If IsCallable(predicate) is false, throw a TypeError exception.
|
// 3. If IsCallable(predicate) is false, throw a TypeError exception.
|
||||||
if (!predicate.is_function())
|
if (!predicate.is_function())
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::NotAFunction, predicate.to_string_without_side_effects());
|
return vm.throw_completion<TypeError>(ErrorType::NotAFunction, predicate.to_string_without_side_effects());
|
||||||
|
|
||||||
// 4. Let k be len - 1.
|
// 4. Let k be len - 1.
|
||||||
// 5. Repeat, while k ≥ 0,
|
// 5. Repeat, while k ≥ 0,
|
||||||
|
@ -578,7 +578,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::find_last_index)
|
||||||
|
|
||||||
// 3. If IsCallable(predicate) is false, throw a TypeError exception.
|
// 3. If IsCallable(predicate) is false, throw a TypeError exception.
|
||||||
if (!predicate.is_function())
|
if (!predicate.is_function())
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::NotAFunction, predicate.to_string_without_side_effects());
|
return vm.throw_completion<TypeError>(ErrorType::NotAFunction, predicate.to_string_without_side_effects());
|
||||||
|
|
||||||
// 4. Let k be len - 1.
|
// 4. Let k be len - 1.
|
||||||
// 5. Repeat, while k ≥ 0,
|
// 5. Repeat, while k ≥ 0,
|
||||||
|
@ -621,7 +621,7 @@ static ThrowCompletionOr<size_t> flatten_into_array(GlobalObject& global_object,
|
||||||
|
|
||||||
if (depth > 0 && TRY(value.is_array(global_object))) {
|
if (depth > 0 && TRY(value.is_array(global_object))) {
|
||||||
if (vm.did_reach_stack_space_limit())
|
if (vm.did_reach_stack_space_limit())
|
||||||
return vm.throw_completion<InternalError>(global_object, ErrorType::CallStackSizeExceeded);
|
return vm.throw_completion<InternalError>(ErrorType::CallStackSizeExceeded);
|
||||||
|
|
||||||
auto length = TRY(length_of_array_like(global_object, value.as_object()));
|
auto length = TRY(length_of_array_like(global_object, value.as_object()));
|
||||||
target_index = TRY(flatten_into_array(global_object, new_array, value.as_object(), length, target_index, depth - 1));
|
target_index = TRY(flatten_into_array(global_object, new_array, value.as_object(), length, target_index, depth - 1));
|
||||||
|
@ -629,7 +629,7 @@ static ThrowCompletionOr<size_t> flatten_into_array(GlobalObject& global_object,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (target_index >= MAX_ARRAY_LIKE_INDEX)
|
if (target_index >= MAX_ARRAY_LIKE_INDEX)
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::InvalidIndex);
|
return vm.throw_completion<TypeError>(ErrorType::InvalidIndex);
|
||||||
|
|
||||||
TRY(new_array.create_data_property_or_throw(target_index, value));
|
TRY(new_array.create_data_property_or_throw(target_index, value));
|
||||||
|
|
||||||
|
@ -671,7 +671,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::flat_map)
|
||||||
|
|
||||||
// 3. If IsCallable(mapperFunction) is false, throw a TypeError exception.
|
// 3. If IsCallable(mapperFunction) is false, throw a TypeError exception.
|
||||||
if (!mapper_function.is_function())
|
if (!mapper_function.is_function())
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::NotAFunction, mapper_function.to_string_without_side_effects());
|
return vm.throw_completion<TypeError>(ErrorType::NotAFunction, mapper_function.to_string_without_side_effects());
|
||||||
|
|
||||||
// 4. Let A be ? ArraySpeciesCreate(O, 0).
|
// 4. Let A be ? ArraySpeciesCreate(O, 0).
|
||||||
auto* array = TRY(array_species_create(global_object, *object, 0));
|
auto* array = TRY(array_species_create(global_object, *object, 0));
|
||||||
|
@ -697,7 +697,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::for_each)
|
||||||
|
|
||||||
// 3. If IsCallable(callbackfn) is false, throw a TypeError exception.
|
// 3. If IsCallable(callbackfn) is false, throw a TypeError exception.
|
||||||
if (!callback_function.is_function())
|
if (!callback_function.is_function())
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::NotAFunction, callback_function.to_string_without_side_effects());
|
return vm.throw_completion<TypeError>(ErrorType::NotAFunction, callback_function.to_string_without_side_effects());
|
||||||
|
|
||||||
// 4. Let k be 0.
|
// 4. Let k be 0.
|
||||||
// 5. Repeat, while k < len,
|
// 5. Repeat, while k < len,
|
||||||
|
@ -768,7 +768,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::group)
|
||||||
|
|
||||||
// 3. If IsCallable(callbackfn) is false, throw a TypeError exception.
|
// 3. If IsCallable(callbackfn) is false, throw a TypeError exception.
|
||||||
if (!callback_function.is_function())
|
if (!callback_function.is_function())
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::NotAFunction, callback_function.to_string_without_side_effects());
|
return vm.throw_completion<TypeError>(ErrorType::NotAFunction, callback_function.to_string_without_side_effects());
|
||||||
|
|
||||||
// 5. Let groups be a new empty List.
|
// 5. Let groups be a new empty List.
|
||||||
OrderedHashMap<PropertyKey, MarkedVector<Value>> groups;
|
OrderedHashMap<PropertyKey, MarkedVector<Value>> groups;
|
||||||
|
@ -824,7 +824,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::group_to_map)
|
||||||
|
|
||||||
// 3. If IsCallable(callbackfn) is false, throw a TypeError exception.
|
// 3. If IsCallable(callbackfn) is false, throw a TypeError exception.
|
||||||
if (!callback_function.is_function())
|
if (!callback_function.is_function())
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::NotAFunction, callback_function.to_string_without_side_effects());
|
return vm.throw_completion<TypeError>(ErrorType::NotAFunction, callback_function.to_string_without_side_effects());
|
||||||
|
|
||||||
struct KeyedGroupTraits : public Traits<Handle<Value>> {
|
struct KeyedGroupTraits : public Traits<Handle<Value>> {
|
||||||
static unsigned hash(Handle<Value> const& value_handle)
|
static unsigned hash(Handle<Value> const& value_handle)
|
||||||
|
@ -1109,7 +1109,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::map)
|
||||||
|
|
||||||
// 3. If IsCallable(callbackfn) is false, throw a TypeError exception.
|
// 3. If IsCallable(callbackfn) is false, throw a TypeError exception.
|
||||||
if (!callback_function.is_function())
|
if (!callback_function.is_function())
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::NotAFunction, callback_function.to_string_without_side_effects());
|
return vm.throw_completion<TypeError>(ErrorType::NotAFunction, callback_function.to_string_without_side_effects());
|
||||||
|
|
||||||
// 4. Let A be ? ArraySpeciesCreate(O, len).
|
// 4. Let A be ? ArraySpeciesCreate(O, len).
|
||||||
auto* array = TRY(array_species_create(global_object, *object, length));
|
auto* array = TRY(array_species_create(global_object, *object, length));
|
||||||
|
@ -1166,7 +1166,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::push)
|
||||||
auto argument_count = vm.argument_count();
|
auto argument_count = vm.argument_count();
|
||||||
auto new_length = length + argument_count;
|
auto new_length = length + argument_count;
|
||||||
if (new_length > MAX_ARRAY_LIKE_INDEX)
|
if (new_length > MAX_ARRAY_LIKE_INDEX)
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::ArrayMaxSize);
|
return vm.throw_completion<TypeError>(ErrorType::ArrayMaxSize);
|
||||||
for (size_t i = 0; i < argument_count; ++i)
|
for (size_t i = 0; i < argument_count; ++i)
|
||||||
TRY(this_object->set(length + i, vm.argument(i), Object::ShouldThrowExceptions::Yes));
|
TRY(this_object->set(length + i, vm.argument(i), Object::ShouldThrowExceptions::Yes));
|
||||||
auto new_length_value = Value(new_length);
|
auto new_length_value = Value(new_length);
|
||||||
|
@ -1188,11 +1188,11 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::reduce)
|
||||||
|
|
||||||
// 3. If IsCallable(callbackfn) is false, throw a TypeError exception.
|
// 3. If IsCallable(callbackfn) is false, throw a TypeError exception.
|
||||||
if (!callback_function.is_function())
|
if (!callback_function.is_function())
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::NotAFunction, callback_function.to_string_without_side_effects());
|
return vm.throw_completion<TypeError>(ErrorType::NotAFunction, callback_function.to_string_without_side_effects());
|
||||||
|
|
||||||
// 4. If len = 0 and initialValue is not present, throw a TypeError exception.
|
// 4. If len = 0 and initialValue is not present, throw a TypeError exception.
|
||||||
if (length == 0 && vm.argument_count() <= 1)
|
if (length == 0 && vm.argument_count() <= 1)
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::ReduceNoInitial);
|
return vm.throw_completion<TypeError>(ErrorType::ReduceNoInitial);
|
||||||
|
|
||||||
// 5. Let k be 0.
|
// 5. Let k be 0.
|
||||||
size_t k = 0;
|
size_t k = 0;
|
||||||
|
@ -1229,7 +1229,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::reduce)
|
||||||
|
|
||||||
// c. If kPresent is false, throw a TypeError exception.
|
// c. If kPresent is false, throw a TypeError exception.
|
||||||
if (!k_present)
|
if (!k_present)
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::ReduceNoInitial);
|
return vm.throw_completion<TypeError>(ErrorType::ReduceNoInitial);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 9. Repeat, while k < len,
|
// 9. Repeat, while k < len,
|
||||||
|
@ -1270,11 +1270,11 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::reduce_right)
|
||||||
|
|
||||||
// 3. If IsCallable(callbackfn) is false, throw a TypeError exception.
|
// 3. If IsCallable(callbackfn) is false, throw a TypeError exception.
|
||||||
if (!callback_function.is_function())
|
if (!callback_function.is_function())
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::NotAFunction, callback_function.to_string_without_side_effects());
|
return vm.throw_completion<TypeError>(ErrorType::NotAFunction, callback_function.to_string_without_side_effects());
|
||||||
|
|
||||||
// 4. If len = 0 and initialValue is not present, throw a TypeError exception.
|
// 4. If len = 0 and initialValue is not present, throw a TypeError exception.
|
||||||
if (length == 0 && vm.argument_count() <= 1)
|
if (length == 0 && vm.argument_count() <= 1)
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::ReduceNoInitial);
|
return vm.throw_completion<TypeError>(ErrorType::ReduceNoInitial);
|
||||||
|
|
||||||
// 5. Let k be len - 1.
|
// 5. Let k be len - 1.
|
||||||
ssize_t k = length - 1;
|
ssize_t k = length - 1;
|
||||||
|
@ -1311,7 +1311,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::reduce_right)
|
||||||
|
|
||||||
// c. If kPresent is false, throw a TypeError exception.
|
// c. If kPresent is false, throw a TypeError exception.
|
||||||
if (!k_present)
|
if (!k_present)
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::ReduceNoInitial);
|
return vm.throw_completion<TypeError>(ErrorType::ReduceNoInitial);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 9. Repeat, while k ≥ 0,
|
// 9. Repeat, while k ≥ 0,
|
||||||
|
@ -1470,7 +1470,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::some)
|
||||||
|
|
||||||
// 3. If IsCallable(callbackfn) is false, throw a TypeError exception.
|
// 3. If IsCallable(callbackfn) is false, throw a TypeError exception.
|
||||||
if (!callback_function.is_function())
|
if (!callback_function.is_function())
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::NotAFunction, callback_function.to_string_without_side_effects());
|
return vm.throw_completion<TypeError>(ErrorType::NotAFunction, callback_function.to_string_without_side_effects());
|
||||||
|
|
||||||
// 4. Let k be 0.
|
// 4. Let k be 0.
|
||||||
// 5. Repeat, while k < len,
|
// 5. Repeat, while k < len,
|
||||||
|
@ -1566,7 +1566,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::sort)
|
||||||
// 1. If comparefn is not undefined and IsCallable(comparefn) is false, throw a TypeError exception.
|
// 1. If comparefn is not undefined and IsCallable(comparefn) is false, throw a TypeError exception.
|
||||||
auto comparefn = vm.argument(0);
|
auto comparefn = vm.argument(0);
|
||||||
if (!comparefn.is_undefined() && !comparefn.is_function())
|
if (!comparefn.is_undefined() && !comparefn.is_function())
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::NotAFunction, comparefn.to_string_without_side_effects());
|
return vm.throw_completion<TypeError>(ErrorType::NotAFunction, comparefn.to_string_without_side_effects());
|
||||||
|
|
||||||
// 2. Let obj be ? ToObject(this value).
|
// 2. Let obj be ? ToObject(this value).
|
||||||
auto* object = TRY(vm.this_value(global_object).to_object(global_object));
|
auto* object = TRY(vm.this_value(global_object).to_object(global_object));
|
||||||
|
@ -1642,7 +1642,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::splice)
|
||||||
double new_length = initial_length + insert_count - actual_delete_count;
|
double new_length = initial_length + insert_count - actual_delete_count;
|
||||||
|
|
||||||
if (new_length > MAX_ARRAY_LIKE_INDEX)
|
if (new_length > MAX_ARRAY_LIKE_INDEX)
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::ArrayMaxSize);
|
return vm.throw_completion<TypeError>(ErrorType::ArrayMaxSize);
|
||||||
|
|
||||||
auto* removed_elements = TRY(array_species_create(global_object, *this_object, actual_delete_count));
|
auto* removed_elements = TRY(array_species_create(global_object, *this_object, actual_delete_count));
|
||||||
|
|
||||||
|
@ -1795,7 +1795,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::to_sorted)
|
||||||
|
|
||||||
// 1. If comparefn is not undefined and IsCallable(comparefn) is false, throw a TypeError exception.
|
// 1. If comparefn is not undefined and IsCallable(comparefn) is false, throw a TypeError exception.
|
||||||
if (!comparefn.is_undefined() && !comparefn.is_function())
|
if (!comparefn.is_undefined() && !comparefn.is_function())
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::NotAFunction, comparefn);
|
return vm.throw_completion<TypeError>(ErrorType::NotAFunction, comparefn);
|
||||||
|
|
||||||
// 2. Let O be ? ToObject(this value).
|
// 2. Let O be ? ToObject(this value).
|
||||||
auto* object = TRY(vm.this_value(global_object).to_object(global_object));
|
auto* object = TRY(vm.this_value(global_object).to_object(global_object));
|
||||||
|
@ -1892,7 +1892,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::to_spliced)
|
||||||
|
|
||||||
// 12. If newLen > 2^53 - 1, throw a TypeError exception.
|
// 12. If newLen > 2^53 - 1, throw a TypeError exception.
|
||||||
if (new_length_double > MAX_ARRAY_LIKE_INDEX)
|
if (new_length_double > MAX_ARRAY_LIKE_INDEX)
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::ArrayMaxSize);
|
return vm.throw_completion<TypeError>(ErrorType::ArrayMaxSize);
|
||||||
|
|
||||||
auto new_length = static_cast<u64>(new_length_double);
|
auto new_length = static_cast<u64>(new_length_double);
|
||||||
|
|
||||||
|
@ -1985,7 +1985,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::unshift)
|
||||||
size_t new_length = length + arg_count;
|
size_t new_length = length + arg_count;
|
||||||
if (arg_count > 0) {
|
if (arg_count > 0) {
|
||||||
if (new_length > MAX_ARRAY_LIKE_INDEX)
|
if (new_length > MAX_ARRAY_LIKE_INDEX)
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::ArrayMaxSize);
|
return vm.throw_completion<TypeError>(ErrorType::ArrayMaxSize);
|
||||||
|
|
||||||
for (size_t k = length; k > 0; --k) {
|
for (size_t k = length; k > 0; --k) {
|
||||||
auto from = k - 1;
|
auto from = k - 1;
|
||||||
|
@ -2046,7 +2046,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::with)
|
||||||
|
|
||||||
// 6. If actualIndex ≥ len or actualIndex < 0, throw a RangeError exception.
|
// 6. If actualIndex ≥ len or actualIndex < 0, throw a RangeError exception.
|
||||||
if (actual_index >= static_cast<double>(length) || actual_index < 0)
|
if (actual_index >= static_cast<double>(length) || actual_index < 0)
|
||||||
return vm.throw_completion<RangeError>(global_object, ErrorType::IndexOutOfRange, actual_index, length);
|
return vm.throw_completion<RangeError>(ErrorType::IndexOutOfRange, actual_index, length);
|
||||||
|
|
||||||
// 7. Let A be ? ArrayCreate(𝔽(len)).
|
// 7. Let A be ? ArrayCreate(𝔽(len)).
|
||||||
auto* array = TRY(Array::create(realm, length));
|
auto* array = TRY(Array::create(realm, length));
|
||||||
|
|
|
@ -33,14 +33,14 @@ static ThrowCompletionOr<ArrayBuffer*> validate_integer_typed_array(GlobalObject
|
||||||
if (waitable) {
|
if (waitable) {
|
||||||
// a. If typedArray.[[TypedArrayName]] is not "Int32Array" or "BigInt64Array", throw a TypeError exception.
|
// a. If typedArray.[[TypedArrayName]] is not "Int32Array" or "BigInt64Array", throw a TypeError exception.
|
||||||
if ((type_name != vm.names.Int32Array.as_string()) && (type_name != vm.names.BigInt64Array.as_string()))
|
if ((type_name != vm.names.Int32Array.as_string()) && (type_name != vm.names.BigInt64Array.as_string()))
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::TypedArrayTypeIsNot, type_name, "Int32 or BigInt64"sv);
|
return vm.throw_completion<TypeError>(ErrorType::TypedArrayTypeIsNot, type_name, "Int32 or BigInt64"sv);
|
||||||
}
|
}
|
||||||
// 5. Else,
|
// 5. Else,
|
||||||
else {
|
else {
|
||||||
// a. Let type be TypedArrayElementType(typedArray).
|
// a. Let type be TypedArrayElementType(typedArray).
|
||||||
// b. If IsUnclampedIntegerElementType(type) is false and IsBigIntElementType(type) is false, throw a TypeError exception.
|
// b. If IsUnclampedIntegerElementType(type) is false and IsBigIntElementType(type) is false, throw a TypeError exception.
|
||||||
if (!typed_array.is_unclamped_integer_element_type() && !typed_array.is_bigint_element_type())
|
if (!typed_array.is_unclamped_integer_element_type() && !typed_array.is_bigint_element_type())
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::TypedArrayTypeIsNot, type_name, "an unclamped integer or BigInt"sv);
|
return vm.throw_completion<TypeError>(ErrorType::TypedArrayTypeIsNot, type_name, "an unclamped integer or BigInt"sv);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 6. Return buffer.
|
// 6. Return buffer.
|
||||||
|
@ -62,7 +62,7 @@ static ThrowCompletionOr<size_t> validate_atomic_access(GlobalObject& global_obj
|
||||||
|
|
||||||
// 4. If accessIndex ≥ length, throw a RangeError exception.
|
// 4. If accessIndex ≥ length, throw a RangeError exception.
|
||||||
if (access_index >= length)
|
if (access_index >= length)
|
||||||
return vm.throw_completion<RangeError>(global_object, ErrorType::IndexOutOfRange, access_index, typed_array.array_length());
|
return vm.throw_completion<RangeError>(ErrorType::IndexOutOfRange, access_index, typed_array.array_length());
|
||||||
|
|
||||||
// 5. Let elementSize be TypedArrayElementSize(typedArray).
|
// 5. Let elementSize be TypedArrayElementSize(typedArray).
|
||||||
auto element_size = typed_array.element_size();
|
auto element_size = typed_array.element_size();
|
||||||
|
@ -96,7 +96,7 @@ static ThrowCompletionOr<Value> atomic_read_modify_write(GlobalObject& global_ob
|
||||||
|
|
||||||
// 5. If IsDetachedBuffer(buffer) is true, throw a TypeError exception.
|
// 5. If IsDetachedBuffer(buffer) is true, throw a TypeError exception.
|
||||||
if (buffer->is_detached())
|
if (buffer->is_detached())
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::DetachedArrayBuffer);
|
return vm.throw_completion<TypeError>(ErrorType::DetachedArrayBuffer);
|
||||||
|
|
||||||
// 6. NOTE: The above check is not redundant with the check in ValidateIntegerTypedArray because the call to ToBigInt or ToIntegerOrInfinity on the preceding lines can have arbitrary side effects, which could cause the buffer to become detached.
|
// 6. NOTE: The above check is not redundant with the check in ValidateIntegerTypedArray because the call to ToBigInt or ToIntegerOrInfinity on the preceding lines can have arbitrary side effects, which could cause the buffer to become detached.
|
||||||
|
|
||||||
|
@ -224,7 +224,7 @@ static ThrowCompletionOr<Value> atomic_compare_exchange_impl(GlobalObject& globa
|
||||||
|
|
||||||
// 6. If IsDetachedBuffer(buffer) is true, throw a TypeError exception.
|
// 6. If IsDetachedBuffer(buffer) is true, throw a TypeError exception.
|
||||||
if (buffer->is_detached())
|
if (buffer->is_detached())
|
||||||
return vm.template throw_completion<TypeError>(global_object, ErrorType::DetachedArrayBuffer);
|
return vm.template throw_completion<TypeError>(ErrorType::DetachedArrayBuffer);
|
||||||
|
|
||||||
// 7. NOTE: The above check is not redundant with the check in ValidateIntegerTypedArray because the call to ToBigInt or ToIntegerOrInfinity on the preceding lines can have arbitrary side effects, which could cause the buffer to become detached.
|
// 7. NOTE: The above check is not redundant with the check in ValidateIntegerTypedArray because the call to ToBigInt or ToIntegerOrInfinity on the preceding lines can have arbitrary side effects, which could cause the buffer to become detached.
|
||||||
|
|
||||||
|
@ -323,7 +323,7 @@ JS_DEFINE_NATIVE_FUNCTION(AtomicsObject::load)
|
||||||
|
|
||||||
// 3. If IsDetachedBuffer(buffer) is true, throw a TypeError exception.
|
// 3. If IsDetachedBuffer(buffer) is true, throw a TypeError exception.
|
||||||
if (typed_array->viewed_array_buffer()->is_detached())
|
if (typed_array->viewed_array_buffer()->is_detached())
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::DetachedArrayBuffer);
|
return vm.throw_completion<TypeError>(ErrorType::DetachedArrayBuffer);
|
||||||
|
|
||||||
// 4. NOTE: The above check is not redundant with the check in ValidateIntegerTypedArray because the call to ValidateAtomicAccess on the preceding line can have arbitrary side effects, which could cause the buffer to become detached.
|
// 4. NOTE: The above check is not redundant with the check in ValidateIntegerTypedArray because the call to ValidateAtomicAccess on the preceding line can have arbitrary side effects, which could cause the buffer to become detached.
|
||||||
|
|
||||||
|
@ -370,7 +370,7 @@ JS_DEFINE_NATIVE_FUNCTION(AtomicsObject::store)
|
||||||
|
|
||||||
// 5. If IsDetachedBuffer(buffer) is true, throw a TypeError exception.
|
// 5. If IsDetachedBuffer(buffer) is true, throw a TypeError exception.
|
||||||
if (typed_array->viewed_array_buffer()->is_detached())
|
if (typed_array->viewed_array_buffer()->is_detached())
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::DetachedArrayBuffer);
|
return vm.throw_completion<TypeError>(ErrorType::DetachedArrayBuffer);
|
||||||
|
|
||||||
// 6. NOTE: The above check is not redundant with the check in ValidateIntegerTypedArray because the call to ToBigInt or ToIntegerOrInfinity on the preceding lines can have arbitrary side effects, which could cause the buffer to become detached.
|
// 6. NOTE: The above check is not redundant with the check in ValidateIntegerTypedArray because the call to ToBigInt or ToIntegerOrInfinity on the preceding lines can have arbitrary side effects, which could cause the buffer to become detached.
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2020-2021, Linus Groh <linusg@serenityos.org>
|
* Copyright (c) 2020-2022, Linus Groh <linusg@serenityos.org>
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: BSD-2-Clause
|
* SPDX-License-Identifier: BSD-2-Clause
|
||||||
*/
|
*/
|
||||||
|
@ -35,7 +35,7 @@ ThrowCompletionOr<BigInt*> number_to_bigint(GlobalObject& global_object, Value n
|
||||||
|
|
||||||
// 1. If IsIntegralNumber(number) is false, throw a RangeError exception.
|
// 1. If IsIntegralNumber(number) is false, throw a RangeError exception.
|
||||||
if (!number.is_integral_number())
|
if (!number.is_integral_number())
|
||||||
return vm.throw_completion<RangeError>(global_object, ErrorType::BigIntFromNonIntegral);
|
return vm.throw_completion<RangeError>(ErrorType::BigIntFromNonIntegral);
|
||||||
|
|
||||||
// 2. Return the BigInt value that represents ℝ(number).
|
// 2. Return the BigInt value that represents ℝ(number).
|
||||||
return js_bigint(vm, Crypto::SignedBigInteger::create_from((i64)number.as_double()));
|
return js_bigint(vm, Crypto::SignedBigInteger::create_from((i64)number.as_double()));
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2020-2021, Linus Groh <linusg@serenityos.org>
|
* Copyright (c) 2020-2022, Linus Groh <linusg@serenityos.org>
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: BSD-2-Clause
|
* SPDX-License-Identifier: BSD-2-Clause
|
||||||
*/
|
*/
|
||||||
|
@ -59,7 +59,7 @@ ThrowCompletionOr<Value> BigIntConstructor::call()
|
||||||
// 21.2.1.1 BigInt ( value ), https://tc39.es/ecma262/#sec-bigint-constructor-number-value
|
// 21.2.1.1 BigInt ( value ), https://tc39.es/ecma262/#sec-bigint-constructor-number-value
|
||||||
ThrowCompletionOr<Object*> BigIntConstructor::construct(FunctionObject&)
|
ThrowCompletionOr<Object*> BigIntConstructor::construct(FunctionObject&)
|
||||||
{
|
{
|
||||||
return vm().throw_completion<TypeError>(global_object(), ErrorType::NotAConstructor, "BigInt");
|
return vm().throw_completion<TypeError>(ErrorType::NotAConstructor, "BigInt");
|
||||||
}
|
}
|
||||||
|
|
||||||
// 21.2.2.1 BigInt.asIntN ( bits, bigint ), https://tc39.es/ecma262/#sec-bigint.asintn
|
// 21.2.2.1 BigInt.asIntN ( bits, bigint ), https://tc39.es/ecma262/#sec-bigint.asintn
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2020-2021, Linus Groh <linusg@serenityos.org>
|
* Copyright (c) 2020-2022, Linus Groh <linusg@serenityos.org>
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: BSD-2-Clause
|
* SPDX-License-Identifier: BSD-2-Clause
|
||||||
*/
|
*/
|
||||||
|
@ -43,7 +43,7 @@ static ThrowCompletionOr<BigInt*> this_bigint_value(GlobalObject& global_object,
|
||||||
if (value.is_object() && is<BigIntObject>(value.as_object()))
|
if (value.is_object() && is<BigIntObject>(value.as_object()))
|
||||||
return &static_cast<BigIntObject&>(value.as_object()).bigint();
|
return &static_cast<BigIntObject&>(value.as_object()).bigint();
|
||||||
auto& vm = global_object.vm();
|
auto& vm = global_object.vm();
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::NotAnObjectOfType, "BigInt");
|
return vm.throw_completion<TypeError>(ErrorType::NotAnObjectOfType, "BigInt");
|
||||||
}
|
}
|
||||||
|
|
||||||
// 21.2.3.3 BigInt.prototype.toString ( [ radix ] ), https://tc39.es/ecma262/#sec-bigint.prototype.tostring
|
// 21.2.3.3 BigInt.prototype.toString ( [ radix ] ), https://tc39.es/ecma262/#sec-bigint.prototype.tostring
|
||||||
|
@ -54,7 +54,7 @@ JS_DEFINE_NATIVE_FUNCTION(BigIntPrototype::to_string)
|
||||||
if (!vm.argument(0).is_undefined()) {
|
if (!vm.argument(0).is_undefined()) {
|
||||||
radix = TRY(vm.argument(0).to_integer_or_infinity(global_object));
|
radix = TRY(vm.argument(0).to_integer_or_infinity(global_object));
|
||||||
if (radix < 2 || radix > 36)
|
if (radix < 2 || radix > 36)
|
||||||
return vm.throw_completion<RangeError>(global_object, ErrorType::InvalidRadix);
|
return vm.throw_completion<RangeError>(ErrorType::InvalidRadix);
|
||||||
}
|
}
|
||||||
return js_string(vm, bigint->big_integer().to_base(radix));
|
return js_string(vm, bigint->big_integer().to_base(radix));
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,7 +33,7 @@ JS_DEFINE_NATIVE_FUNCTION(BooleanPrototype::to_string)
|
||||||
if (this_value.is_boolean())
|
if (this_value.is_boolean())
|
||||||
return js_string(vm, this_value.as_bool() ? "true" : "false");
|
return js_string(vm, this_value.as_bool() ? "true" : "false");
|
||||||
if (!this_value.is_object() || !is<BooleanObject>(this_value.as_object()))
|
if (!this_value.is_object() || !is<BooleanObject>(this_value.as_object()))
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::NotAnObjectOfType, "Boolean");
|
return vm.throw_completion<TypeError>(ErrorType::NotAnObjectOfType, "Boolean");
|
||||||
|
|
||||||
bool bool_value = static_cast<BooleanObject const&>(this_value.as_object()).boolean();
|
bool bool_value = static_cast<BooleanObject const&>(this_value.as_object()).boolean();
|
||||||
return js_string(vm, bool_value ? "true" : "false");
|
return js_string(vm, bool_value ? "true" : "false");
|
||||||
|
@ -46,7 +46,7 @@ JS_DEFINE_NATIVE_FUNCTION(BooleanPrototype::value_of)
|
||||||
if (this_value.is_boolean())
|
if (this_value.is_boolean())
|
||||||
return this_value;
|
return this_value;
|
||||||
if (!this_value.is_object() || !is<BooleanObject>(this_value.as_object()))
|
if (!this_value.is_object() || !is<BooleanObject>(this_value.as_object()))
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::NotAnObjectOfType, "Boolean");
|
return vm.throw_completion<TypeError>(ErrorType::NotAnObjectOfType, "Boolean");
|
||||||
|
|
||||||
return Value(static_cast<BooleanObject const&>(this_value.as_object()).boolean());
|
return Value(static_cast<BooleanObject const&>(this_value.as_object()).boolean());
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,7 +33,7 @@ void DataViewConstructor::initialize(Realm& realm)
|
||||||
ThrowCompletionOr<Value> DataViewConstructor::call()
|
ThrowCompletionOr<Value> DataViewConstructor::call()
|
||||||
{
|
{
|
||||||
auto& vm = this->vm();
|
auto& vm = this->vm();
|
||||||
return vm.throw_completion<TypeError>(global_object(), ErrorType::ConstructorWithoutNew, vm.names.DataView);
|
return vm.throw_completion<TypeError>(ErrorType::ConstructorWithoutNew, vm.names.DataView);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 25.3.2.1 DataView ( buffer [ , byteOffset [ , byteLength ] ] ), https://tc39.es/ecma262/#sec-dataview-buffer-byteoffset-bytelength
|
// 25.3.2.1 DataView ( buffer [ , byteOffset [ , byteLength ] ] ), https://tc39.es/ecma262/#sec-dataview-buffer-byteoffset-bytelength
|
||||||
|
@ -44,18 +44,18 @@ ThrowCompletionOr<Object*> DataViewConstructor::construct(FunctionObject& new_ta
|
||||||
|
|
||||||
auto buffer = vm.argument(0);
|
auto buffer = vm.argument(0);
|
||||||
if (!buffer.is_object() || !is<ArrayBuffer>(buffer.as_object()))
|
if (!buffer.is_object() || !is<ArrayBuffer>(buffer.as_object()))
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::IsNotAn, buffer.to_string_without_side_effects(), vm.names.ArrayBuffer);
|
return vm.throw_completion<TypeError>(ErrorType::IsNotAn, buffer.to_string_without_side_effects(), vm.names.ArrayBuffer);
|
||||||
|
|
||||||
auto& array_buffer = static_cast<ArrayBuffer&>(buffer.as_object());
|
auto& array_buffer = static_cast<ArrayBuffer&>(buffer.as_object());
|
||||||
|
|
||||||
auto offset = TRY(vm.argument(1).to_index(global_object));
|
auto offset = TRY(vm.argument(1).to_index(global_object));
|
||||||
|
|
||||||
if (array_buffer.is_detached())
|
if (array_buffer.is_detached())
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::DetachedArrayBuffer);
|
return vm.throw_completion<TypeError>(ErrorType::DetachedArrayBuffer);
|
||||||
|
|
||||||
auto buffer_byte_length = array_buffer.byte_length();
|
auto buffer_byte_length = array_buffer.byte_length();
|
||||||
if (offset > buffer_byte_length)
|
if (offset > buffer_byte_length)
|
||||||
return vm.throw_completion<RangeError>(global_object, ErrorType::DataViewOutOfRangeByteOffset, offset, buffer_byte_length);
|
return vm.throw_completion<RangeError>(ErrorType::DataViewOutOfRangeByteOffset, offset, buffer_byte_length);
|
||||||
|
|
||||||
size_t view_byte_length;
|
size_t view_byte_length;
|
||||||
if (vm.argument(2).is_undefined()) {
|
if (vm.argument(2).is_undefined()) {
|
||||||
|
@ -64,13 +64,13 @@ ThrowCompletionOr<Object*> DataViewConstructor::construct(FunctionObject& new_ta
|
||||||
view_byte_length = TRY(vm.argument(2).to_index(global_object));
|
view_byte_length = TRY(vm.argument(2).to_index(global_object));
|
||||||
auto const checked_add = AK::make_checked(view_byte_length) + AK::make_checked(offset);
|
auto const checked_add = AK::make_checked(view_byte_length) + AK::make_checked(offset);
|
||||||
if (checked_add.has_overflow() || checked_add.value() > buffer_byte_length)
|
if (checked_add.has_overflow() || checked_add.value() > buffer_byte_length)
|
||||||
return vm.throw_completion<RangeError>(global_object, ErrorType::InvalidLength, vm.names.DataView);
|
return vm.throw_completion<RangeError>(ErrorType::InvalidLength, vm.names.DataView);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto* data_view = TRY(ordinary_create_from_constructor<DataView>(global_object, new_target, &GlobalObject::data_view_prototype, &array_buffer, view_byte_length, offset));
|
auto* data_view = TRY(ordinary_create_from_constructor<DataView>(global_object, new_target, &GlobalObject::data_view_prototype, &array_buffer, view_byte_length, offset));
|
||||||
|
|
||||||
if (array_buffer.is_detached())
|
if (array_buffer.is_detached())
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::DetachedArrayBuffer);
|
return vm.throw_completion<TypeError>(ErrorType::DetachedArrayBuffer);
|
||||||
|
|
||||||
return data_view;
|
return data_view;
|
||||||
}
|
}
|
||||||
|
|
|
@ -61,7 +61,7 @@ static ThrowCompletionOr<Value> get_view_value(GlobalObject& global_object, Valu
|
||||||
|
|
||||||
auto buffer = view->viewed_array_buffer();
|
auto buffer = view->viewed_array_buffer();
|
||||||
if (buffer->is_detached())
|
if (buffer->is_detached())
|
||||||
return vm.template throw_completion<TypeError>(global_object, ErrorType::DetachedArrayBuffer);
|
return vm.template throw_completion<TypeError>(ErrorType::DetachedArrayBuffer);
|
||||||
|
|
||||||
auto view_offset = view->byte_offset();
|
auto view_offset = view->byte_offset();
|
||||||
auto view_size = view->byte_length();
|
auto view_size = view->byte_length();
|
||||||
|
@ -75,7 +75,7 @@ static ThrowCompletionOr<Value> get_view_value(GlobalObject& global_object, Valu
|
||||||
end_index += element_size;
|
end_index += element_size;
|
||||||
|
|
||||||
if (buffer_index.has_overflow() || end_index.has_overflow() || end_index.value() > view_size)
|
if (buffer_index.has_overflow() || end_index.has_overflow() || end_index.value() > view_size)
|
||||||
return vm.throw_completion<RangeError>(global_object, ErrorType::DataViewOutOfRangeByteOffset, get_index, view_size);
|
return vm.throw_completion<RangeError>(ErrorType::DataViewOutOfRangeByteOffset, get_index, view_size);
|
||||||
|
|
||||||
return buffer->get_value<T>(buffer_index.value(), false, ArrayBuffer::Order::Unordered, little_endian);
|
return buffer->get_value<T>(buffer_index.value(), false, ArrayBuffer::Order::Unordered, little_endian);
|
||||||
}
|
}
|
||||||
|
@ -98,7 +98,7 @@ static ThrowCompletionOr<Value> set_view_value(GlobalObject& global_object, Valu
|
||||||
|
|
||||||
auto buffer = view->viewed_array_buffer();
|
auto buffer = view->viewed_array_buffer();
|
||||||
if (buffer->is_detached())
|
if (buffer->is_detached())
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::DetachedArrayBuffer);
|
return vm.throw_completion<TypeError>(ErrorType::DetachedArrayBuffer);
|
||||||
|
|
||||||
auto view_offset = view->byte_offset();
|
auto view_offset = view->byte_offset();
|
||||||
auto view_size = view->byte_length();
|
auto view_size = view->byte_length();
|
||||||
|
@ -112,7 +112,7 @@ static ThrowCompletionOr<Value> set_view_value(GlobalObject& global_object, Valu
|
||||||
end_index += element_size;
|
end_index += element_size;
|
||||||
|
|
||||||
if (buffer_index.has_overflow() || end_index.has_overflow() || end_index.value() > view_size)
|
if (buffer_index.has_overflow() || end_index.has_overflow() || end_index.value() > view_size)
|
||||||
return vm.throw_completion<RangeError>(global_object, ErrorType::DataViewOutOfRangeByteOffset, get_index, view_size);
|
return vm.throw_completion<RangeError>(ErrorType::DataViewOutOfRangeByteOffset, get_index, view_size);
|
||||||
|
|
||||||
buffer->set_value<T>(buffer_index.value(), number_value, false, ArrayBuffer::Order::Unordered, little_endian);
|
buffer->set_value<T>(buffer_index.value(), number_value, false, ArrayBuffer::Order::Unordered, little_endian);
|
||||||
|
|
||||||
|
@ -242,7 +242,7 @@ JS_DEFINE_NATIVE_FUNCTION(DataViewPrototype::byte_length_getter)
|
||||||
{
|
{
|
||||||
auto* data_view = TRY(typed_this_value(global_object));
|
auto* data_view = TRY(typed_this_value(global_object));
|
||||||
if (data_view->viewed_array_buffer()->is_detached())
|
if (data_view->viewed_array_buffer()->is_detached())
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::DetachedArrayBuffer);
|
return vm.throw_completion<TypeError>(ErrorType::DetachedArrayBuffer);
|
||||||
return Value(data_view->byte_length());
|
return Value(data_view->byte_length());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -251,7 +251,7 @@ JS_DEFINE_NATIVE_FUNCTION(DataViewPrototype::byte_offset_getter)
|
||||||
{
|
{
|
||||||
auto* data_view = TRY(typed_this_value(global_object));
|
auto* data_view = TRY(typed_this_value(global_object));
|
||||||
if (data_view->viewed_array_buffer()->is_detached())
|
if (data_view->viewed_array_buffer()->is_detached())
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::DetachedArrayBuffer);
|
return vm.throw_completion<TypeError>(ErrorType::DetachedArrayBuffer);
|
||||||
return Value(data_view->byte_offset());
|
return Value(data_view->byte_offset());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -109,7 +109,7 @@ ThrowCompletionOr<double> this_time_value(GlobalObject& global_object, Value val
|
||||||
|
|
||||||
// 2. Throw a TypeError exception.
|
// 2. Throw a TypeError exception.
|
||||||
auto& vm = global_object.vm();
|
auto& vm = global_object.vm();
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::NotAnObjectOfType, "Date");
|
return vm.throw_completion<TypeError>(ErrorType::NotAnObjectOfType, "Date");
|
||||||
}
|
}
|
||||||
|
|
||||||
// 21.4.4.2 Date.prototype.getDate ( ), https://tc39.es/ecma262/#sec-date.prototype.getdate
|
// 21.4.4.2 Date.prototype.getDate ( ), https://tc39.es/ecma262/#sec-date.prototype.getdate
|
||||||
|
@ -969,7 +969,7 @@ JS_DEFINE_NATIVE_FUNCTION(DatePrototype::to_iso_string)
|
||||||
auto* this_object = TRY(typed_this_object(global_object));
|
auto* this_object = TRY(typed_this_object(global_object));
|
||||||
|
|
||||||
if (!Value(this_object->date_value()).is_finite_number())
|
if (!Value(this_object->date_value()).is_finite_number())
|
||||||
return vm.throw_completion<RangeError>(global_object, ErrorType::InvalidTimeValue);
|
return vm.throw_completion<RangeError>(ErrorType::InvalidTimeValue);
|
||||||
|
|
||||||
auto string = this_object->iso_date_string();
|
auto string = this_object->iso_date_string();
|
||||||
return js_string(vm, move(string));
|
return js_string(vm, move(string));
|
||||||
|
@ -1241,10 +1241,10 @@ JS_DEFINE_NATIVE_FUNCTION(DatePrototype::symbol_to_primitive)
|
||||||
{
|
{
|
||||||
auto this_value = vm.this_value(global_object);
|
auto this_value = vm.this_value(global_object);
|
||||||
if (!this_value.is_object())
|
if (!this_value.is_object())
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::NotAnObject, this_value.to_string_without_side_effects());
|
return vm.throw_completion<TypeError>(ErrorType::NotAnObject, this_value.to_string_without_side_effects());
|
||||||
auto hint_value = vm.argument(0);
|
auto hint_value = vm.argument(0);
|
||||||
if (!hint_value.is_string())
|
if (!hint_value.is_string())
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::InvalidHint, hint_value.to_string_without_side_effects());
|
return vm.throw_completion<TypeError>(ErrorType::InvalidHint, hint_value.to_string_without_side_effects());
|
||||||
auto& hint = hint_value.as_string().string();
|
auto& hint = hint_value.as_string().string();
|
||||||
Value::PreferredType try_first;
|
Value::PreferredType try_first;
|
||||||
if (hint == "string" || hint == "default")
|
if (hint == "string" || hint == "default")
|
||||||
|
@ -1252,7 +1252,7 @@ JS_DEFINE_NATIVE_FUNCTION(DatePrototype::symbol_to_primitive)
|
||||||
else if (hint == "number")
|
else if (hint == "number")
|
||||||
try_first = Value::PreferredType::Number;
|
try_first = Value::PreferredType::Number;
|
||||||
else
|
else
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::InvalidHint, hint);
|
return vm.throw_completion<TypeError>(ErrorType::InvalidHint, hint);
|
||||||
return TRY(this_value.as_object().ordinary_to_primitive(try_first));
|
return TRY(this_value.as_object().ordinary_to_primitive(try_first));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -129,7 +129,7 @@ ThrowCompletionOr<void> DeclarativeEnvironment::set_mutable_binding(GlobalObject
|
||||||
if (!index.has_value()) {
|
if (!index.has_value()) {
|
||||||
// a. If S is true, throw a ReferenceError exception.
|
// a. If S is true, throw a ReferenceError exception.
|
||||||
if (strict)
|
if (strict)
|
||||||
return vm().throw_completion<ReferenceError>(global_object, ErrorType::UnknownIdentifier, name);
|
return vm().throw_completion<ReferenceError>(ErrorType::UnknownIdentifier, name);
|
||||||
|
|
||||||
// b. Perform ! envRec.CreateMutableBinding(N, true).
|
// b. Perform ! envRec.CreateMutableBinding(N, true).
|
||||||
MUST(create_mutable_binding(global_object, name, true));
|
MUST(create_mutable_binding(global_object, name, true));
|
||||||
|
@ -148,20 +148,20 @@ ThrowCompletionOr<void> DeclarativeEnvironment::set_mutable_binding(GlobalObject
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
ThrowCompletionOr<void> DeclarativeEnvironment::set_mutable_binding_direct(GlobalObject& global_object, size_t index, Value value, bool strict)
|
ThrowCompletionOr<void> DeclarativeEnvironment::set_mutable_binding_direct(GlobalObject&, size_t index, Value value, bool strict)
|
||||||
{
|
{
|
||||||
auto& binding = m_bindings[index];
|
auto& binding = m_bindings[index];
|
||||||
if (binding.strict)
|
if (binding.strict)
|
||||||
strict = true;
|
strict = true;
|
||||||
|
|
||||||
if (!binding.initialized)
|
if (!binding.initialized)
|
||||||
return vm().throw_completion<ReferenceError>(global_object, ErrorType::BindingNotInitialized, binding.name);
|
return vm().throw_completion<ReferenceError>(ErrorType::BindingNotInitialized, binding.name);
|
||||||
|
|
||||||
if (binding.mutable_) {
|
if (binding.mutable_) {
|
||||||
binding.value = value;
|
binding.value = value;
|
||||||
} else {
|
} else {
|
||||||
if (strict)
|
if (strict)
|
||||||
return vm().throw_completion<TypeError>(global_object, ErrorType::InvalidAssignToConst);
|
return vm().throw_completion<TypeError>(ErrorType::InvalidAssignToConst);
|
||||||
}
|
}
|
||||||
|
|
||||||
return {};
|
return {};
|
||||||
|
@ -178,13 +178,13 @@ ThrowCompletionOr<Value> DeclarativeEnvironment::get_binding_value(GlobalObject&
|
||||||
return get_binding_value_direct(global_object, *index, strict);
|
return get_binding_value_direct(global_object, *index, strict);
|
||||||
}
|
}
|
||||||
|
|
||||||
ThrowCompletionOr<Value> DeclarativeEnvironment::get_binding_value_direct(GlobalObject& global_object, size_t index, bool)
|
ThrowCompletionOr<Value> DeclarativeEnvironment::get_binding_value_direct(GlobalObject&, size_t index, bool)
|
||||||
{
|
{
|
||||||
auto& binding = m_bindings[index];
|
auto& binding = m_bindings[index];
|
||||||
|
|
||||||
// 2. If the binding for N in envRec is an uninitialized binding, throw a ReferenceError exception.
|
// 2. If the binding for N in envRec is an uninitialized binding, throw a ReferenceError exception.
|
||||||
if (!binding.initialized)
|
if (!binding.initialized)
|
||||||
return vm().throw_completion<ReferenceError>(global_object, ErrorType::BindingNotInitialized, binding.name);
|
return vm().throw_completion<ReferenceError>(ErrorType::BindingNotInitialized, binding.name);
|
||||||
|
|
||||||
// 3. Return the value currently bound to N in envRec.
|
// 3. Return the value currently bound to N in envRec.
|
||||||
return binding.value;
|
return binding.value;
|
||||||
|
|
|
@ -160,7 +160,7 @@ ThrowCompletionOr<Value> ECMAScriptFunctionObject::internal_call(Value this_argu
|
||||||
if (m_is_class_constructor) {
|
if (m_is_class_constructor) {
|
||||||
// a. Let error be a newly created TypeError object.
|
// a. Let error be a newly created TypeError object.
|
||||||
// b. NOTE: error is created in calleeContext with F's associated Realm Record.
|
// b. NOTE: error is created in calleeContext with F's associated Realm Record.
|
||||||
auto throw_completion = vm.throw_completion<TypeError>(global_object(), ErrorType::ClassConstructorWithoutNew, m_name);
|
auto throw_completion = vm.throw_completion<TypeError>(ErrorType::ClassConstructorWithoutNew, m_name);
|
||||||
|
|
||||||
// c. Remove calleeContext from the execution context stack and restore callerContext as the running execution context.
|
// c. Remove calleeContext from the execution context stack and restore callerContext as the running execution context.
|
||||||
vm.pop_execution_context();
|
vm.pop_execution_context();
|
||||||
|
@ -274,7 +274,7 @@ ThrowCompletionOr<Object*> ECMAScriptFunctionObject::internal_construct(MarkedVe
|
||||||
|
|
||||||
// c. If result.[[Value]] is not undefined, throw a TypeError exception.
|
// c. If result.[[Value]] is not undefined, throw a TypeError exception.
|
||||||
if (!result.value()->is_undefined())
|
if (!result.value()->is_undefined())
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::DerivedConstructorReturningInvalidValue);
|
return vm.throw_completion<TypeError>(ErrorType::DerivedConstructorReturningInvalidValue);
|
||||||
}
|
}
|
||||||
// 11. Else, ReturnIfAbrupt(result).
|
// 11. Else, ReturnIfAbrupt(result).
|
||||||
else if (result.is_abrupt()) {
|
else if (result.is_abrupt()) {
|
||||||
|
@ -787,14 +787,14 @@ Completion ECMAScriptFunctionObject::ordinary_call_evaluate_body()
|
||||||
auto* bytecode_interpreter = Bytecode::Interpreter::current();
|
auto* bytecode_interpreter = Bytecode::Interpreter::current();
|
||||||
|
|
||||||
if (m_kind == FunctionKind::AsyncGenerator)
|
if (m_kind == FunctionKind::AsyncGenerator)
|
||||||
return vm.throw_completion<InternalError>(global_object, ErrorType::NotImplemented, "Async Generator function execution");
|
return vm.throw_completion<InternalError>(ErrorType::NotImplemented, "Async Generator function execution");
|
||||||
|
|
||||||
if (bytecode_interpreter) {
|
if (bytecode_interpreter) {
|
||||||
if (!m_bytecode_executable) {
|
if (!m_bytecode_executable) {
|
||||||
auto compile = [&](auto& node, auto kind, auto name) -> ThrowCompletionOr<NonnullOwnPtr<Bytecode::Executable>> {
|
auto compile = [&](auto& node, auto kind, auto name) -> ThrowCompletionOr<NonnullOwnPtr<Bytecode::Executable>> {
|
||||||
auto executable_result = Bytecode::Generator::generate(node, kind);
|
auto executable_result = Bytecode::Generator::generate(node, kind);
|
||||||
if (executable_result.is_error())
|
if (executable_result.is_error())
|
||||||
return vm.throw_completion<InternalError>(bytecode_interpreter->global_object(), ErrorType::NotImplemented, executable_result.error().to_string());
|
return vm.throw_completion<InternalError>(ErrorType::NotImplemented, executable_result.error().to_string());
|
||||||
|
|
||||||
auto bytecode_executable = executable_result.release_value();
|
auto bytecode_executable = executable_result.release_value();
|
||||||
bytecode_executable->name = name;
|
bytecode_executable->name = name;
|
||||||
|
@ -845,7 +845,7 @@ Completion ECMAScriptFunctionObject::ordinary_call_evaluate_body()
|
||||||
return { Completion::Type::Return, generator_object, {} };
|
return { Completion::Type::Return, generator_object, {} };
|
||||||
} else {
|
} else {
|
||||||
if (m_kind == FunctionKind::Generator)
|
if (m_kind == FunctionKind::Generator)
|
||||||
return vm.throw_completion<InternalError>(global_object, ErrorType::NotImplemented, "Generator function execution in AST interpreter");
|
return vm.throw_completion<InternalError>(ErrorType::NotImplemented, "Generator function execution in AST interpreter");
|
||||||
OwnPtr<Interpreter> local_interpreter;
|
OwnPtr<Interpreter> local_interpreter;
|
||||||
Interpreter* ast_interpreter = vm.interpreter_if_exists();
|
Interpreter* ast_interpreter = vm.interpreter_if_exists();
|
||||||
|
|
||||||
|
|
|
@ -110,14 +110,14 @@ JS_DEFINE_NATIVE_FUNCTION(ErrorPrototype::stack_setter)
|
||||||
|
|
||||||
// 2. If ! Type(E) is not Object, throw a TypeError exception.
|
// 2. If ! Type(E) is not Object, throw a TypeError exception.
|
||||||
if (!this_value.is_object())
|
if (!this_value.is_object())
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::NotAnObject, this_value.to_string_without_side_effects());
|
return vm.throw_completion<TypeError>(ErrorType::NotAnObject, this_value.to_string_without_side_effects());
|
||||||
|
|
||||||
auto& this_object = this_value.as_object();
|
auto& this_object = this_value.as_object();
|
||||||
|
|
||||||
// 3. Let numberOfArgs be the number of arguments passed to this function call.
|
// 3. Let numberOfArgs be the number of arguments passed to this function call.
|
||||||
// 4. If numberOfArgs is 0, throw a TypeError exception.
|
// 4. If numberOfArgs is 0, throw a TypeError exception.
|
||||||
if (vm.argument_count() == 0)
|
if (vm.argument_count() == 0)
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::BadArgCountOne, "set stack");
|
return vm.throw_completion<TypeError>(ErrorType::BadArgCountOne, "set stack");
|
||||||
|
|
||||||
// 5. Return ? CreateDataPropertyOrThrow(E, "stack", value);
|
// 5. Return ? CreateDataPropertyOrThrow(E, "stack", value);
|
||||||
return TRY(this_object.create_data_property_or_throw(vm.names.stack, vm.argument(0)));
|
return TRY(this_object.create_data_property_or_throw(vm.names.stack, vm.argument(0)));
|
||||||
|
|
|
@ -33,7 +33,7 @@ void FinalizationRegistryConstructor::initialize(Realm& realm)
|
||||||
ThrowCompletionOr<Value> FinalizationRegistryConstructor::call()
|
ThrowCompletionOr<Value> FinalizationRegistryConstructor::call()
|
||||||
{
|
{
|
||||||
auto& vm = this->vm();
|
auto& vm = this->vm();
|
||||||
return vm.throw_completion<TypeError>(global_object(), ErrorType::ConstructorWithoutNew, vm.names.FinalizationRegistry);
|
return vm.throw_completion<TypeError>(ErrorType::ConstructorWithoutNew, vm.names.FinalizationRegistry);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 26.2.1.1 FinalizationRegistry ( cleanupCallback ), https://tc39.es/ecma262/#sec-finalization-registry-cleanup-callback
|
// 26.2.1.1 FinalizationRegistry ( cleanupCallback ), https://tc39.es/ecma262/#sec-finalization-registry-cleanup-callback
|
||||||
|
@ -47,7 +47,7 @@ ThrowCompletionOr<Object*> FinalizationRegistryConstructor::construct(FunctionOb
|
||||||
// 2. If IsCallable(cleanupCallback) is false, throw a TypeError exception.
|
// 2. If IsCallable(cleanupCallback) is false, throw a TypeError exception.
|
||||||
auto cleanup_callback = vm.argument(0);
|
auto cleanup_callback = vm.argument(0);
|
||||||
if (!cleanup_callback.is_function())
|
if (!cleanup_callback.is_function())
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::NotAFunction, cleanup_callback.to_string_without_side_effects());
|
return vm.throw_completion<TypeError>(ErrorType::NotAFunction, cleanup_callback.to_string_without_side_effects());
|
||||||
|
|
||||||
// 3. Let finalizationRegistry be ? OrdinaryCreateFromConstructor(NewTarget, "%FinalizationRegistry.prototype%", « [[Realm]], [[CleanupCallback]], [[Cells]] »).
|
// 3. Let finalizationRegistry be ? OrdinaryCreateFromConstructor(NewTarget, "%FinalizationRegistry.prototype%", « [[Realm]], [[CleanupCallback]], [[Cells]] »).
|
||||||
// 4. Let fn be the active function object.
|
// 4. Let fn be the active function object.
|
||||||
|
|
|
@ -35,7 +35,7 @@ JS_DEFINE_NATIVE_FUNCTION(FinalizationRegistryPrototype::cleanup_some)
|
||||||
|
|
||||||
auto callback = vm.argument(0);
|
auto callback = vm.argument(0);
|
||||||
if (vm.argument_count() > 0 && !callback.is_function())
|
if (vm.argument_count() > 0 && !callback.is_function())
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::NotAFunction, callback.to_string_without_side_effects());
|
return vm.throw_completion<TypeError>(ErrorType::NotAFunction, callback.to_string_without_side_effects());
|
||||||
|
|
||||||
// IMPLEMENTATION DEFINED: The specification for this function hasn't been updated to accommodate for JobCallback records.
|
// IMPLEMENTATION DEFINED: The specification for this function hasn't been updated to accommodate for JobCallback records.
|
||||||
// This just follows how the constructor immediately converts the callback to a JobCallback using HostMakeJobCallback.
|
// This just follows how the constructor immediately converts the callback to a JobCallback using HostMakeJobCallback.
|
||||||
|
@ -51,15 +51,15 @@ JS_DEFINE_NATIVE_FUNCTION(FinalizationRegistryPrototype::register_)
|
||||||
|
|
||||||
auto target = vm.argument(0);
|
auto target = vm.argument(0);
|
||||||
if (!can_be_held_weakly(target))
|
if (!can_be_held_weakly(target))
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::CannotBeHeldWeakly, target.to_string_without_side_effects());
|
return vm.throw_completion<TypeError>(ErrorType::CannotBeHeldWeakly, target.to_string_without_side_effects());
|
||||||
|
|
||||||
auto held_value = vm.argument(1);
|
auto held_value = vm.argument(1);
|
||||||
if (same_value(target, held_value))
|
if (same_value(target, held_value))
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::FinalizationRegistrySameTargetAndValue);
|
return vm.throw_completion<TypeError>(ErrorType::FinalizationRegistrySameTargetAndValue);
|
||||||
|
|
||||||
auto unregister_token = vm.argument(2);
|
auto unregister_token = vm.argument(2);
|
||||||
if (!can_be_held_weakly(unregister_token) && !unregister_token.is_undefined())
|
if (!can_be_held_weakly(unregister_token) && !unregister_token.is_undefined())
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::CannotBeHeldWeakly, unregister_token.to_string_without_side_effects());
|
return vm.throw_completion<TypeError>(ErrorType::CannotBeHeldWeakly, unregister_token.to_string_without_side_effects());
|
||||||
|
|
||||||
finalization_registry->add_finalization_record(target.as_cell(), held_value, unregister_token.is_undefined() ? nullptr : &unregister_token.as_cell());
|
finalization_registry->add_finalization_record(target.as_cell(), held_value, unregister_token.is_undefined() ? nullptr : &unregister_token.as_cell());
|
||||||
|
|
||||||
|
@ -73,7 +73,7 @@ JS_DEFINE_NATIVE_FUNCTION(FinalizationRegistryPrototype::unregister)
|
||||||
|
|
||||||
auto unregister_token = vm.argument(0);
|
auto unregister_token = vm.argument(0);
|
||||||
if (!can_be_held_weakly(unregister_token))
|
if (!can_be_held_weakly(unregister_token))
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::CannotBeHeldWeakly, unregister_token.to_string_without_side_effects());
|
return vm.throw_completion<TypeError>(ErrorType::CannotBeHeldWeakly, unregister_token.to_string_without_side_effects());
|
||||||
|
|
||||||
return Value(finalization_registry->remove_by_token(unregister_token.as_cell()));
|
return Value(finalization_registry->remove_by_token(unregister_token.as_cell()));
|
||||||
}
|
}
|
||||||
|
|
|
@ -179,7 +179,7 @@ ThrowCompletionOr<ECMAScriptFunctionObject*> FunctionConstructor::create_dynamic
|
||||||
// 17. If parameters is a List of errors, throw a SyntaxError exception.
|
// 17. If parameters is a List of errors, throw a SyntaxError exception.
|
||||||
if (parameters_parser.has_errors()) {
|
if (parameters_parser.has_errors()) {
|
||||||
auto error = parameters_parser.errors()[0];
|
auto error = parameters_parser.errors()[0];
|
||||||
return vm.throw_completion<SyntaxError>(global_object, error.to_string());
|
return vm.throw_completion<SyntaxError>(error.to_string());
|
||||||
}
|
}
|
||||||
|
|
||||||
// 18. Let body be ParseText(StringToCodePoints(bodyString), bodySym).
|
// 18. Let body be ParseText(StringToCodePoints(bodyString), bodySym).
|
||||||
|
@ -196,7 +196,7 @@ ThrowCompletionOr<ECMAScriptFunctionObject*> FunctionConstructor::create_dynamic
|
||||||
// 19. If body is a List of errors, throw a SyntaxError exception.
|
// 19. If body is a List of errors, throw a SyntaxError exception.
|
||||||
if (body_parser.has_errors()) {
|
if (body_parser.has_errors()) {
|
||||||
auto error = body_parser.errors()[0];
|
auto error = body_parser.errors()[0];
|
||||||
return vm.throw_completion<SyntaxError>(global_object, error.to_string());
|
return vm.throw_completion<SyntaxError>(error.to_string());
|
||||||
}
|
}
|
||||||
|
|
||||||
// 20. NOTE: The parameters and body are parsed separately to ensure that each is valid alone. For example, new Function("/*", "*/ ) {") is not legal.
|
// 20. NOTE: The parameters and body are parsed separately to ensure that each is valid alone. For example, new Function("/*", "*/ ) {") is not legal.
|
||||||
|
@ -210,7 +210,7 @@ ThrowCompletionOr<ECMAScriptFunctionObject*> FunctionConstructor::create_dynamic
|
||||||
// 23. If expr is a List of errors, throw a SyntaxError exception.
|
// 23. If expr is a List of errors, throw a SyntaxError exception.
|
||||||
if (source_parser.has_errors()) {
|
if (source_parser.has_errors()) {
|
||||||
auto error = source_parser.errors()[0];
|
auto error = source_parser.errors()[0];
|
||||||
return vm.throw_completion<SyntaxError>(global_object, error.to_string());
|
return vm.throw_completion<SyntaxError>(error.to_string());
|
||||||
}
|
}
|
||||||
|
|
||||||
// 24. Let proto be ? GetPrototypeFromConstructor(newTarget, fallbackProto).
|
// 24. Let proto be ? GetPrototypeFromConstructor(newTarget, fallbackProto).
|
||||||
|
|
|
@ -61,21 +61,21 @@ bool FunctionEnvironment::has_super_binding() const
|
||||||
}
|
}
|
||||||
|
|
||||||
// 9.1.1.3.4 GetThisBinding ( ), https://tc39.es/ecma262/#sec-function-environment-records-getthisbinding
|
// 9.1.1.3.4 GetThisBinding ( ), https://tc39.es/ecma262/#sec-function-environment-records-getthisbinding
|
||||||
ThrowCompletionOr<Value> FunctionEnvironment::get_this_binding(GlobalObject& global_object) const
|
ThrowCompletionOr<Value> FunctionEnvironment::get_this_binding(GlobalObject&) const
|
||||||
{
|
{
|
||||||
// 1. Assert: envRec.[[ThisBindingStatus]] is not lexical.
|
// 1. Assert: envRec.[[ThisBindingStatus]] is not lexical.
|
||||||
VERIFY(m_this_binding_status != ThisBindingStatus::Lexical);
|
VERIFY(m_this_binding_status != ThisBindingStatus::Lexical);
|
||||||
|
|
||||||
// 2. If envRec.[[ThisBindingStatus]] is uninitialized, throw a ReferenceError exception.
|
// 2. If envRec.[[ThisBindingStatus]] is uninitialized, throw a ReferenceError exception.
|
||||||
if (m_this_binding_status == ThisBindingStatus::Uninitialized)
|
if (m_this_binding_status == ThisBindingStatus::Uninitialized)
|
||||||
return vm().throw_completion<ReferenceError>(global_object, ErrorType::ThisHasNotBeenInitialized);
|
return vm().throw_completion<ReferenceError>(ErrorType::ThisHasNotBeenInitialized);
|
||||||
|
|
||||||
// 3. Return envRec.[[ThisValue]].
|
// 3. Return envRec.[[ThisValue]].
|
||||||
return m_this_value;
|
return m_this_value;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 9.1.1.3.1 BindThisValue ( V ), https://tc39.es/ecma262/#sec-bindthisvalue
|
// 9.1.1.3.1 BindThisValue ( V ), https://tc39.es/ecma262/#sec-bindthisvalue
|
||||||
ThrowCompletionOr<Value> FunctionEnvironment::bind_this_value(GlobalObject& global_object, Value this_value)
|
ThrowCompletionOr<Value> FunctionEnvironment::bind_this_value(GlobalObject&, Value this_value)
|
||||||
{
|
{
|
||||||
VERIFY(!this_value.is_empty());
|
VERIFY(!this_value.is_empty());
|
||||||
|
|
||||||
|
@ -84,7 +84,7 @@ ThrowCompletionOr<Value> FunctionEnvironment::bind_this_value(GlobalObject& glob
|
||||||
|
|
||||||
// 2. If envRec.[[ThisBindingStatus]] is initialized, throw a ReferenceError exception.
|
// 2. If envRec.[[ThisBindingStatus]] is initialized, throw a ReferenceError exception.
|
||||||
if (m_this_binding_status == ThisBindingStatus::Initialized)
|
if (m_this_binding_status == ThisBindingStatus::Initialized)
|
||||||
return vm().throw_completion<ReferenceError>(global_object, ErrorType::ThisIsAlreadyInitialized);
|
return vm().throw_completion<ReferenceError>(ErrorType::ThisIsAlreadyInitialized);
|
||||||
|
|
||||||
// 3. Set envRec.[[ThisValue]] to V.
|
// 3. Set envRec.[[ThisValue]] to V.
|
||||||
m_this_value = this_value;
|
m_this_value = this_value;
|
||||||
|
|
|
@ -54,7 +54,7 @@ JS_DEFINE_NATIVE_FUNCTION(FunctionPrototype::apply)
|
||||||
|
|
||||||
// 2. If IsCallable(func) is false, throw a TypeError exception.
|
// 2. If IsCallable(func) is false, throw a TypeError exception.
|
||||||
if (!function_value.is_function())
|
if (!function_value.is_function())
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::NotAFunction, function_value.to_string_without_side_effects());
|
return vm.throw_completion<TypeError>(ErrorType::NotAFunction, function_value.to_string_without_side_effects());
|
||||||
|
|
||||||
auto& function = static_cast<FunctionObject&>(function_value.as_object());
|
auto& function = static_cast<FunctionObject&>(function_value.as_object());
|
||||||
|
|
||||||
|
@ -91,7 +91,7 @@ JS_DEFINE_NATIVE_FUNCTION(FunctionPrototype::bind)
|
||||||
|
|
||||||
// 2. If IsCallable(Target) is false, throw a TypeError exception.
|
// 2. If IsCallable(Target) is false, throw a TypeError exception.
|
||||||
if (!target_value.is_function())
|
if (!target_value.is_function())
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::NotAFunction, target_value.to_string_without_side_effects());
|
return vm.throw_completion<TypeError>(ErrorType::NotAFunction, target_value.to_string_without_side_effects());
|
||||||
|
|
||||||
auto& target = static_cast<FunctionObject&>(target_value.as_object());
|
auto& target = static_cast<FunctionObject&>(target_value.as_object());
|
||||||
|
|
||||||
|
@ -122,7 +122,7 @@ JS_DEFINE_NATIVE_FUNCTION(FunctionPrototype::call)
|
||||||
|
|
||||||
// 2. If IsCallable(func) is false, throw a TypeError exception.
|
// 2. If IsCallable(func) is false, throw a TypeError exception.
|
||||||
if (!function_value.is_function())
|
if (!function_value.is_function())
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::NotAFunction, function_value.to_string_without_side_effects());
|
return vm.throw_completion<TypeError>(ErrorType::NotAFunction, function_value.to_string_without_side_effects());
|
||||||
|
|
||||||
auto& function = static_cast<FunctionObject&>(function_value.as_object());
|
auto& function = static_cast<FunctionObject&>(function_value.as_object());
|
||||||
|
|
||||||
|
@ -148,7 +148,7 @@ JS_DEFINE_NATIVE_FUNCTION(FunctionPrototype::to_string)
|
||||||
// If func is not a function, let's bail out early. The order of this step is not observable.
|
// If func is not a function, let's bail out early. The order of this step is not observable.
|
||||||
if (!function_value.is_function()) {
|
if (!function_value.is_function()) {
|
||||||
// 5. Throw a TypeError exception.
|
// 5. Throw a TypeError exception.
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::NotAnObjectOfType, "Function");
|
return vm.throw_completion<TypeError>(ErrorType::NotAnObjectOfType, "Function");
|
||||||
}
|
}
|
||||||
|
|
||||||
auto& function = function_value.as_function();
|
auto& function = function_value.as_function();
|
||||||
|
|
|
@ -57,7 +57,7 @@ ThrowCompletionOr<void> GlobalEnvironment::create_mutable_binding(GlobalObject&
|
||||||
// 1. Let DclRec be envRec.[[DeclarativeRecord]].
|
// 1. Let DclRec be envRec.[[DeclarativeRecord]].
|
||||||
// 2. If ! DclRec.HasBinding(N) is true, throw a TypeError exception.
|
// 2. If ! DclRec.HasBinding(N) is true, throw a TypeError exception.
|
||||||
if (MUST(m_declarative_record->has_binding(name)))
|
if (MUST(m_declarative_record->has_binding(name)))
|
||||||
return vm().throw_completion<TypeError>(global_object, ErrorType::GlobalEnvironmentAlreadyHasBinding, name);
|
return vm().throw_completion<TypeError>(ErrorType::GlobalEnvironmentAlreadyHasBinding, name);
|
||||||
|
|
||||||
// 3. Return ! DclRec.CreateMutableBinding(N, D).
|
// 3. Return ! DclRec.CreateMutableBinding(N, D).
|
||||||
return MUST(m_declarative_record->create_mutable_binding(global_object, name, can_be_deleted));
|
return MUST(m_declarative_record->create_mutable_binding(global_object, name, can_be_deleted));
|
||||||
|
@ -69,7 +69,7 @@ ThrowCompletionOr<void> GlobalEnvironment::create_immutable_binding(GlobalObject
|
||||||
// 1. Let DclRec be envRec.[[DeclarativeRecord]].
|
// 1. Let DclRec be envRec.[[DeclarativeRecord]].
|
||||||
// 2. If ! DclRec.HasBinding(N) is true, throw a TypeError exception.
|
// 2. If ! DclRec.HasBinding(N) is true, throw a TypeError exception.
|
||||||
if (MUST(m_declarative_record->has_binding(name)))
|
if (MUST(m_declarative_record->has_binding(name)))
|
||||||
return vm().throw_completion<TypeError>(global_object, ErrorType::GlobalEnvironmentAlreadyHasBinding, name);
|
return vm().throw_completion<TypeError>(ErrorType::GlobalEnvironmentAlreadyHasBinding, name);
|
||||||
|
|
||||||
// 3. Return ! DclRec.CreateImmutableBinding(N, S).
|
// 3. Return ! DclRec.CreateImmutableBinding(N, S).
|
||||||
return MUST(m_declarative_record->create_immutable_binding(global_object, name, strict));
|
return MUST(m_declarative_record->create_immutable_binding(global_object, name, strict));
|
||||||
|
|
|
@ -226,8 +226,8 @@ void GlobalObject::initialize_global_object()
|
||||||
|
|
||||||
// 10.2.4.1 %ThrowTypeError% ( ), https://tc39.es/ecma262/#sec-%throwtypeerror%
|
// 10.2.4.1 %ThrowTypeError% ( ), https://tc39.es/ecma262/#sec-%throwtypeerror%
|
||||||
m_throw_type_error_function = NativeFunction::create(
|
m_throw_type_error_function = NativeFunction::create(
|
||||||
realm, [](VM& vm, GlobalObject& global_object) {
|
realm, [](VM& vm, GlobalObject&) {
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::RestrictedFunctionPropertiesAccess);
|
return vm.throw_completion<TypeError>(ErrorType::RestrictedFunctionPropertiesAccess);
|
||||||
},
|
},
|
||||||
0, "", &realm);
|
0, "", &realm);
|
||||||
m_throw_type_error_function->define_direct_property(vm.names.length, Value(0), 0);
|
m_throw_type_error_function->define_direct_property(vm.names.length, Value(0), 0);
|
||||||
|
@ -533,7 +533,7 @@ static ThrowCompletionOr<String> encode(GlobalObject& global_object, String cons
|
||||||
auto code_point = code_point_at(utf16_string.view(), k);
|
auto code_point = code_point_at(utf16_string.view(), k);
|
||||||
// ii. If cp.[[IsUnpairedSurrogate]] is true, throw a URIError exception.
|
// ii. If cp.[[IsUnpairedSurrogate]] is true, throw a URIError exception.
|
||||||
if (code_point.is_unpaired_surrogate)
|
if (code_point.is_unpaired_surrogate)
|
||||||
return vm.throw_completion<URIError>(global_object, ErrorType::URIMalformed);
|
return vm.throw_completion<URIError>(ErrorType::URIMalformed);
|
||||||
|
|
||||||
// iii. Set k to k + cp.[[CodeUnitCount]].
|
// iii. Set k to k + cp.[[CodeUnitCount]].
|
||||||
k += code_point.code_unit_count;
|
k += code_point.code_unit_count;
|
||||||
|
@ -563,22 +563,22 @@ static ThrowCompletionOr<String> decode(GlobalObject& global_object, String cons
|
||||||
auto code_unit = string[k];
|
auto code_unit = string[k];
|
||||||
if (code_unit != '%') {
|
if (code_unit != '%') {
|
||||||
if (expected_continuation_bytes > 0)
|
if (expected_continuation_bytes > 0)
|
||||||
return global_object.vm().throw_completion<URIError>(global_object, ErrorType::URIMalformed);
|
return global_object.vm().throw_completion<URIError>(ErrorType::URIMalformed);
|
||||||
|
|
||||||
decoded_builder.append(code_unit);
|
decoded_builder.append(code_unit);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (k + 2 >= string.length())
|
if (k + 2 >= string.length())
|
||||||
return global_object.vm().throw_completion<URIError>(global_object, ErrorType::URIMalformed);
|
return global_object.vm().throw_completion<URIError>(ErrorType::URIMalformed);
|
||||||
|
|
||||||
auto first_digit = decode_hex_digit(string[k + 1]);
|
auto first_digit = decode_hex_digit(string[k + 1]);
|
||||||
if (first_digit >= 16)
|
if (first_digit >= 16)
|
||||||
return global_object.vm().throw_completion<URIError>(global_object, ErrorType::URIMalformed);
|
return global_object.vm().throw_completion<URIError>(ErrorType::URIMalformed);
|
||||||
|
|
||||||
auto second_digit = decode_hex_digit(string[k + 2]);
|
auto second_digit = decode_hex_digit(string[k + 2]);
|
||||||
if (second_digit >= 16)
|
if (second_digit >= 16)
|
||||||
return global_object.vm().throw_completion<URIError>(global_object, ErrorType::URIMalformed);
|
return global_object.vm().throw_completion<URIError>(ErrorType::URIMalformed);
|
||||||
|
|
||||||
u8 decoded_code_unit = (first_digit << 4) | second_digit;
|
u8 decoded_code_unit = (first_digit << 4) | second_digit;
|
||||||
k += 2;
|
k += 2;
|
||||||
|
@ -586,7 +586,7 @@ static ThrowCompletionOr<String> decode(GlobalObject& global_object, String cons
|
||||||
decoded_builder.append(decoded_code_unit);
|
decoded_builder.append(decoded_code_unit);
|
||||||
expected_continuation_bytes--;
|
expected_continuation_bytes--;
|
||||||
if (expected_continuation_bytes == 0 && !Utf8View(decoded_builder.string_view().substring_view(code_point_start_offset)).validate())
|
if (expected_continuation_bytes == 0 && !Utf8View(decoded_builder.string_view().substring_view(code_point_start_offset)).validate())
|
||||||
return global_object.vm().throw_completion<URIError>(global_object, ErrorType::URIMalformed);
|
return global_object.vm().throw_completion<URIError>(ErrorType::URIMalformed);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -600,14 +600,14 @@ static ThrowCompletionOr<String> decode(GlobalObject& global_object, String cons
|
||||||
|
|
||||||
auto leading_ones = count_leading_zeroes_safe(static_cast<u8>(~decoded_code_unit));
|
auto leading_ones = count_leading_zeroes_safe(static_cast<u8>(~decoded_code_unit));
|
||||||
if (leading_ones == 1 || leading_ones > 4)
|
if (leading_ones == 1 || leading_ones > 4)
|
||||||
return global_object.vm().throw_completion<URIError>(global_object, ErrorType::URIMalformed);
|
return global_object.vm().throw_completion<URIError>(ErrorType::URIMalformed);
|
||||||
|
|
||||||
code_point_start_offset = decoded_builder.length();
|
code_point_start_offset = decoded_builder.length();
|
||||||
decoded_builder.append(decoded_code_unit);
|
decoded_builder.append(decoded_code_unit);
|
||||||
expected_continuation_bytes = leading_ones - 1;
|
expected_continuation_bytes = leading_ones - 1;
|
||||||
}
|
}
|
||||||
if (expected_continuation_bytes > 0)
|
if (expected_continuation_bytes > 0)
|
||||||
return global_object.vm().throw_completion<URIError>(global_object, ErrorType::URIMalformed);
|
return global_object.vm().throw_completion<URIError>(ErrorType::URIMalformed);
|
||||||
return decoded_builder.build();
|
return decoded_builder.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -229,7 +229,7 @@ ThrowCompletionOr<Vector<String>> canonicalize_locale_list(GlobalObject& global_
|
||||||
|
|
||||||
// ii. If Type(kValue) is not String or Object, throw a TypeError exception.
|
// ii. If Type(kValue) is not String or Object, throw a TypeError exception.
|
||||||
if (!key_value.is_string() && !key_value.is_object())
|
if (!key_value.is_string() && !key_value.is_object())
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::NotAnObjectOrString, key_value.to_string_without_side_effects());
|
return vm.throw_completion<TypeError>(ErrorType::NotAnObjectOrString, key_value.to_string_without_side_effects());
|
||||||
|
|
||||||
String tag;
|
String tag;
|
||||||
|
|
||||||
|
@ -247,7 +247,7 @@ ThrowCompletionOr<Vector<String>> canonicalize_locale_list(GlobalObject& global_
|
||||||
// v. If ! IsStructurallyValidLanguageTag(tag) is false, throw a RangeError exception.
|
// v. If ! IsStructurallyValidLanguageTag(tag) is false, throw a RangeError exception.
|
||||||
auto locale_id = is_structurally_valid_language_tag(tag);
|
auto locale_id = is_structurally_valid_language_tag(tag);
|
||||||
if (!locale_id.has_value())
|
if (!locale_id.has_value())
|
||||||
return vm.throw_completion<RangeError>(global_object, ErrorType::IntlInvalidLanguageTag, tag);
|
return vm.throw_completion<RangeError>(ErrorType::IntlInvalidLanguageTag, tag);
|
||||||
|
|
||||||
// vi. Let canonicalizedTag be ! CanonicalizeUnicodeLocaleId(tag).
|
// vi. Let canonicalizedTag be ! CanonicalizeUnicodeLocaleId(tag).
|
||||||
auto canonicalized_tag = JS::Intl::canonicalize_unicode_locale_id(*locale_id);
|
auto canonicalized_tag = JS::Intl::canonicalize_unicode_locale_id(*locale_id);
|
||||||
|
@ -658,7 +658,7 @@ ThrowCompletionOr<Optional<int>> default_number_option(GlobalObject& global_obje
|
||||||
|
|
||||||
// 3. If value is NaN or less than minimum or greater than maximum, throw a RangeError exception.
|
// 3. If value is NaN or less than minimum or greater than maximum, throw a RangeError exception.
|
||||||
if (value.is_nan() || (value.as_double() < minimum) || (value.as_double() > maximum))
|
if (value.is_nan() || (value.as_double() < minimum) || (value.as_double() > maximum))
|
||||||
return vm.throw_completion<RangeError>(global_object, ErrorType::IntlNumberIsNaNOrOutOfRange, value, minimum, maximum);
|
return vm.throw_completion<RangeError>(ErrorType::IntlNumberIsNaNOrOutOfRange, value, minimum, maximum);
|
||||||
|
|
||||||
// 4. Return floor(value).
|
// 4. Return floor(value).
|
||||||
return floor(value.as_double());
|
return floor(value.as_double());
|
||||||
|
|
|
@ -52,7 +52,7 @@ static ThrowCompletionOr<Collator*> initialize_collator(GlobalObject& global_obj
|
||||||
if (!collation.is_undefined()) {
|
if (!collation.is_undefined()) {
|
||||||
// a. If collation does not match the Unicode Locale Identifier type nonterminal, throw a RangeError exception.
|
// a. If collation does not match the Unicode Locale Identifier type nonterminal, throw a RangeError exception.
|
||||||
if (!Unicode::is_type_identifier(collation.as_string().string()))
|
if (!Unicode::is_type_identifier(collation.as_string().string()))
|
||||||
return vm.throw_completion<RangeError>(global_object, ErrorType::OptionIsNotValidValue, collation, "collation"sv);
|
return vm.throw_completion<RangeError>(ErrorType::OptionIsNotValidValue, collation, "collation"sv);
|
||||||
|
|
||||||
// 12. Set opt.[[co]] to collation.
|
// 12. Set opt.[[co]] to collation.
|
||||||
opt.co = collation.as_string().string();
|
opt.co = collation.as_string().string();
|
||||||
|
|
|
@ -119,13 +119,13 @@ ThrowCompletionOr<Object*> to_date_time_options(GlobalObject& global_object, Val
|
||||||
// 9. If required is "date" and timeStyle is not undefined, then
|
// 9. If required is "date" and timeStyle is not undefined, then
|
||||||
if ((required == OptionRequired::Date) && !time_style.is_undefined()) {
|
if ((required == OptionRequired::Date) && !time_style.is_undefined()) {
|
||||||
// a. Throw a TypeError exception.
|
// a. Throw a TypeError exception.
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::IntlInvalidDateTimeFormatOption, "timeStyle"sv, "date"sv);
|
return vm.throw_completion<TypeError>(ErrorType::IntlInvalidDateTimeFormatOption, "timeStyle"sv, "date"sv);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 10. If required is "time" and dateStyle is not undefined, then
|
// 10. If required is "time" and dateStyle is not undefined, then
|
||||||
if ((required == OptionRequired::Time) && !date_style.is_undefined()) {
|
if ((required == OptionRequired::Time) && !date_style.is_undefined()) {
|
||||||
// a. Throw a TypeError exception.
|
// a. Throw a TypeError exception.
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::IntlInvalidDateTimeFormatOption, "dateStyle"sv, "time"sv);
|
return vm.throw_completion<TypeError>(ErrorType::IntlInvalidDateTimeFormatOption, "dateStyle"sv, "time"sv);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 11. If needDefaults is true and defaults is either "date" or "all", then
|
// 11. If needDefaults is true and defaults is either "date" or "all", then
|
||||||
|
@ -540,7 +540,7 @@ ThrowCompletionOr<Vector<PatternPartition>> format_date_time_pattern(GlobalObjec
|
||||||
|
|
||||||
// 2. If x is NaN, throw a RangeError exception.
|
// 2. If x is NaN, throw a RangeError exception.
|
||||||
if (isnan(time))
|
if (isnan(time))
|
||||||
return vm.throw_completion<RangeError>(global_object, ErrorType::IntlInvalidTime);
|
return vm.throw_completion<RangeError>(ErrorType::IntlInvalidTime);
|
||||||
|
|
||||||
// 3. Let locale be dateTimeFormat.[[Locale]].
|
// 3. Let locale be dateTimeFormat.[[Locale]].
|
||||||
auto const& locale = date_time_format.locale();
|
auto const& locale = date_time_format.locale();
|
||||||
|
@ -928,14 +928,14 @@ ThrowCompletionOr<Vector<PatternPartitionWithSource>> partition_date_time_range_
|
||||||
|
|
||||||
// 2. If x is NaN, throw a RangeError exception.
|
// 2. If x is NaN, throw a RangeError exception.
|
||||||
if (isnan(start))
|
if (isnan(start))
|
||||||
return vm.throw_completion<RangeError>(global_object, ErrorType::IntlInvalidTime);
|
return vm.throw_completion<RangeError>(ErrorType::IntlInvalidTime);
|
||||||
|
|
||||||
// 3. Let y be TimeClip(y).
|
// 3. Let y be TimeClip(y).
|
||||||
end = time_clip(end);
|
end = time_clip(end);
|
||||||
|
|
||||||
// 4. If y is NaN, throw a RangeError exception.
|
// 4. If y is NaN, throw a RangeError exception.
|
||||||
if (isnan(end))
|
if (isnan(end))
|
||||||
return vm.throw_completion<RangeError>(global_object, ErrorType::IntlInvalidTime);
|
return vm.throw_completion<RangeError>(ErrorType::IntlInvalidTime);
|
||||||
|
|
||||||
// 5. Let tm1 be ToLocalTime(x, dateTimeFormat.[[Calendar]], dateTimeFormat.[[TimeZone]]).
|
// 5. Let tm1 be ToLocalTime(x, dateTimeFormat.[[Calendar]], dateTimeFormat.[[TimeZone]]).
|
||||||
auto start_local_time = TRY(to_local_time(global_object, start, date_time_format.calendar(), date_time_format.time_zone()));
|
auto start_local_time = TRY(to_local_time(global_object, start, date_time_format.calendar(), date_time_format.time_zone()));
|
||||||
|
@ -1248,7 +1248,7 @@ ThrowCompletionOr<LocalTime> to_local_time(GlobalObject& global_object, double t
|
||||||
// 3. Else,
|
// 3. Else,
|
||||||
// a. Return a record with the fields of Column 1 of Table 7 calculated from t for the given calendar and timeZone. The calculations should use best available information about the specified calendar and timeZone, including current and historical information about time zone offsets from UTC and daylight saving time rules.
|
// a. Return a record with the fields of Column 1 of Table 7 calculated from t for the given calendar and timeZone. The calculations should use best available information about the specified calendar and timeZone, including current and historical information about time zone offsets from UTC and daylight saving time rules.
|
||||||
// FIXME: Implement this when non-Gregorian calendars are supported by LibUnicode.
|
// FIXME: Implement this when non-Gregorian calendars are supported by LibUnicode.
|
||||||
return global_object.vm().throw_completion<InternalError>(global_object, ErrorType::NotImplemented, "Non-Gregorian calendars"sv);
|
return global_object.vm().throw_completion<InternalError>(ErrorType::NotImplemented, "Non-Gregorian calendars"sv);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -109,7 +109,7 @@ ThrowCompletionOr<DateTimeFormat*> initialize_date_time_format(GlobalObject& glo
|
||||||
if (!calendar.is_undefined()) {
|
if (!calendar.is_undefined()) {
|
||||||
// a. If calendar does not match the Unicode Locale Identifier type nonterminal, throw a RangeError exception.
|
// a. If calendar does not match the Unicode Locale Identifier type nonterminal, throw a RangeError exception.
|
||||||
if (!Unicode::is_type_identifier(calendar.as_string().string()))
|
if (!Unicode::is_type_identifier(calendar.as_string().string()))
|
||||||
return vm.throw_completion<RangeError>(global_object, ErrorType::OptionIsNotValidValue, calendar, "calendar"sv);
|
return vm.throw_completion<RangeError>(ErrorType::OptionIsNotValidValue, calendar, "calendar"sv);
|
||||||
|
|
||||||
// 8. Set opt.[[ca]] to calendar.
|
// 8. Set opt.[[ca]] to calendar.
|
||||||
opt.ca = calendar.as_string().string();
|
opt.ca = calendar.as_string().string();
|
||||||
|
@ -122,7 +122,7 @@ ThrowCompletionOr<DateTimeFormat*> initialize_date_time_format(GlobalObject& glo
|
||||||
if (!numbering_system.is_undefined()) {
|
if (!numbering_system.is_undefined()) {
|
||||||
// a. If numberingSystem does not match the Unicode Locale Identifier type nonterminal, throw a RangeError exception.
|
// a. If numberingSystem does not match the Unicode Locale Identifier type nonterminal, throw a RangeError exception.
|
||||||
if (!Unicode::is_type_identifier(numbering_system.as_string().string()))
|
if (!Unicode::is_type_identifier(numbering_system.as_string().string()))
|
||||||
return vm.throw_completion<RangeError>(global_object, ErrorType::OptionIsNotValidValue, numbering_system, "numberingSystem"sv);
|
return vm.throw_completion<RangeError>(ErrorType::OptionIsNotValidValue, numbering_system, "numberingSystem"sv);
|
||||||
|
|
||||||
// 11. Set opt.[[nu]] to numberingSystem.
|
// 11. Set opt.[[nu]] to numberingSystem.
|
||||||
opt.nu = numbering_system.as_string().string();
|
opt.nu = numbering_system.as_string().string();
|
||||||
|
@ -229,7 +229,7 @@ ThrowCompletionOr<DateTimeFormat*> initialize_date_time_format(GlobalObject& glo
|
||||||
// b. If the result of IsValidTimeZoneName(timeZone) is false, then
|
// b. If the result of IsValidTimeZoneName(timeZone) is false, then
|
||||||
if (!Temporal::is_valid_time_zone_name(time_zone)) {
|
if (!Temporal::is_valid_time_zone_name(time_zone)) {
|
||||||
// i. Throw a RangeError exception.
|
// i. Throw a RangeError exception.
|
||||||
return vm.throw_completion<RangeError>(global_object, ErrorType::OptionIsNotValidValue, time_zone, vm.names.timeZone);
|
return vm.throw_completion<RangeError>(ErrorType::OptionIsNotValidValue, time_zone, vm.names.timeZone);
|
||||||
}
|
}
|
||||||
|
|
||||||
// c. Set timeZone to ! CanonicalizeTimeZoneName(timeZone).
|
// c. Set timeZone to ! CanonicalizeTimeZoneName(timeZone).
|
||||||
|
@ -312,7 +312,7 @@ ThrowCompletionOr<DateTimeFormat*> initialize_date_time_format(GlobalObject& glo
|
||||||
// a. If hasExplicitFormatComponents is true, then
|
// a. If hasExplicitFormatComponents is true, then
|
||||||
if (explicit_format_component != nullptr) {
|
if (explicit_format_component != nullptr) {
|
||||||
// i. Throw a TypeError exception.
|
// i. Throw a TypeError exception.
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::IntlInvalidDateTimeFormatOption, *explicit_format_component, "dateStyle or timeStyle"sv);
|
return vm.throw_completion<TypeError>(ErrorType::IntlInvalidDateTimeFormatOption, *explicit_format_component, "dateStyle or timeStyle"sv);
|
||||||
}
|
}
|
||||||
|
|
||||||
// b. Let styles be dataLocaleData.[[styles]].[[<resolvedCalendar>]].
|
// b. Let styles be dataLocaleData.[[styles]].[[<resolvedCalendar>]].
|
||||||
|
|
|
@ -100,9 +100,9 @@ JS_DEFINE_NATIVE_FUNCTION(DateTimeFormatPrototype::format_range)
|
||||||
|
|
||||||
// 3. If startDate is undefined or endDate is undefined, throw a TypeError exception.
|
// 3. If startDate is undefined or endDate is undefined, throw a TypeError exception.
|
||||||
if (start_date.is_undefined())
|
if (start_date.is_undefined())
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::IsUndefined, "startDate"sv);
|
return vm.throw_completion<TypeError>(ErrorType::IsUndefined, "startDate"sv);
|
||||||
if (end_date.is_undefined())
|
if (end_date.is_undefined())
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::IsUndefined, "endDate"sv);
|
return vm.throw_completion<TypeError>(ErrorType::IsUndefined, "endDate"sv);
|
||||||
|
|
||||||
// 4. Let x be ? ToNumber(startDate).
|
// 4. Let x be ? ToNumber(startDate).
|
||||||
auto start_date_number = TRY(start_date.to_number(global_object)).as_double();
|
auto start_date_number = TRY(start_date.to_number(global_object)).as_double();
|
||||||
|
@ -127,9 +127,9 @@ JS_DEFINE_NATIVE_FUNCTION(DateTimeFormatPrototype::format_range_to_parts)
|
||||||
|
|
||||||
// 3. If startDate is undefined or endDate is undefined, throw a TypeError exception.
|
// 3. If startDate is undefined or endDate is undefined, throw a TypeError exception.
|
||||||
if (start_date.is_undefined())
|
if (start_date.is_undefined())
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::IsUndefined, "startDate"sv);
|
return vm.throw_completion<TypeError>(ErrorType::IsUndefined, "startDate"sv);
|
||||||
if (end_date.is_undefined())
|
if (end_date.is_undefined())
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::IsUndefined, "endDate"sv);
|
return vm.throw_completion<TypeError>(ErrorType::IsUndefined, "endDate"sv);
|
||||||
|
|
||||||
// 4. Let x be ? ToNumber(startDate).
|
// 4. Let x be ? ToNumber(startDate).
|
||||||
auto start_date_number = TRY(start_date.to_number(global_object)).as_double();
|
auto start_date_number = TRY(start_date.to_number(global_object)).as_double();
|
||||||
|
|
|
@ -109,12 +109,12 @@ ThrowCompletionOr<Value> canonical_code_for_display_names(GlobalObject& global_o
|
||||||
if (type == DisplayNames::Type::Language) {
|
if (type == DisplayNames::Type::Language) {
|
||||||
// a. If code does not match the unicode_language_id production, throw a RangeError exception.
|
// a. If code does not match the unicode_language_id production, throw a RangeError exception.
|
||||||
if (!Unicode::parse_unicode_language_id(code).has_value())
|
if (!Unicode::parse_unicode_language_id(code).has_value())
|
||||||
return vm.throw_completion<RangeError>(global_object, ErrorType::OptionIsNotValidValue, code, "language"sv);
|
return vm.throw_completion<RangeError>(ErrorType::OptionIsNotValidValue, code, "language"sv);
|
||||||
|
|
||||||
// b. If IsStructurallyValidLanguageTag(code) is false, throw a RangeError exception.
|
// b. If IsStructurallyValidLanguageTag(code) is false, throw a RangeError exception.
|
||||||
auto locale_id = is_structurally_valid_language_tag(code);
|
auto locale_id = is_structurally_valid_language_tag(code);
|
||||||
if (!locale_id.has_value())
|
if (!locale_id.has_value())
|
||||||
return vm.throw_completion<RangeError>(global_object, ErrorType::IntlInvalidLanguageTag, code);
|
return vm.throw_completion<RangeError>(ErrorType::IntlInvalidLanguageTag, code);
|
||||||
|
|
||||||
// c. Return ! CanonicalizeUnicodeLocaleId(code).
|
// c. Return ! CanonicalizeUnicodeLocaleId(code).
|
||||||
auto canonicalized_tag = Intl::canonicalize_unicode_locale_id(*locale_id);
|
auto canonicalized_tag = Intl::canonicalize_unicode_locale_id(*locale_id);
|
||||||
|
@ -125,7 +125,7 @@ ThrowCompletionOr<Value> canonical_code_for_display_names(GlobalObject& global_o
|
||||||
if (type == DisplayNames::Type::Region) {
|
if (type == DisplayNames::Type::Region) {
|
||||||
// a. If code does not match the unicode_region_subtag production, throw a RangeError exception.
|
// a. If code does not match the unicode_region_subtag production, throw a RangeError exception.
|
||||||
if (!Unicode::is_unicode_region_subtag(code))
|
if (!Unicode::is_unicode_region_subtag(code))
|
||||||
return vm.throw_completion<RangeError>(global_object, ErrorType::OptionIsNotValidValue, code, "region"sv);
|
return vm.throw_completion<RangeError>(ErrorType::OptionIsNotValidValue, code, "region"sv);
|
||||||
|
|
||||||
// b. Return the ASCII-uppercase of code.
|
// b. Return the ASCII-uppercase of code.
|
||||||
return js_string(vm, code.to_uppercase_string());
|
return js_string(vm, code.to_uppercase_string());
|
||||||
|
@ -135,7 +135,7 @@ ThrowCompletionOr<Value> canonical_code_for_display_names(GlobalObject& global_o
|
||||||
if (type == DisplayNames::Type::Script) {
|
if (type == DisplayNames::Type::Script) {
|
||||||
// a. If code does not match the unicode_script_subtag production, throw a RangeError exception.
|
// a. If code does not match the unicode_script_subtag production, throw a RangeError exception.
|
||||||
if (!Unicode::is_unicode_script_subtag(code))
|
if (!Unicode::is_unicode_script_subtag(code))
|
||||||
return vm.throw_completion<RangeError>(global_object, ErrorType::OptionIsNotValidValue, code, "script"sv);
|
return vm.throw_completion<RangeError>(ErrorType::OptionIsNotValidValue, code, "script"sv);
|
||||||
|
|
||||||
// Assert: The length of code is 4, and every code unit of code represents an ASCII letter (0x0041 through 0x005A and 0x0061 through 0x007A, both inclusive).
|
// Assert: The length of code is 4, and every code unit of code represents an ASCII letter (0x0041 through 0x005A and 0x0061 through 0x007A, both inclusive).
|
||||||
VERIFY(code.length() == 4);
|
VERIFY(code.length() == 4);
|
||||||
|
@ -151,11 +151,11 @@ ThrowCompletionOr<Value> canonical_code_for_display_names(GlobalObject& global_o
|
||||||
if (type == DisplayNames::Type::Calendar) {
|
if (type == DisplayNames::Type::Calendar) {
|
||||||
// a. If code does not match the Unicode Locale Identifier type nonterminal, throw a RangeError exception.
|
// a. If code does not match the Unicode Locale Identifier type nonterminal, throw a RangeError exception.
|
||||||
if (!Unicode::is_type_identifier(code))
|
if (!Unicode::is_type_identifier(code))
|
||||||
return vm.throw_completion<RangeError>(global_object, ErrorType::OptionIsNotValidValue, code, "calendar"sv);
|
return vm.throw_completion<RangeError>(ErrorType::OptionIsNotValidValue, code, "calendar"sv);
|
||||||
|
|
||||||
// b. If code uses any of the backwards compatibility syntax described in Unicode Technical Standard #35 LDML § 3.3 BCP 47 Conformance, throw a RangeError exception.
|
// b. If code uses any of the backwards compatibility syntax described in Unicode Technical Standard #35 LDML § 3.3 BCP 47 Conformance, throw a RangeError exception.
|
||||||
if (code.contains('_'))
|
if (code.contains('_'))
|
||||||
return vm.throw_completion<RangeError>(global_object, ErrorType::OptionIsNotValidValue, code, "calendar"sv);
|
return vm.throw_completion<RangeError>(ErrorType::OptionIsNotValidValue, code, "calendar"sv);
|
||||||
|
|
||||||
// c. Return the ASCII-lowercase of code.
|
// c. Return the ASCII-lowercase of code.
|
||||||
return js_string(vm, code.to_lowercase_string());
|
return js_string(vm, code.to_lowercase_string());
|
||||||
|
@ -165,7 +165,7 @@ ThrowCompletionOr<Value> canonical_code_for_display_names(GlobalObject& global_o
|
||||||
if (type == DisplayNames::Type::DateTimeField) {
|
if (type == DisplayNames::Type::DateTimeField) {
|
||||||
// a. If the result of IsValidDateTimeFieldCode(code) is false, throw a RangeError exception.
|
// a. If the result of IsValidDateTimeFieldCode(code) is false, throw a RangeError exception.
|
||||||
if (!is_valid_date_time_field_code(code))
|
if (!is_valid_date_time_field_code(code))
|
||||||
return vm.throw_completion<RangeError>(global_object, ErrorType::OptionIsNotValidValue, code, "dateTimeField"sv);
|
return vm.throw_completion<RangeError>(ErrorType::OptionIsNotValidValue, code, "dateTimeField"sv);
|
||||||
|
|
||||||
// b. Return code.
|
// b. Return code.
|
||||||
return js_string(vm, code);
|
return js_string(vm, code);
|
||||||
|
@ -176,7 +176,7 @@ ThrowCompletionOr<Value> canonical_code_for_display_names(GlobalObject& global_o
|
||||||
|
|
||||||
// 7. If ! IsWellFormedCurrencyCode(code) is false, throw a RangeError exception.
|
// 7. If ! IsWellFormedCurrencyCode(code) is false, throw a RangeError exception.
|
||||||
if (!is_well_formed_currency_code(code))
|
if (!is_well_formed_currency_code(code))
|
||||||
return vm.throw_completion<RangeError>(global_object, ErrorType::OptionIsNotValidValue, code, "currency"sv);
|
return vm.throw_completion<RangeError>(ErrorType::OptionIsNotValidValue, code, "currency"sv);
|
||||||
|
|
||||||
// 8. Return the ASCII-uppercase of code.
|
// 8. Return the ASCII-uppercase of code.
|
||||||
return js_string(vm, code.to_uppercase_string());
|
return js_string(vm, code.to_uppercase_string());
|
||||||
|
|
|
@ -40,7 +40,7 @@ void DisplayNamesConstructor::initialize(Realm& realm)
|
||||||
ThrowCompletionOr<Value> DisplayNamesConstructor::call()
|
ThrowCompletionOr<Value> DisplayNamesConstructor::call()
|
||||||
{
|
{
|
||||||
// 1. If NewTarget is undefined, throw a TypeError exception.
|
// 1. If NewTarget is undefined, throw a TypeError exception.
|
||||||
return vm().throw_completion<TypeError>(global_object(), ErrorType::ConstructorWithoutNew, "Intl.DisplayNames");
|
return vm().throw_completion<TypeError>(ErrorType::ConstructorWithoutNew, "Intl.DisplayNames");
|
||||||
}
|
}
|
||||||
|
|
||||||
// 12.1.1 Intl.DisplayNames ( locales, options ), https://tc39.es/ecma402/#sec-Intl.DisplayNames
|
// 12.1.1 Intl.DisplayNames ( locales, options ), https://tc39.es/ecma402/#sec-Intl.DisplayNames
|
||||||
|
@ -60,7 +60,7 @@ ThrowCompletionOr<Object*> DisplayNamesConstructor::construct(FunctionObject& ne
|
||||||
|
|
||||||
// 4. If options is undefined, throw a TypeError exception.
|
// 4. If options is undefined, throw a TypeError exception.
|
||||||
if (options_value.is_undefined())
|
if (options_value.is_undefined())
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::IsUndefined, "options"sv);
|
return vm.throw_completion<TypeError>(ErrorType::IsUndefined, "options"sv);
|
||||||
|
|
||||||
// 5. Set options to ? GetOptionsObject(options).
|
// 5. Set options to ? GetOptionsObject(options).
|
||||||
auto* options = TRY(Temporal::get_options_object(global_object, options_value));
|
auto* options = TRY(Temporal::get_options_object(global_object, options_value));
|
||||||
|
@ -90,7 +90,7 @@ ThrowCompletionOr<Object*> DisplayNamesConstructor::construct(FunctionObject& ne
|
||||||
|
|
||||||
// 14. If type is undefined, throw a TypeError exception.
|
// 14. If type is undefined, throw a TypeError exception.
|
||||||
if (type.is_undefined())
|
if (type.is_undefined())
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::IsUndefined, "options.type"sv);
|
return vm.throw_completion<TypeError>(ErrorType::IsUndefined, "options.type"sv);
|
||||||
|
|
||||||
// 15. Set displayNames.[[Type]] to type.
|
// 15. Set displayNames.[[Type]] to type.
|
||||||
display_names->set_type(type.as_string().string());
|
display_names->set_type(type.as_string().string());
|
||||||
|
|
|
@ -137,7 +137,7 @@ ThrowCompletionOr<Temporal::DurationRecord> to_duration_record(GlobalObject& glo
|
||||||
|
|
||||||
// 1. If Type(input) is not Object, throw a TypeError exception.
|
// 1. If Type(input) is not Object, throw a TypeError exception.
|
||||||
if (!input.is_object())
|
if (!input.is_object())
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::NotAnObject, input);
|
return vm.throw_completion<TypeError>(ErrorType::NotAnObject, input);
|
||||||
auto& input_object = input.as_object();
|
auto& input_object = input.as_object();
|
||||||
|
|
||||||
// 2. Let result be a new Record.
|
// 2. Let result be a new Record.
|
||||||
|
@ -177,7 +177,7 @@ ThrowCompletionOr<Temporal::DurationRecord> to_duration_record(GlobalObject& glo
|
||||||
|
|
||||||
// 5. If any is false, throw a TypeError exception.
|
// 5. If any is false, throw a TypeError exception.
|
||||||
if (!any)
|
if (!any)
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::TemporalInvalidDurationLikeObject);
|
return vm.throw_completion<TypeError>(ErrorType::TemporalInvalidDurationLikeObject);
|
||||||
|
|
||||||
// 6. Return result.
|
// 6. Return result.
|
||||||
return result;
|
return result;
|
||||||
|
@ -281,7 +281,7 @@ ThrowCompletionOr<DurationUnitOptions> get_duration_unit_options(GlobalObject& g
|
||||||
// a. If style is not "numeric" or "2-digit", then
|
// a. If style is not "numeric" or "2-digit", then
|
||||||
if (style != "numeric"sv && style != "2-digit"sv) {
|
if (style != "numeric"sv && style != "2-digit"sv) {
|
||||||
// i. Throw a RangeError exception.
|
// i. Throw a RangeError exception.
|
||||||
return vm.throw_completion<RangeError>(global_object, ErrorType::IntlNonNumericOr2DigitAfterNumericOr2Digit);
|
return vm.throw_completion<RangeError>(ErrorType::IntlNonNumericOr2DigitAfterNumericOr2Digit);
|
||||||
}
|
}
|
||||||
// b. Else if unit is "minutes" or "seconds", then
|
// b. Else if unit is "minutes" or "seconds", then
|
||||||
else if (unit == "minutes"sv || unit == "seconds"sv) {
|
else if (unit == "minutes"sv || unit == "seconds"sv) {
|
||||||
|
|
|
@ -37,7 +37,7 @@ void DurationFormatConstructor::initialize(Realm& realm)
|
||||||
ThrowCompletionOr<Value> DurationFormatConstructor::call()
|
ThrowCompletionOr<Value> DurationFormatConstructor::call()
|
||||||
{
|
{
|
||||||
// 1. If NewTarget is undefined, throw a TypeError exception.
|
// 1. If NewTarget is undefined, throw a TypeError exception.
|
||||||
return vm().throw_completion<TypeError>(global_object(), ErrorType::ConstructorWithoutNew, "Intl.DurationFormat");
|
return vm().throw_completion<TypeError>(ErrorType::ConstructorWithoutNew, "Intl.DurationFormat");
|
||||||
}
|
}
|
||||||
|
|
||||||
// 1.2.1 Intl.DurationFormat ( [ locales [ , options ] ] ), https://tc39.es/proposal-intl-duration-format/#sec-Intl.DurationFormat
|
// 1.2.1 Intl.DurationFormat ( [ locales [ , options ] ] ), https://tc39.es/proposal-intl-duration-format/#sec-Intl.DurationFormat
|
||||||
|
@ -68,7 +68,7 @@ ThrowCompletionOr<Object*> DurationFormatConstructor::construct(FunctionObject&
|
||||||
if (!numbering_system.is_undefined()) {
|
if (!numbering_system.is_undefined()) {
|
||||||
// 7. If numberingSystem does not match the Unicode Locale Identifier type nonterminal, throw a RangeError exception.
|
// 7. If numberingSystem does not match the Unicode Locale Identifier type nonterminal, throw a RangeError exception.
|
||||||
if (numbering_system.is_undefined() || !Unicode::is_type_identifier(numbering_system.as_string().string()))
|
if (numbering_system.is_undefined() || !Unicode::is_type_identifier(numbering_system.as_string().string()))
|
||||||
return vm.throw_completion<RangeError>(global_object, ErrorType::OptionIsNotValidValue, numbering_system, "numberingSystem"sv);
|
return vm.throw_completion<RangeError>(ErrorType::OptionIsNotValidValue, numbering_system, "numberingSystem"sv);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 8. Let opt be the Record { [[localeMatcher]]: matcher, [[nu]]: numberingSystem }.
|
// 8. Let opt be the Record { [[localeMatcher]]: matcher, [[nu]]: numberingSystem }.
|
||||||
|
|
|
@ -43,7 +43,7 @@ JS_DEFINE_NATIVE_FUNCTION(DurationFormatPrototype::format)
|
||||||
|
|
||||||
// 4. If IsValidDurationRecord(record) is false, throw a RangeError exception.
|
// 4. If IsValidDurationRecord(record) is false, throw a RangeError exception.
|
||||||
if (!is_valid_duration_record(record))
|
if (!is_valid_duration_record(record))
|
||||||
return vm.throw_completion<RangeError>(global_object, ErrorType::TemporalInvalidDurationLikeObject);
|
return vm.throw_completion<RangeError>(ErrorType::TemporalInvalidDurationLikeObject);
|
||||||
|
|
||||||
// 5. Let formatted be ? PartitionDurationFormatPattern(df, record).
|
// 5. Let formatted be ? PartitionDurationFormatPattern(df, record).
|
||||||
auto formatted = TRY(partition_duration_format_pattern(global_object, *duration_format, record));
|
auto formatted = TRY(partition_duration_format_pattern(global_object, *duration_format, record));
|
||||||
|
@ -75,7 +75,7 @@ JS_DEFINE_NATIVE_FUNCTION(DurationFormatPrototype::format_to_parts)
|
||||||
|
|
||||||
// 4. If IsValidDurationRecord(record) is false, throw a RangeError exception.
|
// 4. If IsValidDurationRecord(record) is false, throw a RangeError exception.
|
||||||
if (!is_valid_duration_record(record))
|
if (!is_valid_duration_record(record))
|
||||||
return vm.throw_completion<RangeError>(global_object, ErrorType::TemporalInvalidDurationLikeObject);
|
return vm.throw_completion<RangeError>(ErrorType::TemporalInvalidDurationLikeObject);
|
||||||
|
|
||||||
// 5. Let formatted be ? PartitionDurationFormatPattern(df, record).
|
// 5. Let formatted be ? PartitionDurationFormatPattern(df, record).
|
||||||
auto formatted = TRY(partition_duration_format_pattern(global_object, *duration_format, record));
|
auto formatted = TRY(partition_duration_format_pattern(global_object, *duration_format, record));
|
||||||
|
|
|
@ -151,7 +151,7 @@ JS_DEFINE_NATIVE_FUNCTION(Intl::supported_values_of)
|
||||||
// 8. Else,
|
// 8. Else,
|
||||||
else {
|
else {
|
||||||
// a. Throw a RangeError exception.
|
// a. Throw a RangeError exception.
|
||||||
return vm.throw_completion<RangeError>(global_object, ErrorType::IntlInvalidKey, key);
|
return vm.throw_completion<RangeError>(ErrorType::IntlInvalidKey, key);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 9. Return CreateArrayFromList( list ).
|
// 9. Return CreateArrayFromList( list ).
|
||||||
|
|
|
@ -270,7 +270,7 @@ ThrowCompletionOr<Vector<String>> string_list_from_iterable(GlobalObject& global
|
||||||
// ii. If Type(nextValue) is not String, then
|
// ii. If Type(nextValue) is not String, then
|
||||||
if (!next_value.is_string()) {
|
if (!next_value.is_string()) {
|
||||||
// 1. Let error be ThrowCompletion(a newly created TypeError object).
|
// 1. Let error be ThrowCompletion(a newly created TypeError object).
|
||||||
auto error = vm.throw_completion<TypeError>(global_object, ErrorType::NotAString, next_value);
|
auto error = vm.throw_completion<TypeError>(ErrorType::NotAString, next_value);
|
||||||
|
|
||||||
// 2. Return ? IteratorClose(iteratorRecord, error).
|
// 2. Return ? IteratorClose(iteratorRecord, error).
|
||||||
return iterator_close(global_object, iterator_record, move(error));
|
return iterator_close(global_object, iterator_record, move(error));
|
||||||
|
|
|
@ -39,7 +39,7 @@ void ListFormatConstructor::initialize(Realm& realm)
|
||||||
ThrowCompletionOr<Value> ListFormatConstructor::call()
|
ThrowCompletionOr<Value> ListFormatConstructor::call()
|
||||||
{
|
{
|
||||||
// 1. If NewTarget is undefined, throw a TypeError exception.
|
// 1. If NewTarget is undefined, throw a TypeError exception.
|
||||||
return vm().throw_completion<TypeError>(global_object(), ErrorType::ConstructorWithoutNew, "Intl.ListFormat");
|
return vm().throw_completion<TypeError>(ErrorType::ConstructorWithoutNew, "Intl.ListFormat");
|
||||||
}
|
}
|
||||||
|
|
||||||
// 13.1.1 Intl.ListFormat ( [ locales [ , options ] ] ), https://tc39.es/ecma402/#sec-Intl.ListFormat
|
// 13.1.1 Intl.ListFormat ( [ locales [ , options ] ] ), https://tc39.es/ecma402/#sec-Intl.ListFormat
|
||||||
|
|
|
@ -35,7 +35,7 @@ static ThrowCompletionOr<Optional<String>> get_string_option(GlobalObject& globa
|
||||||
return Optional<String> {};
|
return Optional<String> {};
|
||||||
|
|
||||||
if (validator && !validator(option.as_string().string()))
|
if (validator && !validator(option.as_string().string()))
|
||||||
return vm.throw_completion<RangeError>(global_object, ErrorType::OptionIsNotValidValue, option, property);
|
return vm.throw_completion<RangeError>(ErrorType::OptionIsNotValidValue, option, property);
|
||||||
|
|
||||||
return option.as_string().string();
|
return option.as_string().string();
|
||||||
}
|
}
|
||||||
|
@ -51,7 +51,7 @@ static ThrowCompletionOr<String> apply_options_to_tag(GlobalObject& global_objec
|
||||||
// 3. If ! IsStructurallyValidLanguageTag(tag) is false, throw a RangeError exception.
|
// 3. If ! IsStructurallyValidLanguageTag(tag) is false, throw a RangeError exception.
|
||||||
auto locale_id = is_structurally_valid_language_tag(tag);
|
auto locale_id = is_structurally_valid_language_tag(tag);
|
||||||
if (!locale_id.has_value())
|
if (!locale_id.has_value())
|
||||||
return vm.throw_completion<RangeError>(global_object, ErrorType::IntlInvalidLanguageTag, tag);
|
return vm.throw_completion<RangeError>(ErrorType::IntlInvalidLanguageTag, tag);
|
||||||
|
|
||||||
// 4. Let language be ? GetOption(options, "language", "string", undefined, undefined).
|
// 4. Let language be ? GetOption(options, "language", "string", undefined, undefined).
|
||||||
// 5. If language is not undefined, then
|
// 5. If language is not undefined, then
|
||||||
|
@ -240,7 +240,7 @@ void LocaleConstructor::initialize(Realm& realm)
|
||||||
ThrowCompletionOr<Value> LocaleConstructor::call()
|
ThrowCompletionOr<Value> LocaleConstructor::call()
|
||||||
{
|
{
|
||||||
// 1. If NewTarget is undefined, throw a TypeError exception.
|
// 1. If NewTarget is undefined, throw a TypeError exception.
|
||||||
return vm().throw_completion<TypeError>(global_object(), ErrorType::ConstructorWithoutNew, "Intl.Locale");
|
return vm().throw_completion<TypeError>(ErrorType::ConstructorWithoutNew, "Intl.Locale");
|
||||||
}
|
}
|
||||||
|
|
||||||
// 14.1.1 Intl.Locale ( tag [ , options ] ), https://tc39.es/ecma402/#sec-Intl.Locale
|
// 14.1.1 Intl.Locale ( tag [ , options ] ), https://tc39.es/ecma402/#sec-Intl.Locale
|
||||||
|
@ -268,7 +268,7 @@ ThrowCompletionOr<Object*> LocaleConstructor::construct(FunctionObject& new_targ
|
||||||
|
|
||||||
// 7. If Type(tag) is not String or Object, throw a TypeError exception.
|
// 7. If Type(tag) is not String or Object, throw a TypeError exception.
|
||||||
if (!tag_value.is_string() && !tag_value.is_object())
|
if (!tag_value.is_string() && !tag_value.is_object())
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::NotAnObjectOrString, "tag"sv);
|
return vm.throw_completion<TypeError>(ErrorType::NotAnObjectOrString, "tag"sv);
|
||||||
|
|
||||||
// 8. If Type(tag) is Object and tag has an [[InitializedLocale]] internal slot, then
|
// 8. If Type(tag) is Object and tag has an [[InitializedLocale]] internal slot, then
|
||||||
if (tag_value.is_object() && is<Locale>(tag_value.as_object())) {
|
if (tag_value.is_object() && is<Locale>(tag_value.as_object())) {
|
||||||
|
|
|
@ -1726,9 +1726,9 @@ ThrowCompletionOr<Vector<PatternPartitionWithSource>> partition_number_range_pat
|
||||||
|
|
||||||
// 1. If x is NaN or y is NaN, throw a RangeError exception.
|
// 1. If x is NaN or y is NaN, throw a RangeError exception.
|
||||||
if (start.is_nan())
|
if (start.is_nan())
|
||||||
return vm.throw_completion<RangeError>(global_object, ErrorType::IntlNumberIsNaN, "start"sv);
|
return vm.throw_completion<RangeError>(ErrorType::IntlNumberIsNaN, "start"sv);
|
||||||
if (end.is_nan())
|
if (end.is_nan())
|
||||||
return vm.throw_completion<RangeError>(global_object, ErrorType::IntlNumberIsNaN, "end"sv);
|
return vm.throw_completion<RangeError>(ErrorType::IntlNumberIsNaN, "end"sv);
|
||||||
|
|
||||||
// 2. Let result be a new empty List.
|
// 2. Let result be a new empty List.
|
||||||
Vector<PatternPartitionWithSource> result;
|
Vector<PatternPartitionWithSource> result;
|
||||||
|
|
|
@ -107,7 +107,7 @@ ThrowCompletionOr<NumberFormat*> initialize_number_format(GlobalObject& global_o
|
||||||
if (!numbering_system.is_undefined()) {
|
if (!numbering_system.is_undefined()) {
|
||||||
// a. If numberingSystem does not match the Unicode Locale Identifier type nonterminal, throw a RangeError exception.
|
// a. If numberingSystem does not match the Unicode Locale Identifier type nonterminal, throw a RangeError exception.
|
||||||
if (!Unicode::is_type_identifier(numbering_system.as_string().string()))
|
if (!Unicode::is_type_identifier(numbering_system.as_string().string()))
|
||||||
return vm.throw_completion<RangeError>(global_object, ErrorType::OptionIsNotValidValue, numbering_system, "numberingSystem"sv);
|
return vm.throw_completion<RangeError>(ErrorType::OptionIsNotValidValue, numbering_system, "numberingSystem"sv);
|
||||||
|
|
||||||
// 8. Set opt.[[nu]] to numberingSystem.
|
// 8. Set opt.[[nu]] to numberingSystem.
|
||||||
opt.nu = numbering_system.as_string().string();
|
opt.nu = numbering_system.as_string().string();
|
||||||
|
@ -178,15 +178,15 @@ ThrowCompletionOr<NumberFormat*> initialize_number_format(GlobalObject& global_o
|
||||||
static constexpr auto sanctioned_rounding_increments = AK::Array { 1, 2, 5, 10, 20, 25, 50, 100, 200, 250, 500, 1000, 2000, 2500, 5000 };
|
static constexpr auto sanctioned_rounding_increments = AK::Array { 1, 2, 5, 10, 20, 25, 50, 100, 200, 250, 500, 1000, 2000, 2500, 5000 };
|
||||||
|
|
||||||
if (!sanctioned_rounding_increments.span().contains_slow(*rounding_increment))
|
if (!sanctioned_rounding_increments.span().contains_slow(*rounding_increment))
|
||||||
return vm.throw_completion<RangeError>(global_object, ErrorType::IntlInvalidRoundingIncrement, *rounding_increment);
|
return vm.throw_completion<RangeError>(ErrorType::IntlInvalidRoundingIncrement, *rounding_increment);
|
||||||
|
|
||||||
// 23. If roundingIncrement is not 1 and numberFormat.[[RoundingType]] is not fractionDigits, throw a TypeError exception.
|
// 23. If roundingIncrement is not 1 and numberFormat.[[RoundingType]] is not fractionDigits, throw a TypeError exception.
|
||||||
if ((rounding_increment != 1) && (number_format.rounding_type() != NumberFormatBase::RoundingType::FractionDigits))
|
if ((rounding_increment != 1) && (number_format.rounding_type() != NumberFormatBase::RoundingType::FractionDigits))
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::IntlInvalidRoundingIncrementForRoundingType, *rounding_increment, number_format.rounding_type_string());
|
return vm.throw_completion<TypeError>(ErrorType::IntlInvalidRoundingIncrementForRoundingType, *rounding_increment, number_format.rounding_type_string());
|
||||||
|
|
||||||
// 24. If roundingIncrement is not 1 and numberFormat.[[MaximumFractionDigits]] is not equal to numberFormat.[[MinimumFractionDigits]], throw a RangeError exception.
|
// 24. If roundingIncrement is not 1 and numberFormat.[[MaximumFractionDigits]] is not equal to numberFormat.[[MinimumFractionDigits]], throw a RangeError exception.
|
||||||
if ((rounding_increment != 1) && (number_format.max_fraction_digits() != number_format.min_fraction_digits()))
|
if ((rounding_increment != 1) && (number_format.max_fraction_digits() != number_format.min_fraction_digits()))
|
||||||
return vm.throw_completion<RangeError>(global_object, ErrorType::IntlInvalidRoundingIncrementForFractionDigits, *rounding_increment);
|
return vm.throw_completion<RangeError>(ErrorType::IntlInvalidRoundingIncrementForFractionDigits, *rounding_increment);
|
||||||
|
|
||||||
// 25. Set numberFormat.[[RoundingIncrement]] to roundingIncrement.
|
// 25. Set numberFormat.[[RoundingIncrement]] to roundingIncrement.
|
||||||
number_format.set_rounding_increment(*rounding_increment);
|
number_format.set_rounding_increment(*rounding_increment);
|
||||||
|
@ -335,7 +335,7 @@ ThrowCompletionOr<void> set_number_format_digit_options(GlobalObject& global_obj
|
||||||
max_digits = max(default_max_fraction_digits, *min_digits);
|
max_digits = max(default_max_fraction_digits, *min_digits);
|
||||||
// v. Else if mnfd is greater than mxfd, throw a RangeError exception.
|
// v. Else if mnfd is greater than mxfd, throw a RangeError exception.
|
||||||
else if (*min_digits > *max_digits)
|
else if (*min_digits > *max_digits)
|
||||||
return vm.throw_completion<RangeError>(global_object, ErrorType::IntlMinimumExceedsMaximum, *min_digits, *max_digits);
|
return vm.throw_completion<RangeError>(ErrorType::IntlMinimumExceedsMaximum, *min_digits, *max_digits);
|
||||||
|
|
||||||
// vi. Set intlObj.[[MinimumFractionDigits]] to mnfd.
|
// vi. Set intlObj.[[MinimumFractionDigits]] to mnfd.
|
||||||
intl_object.set_min_fraction_digits(*min_digits);
|
intl_object.set_min_fraction_digits(*min_digits);
|
||||||
|
@ -419,12 +419,12 @@ ThrowCompletionOr<void> set_number_format_unit_options(GlobalObject& global_obje
|
||||||
if (currency.is_undefined()) {
|
if (currency.is_undefined()) {
|
||||||
// a. If style is "currency", throw a TypeError exception.
|
// a. If style is "currency", throw a TypeError exception.
|
||||||
if (intl_object.style() == NumberFormat::Style::Currency)
|
if (intl_object.style() == NumberFormat::Style::Currency)
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::IntlOptionUndefined, "currency"sv, "style"sv, style);
|
return vm.throw_completion<TypeError>(ErrorType::IntlOptionUndefined, "currency"sv, "style"sv, style);
|
||||||
}
|
}
|
||||||
// 7. Else,
|
// 7. Else,
|
||||||
// a. If ! IsWellFormedCurrencyCode(currency) is false, throw a RangeError exception.
|
// a. If ! IsWellFormedCurrencyCode(currency) is false, throw a RangeError exception.
|
||||||
else if (!is_well_formed_currency_code(currency.as_string().string()))
|
else if (!is_well_formed_currency_code(currency.as_string().string()))
|
||||||
return vm.throw_completion<RangeError>(global_object, ErrorType::OptionIsNotValidValue, currency, "currency"sv);
|
return vm.throw_completion<RangeError>(ErrorType::OptionIsNotValidValue, currency, "currency"sv);
|
||||||
|
|
||||||
// 8. Let currencyDisplay be ? GetOption(options, "currencyDisplay", "string", « "code", "symbol", "narrowSymbol", "name" », "symbol").
|
// 8. Let currencyDisplay be ? GetOption(options, "currencyDisplay", "string", « "code", "symbol", "narrowSymbol", "name" », "symbol").
|
||||||
auto currency_display = TRY(get_option(global_object, options, vm.names.currencyDisplay, OptionType::String, { "code"sv, "symbol"sv, "narrowSymbol"sv, "name"sv }, "symbol"sv));
|
auto currency_display = TRY(get_option(global_object, options, vm.names.currencyDisplay, OptionType::String, { "code"sv, "symbol"sv, "narrowSymbol"sv, "name"sv }, "symbol"sv));
|
||||||
|
@ -439,12 +439,12 @@ ThrowCompletionOr<void> set_number_format_unit_options(GlobalObject& global_obje
|
||||||
if (unit.is_undefined()) {
|
if (unit.is_undefined()) {
|
||||||
// a. If style is "unit", throw a TypeError exception.
|
// a. If style is "unit", throw a TypeError exception.
|
||||||
if (intl_object.style() == NumberFormat::Style::Unit)
|
if (intl_object.style() == NumberFormat::Style::Unit)
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::IntlOptionUndefined, "unit"sv, "style"sv, style);
|
return vm.throw_completion<TypeError>(ErrorType::IntlOptionUndefined, "unit"sv, "style"sv, style);
|
||||||
}
|
}
|
||||||
// 12. Else,
|
// 12. Else,
|
||||||
// a. If ! IsWellFormedUnitIdentifier(unit) is false, throw a RangeError exception.
|
// a. If ! IsWellFormedUnitIdentifier(unit) is false, throw a RangeError exception.
|
||||||
else if (!is_well_formed_unit_identifier(unit.as_string().string()))
|
else if (!is_well_formed_unit_identifier(unit.as_string().string()))
|
||||||
return vm.throw_completion<RangeError>(global_object, ErrorType::OptionIsNotValidValue, unit, "unit"sv);
|
return vm.throw_completion<RangeError>(ErrorType::OptionIsNotValidValue, unit, "unit"sv);
|
||||||
|
|
||||||
// 13. Let unitDisplay be ? GetOption(options, "unitDisplay", "string", « "short", "narrow", "long" », "short").
|
// 13. Let unitDisplay be ? GetOption(options, "unitDisplay", "string", « "short", "narrow", "long" », "short").
|
||||||
auto unit_display = TRY(get_option(global_object, options, vm.names.unitDisplay, OptionType::String, { "short"sv, "narrow"sv, "long"sv }, "short"sv));
|
auto unit_display = TRY(get_option(global_object, options, vm.names.unitDisplay, OptionType::String, { "short"sv, "narrow"sv, "long"sv }, "short"sv));
|
||||||
|
|
|
@ -92,9 +92,9 @@ JS_DEFINE_NATIVE_FUNCTION(NumberFormatPrototype::format_range)
|
||||||
|
|
||||||
// 3. If start is undefined or end is undefined, throw a TypeError exception.
|
// 3. If start is undefined or end is undefined, throw a TypeError exception.
|
||||||
if (start.is_undefined())
|
if (start.is_undefined())
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::IsUndefined, "start"sv);
|
return vm.throw_completion<TypeError>(ErrorType::IsUndefined, "start"sv);
|
||||||
if (end.is_undefined())
|
if (end.is_undefined())
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::IsUndefined, "end"sv);
|
return vm.throw_completion<TypeError>(ErrorType::IsUndefined, "end"sv);
|
||||||
|
|
||||||
// 4. Let x be ? ToIntlMathematicalValue(start).
|
// 4. Let x be ? ToIntlMathematicalValue(start).
|
||||||
auto x = TRY(to_intl_mathematical_value(global_object, start));
|
auto x = TRY(to_intl_mathematical_value(global_object, start));
|
||||||
|
@ -119,9 +119,9 @@ JS_DEFINE_NATIVE_FUNCTION(NumberFormatPrototype::format_range_to_parts)
|
||||||
|
|
||||||
// 3. If start is undefined or end is undefined, throw a TypeError exception.
|
// 3. If start is undefined or end is undefined, throw a TypeError exception.
|
||||||
if (start.is_undefined())
|
if (start.is_undefined())
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::IsUndefined, "start"sv);
|
return vm.throw_completion<TypeError>(ErrorType::IsUndefined, "start"sv);
|
||||||
if (end.is_undefined())
|
if (end.is_undefined())
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::IsUndefined, "end"sv);
|
return vm.throw_completion<TypeError>(ErrorType::IsUndefined, "end"sv);
|
||||||
|
|
||||||
// 4. Let x be ? ToIntlMathematicalValue(start).
|
// 4. Let x be ? ToIntlMathematicalValue(start).
|
||||||
auto x = TRY(to_intl_mathematical_value(global_object, start));
|
auto x = TRY(to_intl_mathematical_value(global_object, start));
|
||||||
|
|
|
@ -148,9 +148,9 @@ ThrowCompletionOr<Unicode::PluralCategory> resolve_plural_range(GlobalObject& gl
|
||||||
|
|
||||||
// 5. If x is NaN or y is NaN, throw a RangeError exception.
|
// 5. If x is NaN or y is NaN, throw a RangeError exception.
|
||||||
if (start.is_nan())
|
if (start.is_nan())
|
||||||
return vm.throw_completion<RangeError>(global_object, ErrorType::IntlNumberIsNaN, "start"sv);
|
return vm.throw_completion<RangeError>(ErrorType::IntlNumberIsNaN, "start"sv);
|
||||||
if (end.is_nan())
|
if (end.is_nan())
|
||||||
return vm.throw_completion<RangeError>(global_object, ErrorType::IntlNumberIsNaN, "end"sv);
|
return vm.throw_completion<RangeError>(ErrorType::IntlNumberIsNaN, "end"sv);
|
||||||
|
|
||||||
// 6. Let xp be ! ResolvePlural(pluralRules, x).
|
// 6. Let xp be ! ResolvePlural(pluralRules, x).
|
||||||
auto start_plurality = resolve_plural(plural_rules, start);
|
auto start_plurality = resolve_plural(plural_rules, start);
|
||||||
|
|
|
@ -39,7 +39,7 @@ void PluralRulesConstructor::initialize(Realm& realm)
|
||||||
ThrowCompletionOr<Value> PluralRulesConstructor::call()
|
ThrowCompletionOr<Value> PluralRulesConstructor::call()
|
||||||
{
|
{
|
||||||
// 1. If NewTarget is undefined, throw a TypeError exception.
|
// 1. If NewTarget is undefined, throw a TypeError exception.
|
||||||
return vm().throw_completion<TypeError>(global_object(), ErrorType::ConstructorWithoutNew, "Intl.PluralRules");
|
return vm().throw_completion<TypeError>(ErrorType::ConstructorWithoutNew, "Intl.PluralRules");
|
||||||
}
|
}
|
||||||
|
|
||||||
// 16.1.1 Intl.PluralRules ( [ locales [ , options ] ] ), https://tc39.es/ecma402/#sec-intl.pluralrules
|
// 16.1.1 Intl.PluralRules ( [ locales [ , options ] ] ), https://tc39.es/ecma402/#sec-intl.pluralrules
|
||||||
|
|
|
@ -60,9 +60,9 @@ JS_DEFINE_NATIVE_FUNCTION(PluralRulesPrototype::select_range)
|
||||||
|
|
||||||
// 3. If start is undefined or end is undefined, throw a TypeError exception.
|
// 3. If start is undefined or end is undefined, throw a TypeError exception.
|
||||||
if (start.is_undefined())
|
if (start.is_undefined())
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::IsUndefined, "start"sv);
|
return vm.throw_completion<TypeError>(ErrorType::IsUndefined, "start"sv);
|
||||||
if (end.is_undefined())
|
if (end.is_undefined())
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::IsUndefined, "end"sv);
|
return vm.throw_completion<TypeError>(ErrorType::IsUndefined, "end"sv);
|
||||||
|
|
||||||
// 4. Let x be ? ToNumber(start).
|
// 4. Let x be ? ToNumber(start).
|
||||||
auto x = TRY(start.to_number(global_object));
|
auto x = TRY(start.to_number(global_object));
|
||||||
|
|
|
@ -89,7 +89,7 @@ ThrowCompletionOr<Unicode::TimeUnit> singular_relative_time_unit(GlobalObject& g
|
||||||
// 11. Return unit.
|
// 11. Return unit.
|
||||||
if (auto time_unit = Unicode::time_unit_from_string(unit); time_unit.has_value())
|
if (auto time_unit = Unicode::time_unit_from_string(unit); time_unit.has_value())
|
||||||
return *time_unit;
|
return *time_unit;
|
||||||
return vm.throw_completion<RangeError>(global_object, ErrorType::IntlInvalidUnit, unit);
|
return vm.throw_completion<RangeError>(ErrorType::IntlInvalidUnit, unit);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 17.5.2 PartitionRelativeTimePattern ( relativeTimeFormat, value, unit ), https://tc39.es/ecma402/#sec-PartitionRelativeTimePattern
|
// 17.5.2 PartitionRelativeTimePattern ( relativeTimeFormat, value, unit ), https://tc39.es/ecma402/#sec-PartitionRelativeTimePattern
|
||||||
|
@ -103,7 +103,7 @@ ThrowCompletionOr<Vector<PatternPartitionWithUnit>> partition_relative_time_patt
|
||||||
|
|
||||||
// 4. If value is NaN, +∞𝔽, or -∞𝔽, throw a RangeError exception.
|
// 4. If value is NaN, +∞𝔽, or -∞𝔽, throw a RangeError exception.
|
||||||
if (!Value(value).is_finite_number())
|
if (!Value(value).is_finite_number())
|
||||||
return vm.throw_completion<RangeError>(global_object, ErrorType::IntlNumberIsNaNOrInfinity);
|
return vm.throw_completion<RangeError>(ErrorType::IntlNumberIsNaNOrInfinity);
|
||||||
|
|
||||||
// 5. Let unit be ? SingularRelativeTimeUnit(unit).
|
// 5. Let unit be ? SingularRelativeTimeUnit(unit).
|
||||||
auto time_unit = TRY(singular_relative_time_unit(global_object, unit));
|
auto time_unit = TRY(singular_relative_time_unit(global_object, unit));
|
||||||
|
|
|
@ -42,7 +42,7 @@ void RelativeTimeFormatConstructor::initialize(Realm& realm)
|
||||||
ThrowCompletionOr<Value> RelativeTimeFormatConstructor::call()
|
ThrowCompletionOr<Value> RelativeTimeFormatConstructor::call()
|
||||||
{
|
{
|
||||||
// 1. If NewTarget is undefined, throw a TypeError exception.
|
// 1. If NewTarget is undefined, throw a TypeError exception.
|
||||||
return vm().throw_completion<TypeError>(global_object(), ErrorType::ConstructorWithoutNew, "Intl.RelativeTimeFormat");
|
return vm().throw_completion<TypeError>(ErrorType::ConstructorWithoutNew, "Intl.RelativeTimeFormat");
|
||||||
}
|
}
|
||||||
|
|
||||||
// 17.1.1 Intl.RelativeTimeFormat ( [ locales [ , options ] ] ), https://tc39.es/ecma402/#sec-Intl.RelativeTimeFormat
|
// 17.1.1 Intl.RelativeTimeFormat ( [ locales [ , options ] ] ), https://tc39.es/ecma402/#sec-Intl.RelativeTimeFormat
|
||||||
|
@ -103,7 +103,7 @@ ThrowCompletionOr<RelativeTimeFormat*> initialize_relative_time_format(GlobalObj
|
||||||
if (!numbering_system.is_undefined()) {
|
if (!numbering_system.is_undefined()) {
|
||||||
// a. If numberingSystem does not match the Unicode Locale Identifier type nonterminal, throw a RangeError exception.
|
// a. If numberingSystem does not match the Unicode Locale Identifier type nonterminal, throw a RangeError exception.
|
||||||
if (!Unicode::is_type_identifier(numbering_system.as_string().string()))
|
if (!Unicode::is_type_identifier(numbering_system.as_string().string()))
|
||||||
return vm.throw_completion<RangeError>(global_object, ErrorType::OptionIsNotValidValue, numbering_system, "numberingSystem"sv);
|
return vm.throw_completion<RangeError>(ErrorType::OptionIsNotValidValue, numbering_system, "numberingSystem"sv);
|
||||||
|
|
||||||
// 8. Set opt.[[nu]] to numberingSystem.
|
// 8. Set opt.[[nu]] to numberingSystem.
|
||||||
opt.nu = numbering_system.as_string().string();
|
opt.nu = numbering_system.as_string().string();
|
||||||
|
|
|
@ -38,7 +38,7 @@ void SegmenterConstructor::initialize(Realm& realm)
|
||||||
ThrowCompletionOr<Value> SegmenterConstructor::call()
|
ThrowCompletionOr<Value> SegmenterConstructor::call()
|
||||||
{
|
{
|
||||||
// 1. If NewTarget is undefined, throw a TypeError exception.
|
// 1. If NewTarget is undefined, throw a TypeError exception.
|
||||||
return vm().throw_completion<TypeError>(global_object(), ErrorType::ConstructorWithoutNew, "Intl.Segmenter");
|
return vm().throw_completion<TypeError>(ErrorType::ConstructorWithoutNew, "Intl.Segmenter");
|
||||||
}
|
}
|
||||||
|
|
||||||
// 18.1.1 Intl.Segmenter ( [ locales [ , options ] ] ), https://tc39.es/ecma402/#sec-intl.segmenter
|
// 18.1.1 Intl.Segmenter ( [ locales [ , options ] ] ), https://tc39.es/ecma402/#sec-intl.segmenter
|
||||||
|
|
|
@ -50,14 +50,14 @@ ThrowCompletionOr<Iterator> get_iterator(GlobalObject& global_object, Value valu
|
||||||
|
|
||||||
// NOTE: Additional type check to produce a better error message than Call().
|
// NOTE: Additional type check to produce a better error message than Call().
|
||||||
if (!method->is_function())
|
if (!method->is_function())
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::NotIterable, value.to_string_without_side_effects());
|
return vm.throw_completion<TypeError>(ErrorType::NotIterable, value.to_string_without_side_effects());
|
||||||
|
|
||||||
// 3. Let iterator be ? Call(method, obj).
|
// 3. Let iterator be ? Call(method, obj).
|
||||||
auto iterator = TRY(call(global_object, *method, value));
|
auto iterator = TRY(call(global_object, *method, value));
|
||||||
|
|
||||||
// 4. If Type(iterator) is not Object, throw a TypeError exception.
|
// 4. If Type(iterator) is not Object, throw a TypeError exception.
|
||||||
if (!iterator.is_object())
|
if (!iterator.is_object())
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::NotIterable, value.to_string_without_side_effects());
|
return vm.throw_completion<TypeError>(ErrorType::NotIterable, value.to_string_without_side_effects());
|
||||||
|
|
||||||
// 5. Let nextMethod be ? GetV(iterator, "next").
|
// 5. Let nextMethod be ? GetV(iterator, "next").
|
||||||
auto next_method = TRY(iterator.get(global_object, vm.names.next));
|
auto next_method = TRY(iterator.get(global_object, vm.names.next));
|
||||||
|
@ -87,7 +87,7 @@ ThrowCompletionOr<Object*> iterator_next(GlobalObject& global_object, Iterator c
|
||||||
|
|
||||||
// 3. If Type(result) is not Object, throw a TypeError exception.
|
// 3. If Type(result) is not Object, throw a TypeError exception.
|
||||||
if (!result.is_object())
|
if (!result.is_object())
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::IterableNextBadReturn);
|
return vm.throw_completion<TypeError>(ErrorType::IterableNextBadReturn);
|
||||||
|
|
||||||
// 4. Return result.
|
// 4. Return result.
|
||||||
return &result.as_object();
|
return &result.as_object();
|
||||||
|
@ -175,7 +175,7 @@ static Completion iterator_close_impl(GlobalObject& global_object, Iterator cons
|
||||||
|
|
||||||
// 7. If Type(innerResult.[[Value]]) is not Object, throw a TypeError exception.
|
// 7. If Type(innerResult.[[Value]]) is not Object, throw a TypeError exception.
|
||||||
if (!inner_result.value().is_object())
|
if (!inner_result.value().is_object())
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::IterableReturnBadReturn);
|
return vm.throw_completion<TypeError>(ErrorType::IterableReturnBadReturn);
|
||||||
|
|
||||||
// 8. Return ? completion.
|
// 8. Return ? completion.
|
||||||
return completion;
|
return completion;
|
||||||
|
|
|
@ -200,7 +200,7 @@ ThrowCompletionOr<String> JSONObject::serialize_json_property(GlobalObject& glob
|
||||||
|
|
||||||
// 10. If Type(value) is BigInt, throw a TypeError exception.
|
// 10. If Type(value) is BigInt, throw a TypeError exception.
|
||||||
if (value.is_bigint())
|
if (value.is_bigint())
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::JsonBigInt);
|
return vm.throw_completion<TypeError>(ErrorType::JsonBigInt);
|
||||||
|
|
||||||
// 11. If Type(value) is Object and IsCallable(value) is false, then
|
// 11. If Type(value) is Object and IsCallable(value) is false, then
|
||||||
if (value.is_object() && !value.is_function()) {
|
if (value.is_object() && !value.is_function()) {
|
||||||
|
@ -224,7 +224,7 @@ ThrowCompletionOr<String> JSONObject::serialize_json_object(GlobalObject& global
|
||||||
{
|
{
|
||||||
auto& vm = global_object.vm();
|
auto& vm = global_object.vm();
|
||||||
if (state.seen_objects.contains(&object))
|
if (state.seen_objects.contains(&object))
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::JsonCircular);
|
return vm.throw_completion<TypeError>(ErrorType::JsonCircular);
|
||||||
|
|
||||||
state.seen_objects.set(&object);
|
state.seen_objects.set(&object);
|
||||||
String previous_indent = state.indent;
|
String previous_indent = state.indent;
|
||||||
|
@ -293,7 +293,7 @@ ThrowCompletionOr<String> JSONObject::serialize_json_array(GlobalObject& global_
|
||||||
{
|
{
|
||||||
auto& vm = global_object.vm();
|
auto& vm = global_object.vm();
|
||||||
if (state.seen_objects.contains(&object))
|
if (state.seen_objects.contains(&object))
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::JsonCircular);
|
return vm.throw_completion<TypeError>(ErrorType::JsonCircular);
|
||||||
|
|
||||||
state.seen_objects.set(&object);
|
state.seen_objects.set(&object);
|
||||||
String previous_indent = state.indent;
|
String previous_indent = state.indent;
|
||||||
|
@ -401,7 +401,7 @@ JS_DEFINE_NATIVE_FUNCTION(JSONObject::parse)
|
||||||
|
|
||||||
auto json = JsonValue::from_string(string);
|
auto json = JsonValue::from_string(string);
|
||||||
if (json.is_error())
|
if (json.is_error())
|
||||||
return vm.throw_completion<SyntaxError>(global_object, ErrorType::JsonMalformed);
|
return vm.throw_completion<SyntaxError>(ErrorType::JsonMalformed);
|
||||||
Value unfiltered = parse_json_value(global_object, json.value());
|
Value unfiltered = parse_json_value(global_object, json.value());
|
||||||
if (reviver.is_function()) {
|
if (reviver.is_function()) {
|
||||||
auto* root = Object::create(realm, global_object.object_prototype());
|
auto* root = Object::create(realm, global_object.object_prototype());
|
||||||
|
|
|
@ -35,7 +35,7 @@ void MapConstructor::initialize(Realm& realm)
|
||||||
ThrowCompletionOr<Value> MapConstructor::call()
|
ThrowCompletionOr<Value> MapConstructor::call()
|
||||||
{
|
{
|
||||||
auto& vm = this->vm();
|
auto& vm = this->vm();
|
||||||
return vm.throw_completion<TypeError>(global_object(), ErrorType::ConstructorWithoutNew, vm.names.Map);
|
return vm.throw_completion<TypeError>(ErrorType::ConstructorWithoutNew, vm.names.Map);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 24.1.1.1 Map ( [ iterable ] ), https://tc39.es/ecma262/#sec-map-iterable
|
// 24.1.1.1 Map ( [ iterable ] ), https://tc39.es/ecma262/#sec-map-iterable
|
||||||
|
@ -51,11 +51,11 @@ ThrowCompletionOr<Object*> MapConstructor::construct(FunctionObject& new_target)
|
||||||
|
|
||||||
auto adder = TRY(map->get(vm.names.set));
|
auto adder = TRY(map->get(vm.names.set));
|
||||||
if (!adder.is_function())
|
if (!adder.is_function())
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::NotAFunction, "'set' property of Map");
|
return vm.throw_completion<TypeError>(ErrorType::NotAFunction, "'set' property of Map");
|
||||||
|
|
||||||
(void)TRY(get_iterator_values(global_object, vm.argument(0), [&](Value iterator_value) -> Optional<Completion> {
|
(void)TRY(get_iterator_values(global_object, vm.argument(0), [&](Value iterator_value) -> Optional<Completion> {
|
||||||
if (!iterator_value.is_object())
|
if (!iterator_value.is_object())
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::NotAnObject, String::formatted("Iterator value {}", iterator_value.to_string_without_side_effects()));
|
return vm.throw_completion<TypeError>(ErrorType::NotAnObject, String::formatted("Iterator value {}", iterator_value.to_string_without_side_effects()));
|
||||||
|
|
||||||
auto key = TRY(iterator_value.as_object().get(0));
|
auto key = TRY(iterator_value.as_object().get(0));
|
||||||
auto value = TRY(iterator_value.as_object().get(1));
|
auto value = TRY(iterator_value.as_object().get(1));
|
||||||
|
|
|
@ -69,7 +69,7 @@ JS_DEFINE_NATIVE_FUNCTION(MapPrototype::for_each)
|
||||||
{
|
{
|
||||||
auto* map = TRY(typed_this_object(global_object));
|
auto* map = TRY(typed_this_object(global_object));
|
||||||
if (!vm.argument(0).is_function())
|
if (!vm.argument(0).is_function())
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::NotAFunction, vm.argument(0).to_string_without_side_effects());
|
return vm.throw_completion<TypeError>(ErrorType::NotAFunction, vm.argument(0).to_string_without_side_effects());
|
||||||
auto this_value = vm.this_value(global_object);
|
auto this_value = vm.this_value(global_object);
|
||||||
for (auto& entry : *map)
|
for (auto& entry : *map)
|
||||||
TRY(call(global_object, vm.argument(0).as_function(), vm.argument(1), entry.value, entry.key, this_value));
|
TRY(call(global_object, vm.argument(0).as_function(), vm.argument(1), entry.value, entry.key, this_value));
|
||||||
|
|
|
@ -36,7 +36,7 @@ ThrowCompletionOr<Value> ModuleEnvironment::get_binding_value(GlobalObject& glob
|
||||||
|
|
||||||
// c. If targetEnv is empty, throw a ReferenceError exception.
|
// c. If targetEnv is empty, throw a ReferenceError exception.
|
||||||
if (!target_env)
|
if (!target_env)
|
||||||
return vm().throw_completion<ReferenceError>(global_object, ErrorType::ModuleNoEnvironment);
|
return vm().throw_completion<ReferenceError>(ErrorType::ModuleNoEnvironment);
|
||||||
|
|
||||||
// d. Return ? targetEnv.GetBindingValue(N2, true).
|
// d. Return ? targetEnv.GetBindingValue(N2, true).
|
||||||
return target_env->get_binding_value(global_object, indirect_binding->binding_name, true);
|
return target_env->get_binding_value(global_object, indirect_binding->binding_name, true);
|
||||||
|
|
|
@ -172,7 +172,7 @@ ThrowCompletionOr<Value> ModuleNamespaceObject::internal_get(PropertyKey const&
|
||||||
|
|
||||||
// 11. If targetEnv is empty, throw a ReferenceError exception.
|
// 11. If targetEnv is empty, throw a ReferenceError exception.
|
||||||
if (!target_environment)
|
if (!target_environment)
|
||||||
return vm().throw_completion<ReferenceError>(global_object(), ErrorType::ModuleNoEnvironment);
|
return vm().throw_completion<ReferenceError>(ErrorType::ModuleNoEnvironment);
|
||||||
|
|
||||||
// 12. Return ? targetEnv.GetBindingValue(binding.[[BindingName]], true).
|
// 12. Return ? targetEnv.GetBindingValue(binding.[[BindingName]], true).
|
||||||
return target_environment->get_binding_value(global_object(), binding.export_name, true);
|
return target_environment->get_binding_value(global_object(), binding.export_name, true);
|
||||||
|
|
|
@ -119,7 +119,7 @@ static ThrowCompletionOr<Value> this_number_value(GlobalObject& global_object, V
|
||||||
auto& vm = global_object.vm();
|
auto& vm = global_object.vm();
|
||||||
|
|
||||||
// 3. Throw a TypeError exception.
|
// 3. Throw a TypeError exception.
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::NotAnObjectOfType, "Number");
|
return vm.throw_completion<TypeError>(ErrorType::NotAnObjectOfType, "Number");
|
||||||
}
|
}
|
||||||
|
|
||||||
// 21.1.3.2 Number.prototype.toExponential ( fractionDigits ), https://tc39.es/ecma262/#sec-number.prototype.toexponential
|
// 21.1.3.2 Number.prototype.toExponential ( fractionDigits ), https://tc39.es/ecma262/#sec-number.prototype.toexponential
|
||||||
|
@ -142,7 +142,7 @@ JS_DEFINE_NATIVE_FUNCTION(NumberPrototype::to_exponential)
|
||||||
|
|
||||||
// 5. If f < 0 or f > 100, throw a RangeError exception.
|
// 5. If f < 0 or f > 100, throw a RangeError exception.
|
||||||
if (fraction_digits < 0 || fraction_digits > 100)
|
if (fraction_digits < 0 || fraction_digits > 100)
|
||||||
return vm.throw_completion<RangeError>(global_object, ErrorType::InvalidFractionDigits);
|
return vm.throw_completion<RangeError>(ErrorType::InvalidFractionDigits);
|
||||||
|
|
||||||
// 6. Set x to ℝ(x).
|
// 6. Set x to ℝ(x).
|
||||||
auto number = number_value.as_double();
|
auto number = number_value.as_double();
|
||||||
|
@ -255,11 +255,11 @@ JS_DEFINE_NATIVE_FUNCTION(NumberPrototype::to_fixed)
|
||||||
|
|
||||||
// 4. If f is not finite, throw a RangeError exception.
|
// 4. If f is not finite, throw a RangeError exception.
|
||||||
if (!Value(fraction_digits).is_finite_number())
|
if (!Value(fraction_digits).is_finite_number())
|
||||||
return vm.throw_completion<RangeError>(global_object, ErrorType::InvalidFractionDigits);
|
return vm.throw_completion<RangeError>(ErrorType::InvalidFractionDigits);
|
||||||
|
|
||||||
// 5. If f < 0 or f > 100, throw a RangeError exception.
|
// 5. If f < 0 or f > 100, throw a RangeError exception.
|
||||||
if (fraction_digits < 0 || fraction_digits > 100)
|
if (fraction_digits < 0 || fraction_digits > 100)
|
||||||
return vm.throw_completion<RangeError>(global_object, ErrorType::InvalidFractionDigits);
|
return vm.throw_completion<RangeError>(ErrorType::InvalidFractionDigits);
|
||||||
|
|
||||||
// 6. If x is not finite, return Number::toString(x).
|
// 6. If x is not finite, return Number::toString(x).
|
||||||
if (!number_value.is_finite_number())
|
if (!number_value.is_finite_number())
|
||||||
|
@ -356,7 +356,7 @@ JS_DEFINE_NATIVE_FUNCTION(NumberPrototype::to_precision)
|
||||||
|
|
||||||
// 5. If p < 1 or p > 100, throw a RangeError exception.
|
// 5. If p < 1 or p > 100, throw a RangeError exception.
|
||||||
if ((precision < 1) || (precision > 100))
|
if ((precision < 1) || (precision > 100))
|
||||||
return vm.throw_completion<RangeError>(global_object, ErrorType::InvalidPrecision);
|
return vm.throw_completion<RangeError>(ErrorType::InvalidPrecision);
|
||||||
|
|
||||||
// 6. Set x to ℝ(x).
|
// 6. Set x to ℝ(x).
|
||||||
auto number = number_value.as_double();
|
auto number = number_value.as_double();
|
||||||
|
@ -484,7 +484,7 @@ JS_DEFINE_NATIVE_FUNCTION(NumberPrototype::to_string)
|
||||||
|
|
||||||
// 4. If radixMV < 2 or radixMV > 36, throw a RangeError exception.
|
// 4. If radixMV < 2 or radixMV > 36, throw a RangeError exception.
|
||||||
if (radix_mv < 2 || radix_mv > 36)
|
if (radix_mv < 2 || radix_mv > 36)
|
||||||
return vm.throw_completion<RangeError>(global_object, ErrorType::InvalidRadix);
|
return vm.throw_completion<RangeError>(ErrorType::InvalidRadix);
|
||||||
|
|
||||||
// 5. If radixMV = 10, return ! ToString(x).
|
// 5. If radixMV = 10, return ! ToString(x).
|
||||||
if (radix_mv == 10)
|
if (radix_mv == 10)
|
||||||
|
|
|
@ -109,7 +109,7 @@ ThrowCompletionOr<void> Object::set(PropertyKey const& property_key, Value value
|
||||||
// 2. If success is false and Throw is true, throw a TypeError exception.
|
// 2. If success is false and Throw is true, throw a TypeError exception.
|
||||||
if (!success && throw_exceptions == ShouldThrowExceptions::Yes) {
|
if (!success && throw_exceptions == ShouldThrowExceptions::Yes) {
|
||||||
// FIXME: Improve/contextualize error message
|
// FIXME: Improve/contextualize error message
|
||||||
return vm.throw_completion<TypeError>(global_object(), ErrorType::ObjectSetReturnedFalse);
|
return vm.throw_completion<TypeError>(ErrorType::ObjectSetReturnedFalse);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 3. Return unused.
|
// 3. Return unused.
|
||||||
|
@ -170,7 +170,7 @@ ThrowCompletionOr<bool> Object::create_data_property_or_throw(PropertyKey const&
|
||||||
// 2. If success is false, throw a TypeError exception.
|
// 2. If success is false, throw a TypeError exception.
|
||||||
if (!success) {
|
if (!success) {
|
||||||
// FIXME: Improve/contextualize error message
|
// FIXME: Improve/contextualize error message
|
||||||
return vm.throw_completion<TypeError>(global_object(), ErrorType::ObjectDefineOwnPropertyReturnedFalse);
|
return vm.throw_completion<TypeError>(ErrorType::ObjectDefineOwnPropertyReturnedFalse);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 3. Return success.
|
// 3. Return success.
|
||||||
|
@ -207,7 +207,7 @@ ThrowCompletionOr<void> Object::define_property_or_throw(PropertyKey const& prop
|
||||||
// 2. If success is false, throw a TypeError exception.
|
// 2. If success is false, throw a TypeError exception.
|
||||||
if (!success) {
|
if (!success) {
|
||||||
// FIXME: Improve/contextualize error message
|
// FIXME: Improve/contextualize error message
|
||||||
return vm.throw_completion<TypeError>(global_object(), ErrorType::ObjectDefineOwnPropertyReturnedFalse);
|
return vm.throw_completion<TypeError>(ErrorType::ObjectDefineOwnPropertyReturnedFalse);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 3. Return unused.
|
// 3. Return unused.
|
||||||
|
@ -227,7 +227,7 @@ ThrowCompletionOr<void> Object::delete_property_or_throw(PropertyKey const& prop
|
||||||
// 2. If success is false, throw a TypeError exception.
|
// 2. If success is false, throw a TypeError exception.
|
||||||
if (!success) {
|
if (!success) {
|
||||||
// FIXME: Improve/contextualize error message
|
// FIXME: Improve/contextualize error message
|
||||||
return vm.throw_completion<TypeError>(global_object(), ErrorType::ObjectDeleteReturnedFalse);
|
return vm.throw_completion<TypeError>(ErrorType::ObjectDeleteReturnedFalse);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 3. Return unused.
|
// 3. Return unused.
|
||||||
|
@ -462,15 +462,17 @@ PrivateElement* Object::private_element_find(PrivateName const& name)
|
||||||
// 7.3.28 PrivateFieldAdd ( O, P, value ), https://tc39.es/ecma262/#sec-privatefieldadd
|
// 7.3.28 PrivateFieldAdd ( O, P, value ), https://tc39.es/ecma262/#sec-privatefieldadd
|
||||||
ThrowCompletionOr<void> Object::private_field_add(PrivateName const& name, Value value)
|
ThrowCompletionOr<void> Object::private_field_add(PrivateName const& name, Value value)
|
||||||
{
|
{
|
||||||
|
auto& vm = this->vm();
|
||||||
|
|
||||||
// 1. If the host is a web browser, then
|
// 1. If the host is a web browser, then
|
||||||
// a. Perform ? HostEnsureCanAddPrivateElement(O).
|
// a. Perform ? HostEnsureCanAddPrivateElement(O).
|
||||||
// NOTE: Since LibJS has no way of knowing whether it is in a browser we just always call the hook.
|
// NOTE: Since LibJS has no way of knowing whether it is in a browser we just always call the hook.
|
||||||
TRY(vm().host_ensure_can_add_private_element(*this));
|
TRY(vm.host_ensure_can_add_private_element(*this));
|
||||||
|
|
||||||
// 2. Let entry be PrivateElementFind(O, P).
|
// 2. Let entry be PrivateElementFind(O, P).
|
||||||
// 3. If entry is not empty, throw a TypeError exception.
|
// 3. If entry is not empty, throw a TypeError exception.
|
||||||
if (auto* entry = private_element_find(name); entry)
|
if (auto* entry = private_element_find(name); entry)
|
||||||
return vm().throw_completion<TypeError>(global_object(), ErrorType::PrivateFieldAlreadyDeclared, name.description);
|
return vm.throw_completion<TypeError>(ErrorType::PrivateFieldAlreadyDeclared, name.description);
|
||||||
|
|
||||||
if (!m_private_elements)
|
if (!m_private_elements)
|
||||||
m_private_elements = make<Vector<PrivateElement>>();
|
m_private_elements = make<Vector<PrivateElement>>();
|
||||||
|
@ -485,18 +487,20 @@ ThrowCompletionOr<void> Object::private_field_add(PrivateName const& name, Value
|
||||||
// 7.3.29 PrivateMethodOrAccessorAdd ( O, method ), https://tc39.es/ecma262/#sec-privatemethodoraccessoradd
|
// 7.3.29 PrivateMethodOrAccessorAdd ( O, method ), https://tc39.es/ecma262/#sec-privatemethodoraccessoradd
|
||||||
ThrowCompletionOr<void> Object::private_method_or_accessor_add(PrivateElement element)
|
ThrowCompletionOr<void> Object::private_method_or_accessor_add(PrivateElement element)
|
||||||
{
|
{
|
||||||
|
auto& vm = this->vm();
|
||||||
|
|
||||||
// 1. Assert: method.[[Kind]] is either method or accessor.
|
// 1. Assert: method.[[Kind]] is either method or accessor.
|
||||||
VERIFY(element.kind == PrivateElement::Kind::Method || element.kind == PrivateElement::Kind::Accessor);
|
VERIFY(element.kind == PrivateElement::Kind::Method || element.kind == PrivateElement::Kind::Accessor);
|
||||||
|
|
||||||
// 2. If the host is a web browser, then
|
// 2. If the host is a web browser, then
|
||||||
// a. Perform ? HostEnsureCanAddPrivateElement(O).
|
// a. Perform ? HostEnsureCanAddPrivateElement(O).
|
||||||
// NOTE: Since LibJS has no way of knowing whether it is in a browser we just always call the hook.
|
// NOTE: Since LibJS has no way of knowing whether it is in a browser we just always call the hook.
|
||||||
TRY(vm().host_ensure_can_add_private_element(*this));
|
TRY(vm.host_ensure_can_add_private_element(*this));
|
||||||
|
|
||||||
// 3. Let entry be PrivateElementFind(O, method.[[Key]]).
|
// 3. Let entry be PrivateElementFind(O, method.[[Key]]).
|
||||||
// 4. If entry is not empty, throw a TypeError exception.
|
// 4. If entry is not empty, throw a TypeError exception.
|
||||||
if (auto* entry = private_element_find(element.key); entry)
|
if (auto* entry = private_element_find(element.key); entry)
|
||||||
return vm().throw_completion<TypeError>(global_object(), ErrorType::PrivateFieldAlreadyDeclared, element.key.description);
|
return vm.throw_completion<TypeError>(ErrorType::PrivateFieldAlreadyDeclared, element.key.description);
|
||||||
|
|
||||||
if (!m_private_elements)
|
if (!m_private_elements)
|
||||||
m_private_elements = make<Vector<PrivateElement>>();
|
m_private_elements = make<Vector<PrivateElement>>();
|
||||||
|
@ -513,7 +517,7 @@ ThrowCompletionOr<Value> Object::private_get(PrivateName const& name)
|
||||||
{
|
{
|
||||||
auto* entry = private_element_find(name);
|
auto* entry = private_element_find(name);
|
||||||
if (!entry)
|
if (!entry)
|
||||||
return vm().throw_completion<TypeError>(global_object(), ErrorType::PrivateFieldDoesNotExistOnObject, name.description);
|
return vm().throw_completion<TypeError>(ErrorType::PrivateFieldDoesNotExistOnObject, name.description);
|
||||||
|
|
||||||
auto& value = entry->value;
|
auto& value = entry->value;
|
||||||
|
|
||||||
|
@ -523,7 +527,7 @@ ThrowCompletionOr<Value> Object::private_get(PrivateName const& name)
|
||||||
VERIFY(value.is_accessor());
|
VERIFY(value.is_accessor());
|
||||||
auto* getter = value.as_accessor().getter();
|
auto* getter = value.as_accessor().getter();
|
||||||
if (!getter)
|
if (!getter)
|
||||||
return vm().throw_completion<TypeError>(global_object(), ErrorType::PrivateFieldGetAccessorWithoutGetter, name.description);
|
return vm().throw_completion<TypeError>(ErrorType::PrivateFieldGetAccessorWithoutGetter, name.description);
|
||||||
|
|
||||||
// 8. Return ? Call(getter, Receiver).
|
// 8. Return ? Call(getter, Receiver).
|
||||||
return TRY(call(global_object(), *getter, this));
|
return TRY(call(global_object(), *getter, this));
|
||||||
|
@ -534,13 +538,13 @@ ThrowCompletionOr<void> Object::private_set(PrivateName const& name, Value value
|
||||||
{
|
{
|
||||||
auto* entry = private_element_find(name);
|
auto* entry = private_element_find(name);
|
||||||
if (!entry)
|
if (!entry)
|
||||||
return vm().throw_completion<TypeError>(global_object(), ErrorType::PrivateFieldDoesNotExistOnObject, name.description);
|
return vm().throw_completion<TypeError>(ErrorType::PrivateFieldDoesNotExistOnObject, name.description);
|
||||||
|
|
||||||
if (entry->kind == PrivateElement::Kind::Field) {
|
if (entry->kind == PrivateElement::Kind::Field) {
|
||||||
entry->value = value;
|
entry->value = value;
|
||||||
return {};
|
return {};
|
||||||
} else if (entry->kind == PrivateElement::Kind::Method) {
|
} else if (entry->kind == PrivateElement::Kind::Method) {
|
||||||
return vm().throw_completion<TypeError>(global_object(), ErrorType::PrivateFieldSetMethod, name.description);
|
return vm().throw_completion<TypeError>(ErrorType::PrivateFieldSetMethod, name.description);
|
||||||
}
|
}
|
||||||
|
|
||||||
VERIFY(entry->kind == PrivateElement::Kind::Accessor);
|
VERIFY(entry->kind == PrivateElement::Kind::Accessor);
|
||||||
|
@ -549,7 +553,7 @@ ThrowCompletionOr<void> Object::private_set(PrivateName const& name, Value value
|
||||||
VERIFY(accessor.is_accessor());
|
VERIFY(accessor.is_accessor());
|
||||||
auto* setter = accessor.as_accessor().setter();
|
auto* setter = accessor.as_accessor().setter();
|
||||||
if (!setter)
|
if (!setter)
|
||||||
return vm().throw_completion<TypeError>(global_object(), ErrorType::PrivateFieldSetAccessorWithoutSetter, name.description);
|
return vm().throw_completion<TypeError>(ErrorType::PrivateFieldSetAccessorWithoutSetter, name.description);
|
||||||
|
|
||||||
TRY(call(global_object(), *setter, this, value));
|
TRY(call(global_object(), *setter, this, value));
|
||||||
return {};
|
return {};
|
||||||
|
@ -1259,7 +1263,7 @@ ThrowCompletionOr<Value> Object::ordinary_to_primitive(Value::PreferredType pref
|
||||||
}
|
}
|
||||||
|
|
||||||
// 4. Throw a TypeError exception.
|
// 4. Throw a TypeError exception.
|
||||||
return vm.throw_completion<TypeError>(global_object(), ErrorType::Convert, "object", preferred_type == Value::PreferredType::String ? "string" : "number");
|
return vm.throw_completion<TypeError>(ErrorType::Convert, "object", preferred_type == Value::PreferredType::String ? "string" : "number");
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -148,7 +148,7 @@ JS_DEFINE_NATIVE_FUNCTION(ObjectConstructor::set_prototype_of)
|
||||||
|
|
||||||
// 2. If Type(proto) is neither Object nor Null, throw a TypeError exception.
|
// 2. If Type(proto) is neither Object nor Null, throw a TypeError exception.
|
||||||
if (!proto.is_object() && !proto.is_null())
|
if (!proto.is_object() && !proto.is_null())
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::ObjectPrototypeWrongType);
|
return vm.throw_completion<TypeError>(ErrorType::ObjectPrototypeWrongType);
|
||||||
|
|
||||||
// 3. If Type(O) is not Object, return O.
|
// 3. If Type(O) is not Object, return O.
|
||||||
if (!object.is_object())
|
if (!object.is_object())
|
||||||
|
@ -160,7 +160,7 @@ JS_DEFINE_NATIVE_FUNCTION(ObjectConstructor::set_prototype_of)
|
||||||
// 5. If status is false, throw a TypeError exception.
|
// 5. If status is false, throw a TypeError exception.
|
||||||
if (!status) {
|
if (!status) {
|
||||||
// FIXME: Improve/contextualize error message
|
// FIXME: Improve/contextualize error message
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::ObjectSetPrototypeOfReturnedFalse);
|
return vm.throw_completion<TypeError>(ErrorType::ObjectSetPrototypeOfReturnedFalse);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 6. Return O.
|
// 6. Return O.
|
||||||
|
@ -203,7 +203,7 @@ JS_DEFINE_NATIVE_FUNCTION(ObjectConstructor::prevent_extensions)
|
||||||
auto status = TRY(argument.as_object().internal_prevent_extensions());
|
auto status = TRY(argument.as_object().internal_prevent_extensions());
|
||||||
if (!status) {
|
if (!status) {
|
||||||
// FIXME: Improve/contextualize error message
|
// FIXME: Improve/contextualize error message
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::ObjectPreventExtensionsReturnedFalse);
|
return vm.throw_completion<TypeError>(ErrorType::ObjectPreventExtensionsReturnedFalse);
|
||||||
}
|
}
|
||||||
return argument;
|
return argument;
|
||||||
}
|
}
|
||||||
|
@ -216,7 +216,7 @@ JS_DEFINE_NATIVE_FUNCTION(ObjectConstructor::freeze)
|
||||||
return argument;
|
return argument;
|
||||||
auto status = TRY(argument.as_object().set_integrity_level(Object::IntegrityLevel::Frozen));
|
auto status = TRY(argument.as_object().set_integrity_level(Object::IntegrityLevel::Frozen));
|
||||||
if (!status)
|
if (!status)
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::ObjectFreezeFailed);
|
return vm.throw_completion<TypeError>(ErrorType::ObjectFreezeFailed);
|
||||||
return argument;
|
return argument;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -230,7 +230,7 @@ JS_DEFINE_NATIVE_FUNCTION(ObjectConstructor::from_entries)
|
||||||
|
|
||||||
(void)TRY(get_iterator_values(global_object, iterable, [&](Value iterator_value) -> Optional<Completion> {
|
(void)TRY(get_iterator_values(global_object, iterable, [&](Value iterator_value) -> Optional<Completion> {
|
||||||
if (!iterator_value.is_object())
|
if (!iterator_value.is_object())
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::NotAnObject, String::formatted("Iterator value {}", iterator_value.to_string_without_side_effects()));
|
return vm.throw_completion<TypeError>(ErrorType::NotAnObject, String::formatted("Iterator value {}", iterator_value.to_string_without_side_effects()));
|
||||||
|
|
||||||
auto key = TRY(iterator_value.as_object().get(0));
|
auto key = TRY(iterator_value.as_object().get(0));
|
||||||
auto value = TRY(iterator_value.as_object().get(1));
|
auto value = TRY(iterator_value.as_object().get(1));
|
||||||
|
@ -252,7 +252,7 @@ JS_DEFINE_NATIVE_FUNCTION(ObjectConstructor::seal)
|
||||||
return argument;
|
return argument;
|
||||||
auto status = TRY(argument.as_object().set_integrity_level(Object::IntegrityLevel::Sealed));
|
auto status = TRY(argument.as_object().set_integrity_level(Object::IntegrityLevel::Sealed));
|
||||||
if (!status)
|
if (!status)
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::ObjectSealFailed);
|
return vm.throw_completion<TypeError>(ErrorType::ObjectSealFailed);
|
||||||
return argument;
|
return argument;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -302,7 +302,7 @@ JS_DEFINE_NATIVE_FUNCTION(ObjectConstructor::get_own_property_descriptors)
|
||||||
JS_DEFINE_NATIVE_FUNCTION(ObjectConstructor::define_property)
|
JS_DEFINE_NATIVE_FUNCTION(ObjectConstructor::define_property)
|
||||||
{
|
{
|
||||||
if (!vm.argument(0).is_object())
|
if (!vm.argument(0).is_object())
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::NotAnObject, vm.argument(0).to_string_without_side_effects());
|
return vm.throw_completion<TypeError>(ErrorType::NotAnObject, vm.argument(0).to_string_without_side_effects());
|
||||||
auto key = TRY(vm.argument(1).to_property_key(global_object));
|
auto key = TRY(vm.argument(1).to_property_key(global_object));
|
||||||
auto descriptor = TRY(to_property_descriptor(global_object, vm.argument(2)));
|
auto descriptor = TRY(to_property_descriptor(global_object, vm.argument(2)));
|
||||||
TRY(vm.argument(0).as_object().define_property_or_throw(key, descriptor));
|
TRY(vm.argument(0).as_object().define_property_or_throw(key, descriptor));
|
||||||
|
@ -317,7 +317,7 @@ JS_DEFINE_NATIVE_FUNCTION(ObjectConstructor::define_properties)
|
||||||
|
|
||||||
// 1. If Type(O) is not Object, throw a TypeError exception.
|
// 1. If Type(O) is not Object, throw a TypeError exception.
|
||||||
if (!object.is_object())
|
if (!object.is_object())
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::NotAnObject, "Object argument");
|
return vm.throw_completion<TypeError>(ErrorType::NotAnObject, "Object argument");
|
||||||
|
|
||||||
// 2. Return ? ObjectDefineProperties(O, Properties).
|
// 2. Return ? ObjectDefineProperties(O, Properties).
|
||||||
return TRY(object.as_object().define_properties(properties));
|
return TRY(object.as_object().define_properties(properties));
|
||||||
|
@ -369,7 +369,7 @@ JS_DEFINE_NATIVE_FUNCTION(ObjectConstructor::create)
|
||||||
|
|
||||||
// 1. If Type(O) is neither Object nor Null, throw a TypeError exception.
|
// 1. If Type(O) is neither Object nor Null, throw a TypeError exception.
|
||||||
if (!proto.is_object() && !proto.is_null())
|
if (!proto.is_object() && !proto.is_null())
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::ObjectPrototypeWrongType);
|
return vm.throw_completion<TypeError>(ErrorType::ObjectPrototypeWrongType);
|
||||||
|
|
||||||
// 2. Let obj be OrdinaryObjectCreate(O).
|
// 2. Let obj be OrdinaryObjectCreate(O).
|
||||||
auto* object = Object::create(realm, proto.is_null() ? nullptr : &proto.as_object());
|
auto* object = Object::create(realm, proto.is_null() ? nullptr : &proto.as_object());
|
||||||
|
|
|
@ -88,7 +88,7 @@ ThrowCompletionOr<void> ObjectEnvironment::initialize_binding(GlobalObject& glob
|
||||||
}
|
}
|
||||||
|
|
||||||
// 9.1.1.2.5 SetMutableBinding ( N, V, S ), https://tc39.es/ecma262/#sec-object-environment-records-setmutablebinding-n-v-s
|
// 9.1.1.2.5 SetMutableBinding ( N, V, S ), https://tc39.es/ecma262/#sec-object-environment-records-setmutablebinding-n-v-s
|
||||||
ThrowCompletionOr<void> ObjectEnvironment::set_mutable_binding(GlobalObject& global_object, FlyString const& name, Value value, bool strict)
|
ThrowCompletionOr<void> ObjectEnvironment::set_mutable_binding(GlobalObject&, FlyString const& name, Value value, bool strict)
|
||||||
{
|
{
|
||||||
auto& vm = this->vm();
|
auto& vm = this->vm();
|
||||||
|
|
||||||
|
@ -98,7 +98,7 @@ ThrowCompletionOr<void> ObjectEnvironment::set_mutable_binding(GlobalObject& glo
|
||||||
|
|
||||||
// 3. If stillExists is false and S is true, throw a ReferenceError exception.
|
// 3. If stillExists is false and S is true, throw a ReferenceError exception.
|
||||||
if (!still_exists && strict)
|
if (!still_exists && strict)
|
||||||
return vm.throw_completion<ReferenceError>(global_object, ErrorType::UnknownIdentifier, name);
|
return vm.throw_completion<ReferenceError>(ErrorType::UnknownIdentifier, name);
|
||||||
|
|
||||||
// 4. Perform ? Set(bindingObject, N, V, S).
|
// 4. Perform ? Set(bindingObject, N, V, S).
|
||||||
auto result_or_error = m_binding_object.set(name, value, strict ? Object::ShouldThrowExceptions::Yes : Object::ShouldThrowExceptions::No);
|
auto result_or_error = m_binding_object.set(name, value, strict ? Object::ShouldThrowExceptions::Yes : Object::ShouldThrowExceptions::No);
|
||||||
|
@ -111,7 +111,7 @@ ThrowCompletionOr<void> ObjectEnvironment::set_mutable_binding(GlobalObject& glo
|
||||||
return result_or_error.release_error();
|
return result_or_error.release_error();
|
||||||
auto property = property_or_error.release_value();
|
auto property = property_or_error.release_value();
|
||||||
if (property.has_value() && !property->writable.value_or(true)) {
|
if (property.has_value() && !property->writable.value_or(true)) {
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::DescWriteNonWritable, name);
|
return vm.throw_completion<TypeError>(ErrorType::DescWriteNonWritable, name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -123,7 +123,7 @@ ThrowCompletionOr<void> ObjectEnvironment::set_mutable_binding(GlobalObject& glo
|
||||||
}
|
}
|
||||||
|
|
||||||
// 9.1.1.2.6 GetBindingValue ( N, S ), https://tc39.es/ecma262/#sec-object-environment-records-getbindingvalue-n-s
|
// 9.1.1.2.6 GetBindingValue ( N, S ), https://tc39.es/ecma262/#sec-object-environment-records-getbindingvalue-n-s
|
||||||
ThrowCompletionOr<Value> ObjectEnvironment::get_binding_value(GlobalObject& global_object, FlyString const& name, bool strict)
|
ThrowCompletionOr<Value> ObjectEnvironment::get_binding_value(GlobalObject&, FlyString const& name, bool strict)
|
||||||
{
|
{
|
||||||
auto& vm = this->vm();
|
auto& vm = this->vm();
|
||||||
|
|
||||||
|
@ -136,7 +136,7 @@ ThrowCompletionOr<Value> ObjectEnvironment::get_binding_value(GlobalObject& glob
|
||||||
// a. If S is false, return undefined; otherwise throw a ReferenceError exception.
|
// a. If S is false, return undefined; otherwise throw a ReferenceError exception.
|
||||||
if (!strict)
|
if (!strict)
|
||||||
return js_undefined();
|
return js_undefined();
|
||||||
return vm.throw_completion<ReferenceError>(global_object, ErrorType::UnknownIdentifier, name);
|
return vm.throw_completion<ReferenceError>(ErrorType::UnknownIdentifier, name);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 4. Return ? Get(bindingObject, N).
|
// 4. Return ? Get(bindingObject, N).
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2020, Andreas Kling <kling@serenityos.org>
|
* Copyright (c) 2020, Andreas Kling <kling@serenityos.org>
|
||||||
* Copyright (c) 2020-2021, Linus Groh <linusg@serenityos.org>
|
* Copyright (c) 2020-2022, Linus Groh <linusg@serenityos.org>
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: BSD-2-Clause
|
* SPDX-License-Identifier: BSD-2-Clause
|
||||||
*/
|
*/
|
||||||
|
@ -185,7 +185,7 @@ JS_DEFINE_NATIVE_FUNCTION(ObjectPrototype::define_getter)
|
||||||
|
|
||||||
auto getter = vm.argument(1);
|
auto getter = vm.argument(1);
|
||||||
if (!getter.is_function())
|
if (!getter.is_function())
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::NotAFunction, getter.to_string_without_side_effects());
|
return vm.throw_completion<TypeError>(ErrorType::NotAFunction, getter.to_string_without_side_effects());
|
||||||
|
|
||||||
auto descriptor = PropertyDescriptor { .get = &getter.as_function(), .enumerable = true, .configurable = true };
|
auto descriptor = PropertyDescriptor { .get = &getter.as_function(), .enumerable = true, .configurable = true };
|
||||||
|
|
||||||
|
@ -203,7 +203,7 @@ JS_DEFINE_NATIVE_FUNCTION(ObjectPrototype::define_setter)
|
||||||
|
|
||||||
auto setter = vm.argument(1);
|
auto setter = vm.argument(1);
|
||||||
if (!setter.is_function())
|
if (!setter.is_function())
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::NotAFunction, setter.to_string_without_side_effects());
|
return vm.throw_completion<TypeError>(ErrorType::NotAFunction, setter.to_string_without_side_effects());
|
||||||
|
|
||||||
auto descriptor = PropertyDescriptor { .set = &setter.as_function(), .enumerable = true, .configurable = true };
|
auto descriptor = PropertyDescriptor { .set = &setter.as_function(), .enumerable = true, .configurable = true };
|
||||||
|
|
||||||
|
@ -276,7 +276,7 @@ JS_DEFINE_NATIVE_FUNCTION(ObjectPrototype::proto_setter)
|
||||||
auto status = TRY(object.as_object().internal_set_prototype_of(proto.is_object() ? &proto.as_object() : nullptr));
|
auto status = TRY(object.as_object().internal_set_prototype_of(proto.is_object() ? &proto.as_object() : nullptr));
|
||||||
if (!status) {
|
if (!status) {
|
||||||
// FIXME: Improve/contextualize error message
|
// FIXME: Improve/contextualize error message
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::ObjectSetPrototypeOfReturnedFalse);
|
return vm.throw_completion<TypeError>(ErrorType::ObjectSetPrototypeOfReturnedFalse);
|
||||||
}
|
}
|
||||||
return js_undefined();
|
return js_undefined();
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,7 +31,7 @@ static ThrowCompletionOr<Value> get_promise_resolve(GlobalObject& global_object,
|
||||||
|
|
||||||
// 2. If IsCallable(promiseResolve) is false, throw a TypeError exception.
|
// 2. If IsCallable(promiseResolve) is false, throw a TypeError exception.
|
||||||
if (!promise_resolve.is_function())
|
if (!promise_resolve.is_function())
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::NotAFunction, promise_resolve.to_string_without_side_effects());
|
return vm.throw_completion<TypeError>(ErrorType::NotAFunction, promise_resolve.to_string_without_side_effects());
|
||||||
|
|
||||||
// 3. Return promiseResolve.
|
// 3. Return promiseResolve.
|
||||||
return promise_resolve;
|
return promise_resolve;
|
||||||
|
@ -279,7 +279,7 @@ ThrowCompletionOr<Value> PromiseConstructor::call()
|
||||||
auto& vm = this->vm();
|
auto& vm = this->vm();
|
||||||
|
|
||||||
// 1. If NewTarget is undefined, throw a TypeError exception.
|
// 1. If NewTarget is undefined, throw a TypeError exception.
|
||||||
return vm.throw_completion<TypeError>(global_object(), ErrorType::ConstructorWithoutNew, vm.names.Promise);
|
return vm.throw_completion<TypeError>(ErrorType::ConstructorWithoutNew, vm.names.Promise);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 27.2.3.1 Promise ( executor ), https://tc39.es/ecma262/#sec-promise-executor
|
// 27.2.3.1 Promise ( executor ), https://tc39.es/ecma262/#sec-promise-executor
|
||||||
|
@ -292,7 +292,7 @@ ThrowCompletionOr<Object*> PromiseConstructor::construct(FunctionObject& new_tar
|
||||||
|
|
||||||
// 2. If IsCallable(executor) is false, throw a TypeError exception.
|
// 2. If IsCallable(executor) is false, throw a TypeError exception.
|
||||||
if (!executor.is_function())
|
if (!executor.is_function())
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::PromiseExecutorNotAFunction);
|
return vm.throw_completion<TypeError>(ErrorType::PromiseExecutorNotAFunction);
|
||||||
|
|
||||||
// 3. Let promise be ? OrdinaryCreateFromConstructor(NewTarget, "%Promise.prototype%", « [[PromiseState]], [[PromiseResult]], [[PromiseFulfillReactions]], [[PromiseRejectReactions]], [[PromiseIsHandled]] »).
|
// 3. Let promise be ? OrdinaryCreateFromConstructor(NewTarget, "%Promise.prototype%", « [[PromiseState]], [[PromiseResult]], [[PromiseFulfillReactions]], [[PromiseRejectReactions]], [[PromiseIsHandled]] »).
|
||||||
// 4. Set promise.[[PromiseState]] to pending.
|
// 4. Set promise.[[PromiseState]] to pending.
|
||||||
|
@ -481,7 +481,7 @@ JS_DEFINE_NATIVE_FUNCTION(PromiseConstructor::resolve)
|
||||||
|
|
||||||
// 2. If Type(C) is not Object, throw a TypeError exception.
|
// 2. If Type(C) is not Object, throw a TypeError exception.
|
||||||
if (!constructor.is_object())
|
if (!constructor.is_object())
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::NotAnObject, constructor.to_string_without_side_effects());
|
return vm.throw_completion<TypeError>(ErrorType::NotAnObject, constructor.to_string_without_side_effects());
|
||||||
|
|
||||||
// 3. Return ? PromiseResolve(C, x).
|
// 3. Return ? PromiseResolve(C, x).
|
||||||
return TRY(promise_resolve(global_object, constructor.as_object(), value));
|
return TRY(promise_resolve(global_object, constructor.as_object(), value));
|
||||||
|
|
|
@ -79,7 +79,7 @@ JS_DEFINE_NATIVE_FUNCTION(PromisePrototype::finally)
|
||||||
|
|
||||||
// 2. If Type(promise) is not Object, throw a TypeError exception.
|
// 2. If Type(promise) is not Object, throw a TypeError exception.
|
||||||
if (!promise.is_object())
|
if (!promise.is_object())
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::NotAnObject, promise.to_string_without_side_effects());
|
return vm.throw_completion<TypeError>(ErrorType::NotAnObject, promise.to_string_without_side_effects());
|
||||||
|
|
||||||
// 3. Let C be ? SpeciesConstructor(promise, %Promise%).
|
// 3. Let C be ? SpeciesConstructor(promise, %Promise%).
|
||||||
auto* constructor = TRY(species_constructor(global_object, promise.as_object(), *global_object.promise_constructor()));
|
auto* constructor = TRY(species_constructor(global_object, promise.as_object(), *global_object.promise_constructor()));
|
||||||
|
|
|
@ -19,7 +19,7 @@ ThrowCompletionOr<PromiseCapability> new_promise_capability(GlobalObject& global
|
||||||
|
|
||||||
// 1. If IsConstructor(C) is false, throw a TypeError exception.
|
// 1. If IsConstructor(C) is false, throw a TypeError exception.
|
||||||
if (!constructor.is_constructor())
|
if (!constructor.is_constructor())
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::NotAConstructor, constructor.to_string_without_side_effects());
|
return vm.throw_completion<TypeError>(ErrorType::NotAConstructor, constructor.to_string_without_side_effects());
|
||||||
|
|
||||||
// 2. NOTE: C is assumed to be a constructor function that supports the parameter conventions of the Promise constructor (see 27.2.3.1).
|
// 2. NOTE: C is assumed to be a constructor function that supports the parameter conventions of the Promise constructor (see 27.2.3.1).
|
||||||
|
|
||||||
|
@ -32,18 +32,18 @@ ThrowCompletionOr<PromiseCapability> new_promise_capability(GlobalObject& global
|
||||||
} promise_capability_functions;
|
} promise_capability_functions;
|
||||||
|
|
||||||
// 4. Let executorClosure be a new Abstract Closure with parameters (resolve, reject) that captures promiseCapability and performs the following steps when called:
|
// 4. Let executorClosure be a new Abstract Closure with parameters (resolve, reject) that captures promiseCapability and performs the following steps when called:
|
||||||
auto executor_closure = [&promise_capability_functions](auto& vm, auto& global_object) -> ThrowCompletionOr<Value> {
|
auto executor_closure = [&promise_capability_functions](auto& vm, auto&) -> ThrowCompletionOr<Value> {
|
||||||
auto resolve = vm.argument(0);
|
auto resolve = vm.argument(0);
|
||||||
auto reject = vm.argument(1);
|
auto reject = vm.argument(1);
|
||||||
|
|
||||||
// No idea what other engines say here.
|
// No idea what other engines say here.
|
||||||
// a. If promiseCapability.[[Resolve]] is not undefined, throw a TypeError exception.
|
// a. If promiseCapability.[[Resolve]] is not undefined, throw a TypeError exception.
|
||||||
if (!promise_capability_functions.resolve.is_undefined())
|
if (!promise_capability_functions.resolve.is_undefined())
|
||||||
return vm.template throw_completion<TypeError>(global_object, ErrorType::GetCapabilitiesExecutorCalledMultipleTimes);
|
return vm.template throw_completion<TypeError>(ErrorType::GetCapabilitiesExecutorCalledMultipleTimes);
|
||||||
|
|
||||||
// b. If promiseCapability.[[Reject]] is not undefined, throw a TypeError exception.
|
// b. If promiseCapability.[[Reject]] is not undefined, throw a TypeError exception.
|
||||||
if (!promise_capability_functions.reject.is_undefined())
|
if (!promise_capability_functions.reject.is_undefined())
|
||||||
return vm.template throw_completion<TypeError>(global_object, ErrorType::GetCapabilitiesExecutorCalledMultipleTimes);
|
return vm.template throw_completion<TypeError>(ErrorType::GetCapabilitiesExecutorCalledMultipleTimes);
|
||||||
|
|
||||||
// c. Set promiseCapability.[[Resolve]] to resolve.
|
// c. Set promiseCapability.[[Resolve]] to resolve.
|
||||||
promise_capability_functions.resolve = resolve;
|
promise_capability_functions.resolve = resolve;
|
||||||
|
@ -63,11 +63,11 @@ ThrowCompletionOr<PromiseCapability> new_promise_capability(GlobalObject& global
|
||||||
|
|
||||||
// 7. If IsCallable(promiseCapability.[[Resolve]]) is false, throw a TypeError exception.
|
// 7. If IsCallable(promiseCapability.[[Resolve]]) is false, throw a TypeError exception.
|
||||||
if (!promise_capability_functions.resolve.is_function())
|
if (!promise_capability_functions.resolve.is_function())
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::NotAFunction, promise_capability_functions.resolve.to_string_without_side_effects());
|
return vm.throw_completion<TypeError>(ErrorType::NotAFunction, promise_capability_functions.resolve.to_string_without_side_effects());
|
||||||
|
|
||||||
// 8. If IsCallable(promiseCapability.[[Reject]]) is false, throw a TypeError exception.
|
// 8. If IsCallable(promiseCapability.[[Reject]]) is false, throw a TypeError exception.
|
||||||
if (!promise_capability_functions.reject.is_function())
|
if (!promise_capability_functions.reject.is_function())
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::NotAFunction, promise_capability_functions.reject.to_string_without_side_effects());
|
return vm.throw_completion<TypeError>(ErrorType::NotAFunction, promise_capability_functions.reject.to_string_without_side_effects());
|
||||||
|
|
||||||
// 9. Set promiseCapability.[[Promise]] to promise.
|
// 9. Set promiseCapability.[[Promise]] to promise.
|
||||||
// 10. Return promiseCapability.
|
// 10. Return promiseCapability.
|
||||||
|
|
|
@ -94,7 +94,7 @@ ThrowCompletionOr<PropertyDescriptor> to_property_descriptor(GlobalObject& globa
|
||||||
|
|
||||||
// 1. If Type(Obj) is not Object, throw a TypeError exception.
|
// 1. If Type(Obj) is not Object, throw a TypeError exception.
|
||||||
if (!argument.is_object())
|
if (!argument.is_object())
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::NotAnObject, argument.to_string_without_side_effects());
|
return vm.throw_completion<TypeError>(ErrorType::NotAnObject, argument.to_string_without_side_effects());
|
||||||
|
|
||||||
auto& object = argument.as_object();
|
auto& object = argument.as_object();
|
||||||
|
|
||||||
|
@ -159,7 +159,7 @@ ThrowCompletionOr<PropertyDescriptor> to_property_descriptor(GlobalObject& globa
|
||||||
|
|
||||||
// b. If IsCallable(getter) is false and getter is not undefined, throw a TypeError exception.
|
// b. If IsCallable(getter) is false and getter is not undefined, throw a TypeError exception.
|
||||||
if (!getter.is_function() && !getter.is_undefined())
|
if (!getter.is_function() && !getter.is_undefined())
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::AccessorBadField, "get");
|
return vm.throw_completion<TypeError>(ErrorType::AccessorBadField, "get");
|
||||||
|
|
||||||
// c. Set desc.[[Get]] to getter.
|
// c. Set desc.[[Get]] to getter.
|
||||||
descriptor.get = getter.is_function() ? &getter.as_function() : nullptr;
|
descriptor.get = getter.is_function() ? &getter.as_function() : nullptr;
|
||||||
|
@ -175,7 +175,7 @@ ThrowCompletionOr<PropertyDescriptor> to_property_descriptor(GlobalObject& globa
|
||||||
|
|
||||||
// b. If IsCallable(setter) is false and setter is not undefined, throw a TypeError exception.
|
// b. If IsCallable(setter) is false and setter is not undefined, throw a TypeError exception.
|
||||||
if (!setter.is_function() && !setter.is_undefined())
|
if (!setter.is_function() && !setter.is_undefined())
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::AccessorBadField, "set");
|
return vm.throw_completion<TypeError>(ErrorType::AccessorBadField, "set");
|
||||||
|
|
||||||
// c. Set desc.[[Set]] to setter.
|
// c. Set desc.[[Set]] to setter.
|
||||||
descriptor.set = setter.is_function() ? &setter.as_function() : nullptr;
|
descriptor.set = setter.is_function() ? &setter.as_function() : nullptr;
|
||||||
|
@ -185,7 +185,7 @@ ThrowCompletionOr<PropertyDescriptor> to_property_descriptor(GlobalObject& globa
|
||||||
if (descriptor.get.has_value() || descriptor.set.has_value()) {
|
if (descriptor.get.has_value() || descriptor.set.has_value()) {
|
||||||
// a. If desc has a [[Value]] field or desc has a [[Writable]] field, throw a TypeError exception.
|
// a. If desc has a [[Value]] field or desc has a [[Writable]] field, throw a TypeError exception.
|
||||||
if (descriptor.value.has_value() || descriptor.writable.has_value())
|
if (descriptor.value.has_value() || descriptor.writable.has_value())
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::AccessorValueOrWritable);
|
return vm.throw_completion<TypeError>(ErrorType::AccessorValueOrWritable);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 16. Return desc.
|
// 16. Return desc.
|
||||||
|
|
|
@ -31,7 +31,7 @@ public:
|
||||||
auto& vm = global_object.vm();
|
auto& vm = global_object.vm();
|
||||||
auto this_value = vm.this_value(global_object);
|
auto this_value = vm.this_value(global_object);
|
||||||
if (!this_value.is_object())
|
if (!this_value.is_object())
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::NotAnObject, this_value);
|
return vm.throw_completion<TypeError>(ErrorType::NotAnObject, this_value);
|
||||||
return &this_value.as_object();
|
return &this_value.as_object();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -41,7 +41,7 @@ public:
|
||||||
auto& vm = global_object.vm();
|
auto& vm = global_object.vm();
|
||||||
auto* this_object = TRY(vm.this_value(global_object).to_object(global_object));
|
auto* this_object = TRY(vm.this_value(global_object).to_object(global_object));
|
||||||
if (!is<ObjectType>(this_object))
|
if (!is<ObjectType>(this_object))
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::NotAnObjectOfType, PrototypeType::display_name());
|
return vm.throw_completion<TypeError>(ErrorType::NotAnObjectOfType, PrototypeType::display_name());
|
||||||
return static_cast<ObjectType*>(this_object);
|
return static_cast<ObjectType*>(this_object);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -51,7 +51,7 @@ public:
|
||||||
auto& vm = global_object.vm();
|
auto& vm = global_object.vm();
|
||||||
auto this_value = vm.this_value(global_object);
|
auto this_value = vm.this_value(global_object);
|
||||||
if (!this_value.is_object() || !is<ObjectType>(this_value.as_object()))
|
if (!this_value.is_object() || !is<ObjectType>(this_value.as_object()))
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::NotAnObjectOfType, PrototypeType::display_name());
|
return vm.throw_completion<TypeError>(ErrorType::NotAnObjectOfType, PrototypeType::display_name());
|
||||||
return static_cast<ObjectType*>(&this_value.as_object());
|
return static_cast<ObjectType*>(&this_value.as_object());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -19,9 +19,9 @@ static ThrowCompletionOr<ProxyObject*> proxy_create(GlobalObject& global_object,
|
||||||
auto& vm = global_object.vm();
|
auto& vm = global_object.vm();
|
||||||
auto& realm = *global_object.associated_realm();
|
auto& realm = *global_object.associated_realm();
|
||||||
if (!target.is_object())
|
if (!target.is_object())
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::ProxyConstructorBadType, "target", target.to_string_without_side_effects());
|
return vm.throw_completion<TypeError>(ErrorType::ProxyConstructorBadType, "target", target.to_string_without_side_effects());
|
||||||
if (!handler.is_object())
|
if (!handler.is_object())
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::ProxyConstructorBadType, "handler", handler.to_string_without_side_effects());
|
return vm.throw_completion<TypeError>(ErrorType::ProxyConstructorBadType, "handler", handler.to_string_without_side_effects());
|
||||||
return ProxyObject::create(realm, target.as_object(), handler.as_object());
|
return ProxyObject::create(realm, target.as_object(), handler.as_object());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -44,7 +44,7 @@ void ProxyConstructor::initialize(Realm& realm)
|
||||||
ThrowCompletionOr<Value> ProxyConstructor::call()
|
ThrowCompletionOr<Value> ProxyConstructor::call()
|
||||||
{
|
{
|
||||||
auto& vm = this->vm();
|
auto& vm = this->vm();
|
||||||
return vm.throw_completion<TypeError>(global_object(), ErrorType::ConstructorWithoutNew, vm.names.Proxy);
|
return vm.throw_completion<TypeError>(ErrorType::ConstructorWithoutNew, vm.names.Proxy);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 28.2.1.1 Proxy ( target, handler ), https://tc39.es/ecma262/#sec-proxy-target-handler
|
// 28.2.1.1 Proxy ( target, handler ), https://tc39.es/ecma262/#sec-proxy-target-handler
|
||||||
|
|
|
@ -50,7 +50,7 @@ ThrowCompletionOr<Object*> ProxyObject::internal_get_prototype_of() const
|
||||||
|
|
||||||
// 2. If handler is null, throw a TypeError exception.
|
// 2. If handler is null, throw a TypeError exception.
|
||||||
if (m_is_revoked)
|
if (m_is_revoked)
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::ProxyRevoked);
|
return vm.throw_completion<TypeError>(ErrorType::ProxyRevoked);
|
||||||
|
|
||||||
// 3. Assert: Type(handler) is Object.
|
// 3. Assert: Type(handler) is Object.
|
||||||
// 4. Let target be O.[[ProxyTarget]].
|
// 4. Let target be O.[[ProxyTarget]].
|
||||||
|
@ -69,7 +69,7 @@ ThrowCompletionOr<Object*> ProxyObject::internal_get_prototype_of() const
|
||||||
|
|
||||||
// 8. If Type(handlerProto) is neither Object nor Null, throw a TypeError exception.
|
// 8. If Type(handlerProto) is neither Object nor Null, throw a TypeError exception.
|
||||||
if (!handler_proto.is_object() && !handler_proto.is_null())
|
if (!handler_proto.is_object() && !handler_proto.is_null())
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::ProxyGetPrototypeOfReturn);
|
return vm.throw_completion<TypeError>(ErrorType::ProxyGetPrototypeOfReturn);
|
||||||
|
|
||||||
// 9. Let extensibleTarget be ? IsExtensible(target).
|
// 9. Let extensibleTarget be ? IsExtensible(target).
|
||||||
auto extensible_target = TRY(m_target.is_extensible());
|
auto extensible_target = TRY(m_target.is_extensible());
|
||||||
|
@ -83,7 +83,7 @@ ThrowCompletionOr<Object*> ProxyObject::internal_get_prototype_of() const
|
||||||
|
|
||||||
// 12. If SameValue(handlerProto, targetProto) is false, throw a TypeError exception.
|
// 12. If SameValue(handlerProto, targetProto) is false, throw a TypeError exception.
|
||||||
if (!same_value(handler_proto, target_proto))
|
if (!same_value(handler_proto, target_proto))
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::ProxyGetPrototypeOfNonExtensible);
|
return vm.throw_completion<TypeError>(ErrorType::ProxyGetPrototypeOfNonExtensible);
|
||||||
|
|
||||||
// 13. Return handlerProto.
|
// 13. Return handlerProto.
|
||||||
return handler_proto.is_null() ? nullptr : &handler_proto.as_object();
|
return handler_proto.is_null() ? nullptr : &handler_proto.as_object();
|
||||||
|
@ -99,7 +99,7 @@ ThrowCompletionOr<bool> ProxyObject::internal_set_prototype_of(Object* prototype
|
||||||
|
|
||||||
// 2. If handler is null, throw a TypeError exception.
|
// 2. If handler is null, throw a TypeError exception.
|
||||||
if (m_is_revoked)
|
if (m_is_revoked)
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::ProxyRevoked);
|
return vm.throw_completion<TypeError>(ErrorType::ProxyRevoked);
|
||||||
|
|
||||||
// 3. Assert: Type(handler) is Object.
|
// 3. Assert: Type(handler) is Object.
|
||||||
// 4. Let target be O.[[ProxyTarget]].
|
// 4. Let target be O.[[ProxyTarget]].
|
||||||
|
@ -132,7 +132,7 @@ ThrowCompletionOr<bool> ProxyObject::internal_set_prototype_of(Object* prototype
|
||||||
|
|
||||||
// 12. If SameValue(V, targetProto) is false, throw a TypeError exception.
|
// 12. If SameValue(V, targetProto) is false, throw a TypeError exception.
|
||||||
if (!same_value(prototype, target_proto))
|
if (!same_value(prototype, target_proto))
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::ProxySetPrototypeOfNonExtensible);
|
return vm.throw_completion<TypeError>(ErrorType::ProxySetPrototypeOfNonExtensible);
|
||||||
|
|
||||||
// 13. Return true.
|
// 13. Return true.
|
||||||
return true;
|
return true;
|
||||||
|
@ -148,7 +148,7 @@ ThrowCompletionOr<bool> ProxyObject::internal_is_extensible() const
|
||||||
|
|
||||||
// 2. If handler is null, throw a TypeError exception.
|
// 2. If handler is null, throw a TypeError exception.
|
||||||
if (m_is_revoked)
|
if (m_is_revoked)
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::ProxyRevoked);
|
return vm.throw_completion<TypeError>(ErrorType::ProxyRevoked);
|
||||||
|
|
||||||
// 3. Assert: Type(handler) is Object.
|
// 3. Assert: Type(handler) is Object.
|
||||||
// 4. Let target be O.[[ProxyTarget]].
|
// 4. Let target be O.[[ProxyTarget]].
|
||||||
|
@ -170,7 +170,7 @@ ThrowCompletionOr<bool> ProxyObject::internal_is_extensible() const
|
||||||
|
|
||||||
// 9. If SameValue(booleanTrapResult, targetResult) is false, throw a TypeError exception.
|
// 9. If SameValue(booleanTrapResult, targetResult) is false, throw a TypeError exception.
|
||||||
if (trap_result != target_result)
|
if (trap_result != target_result)
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::ProxyIsExtensibleReturn);
|
return vm.throw_completion<TypeError>(ErrorType::ProxyIsExtensibleReturn);
|
||||||
|
|
||||||
// 10. Return booleanTrapResult.
|
// 10. Return booleanTrapResult.
|
||||||
return trap_result;
|
return trap_result;
|
||||||
|
@ -186,7 +186,7 @@ ThrowCompletionOr<bool> ProxyObject::internal_prevent_extensions()
|
||||||
|
|
||||||
// 2. If handler is null, throw a TypeError exception.
|
// 2. If handler is null, throw a TypeError exception.
|
||||||
if (m_is_revoked)
|
if (m_is_revoked)
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::ProxyRevoked);
|
return vm.throw_completion<TypeError>(ErrorType::ProxyRevoked);
|
||||||
|
|
||||||
// 3. Assert: Type(handler) is Object.
|
// 3. Assert: Type(handler) is Object.
|
||||||
// 4. Let target be O.[[ProxyTarget]].
|
// 4. Let target be O.[[ProxyTarget]].
|
||||||
|
@ -210,7 +210,7 @@ ThrowCompletionOr<bool> ProxyObject::internal_prevent_extensions()
|
||||||
|
|
||||||
// b. If extensibleTarget is true, throw a TypeError exception.
|
// b. If extensibleTarget is true, throw a TypeError exception.
|
||||||
if (extensible_target)
|
if (extensible_target)
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::ProxyPreventExtensionsReturn);
|
return vm.throw_completion<TypeError>(ErrorType::ProxyPreventExtensionsReturn);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 9. Return booleanTrapResult.
|
// 9. Return booleanTrapResult.
|
||||||
|
@ -229,7 +229,7 @@ ThrowCompletionOr<Optional<PropertyDescriptor>> ProxyObject::internal_get_own_pr
|
||||||
|
|
||||||
// 2. If handler is null, throw a TypeError exception.
|
// 2. If handler is null, throw a TypeError exception.
|
||||||
if (m_is_revoked)
|
if (m_is_revoked)
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::ProxyRevoked);
|
return vm.throw_completion<TypeError>(ErrorType::ProxyRevoked);
|
||||||
|
|
||||||
// 3. Assert: Type(handler) is Object.
|
// 3. Assert: Type(handler) is Object.
|
||||||
// 4. Let target be O.[[ProxyTarget]].
|
// 4. Let target be O.[[ProxyTarget]].
|
||||||
|
@ -248,7 +248,7 @@ ThrowCompletionOr<Optional<PropertyDescriptor>> ProxyObject::internal_get_own_pr
|
||||||
|
|
||||||
// 8. If Type(trapResultObj) is neither Object nor Undefined, throw a TypeError exception.
|
// 8. If Type(trapResultObj) is neither Object nor Undefined, throw a TypeError exception.
|
||||||
if (!trap_result.is_object() && !trap_result.is_undefined())
|
if (!trap_result.is_object() && !trap_result.is_undefined())
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::ProxyGetOwnDescriptorReturn);
|
return vm.throw_completion<TypeError>(ErrorType::ProxyGetOwnDescriptorReturn);
|
||||||
|
|
||||||
// 9. Let targetDesc be ? target.[[GetOwnProperty]](P).
|
// 9. Let targetDesc be ? target.[[GetOwnProperty]](P).
|
||||||
auto target_descriptor = TRY(m_target.internal_get_own_property(property_key));
|
auto target_descriptor = TRY(m_target.internal_get_own_property(property_key));
|
||||||
|
@ -261,14 +261,14 @@ ThrowCompletionOr<Optional<PropertyDescriptor>> ProxyObject::internal_get_own_pr
|
||||||
|
|
||||||
// b. If targetDesc.[[Configurable]] is false, throw a TypeError exception.
|
// b. If targetDesc.[[Configurable]] is false, throw a TypeError exception.
|
||||||
if (!*target_descriptor->configurable)
|
if (!*target_descriptor->configurable)
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::ProxyGetOwnDescriptorNonConfigurable);
|
return vm.throw_completion<TypeError>(ErrorType::ProxyGetOwnDescriptorNonConfigurable);
|
||||||
|
|
||||||
// c. Let extensibleTarget be ? IsExtensible(target).
|
// c. Let extensibleTarget be ? IsExtensible(target).
|
||||||
auto extensible_target = TRY(m_target.is_extensible());
|
auto extensible_target = TRY(m_target.is_extensible());
|
||||||
|
|
||||||
// d. If extensibleTarget is false, throw a TypeError exception.
|
// d. If extensibleTarget is false, throw a TypeError exception.
|
||||||
if (!extensible_target)
|
if (!extensible_target)
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::ProxyGetOwnDescriptorUndefinedReturn);
|
return vm.throw_completion<TypeError>(ErrorType::ProxyGetOwnDescriptorUndefinedReturn);
|
||||||
|
|
||||||
// e. Return undefined.
|
// e. Return undefined.
|
||||||
return Optional<PropertyDescriptor> {};
|
return Optional<PropertyDescriptor> {};
|
||||||
|
@ -288,20 +288,20 @@ ThrowCompletionOr<Optional<PropertyDescriptor>> ProxyObject::internal_get_own_pr
|
||||||
|
|
||||||
// 15. If valid is false, throw a TypeError exception.
|
// 15. If valid is false, throw a TypeError exception.
|
||||||
if (!valid)
|
if (!valid)
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::ProxyGetOwnDescriptorInvalidDescriptor);
|
return vm.throw_completion<TypeError>(ErrorType::ProxyGetOwnDescriptorInvalidDescriptor);
|
||||||
|
|
||||||
// 16. If resultDesc.[[Configurable]] is false, then
|
// 16. If resultDesc.[[Configurable]] is false, then
|
||||||
if (!*result_desc.configurable) {
|
if (!*result_desc.configurable) {
|
||||||
// a. If targetDesc is undefined or targetDesc.[[Configurable]] is true, then
|
// a. If targetDesc is undefined or targetDesc.[[Configurable]] is true, then
|
||||||
if (!target_descriptor.has_value() || *target_descriptor->configurable)
|
if (!target_descriptor.has_value() || *target_descriptor->configurable)
|
||||||
// i. Throw a TypeError exception.
|
// i. Throw a TypeError exception.
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::ProxyGetOwnDescriptorInvalidNonConfig);
|
return vm.throw_completion<TypeError>(ErrorType::ProxyGetOwnDescriptorInvalidNonConfig);
|
||||||
|
|
||||||
// b. If resultDesc has a [[Writable]] field and resultDesc.[[Writable]] is false, then
|
// b. If resultDesc has a [[Writable]] field and resultDesc.[[Writable]] is false, then
|
||||||
if (result_desc.writable.has_value() && !*result_desc.writable) {
|
if (result_desc.writable.has_value() && !*result_desc.writable) {
|
||||||
// i. If targetDesc.[[Writable]] is true, throw a TypeError exception.
|
// i. If targetDesc.[[Writable]] is true, throw a TypeError exception.
|
||||||
if (*target_descriptor->writable)
|
if (*target_descriptor->writable)
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::ProxyGetOwnDescriptorNonConfigurableNonWritable);
|
return vm.throw_completion<TypeError>(ErrorType::ProxyGetOwnDescriptorNonConfigurableNonWritable);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -321,7 +321,7 @@ ThrowCompletionOr<bool> ProxyObject::internal_define_own_property(PropertyKey co
|
||||||
|
|
||||||
// 2. If handler is null, throw a TypeError exception.
|
// 2. If handler is null, throw a TypeError exception.
|
||||||
if (m_is_revoked)
|
if (m_is_revoked)
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::ProxyRevoked);
|
return vm.throw_completion<TypeError>(ErrorType::ProxyRevoked);
|
||||||
|
|
||||||
// 3. Assert: Type(handler) is Object.
|
// 3. Assert: Type(handler) is Object.
|
||||||
// 4. Let target be O.[[ProxyTarget]].
|
// 4. Let target be O.[[ProxyTarget]].
|
||||||
|
@ -364,27 +364,27 @@ ThrowCompletionOr<bool> ProxyObject::internal_define_own_property(PropertyKey co
|
||||||
if (!target_descriptor.has_value()) {
|
if (!target_descriptor.has_value()) {
|
||||||
// a. If extensibleTarget is false, throw a TypeError exception.
|
// a. If extensibleTarget is false, throw a TypeError exception.
|
||||||
if (!extensible_target)
|
if (!extensible_target)
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::ProxyDefinePropNonExtensible);
|
return vm.throw_completion<TypeError>(ErrorType::ProxyDefinePropNonExtensible);
|
||||||
|
|
||||||
// b. If settingConfigFalse is true, throw a TypeError exception.
|
// b. If settingConfigFalse is true, throw a TypeError exception.
|
||||||
if (setting_config_false)
|
if (setting_config_false)
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::ProxyDefinePropNonConfigurableNonExisting);
|
return vm.throw_completion<TypeError>(ErrorType::ProxyDefinePropNonConfigurableNonExisting);
|
||||||
}
|
}
|
||||||
// 15. Else,
|
// 15. Else,
|
||||||
else {
|
else {
|
||||||
// a. If IsCompatiblePropertyDescriptor(extensibleTarget, Desc, targetDesc) is false, throw a TypeError exception.
|
// a. If IsCompatiblePropertyDescriptor(extensibleTarget, Desc, targetDesc) is false, throw a TypeError exception.
|
||||||
if (!is_compatible_property_descriptor(extensible_target, property_descriptor, target_descriptor))
|
if (!is_compatible_property_descriptor(extensible_target, property_descriptor, target_descriptor))
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::ProxyDefinePropIncompatibleDescriptor);
|
return vm.throw_completion<TypeError>(ErrorType::ProxyDefinePropIncompatibleDescriptor);
|
||||||
|
|
||||||
// b. If settingConfigFalse is true and targetDesc.[[Configurable]] is true, throw a TypeError exception.
|
// b. If settingConfigFalse is true and targetDesc.[[Configurable]] is true, throw a TypeError exception.
|
||||||
if (setting_config_false && *target_descriptor->configurable)
|
if (setting_config_false && *target_descriptor->configurable)
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::ProxyDefinePropExistingConfigurable);
|
return vm.throw_completion<TypeError>(ErrorType::ProxyDefinePropExistingConfigurable);
|
||||||
|
|
||||||
// c. If IsDataDescriptor(targetDesc) is true, targetDesc.[[Configurable]] is false, and targetDesc.[[Writable]] is true, then
|
// c. If IsDataDescriptor(targetDesc) is true, targetDesc.[[Configurable]] is false, and targetDesc.[[Writable]] is true, then
|
||||||
if (target_descriptor->is_data_descriptor() && !*target_descriptor->configurable && *target_descriptor->writable) {
|
if (target_descriptor->is_data_descriptor() && !*target_descriptor->configurable && *target_descriptor->writable) {
|
||||||
// i. If Desc has a [[Writable]] field and Desc.[[Writable]] is false, throw a TypeError exception.
|
// i. If Desc has a [[Writable]] field and Desc.[[Writable]] is false, throw a TypeError exception.
|
||||||
if (property_descriptor.writable.has_value() && !*property_descriptor.writable)
|
if (property_descriptor.writable.has_value() && !*property_descriptor.writable)
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::ProxyDefinePropNonWritable);
|
return vm.throw_completion<TypeError>(ErrorType::ProxyDefinePropNonWritable);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -404,7 +404,7 @@ ThrowCompletionOr<bool> ProxyObject::internal_has_property(PropertyKey const& pr
|
||||||
|
|
||||||
// 2. If handler is null, throw a TypeError exception.
|
// 2. If handler is null, throw a TypeError exception.
|
||||||
if (m_is_revoked)
|
if (m_is_revoked)
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::ProxyRevoked);
|
return vm.throw_completion<TypeError>(ErrorType::ProxyRevoked);
|
||||||
|
|
||||||
// 3. Assert: Type(handler) is Object.
|
// 3. Assert: Type(handler) is Object.
|
||||||
// 4. Let target be O.[[ProxyTarget]].
|
// 4. Let target be O.[[ProxyTarget]].
|
||||||
|
@ -430,14 +430,14 @@ ThrowCompletionOr<bool> ProxyObject::internal_has_property(PropertyKey const& pr
|
||||||
if (target_descriptor.has_value()) {
|
if (target_descriptor.has_value()) {
|
||||||
// i. If targetDesc.[[Configurable]] is false, throw a TypeError exception.
|
// i. If targetDesc.[[Configurable]] is false, throw a TypeError exception.
|
||||||
if (!*target_descriptor->configurable)
|
if (!*target_descriptor->configurable)
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::ProxyHasExistingNonConfigurable);
|
return vm.throw_completion<TypeError>(ErrorType::ProxyHasExistingNonConfigurable);
|
||||||
|
|
||||||
// ii. Let extensibleTarget be ? IsExtensible(target).
|
// ii. Let extensibleTarget be ? IsExtensible(target).
|
||||||
auto extensible_target = TRY(m_target.is_extensible());
|
auto extensible_target = TRY(m_target.is_extensible());
|
||||||
|
|
||||||
// iii. If extensibleTarget is false, throw a TypeError exception.
|
// iii. If extensibleTarget is false, throw a TypeError exception.
|
||||||
if (!extensible_target)
|
if (!extensible_target)
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::ProxyHasExistingNonExtensible);
|
return vm.throw_completion<TypeError>(ErrorType::ProxyHasExistingNonExtensible);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -460,7 +460,7 @@ ThrowCompletionOr<Value> ProxyObject::internal_get(PropertyKey const& property_k
|
||||||
|
|
||||||
// 2. If handler is null, throw a TypeError exception.
|
// 2. If handler is null, throw a TypeError exception.
|
||||||
if (m_is_revoked)
|
if (m_is_revoked)
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::ProxyRevoked);
|
return vm.throw_completion<TypeError>(ErrorType::ProxyRevoked);
|
||||||
|
|
||||||
// 3. Assert: Type(handler) is Object.
|
// 3. Assert: Type(handler) is Object.
|
||||||
// 4. Let target be O.[[ProxyTarget]].
|
// 4. Let target be O.[[ProxyTarget]].
|
||||||
|
@ -479,7 +479,7 @@ ThrowCompletionOr<Value> ProxyObject::internal_get(PropertyKey const& property_k
|
||||||
//
|
//
|
||||||
// In JS code: `h = {}; p = new Proxy({}, h); h.__proto__ = p; p.foo // or h.foo`
|
// In JS code: `h = {}; p = new Proxy({}, h); h.__proto__ = p; p.foo // or h.foo`
|
||||||
if (vm.did_reach_stack_space_limit())
|
if (vm.did_reach_stack_space_limit())
|
||||||
return vm.throw_completion<InternalError>(global_object, ErrorType::CallStackSizeExceeded);
|
return vm.throw_completion<InternalError>(ErrorType::CallStackSizeExceeded);
|
||||||
|
|
||||||
// 5. Let trap be ? GetMethod(handler, "get").
|
// 5. Let trap be ? GetMethod(handler, "get").
|
||||||
auto trap = TRY(Value(&m_handler).get_method(global_object, vm.names.get));
|
auto trap = TRY(Value(&m_handler).get_method(global_object, vm.names.get));
|
||||||
|
@ -502,13 +502,13 @@ ThrowCompletionOr<Value> ProxyObject::internal_get(PropertyKey const& property_k
|
||||||
if (target_descriptor->is_data_descriptor() && !*target_descriptor->writable) {
|
if (target_descriptor->is_data_descriptor() && !*target_descriptor->writable) {
|
||||||
// i. If SameValue(trapResult, targetDesc.[[Value]]) is false, throw a TypeError exception.
|
// i. If SameValue(trapResult, targetDesc.[[Value]]) is false, throw a TypeError exception.
|
||||||
if (!same_value(trap_result, *target_descriptor->value))
|
if (!same_value(trap_result, *target_descriptor->value))
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::ProxyGetImmutableDataProperty);
|
return vm.throw_completion<TypeError>(ErrorType::ProxyGetImmutableDataProperty);
|
||||||
}
|
}
|
||||||
// b. If IsAccessorDescriptor(targetDesc) is true and targetDesc.[[Get]] is undefined, then
|
// b. If IsAccessorDescriptor(targetDesc) is true and targetDesc.[[Get]] is undefined, then
|
||||||
if (target_descriptor->is_accessor_descriptor() && !*target_descriptor->get) {
|
if (target_descriptor->is_accessor_descriptor() && !*target_descriptor->get) {
|
||||||
// i. If trapResult is not undefined, throw a TypeError exception.
|
// i. If trapResult is not undefined, throw a TypeError exception.
|
||||||
if (!trap_result.is_undefined())
|
if (!trap_result.is_undefined())
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::ProxyGetNonConfigurableAccessor);
|
return vm.throw_completion<TypeError>(ErrorType::ProxyGetNonConfigurableAccessor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -530,7 +530,7 @@ ThrowCompletionOr<bool> ProxyObject::internal_set(PropertyKey const& property_ke
|
||||||
|
|
||||||
// 2. If handler is null, throw a TypeError exception.
|
// 2. If handler is null, throw a TypeError exception.
|
||||||
if (m_is_revoked)
|
if (m_is_revoked)
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::ProxyRevoked);
|
return vm.throw_completion<TypeError>(ErrorType::ProxyRevoked);
|
||||||
|
|
||||||
// 3. Assert: Type(handler) is Object.
|
// 3. Assert: Type(handler) is Object.
|
||||||
// 4. Let target be O.[[ProxyTarget]].
|
// 4. Let target be O.[[ProxyTarget]].
|
||||||
|
@ -560,13 +560,13 @@ ThrowCompletionOr<bool> ProxyObject::internal_set(PropertyKey const& property_ke
|
||||||
if (target_descriptor->is_data_descriptor() && !*target_descriptor->writable) {
|
if (target_descriptor->is_data_descriptor() && !*target_descriptor->writable) {
|
||||||
// i. If SameValue(V, targetDesc.[[Value]]) is false, throw a TypeError exception.
|
// i. If SameValue(V, targetDesc.[[Value]]) is false, throw a TypeError exception.
|
||||||
if (!same_value(value, *target_descriptor->value))
|
if (!same_value(value, *target_descriptor->value))
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::ProxySetImmutableDataProperty);
|
return vm.throw_completion<TypeError>(ErrorType::ProxySetImmutableDataProperty);
|
||||||
}
|
}
|
||||||
// b. If IsAccessorDescriptor(targetDesc) is true, then
|
// b. If IsAccessorDescriptor(targetDesc) is true, then
|
||||||
if (target_descriptor->is_accessor_descriptor()) {
|
if (target_descriptor->is_accessor_descriptor()) {
|
||||||
// i. If targetDesc.[[Set]] is undefined, throw a TypeError exception.
|
// i. If targetDesc.[[Set]] is undefined, throw a TypeError exception.
|
||||||
if (!*target_descriptor->set)
|
if (!*target_descriptor->set)
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::ProxySetNonConfigurableAccessor);
|
return vm.throw_completion<TypeError>(ErrorType::ProxySetNonConfigurableAccessor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -586,7 +586,7 @@ ThrowCompletionOr<bool> ProxyObject::internal_delete(PropertyKey const& property
|
||||||
|
|
||||||
// 2. If handler is null, throw a TypeError exception.
|
// 2. If handler is null, throw a TypeError exception.
|
||||||
if (m_is_revoked)
|
if (m_is_revoked)
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::ProxyRevoked);
|
return vm.throw_completion<TypeError>(ErrorType::ProxyRevoked);
|
||||||
|
|
||||||
// 3. Assert: Type(handler) is Object.
|
// 3. Assert: Type(handler) is Object.
|
||||||
// 4. Let target be O.[[ProxyTarget]].
|
// 4. Let target be O.[[ProxyTarget]].
|
||||||
|
@ -616,14 +616,14 @@ ThrowCompletionOr<bool> ProxyObject::internal_delete(PropertyKey const& property
|
||||||
|
|
||||||
// 11. If targetDesc.[[Configurable]] is false, throw a TypeError exception.
|
// 11. If targetDesc.[[Configurable]] is false, throw a TypeError exception.
|
||||||
if (!*target_descriptor->configurable)
|
if (!*target_descriptor->configurable)
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::ProxyDeleteNonConfigurable);
|
return vm.throw_completion<TypeError>(ErrorType::ProxyDeleteNonConfigurable);
|
||||||
|
|
||||||
// 12. Let extensibleTarget be ? IsExtensible(target).
|
// 12. Let extensibleTarget be ? IsExtensible(target).
|
||||||
auto extensible_target = TRY(m_target.is_extensible());
|
auto extensible_target = TRY(m_target.is_extensible());
|
||||||
|
|
||||||
// 13. If extensibleTarget is false, throw a TypeError exception.
|
// 13. If extensibleTarget is false, throw a TypeError exception.
|
||||||
if (!extensible_target)
|
if (!extensible_target)
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::ProxyDeleteNonExtensible);
|
return vm.throw_completion<TypeError>(ErrorType::ProxyDeleteNonExtensible);
|
||||||
|
|
||||||
// 14. Return true.
|
// 14. Return true.
|
||||||
return true;
|
return true;
|
||||||
|
@ -639,7 +639,7 @@ ThrowCompletionOr<MarkedVector<Value>> ProxyObject::internal_own_property_keys()
|
||||||
|
|
||||||
// 2. If handler is null, throw a TypeError exception.
|
// 2. If handler is null, throw a TypeError exception.
|
||||||
if (m_is_revoked)
|
if (m_is_revoked)
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::ProxyRevoked);
|
return vm.throw_completion<TypeError>(ErrorType::ProxyRevoked);
|
||||||
|
|
||||||
// 3. Assert: Type(handler) is Object.
|
// 3. Assert: Type(handler) is Object.
|
||||||
// 4. Let target be O.[[ProxyTarget]].
|
// 4. Let target be O.[[ProxyTarget]].
|
||||||
|
@ -661,7 +661,7 @@ ThrowCompletionOr<MarkedVector<Value>> ProxyObject::internal_own_property_keys()
|
||||||
auto trap_result = TRY(create_list_from_array_like(global_object, trap_result_array, [&](auto value) -> ThrowCompletionOr<void> {
|
auto trap_result = TRY(create_list_from_array_like(global_object, trap_result_array, [&](auto value) -> ThrowCompletionOr<void> {
|
||||||
auto& vm = global_object.vm();
|
auto& vm = global_object.vm();
|
||||||
if (!value.is_string() && !value.is_symbol())
|
if (!value.is_string() && !value.is_symbol())
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::ProxyOwnPropertyKeysNotStringOrSymbol);
|
return vm.throw_completion<TypeError>(ErrorType::ProxyOwnPropertyKeysNotStringOrSymbol);
|
||||||
auto property_key = MUST(value.to_property_key(global_object));
|
auto property_key = MUST(value.to_property_key(global_object));
|
||||||
unique_keys.set(property_key, AK::HashSetExistingEntryBehavior::Keep);
|
unique_keys.set(property_key, AK::HashSetExistingEntryBehavior::Keep);
|
||||||
return {};
|
return {};
|
||||||
|
@ -669,7 +669,7 @@ ThrowCompletionOr<MarkedVector<Value>> ProxyObject::internal_own_property_keys()
|
||||||
|
|
||||||
// 9. If trapResult contains any duplicate entries, throw a TypeError exception.
|
// 9. If trapResult contains any duplicate entries, throw a TypeError exception.
|
||||||
if (unique_keys.size() != trap_result.size())
|
if (unique_keys.size() != trap_result.size())
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::ProxyOwnPropertyKeysDuplicates);
|
return vm.throw_completion<TypeError>(ErrorType::ProxyOwnPropertyKeysDuplicates);
|
||||||
|
|
||||||
// 10. Let extensibleTarget be ? IsExtensible(target).
|
// 10. Let extensibleTarget be ? IsExtensible(target).
|
||||||
auto extensible_target = TRY(m_target.is_extensible());
|
auto extensible_target = TRY(m_target.is_extensible());
|
||||||
|
@ -719,7 +719,7 @@ ThrowCompletionOr<MarkedVector<Value>> ProxyObject::internal_own_property_keys()
|
||||||
for (auto& key : target_nonconfigurable_keys) {
|
for (auto& key : target_nonconfigurable_keys) {
|
||||||
// a. If key is not an element of uncheckedResultKeys, throw a TypeError exception.
|
// a. If key is not an element of uncheckedResultKeys, throw a TypeError exception.
|
||||||
if (!unchecked_result_keys.contains_slow(key))
|
if (!unchecked_result_keys.contains_slow(key))
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::ProxyOwnPropertyKeysSkippedNonconfigurableProperty, key.to_string_without_side_effects());
|
return vm.throw_completion<TypeError>(ErrorType::ProxyOwnPropertyKeysSkippedNonconfigurableProperty, key.to_string_without_side_effects());
|
||||||
|
|
||||||
// b. Remove key from uncheckedResultKeys.
|
// b. Remove key from uncheckedResultKeys.
|
||||||
unchecked_result_keys.remove_first_matching([&](auto& value) {
|
unchecked_result_keys.remove_first_matching([&](auto& value) {
|
||||||
|
@ -735,7 +735,7 @@ ThrowCompletionOr<MarkedVector<Value>> ProxyObject::internal_own_property_keys()
|
||||||
for (auto& key : target_configurable_keys) {
|
for (auto& key : target_configurable_keys) {
|
||||||
// a. If key is not an element of uncheckedResultKeys, throw a TypeError exception.
|
// a. If key is not an element of uncheckedResultKeys, throw a TypeError exception.
|
||||||
if (!unchecked_result_keys.contains_slow(key))
|
if (!unchecked_result_keys.contains_slow(key))
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::ProxyOwnPropertyKeysNonExtensibleSkippedProperty, key.to_string_without_side_effects());
|
return vm.throw_completion<TypeError>(ErrorType::ProxyOwnPropertyKeysNonExtensibleSkippedProperty, key.to_string_without_side_effects());
|
||||||
|
|
||||||
// b. Remove key from uncheckedResultKeys.
|
// b. Remove key from uncheckedResultKeys.
|
||||||
unchecked_result_keys.remove_first_matching([&](auto& value) {
|
unchecked_result_keys.remove_first_matching([&](auto& value) {
|
||||||
|
@ -745,7 +745,7 @@ ThrowCompletionOr<MarkedVector<Value>> ProxyObject::internal_own_property_keys()
|
||||||
|
|
||||||
// 22. If uncheckedResultKeys is not empty, throw a TypeError exception.
|
// 22. If uncheckedResultKeys is not empty, throw a TypeError exception.
|
||||||
if (!unchecked_result_keys.is_empty())
|
if (!unchecked_result_keys.is_empty())
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::ProxyOwnPropertyKeysNonExtensibleNewProperty, unchecked_result_keys[0].to_string_without_side_effects());
|
return vm.throw_completion<TypeError>(ErrorType::ProxyOwnPropertyKeysNonExtensibleNewProperty, unchecked_result_keys[0].to_string_without_side_effects());
|
||||||
|
|
||||||
// 23. Return trapResult.
|
// 23. Return trapResult.
|
||||||
return { move(trap_result) };
|
return { move(trap_result) };
|
||||||
|
@ -763,13 +763,13 @@ ThrowCompletionOr<Value> ProxyObject::internal_call(Value this_argument, MarkedV
|
||||||
// According to the spec, the Call() AO may be called with a non-function argument, but
|
// According to the spec, the Call() AO may be called with a non-function argument, but
|
||||||
// throws before calling [[Call]]() if that's the case.
|
// throws before calling [[Call]]() if that's the case.
|
||||||
if (!is_function())
|
if (!is_function())
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::NotAFunction, Value(this).to_string_without_side_effects());
|
return vm.throw_completion<TypeError>(ErrorType::NotAFunction, Value(this).to_string_without_side_effects());
|
||||||
|
|
||||||
// 1. Let handler be O.[[ProxyHandler]].
|
// 1. Let handler be O.[[ProxyHandler]].
|
||||||
|
|
||||||
// 2. If handler is null, throw a TypeError exception.
|
// 2. If handler is null, throw a TypeError exception.
|
||||||
if (m_is_revoked)
|
if (m_is_revoked)
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::ProxyRevoked);
|
return vm.throw_completion<TypeError>(ErrorType::ProxyRevoked);
|
||||||
|
|
||||||
// 3. Assert: Type(handler) is Object.
|
// 3. Assert: Type(handler) is Object.
|
||||||
// 4. Let target be O.[[ProxyTarget]].
|
// 4. Let target be O.[[ProxyTarget]].
|
||||||
|
@ -811,13 +811,13 @@ ThrowCompletionOr<Object*> ProxyObject::internal_construct(MarkedVector<Value> a
|
||||||
// TODO: We should be able to turn this into a VERIFY(), this must be checked at the call site.
|
// TODO: We should be able to turn this into a VERIFY(), this must be checked at the call site.
|
||||||
// According to the spec, the Construct() AO is only ever called with a constructor argument.
|
// According to the spec, the Construct() AO is only ever called with a constructor argument.
|
||||||
if (!is_function())
|
if (!is_function())
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::NotAConstructor, Value(this).to_string_without_side_effects());
|
return vm.throw_completion<TypeError>(ErrorType::NotAConstructor, Value(this).to_string_without_side_effects());
|
||||||
|
|
||||||
// 1. Let handler be O.[[ProxyHandler]].
|
// 1. Let handler be O.[[ProxyHandler]].
|
||||||
|
|
||||||
// 2. If handler is null, throw a TypeError exception.
|
// 2. If handler is null, throw a TypeError exception.
|
||||||
if (m_is_revoked)
|
if (m_is_revoked)
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::ProxyRevoked);
|
return vm.throw_completion<TypeError>(ErrorType::ProxyRevoked);
|
||||||
|
|
||||||
// 3. Assert: Type(handler) is Object.
|
// 3. Assert: Type(handler) is Object.
|
||||||
// 4. Let target be O.[[ProxyTarget]].
|
// 4. Let target be O.[[ProxyTarget]].
|
||||||
|
@ -840,7 +840,7 @@ ThrowCompletionOr<Object*> ProxyObject::internal_construct(MarkedVector<Value> a
|
||||||
|
|
||||||
// 10. If Type(newObj) is not Object, throw a TypeError exception.
|
// 10. If Type(newObj) is not Object, throw a TypeError exception.
|
||||||
if (!new_object.is_object())
|
if (!new_object.is_object())
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::ProxyConstructBadReturnType);
|
return vm.throw_completion<TypeError>(ErrorType::ProxyConstructBadReturnType);
|
||||||
|
|
||||||
// 11. Return newObj.
|
// 11. Return newObj.
|
||||||
return &new_object.as_object();
|
return &new_object.as_object();
|
||||||
|
|
|
@ -22,7 +22,7 @@ ThrowCompletionOr<void> Reference::put_value(GlobalObject& global_object, Value
|
||||||
|
|
||||||
// 3. If V is not a Reference Record, throw a ReferenceError exception.
|
// 3. If V is not a Reference Record, throw a ReferenceError exception.
|
||||||
if (!is_valid_reference())
|
if (!is_valid_reference())
|
||||||
return vm.throw_completion<ReferenceError>(global_object, ErrorType::InvalidLeftHandAssignment);
|
return vm.throw_completion<ReferenceError>(ErrorType::InvalidLeftHandAssignment);
|
||||||
|
|
||||||
// 4. If IsUnresolvableReference(V) is true, then
|
// 4. If IsUnresolvableReference(V) is true, then
|
||||||
if (is_unresolvable()) {
|
if (is_unresolvable()) {
|
||||||
|
@ -54,7 +54,7 @@ ThrowCompletionOr<void> Reference::put_value(GlobalObject& global_object, Value
|
||||||
|
|
||||||
// d. If succeeded is false and V.[[Strict]] is true, throw a TypeError exception.
|
// d. If succeeded is false and V.[[Strict]] is true, throw a TypeError exception.
|
||||||
if (!succeeded && m_strict)
|
if (!succeeded && m_strict)
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::ReferenceNullishSetProperty, m_name, m_base_value.to_string_without_side_effects());
|
return vm.throw_completion<TypeError>(ErrorType::ReferenceNullishSetProperty, m_name, m_base_value.to_string_without_side_effects());
|
||||||
|
|
||||||
// e. Return unused.
|
// e. Return unused.
|
||||||
return {};
|
return {};
|
||||||
|
@ -78,9 +78,9 @@ Completion Reference::throw_reference_error(GlobalObject& global_object) const
|
||||||
{
|
{
|
||||||
auto& vm = global_object.vm();
|
auto& vm = global_object.vm();
|
||||||
if (!m_name.is_valid())
|
if (!m_name.is_valid())
|
||||||
return vm.throw_completion<ReferenceError>(global_object, ErrorType::ReferenceUnresolvable);
|
return vm.throw_completion<ReferenceError>(ErrorType::ReferenceUnresolvable);
|
||||||
else
|
else
|
||||||
return vm.throw_completion<ReferenceError>(global_object, ErrorType::UnknownIdentifier, m_name.to_string_or_symbol().to_display_string());
|
return vm.throw_completion<ReferenceError>(ErrorType::UnknownIdentifier, m_name.to_string_or_symbol().to_display_string());
|
||||||
}
|
}
|
||||||
|
|
||||||
// 6.2.4.5 GetValue ( V ), https://tc39.es/ecma262/#sec-getvalue
|
// 6.2.4.5 GetValue ( V ), https://tc39.es/ecma262/#sec-getvalue
|
||||||
|
@ -170,7 +170,7 @@ ThrowCompletionOr<bool> Reference::delete_(GlobalObject& global_object)
|
||||||
|
|
||||||
// b. If IsSuperReference(ref) is true, throw a ReferenceError exception.
|
// b. If IsSuperReference(ref) is true, throw a ReferenceError exception.
|
||||||
if (is_super_reference())
|
if (is_super_reference())
|
||||||
return vm.throw_completion<ReferenceError>(global_object, ErrorType::UnsupportedDeleteSuperProperty);
|
return vm.throw_completion<ReferenceError>(ErrorType::UnsupportedDeleteSuperProperty);
|
||||||
|
|
||||||
// c. Let baseObj be ! ToObject(ref.[[Base]]).
|
// c. Let baseObj be ! ToObject(ref.[[Base]]).
|
||||||
auto* base_obj = MUST(m_base_value.to_object(global_object));
|
auto* base_obj = MUST(m_base_value.to_object(global_object));
|
||||||
|
@ -180,7 +180,7 @@ ThrowCompletionOr<bool> Reference::delete_(GlobalObject& global_object)
|
||||||
|
|
||||||
// e. If deleteStatus is false and ref.[[Strict]] is true, throw a TypeError exception.
|
// e. If deleteStatus is false and ref.[[Strict]] is true, throw a TypeError exception.
|
||||||
if (!delete_status && m_strict)
|
if (!delete_status && m_strict)
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::ReferenceNullishDeleteProperty, m_name, m_base_value.to_string_without_side_effects());
|
return vm.throw_completion<TypeError>(ErrorType::ReferenceNullishDeleteProperty, m_name, m_base_value.to_string_without_side_effects());
|
||||||
|
|
||||||
// f. Return deleteStatus.
|
// f. Return deleteStatus.
|
||||||
return delete_status;
|
return delete_status;
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2020-2021, Linus Groh <linusg@serenityos.org>
|
* Copyright (c) 2020-2022, Linus Groh <linusg@serenityos.org>
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: BSD-2-Clause
|
* SPDX-License-Identifier: BSD-2-Clause
|
||||||
*/
|
*/
|
||||||
|
@ -52,7 +52,7 @@ JS_DEFINE_NATIVE_FUNCTION(ReflectObject::apply)
|
||||||
|
|
||||||
// 1. If IsCallable(target) is false, throw a TypeError exception.
|
// 1. If IsCallable(target) is false, throw a TypeError exception.
|
||||||
if (!target.is_function())
|
if (!target.is_function())
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::NotAFunction, target.to_string_without_side_effects());
|
return vm.throw_completion<TypeError>(ErrorType::NotAFunction, target.to_string_without_side_effects());
|
||||||
|
|
||||||
// 2. Let args be ? CreateListFromArrayLike(argumentsList).
|
// 2. Let args be ? CreateListFromArrayLike(argumentsList).
|
||||||
auto args = TRY(create_list_from_array_like(global_object, arguments_list));
|
auto args = TRY(create_list_from_array_like(global_object, arguments_list));
|
||||||
|
@ -71,14 +71,14 @@ JS_DEFINE_NATIVE_FUNCTION(ReflectObject::construct)
|
||||||
|
|
||||||
// 1. If IsConstructor(target) is false, throw a TypeError exception.
|
// 1. If IsConstructor(target) is false, throw a TypeError exception.
|
||||||
if (!target.is_constructor())
|
if (!target.is_constructor())
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::NotAConstructor, target.to_string_without_side_effects());
|
return vm.throw_completion<TypeError>(ErrorType::NotAConstructor, target.to_string_without_side_effects());
|
||||||
|
|
||||||
// 2. If newTarget is not present, set newTarget to target.
|
// 2. If newTarget is not present, set newTarget to target.
|
||||||
if (vm.argument_count() < 3)
|
if (vm.argument_count() < 3)
|
||||||
new_target = target;
|
new_target = target;
|
||||||
// 3. Else if IsConstructor(newTarget) is false, throw a TypeError exception.
|
// 3. Else if IsConstructor(newTarget) is false, throw a TypeError exception.
|
||||||
else if (!new_target.is_constructor())
|
else if (!new_target.is_constructor())
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::NotAConstructor, new_target.to_string_without_side_effects());
|
return vm.throw_completion<TypeError>(ErrorType::NotAConstructor, new_target.to_string_without_side_effects());
|
||||||
|
|
||||||
// 4. Let args be ? CreateListFromArrayLike(argumentsList).
|
// 4. Let args be ? CreateListFromArrayLike(argumentsList).
|
||||||
auto args = TRY(create_list_from_array_like(global_object, arguments_list));
|
auto args = TRY(create_list_from_array_like(global_object, arguments_list));
|
||||||
|
@ -96,7 +96,7 @@ JS_DEFINE_NATIVE_FUNCTION(ReflectObject::define_property)
|
||||||
|
|
||||||
// 1. If Type(target) is not Object, throw a TypeError exception.
|
// 1. If Type(target) is not Object, throw a TypeError exception.
|
||||||
if (!target.is_object())
|
if (!target.is_object())
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::NotAnObject, target.to_string_without_side_effects());
|
return vm.throw_completion<TypeError>(ErrorType::NotAnObject, target.to_string_without_side_effects());
|
||||||
|
|
||||||
// 2. Let key be ? ToPropertyKey(propertyKey).
|
// 2. Let key be ? ToPropertyKey(propertyKey).
|
||||||
auto key = TRY(property_key.to_property_key(global_object));
|
auto key = TRY(property_key.to_property_key(global_object));
|
||||||
|
@ -116,7 +116,7 @@ JS_DEFINE_NATIVE_FUNCTION(ReflectObject::delete_property)
|
||||||
|
|
||||||
// 1. If Type(target) is not Object, throw a TypeError exception.
|
// 1. If Type(target) is not Object, throw a TypeError exception.
|
||||||
if (!target.is_object())
|
if (!target.is_object())
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::NotAnObject, target.to_string_without_side_effects());
|
return vm.throw_completion<TypeError>(ErrorType::NotAnObject, target.to_string_without_side_effects());
|
||||||
|
|
||||||
// 2. Let key be ? ToPropertyKey(propertyKey).
|
// 2. Let key be ? ToPropertyKey(propertyKey).
|
||||||
auto key = TRY(property_key.to_property_key(global_object));
|
auto key = TRY(property_key.to_property_key(global_object));
|
||||||
|
@ -134,7 +134,7 @@ JS_DEFINE_NATIVE_FUNCTION(ReflectObject::get)
|
||||||
|
|
||||||
// 1. If Type(target) is not Object, throw a TypeError exception.
|
// 1. If Type(target) is not Object, throw a TypeError exception.
|
||||||
if (!target.is_object())
|
if (!target.is_object())
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::NotAnObject, target.to_string_without_side_effects());
|
return vm.throw_completion<TypeError>(ErrorType::NotAnObject, target.to_string_without_side_effects());
|
||||||
|
|
||||||
// 2. Let key be ? ToPropertyKey(propertyKey).
|
// 2. Let key be ? ToPropertyKey(propertyKey).
|
||||||
auto key = TRY(property_key.to_property_key(global_object));
|
auto key = TRY(property_key.to_property_key(global_object));
|
||||||
|
@ -157,7 +157,7 @@ JS_DEFINE_NATIVE_FUNCTION(ReflectObject::get_own_property_descriptor)
|
||||||
|
|
||||||
// 1. If Type(target) is not Object, throw a TypeError exception.
|
// 1. If Type(target) is not Object, throw a TypeError exception.
|
||||||
if (!target.is_object())
|
if (!target.is_object())
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::NotAnObject, target.to_string_without_side_effects());
|
return vm.throw_completion<TypeError>(ErrorType::NotAnObject, target.to_string_without_side_effects());
|
||||||
|
|
||||||
// 2. Let key be ? ToPropertyKey(propertyKey).
|
// 2. Let key be ? ToPropertyKey(propertyKey).
|
||||||
auto key = TRY(property_key.to_property_key(global_object));
|
auto key = TRY(property_key.to_property_key(global_object));
|
||||||
|
@ -176,7 +176,7 @@ JS_DEFINE_NATIVE_FUNCTION(ReflectObject::get_prototype_of)
|
||||||
|
|
||||||
// 1. If Type(target) is not Object, throw a TypeError exception.
|
// 1. If Type(target) is not Object, throw a TypeError exception.
|
||||||
if (!target.is_object())
|
if (!target.is_object())
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::NotAnObject, target.to_string_without_side_effects());
|
return vm.throw_completion<TypeError>(ErrorType::NotAnObject, target.to_string_without_side_effects());
|
||||||
|
|
||||||
// 2. Return ? target.[[GetPrototypeOf]]().
|
// 2. Return ? target.[[GetPrototypeOf]]().
|
||||||
return TRY(target.as_object().internal_get_prototype_of());
|
return TRY(target.as_object().internal_get_prototype_of());
|
||||||
|
@ -190,7 +190,7 @@ JS_DEFINE_NATIVE_FUNCTION(ReflectObject::has)
|
||||||
|
|
||||||
// 1. If Type(target) is not Object, throw a TypeError exception.
|
// 1. If Type(target) is not Object, throw a TypeError exception.
|
||||||
if (!target.is_object())
|
if (!target.is_object())
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::NotAnObject, target.to_string_without_side_effects());
|
return vm.throw_completion<TypeError>(ErrorType::NotAnObject, target.to_string_without_side_effects());
|
||||||
|
|
||||||
// 2. Let key be ? ToPropertyKey(propertyKey).
|
// 2. Let key be ? ToPropertyKey(propertyKey).
|
||||||
auto key = TRY(property_key.to_property_key(global_object));
|
auto key = TRY(property_key.to_property_key(global_object));
|
||||||
|
@ -206,7 +206,7 @@ JS_DEFINE_NATIVE_FUNCTION(ReflectObject::is_extensible)
|
||||||
|
|
||||||
// 1. If Type(target) is not Object, throw a TypeError exception.
|
// 1. If Type(target) is not Object, throw a TypeError exception.
|
||||||
if (!target.is_object())
|
if (!target.is_object())
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::NotAnObject, target.to_string_without_side_effects());
|
return vm.throw_completion<TypeError>(ErrorType::NotAnObject, target.to_string_without_side_effects());
|
||||||
|
|
||||||
// 2. Return ? target.[[IsExtensible]]().
|
// 2. Return ? target.[[IsExtensible]]().
|
||||||
return Value(TRY(target.as_object().internal_is_extensible()));
|
return Value(TRY(target.as_object().internal_is_extensible()));
|
||||||
|
@ -221,7 +221,7 @@ JS_DEFINE_NATIVE_FUNCTION(ReflectObject::own_keys)
|
||||||
|
|
||||||
// 1. If Type(target) is not Object, throw a TypeError exception.
|
// 1. If Type(target) is not Object, throw a TypeError exception.
|
||||||
if (!target.is_object())
|
if (!target.is_object())
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::NotAnObject, target.to_string_without_side_effects());
|
return vm.throw_completion<TypeError>(ErrorType::NotAnObject, target.to_string_without_side_effects());
|
||||||
|
|
||||||
// 2. Let keys be ? target.[[OwnPropertyKeys]]().
|
// 2. Let keys be ? target.[[OwnPropertyKeys]]().
|
||||||
auto keys = TRY(target.as_object().internal_own_property_keys());
|
auto keys = TRY(target.as_object().internal_own_property_keys());
|
||||||
|
@ -237,7 +237,7 @@ JS_DEFINE_NATIVE_FUNCTION(ReflectObject::prevent_extensions)
|
||||||
|
|
||||||
// 1. If Type(target) is not Object, throw a TypeError exception.
|
// 1. If Type(target) is not Object, throw a TypeError exception.
|
||||||
if (!target.is_object())
|
if (!target.is_object())
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::NotAnObject, target.to_string_without_side_effects());
|
return vm.throw_completion<TypeError>(ErrorType::NotAnObject, target.to_string_without_side_effects());
|
||||||
|
|
||||||
// 2. Return ? target.[[PreventExtensions]]().
|
// 2. Return ? target.[[PreventExtensions]]().
|
||||||
return Value(TRY(target.as_object().internal_prevent_extensions()));
|
return Value(TRY(target.as_object().internal_prevent_extensions()));
|
||||||
|
@ -253,7 +253,7 @@ JS_DEFINE_NATIVE_FUNCTION(ReflectObject::set)
|
||||||
|
|
||||||
// 1. If Type(target) is not Object, throw a TypeError exception.
|
// 1. If Type(target) is not Object, throw a TypeError exception.
|
||||||
if (!target.is_object())
|
if (!target.is_object())
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::NotAnObject, target.to_string_without_side_effects());
|
return vm.throw_completion<TypeError>(ErrorType::NotAnObject, target.to_string_without_side_effects());
|
||||||
|
|
||||||
// 2. Let key be ? ToPropertyKey(propertyKey).
|
// 2. Let key be ? ToPropertyKey(propertyKey).
|
||||||
auto key = TRY(property_key.to_property_key(global_object));
|
auto key = TRY(property_key.to_property_key(global_object));
|
||||||
|
@ -276,11 +276,11 @@ JS_DEFINE_NATIVE_FUNCTION(ReflectObject::set_prototype_of)
|
||||||
|
|
||||||
// 1. If Type(target) is not Object, throw a TypeError exception.
|
// 1. If Type(target) is not Object, throw a TypeError exception.
|
||||||
if (!target.is_object())
|
if (!target.is_object())
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::NotAnObject, target.to_string_without_side_effects());
|
return vm.throw_completion<TypeError>(ErrorType::NotAnObject, target.to_string_without_side_effects());
|
||||||
|
|
||||||
// 2. If Type(proto) is not Object and proto is not null, throw a TypeError exception.
|
// 2. If Type(proto) is not Object and proto is not null, throw a TypeError exception.
|
||||||
if (!proto.is_object() && !proto.is_null())
|
if (!proto.is_object() && !proto.is_null())
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::ObjectPrototypeWrongType);
|
return vm.throw_completion<TypeError>(ErrorType::ObjectPrototypeWrongType);
|
||||||
|
|
||||||
// 3. Return ? target.[[SetPrototypeOf]](proto).
|
// 3. Return ? target.[[SetPrototypeOf]](proto).
|
||||||
return Value(TRY(target.as_object().internal_set_prototype_of(proto.is_null() ? nullptr : &proto.as_object())));
|
return Value(TRY(target.as_object().internal_set_prototype_of(proto.is_null() ? nullptr : &proto.as_object())));
|
||||||
|
|
|
@ -113,11 +113,11 @@ ErrorOr<String, ParseRegexPatternError> parse_regex_pattern(StringView pattern,
|
||||||
return builder.build();
|
return builder.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
ThrowCompletionOr<String> parse_regex_pattern(StringView pattern, VM& vm, GlobalObject& global_object, bool unicode, bool unicode_sets)
|
ThrowCompletionOr<String> parse_regex_pattern(VM& vm, StringView pattern, bool unicode, bool unicode_sets)
|
||||||
{
|
{
|
||||||
auto result = parse_regex_pattern(pattern, unicode, unicode_sets);
|
auto result = parse_regex_pattern(pattern, unicode, unicode_sets);
|
||||||
if (result.is_error())
|
if (result.is_error())
|
||||||
return vm.throw_completion<JS::SyntaxError>(global_object, result.release_error().error);
|
return vm.throw_completion<JS::SyntaxError>(result.release_error().error);
|
||||||
|
|
||||||
return result.release_value();
|
return result.release_value();
|
||||||
}
|
}
|
||||||
|
@ -175,16 +175,16 @@ ThrowCompletionOr<RegExpObject*> RegExpObject::regexp_initialize(GlobalObject& g
|
||||||
original_pattern = TRY(pattern.to_string(global_object));
|
original_pattern = TRY(pattern.to_string(global_object));
|
||||||
bool unicode = f.find('u').has_value();
|
bool unicode = f.find('u').has_value();
|
||||||
bool unicode_sets = f.find('v').has_value();
|
bool unicode_sets = f.find('v').has_value();
|
||||||
parsed_pattern = TRY(parse_regex_pattern(original_pattern, vm, global_object, unicode, unicode_sets));
|
parsed_pattern = TRY(parse_regex_pattern(vm, original_pattern, unicode, unicode_sets));
|
||||||
}
|
}
|
||||||
|
|
||||||
auto parsed_flags_or_error = regex_flags_from_string(f);
|
auto parsed_flags_or_error = regex_flags_from_string(f);
|
||||||
if (parsed_flags_or_error.is_error())
|
if (parsed_flags_or_error.is_error())
|
||||||
return vm.throw_completion<SyntaxError>(global_object, parsed_flags_or_error.release_error());
|
return vm.throw_completion<SyntaxError>(parsed_flags_or_error.release_error());
|
||||||
|
|
||||||
Regex<ECMA262> regex(move(parsed_pattern), parsed_flags_or_error.release_value());
|
Regex<ECMA262> regex(move(parsed_pattern), parsed_flags_or_error.release_value());
|
||||||
if (regex.parser_result.error != regex::Error::NoError)
|
if (regex.parser_result.error != regex::Error::NoError)
|
||||||
return vm.throw_completion<SyntaxError>(global_object, ErrorType::RegExpCompileError, regex.error_string());
|
return vm.throw_completion<SyntaxError>(ErrorType::RegExpCompileError, regex.error_string());
|
||||||
|
|
||||||
m_pattern = move(original_pattern);
|
m_pattern = move(original_pattern);
|
||||||
m_flags = move(f);
|
m_flags = move(f);
|
||||||
|
|
|
@ -21,7 +21,7 @@ struct ParseRegexPatternError {
|
||||||
String error;
|
String error;
|
||||||
};
|
};
|
||||||
ErrorOr<String, ParseRegexPatternError> parse_regex_pattern(StringView pattern, bool unicode, bool unicode_sets);
|
ErrorOr<String, ParseRegexPatternError> parse_regex_pattern(StringView pattern, bool unicode, bool unicode_sets);
|
||||||
ThrowCompletionOr<String> parse_regex_pattern(StringView pattern, VM& vm, GlobalObject& global_object, bool unicode, bool unicode_sets);
|
ThrowCompletionOr<String> parse_regex_pattern(VM& vm, StringView pattern, bool unicode, bool unicode_sets);
|
||||||
|
|
||||||
class RegExpObject : public Object {
|
class RegExpObject : public Object {
|
||||||
JS_OBJECT(RegExpObject, Object);
|
JS_OBJECT(RegExpObject, Object);
|
||||||
|
|
|
@ -372,7 +372,7 @@ ThrowCompletionOr<Value> regexp_exec(GlobalObject& global_object, Object& regexp
|
||||||
|
|
||||||
// b. If Type(result) is neither Object nor Null, throw a TypeError exception.
|
// b. If Type(result) is neither Object nor Null, throw a TypeError exception.
|
||||||
if (!result.is_object() && !result.is_null())
|
if (!result.is_object() && !result.is_null())
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::NotAnObjectOrNull, result.to_string_without_side_effects());
|
return vm.throw_completion<TypeError>(ErrorType::NotAnObjectOrNull, result.to_string_without_side_effects());
|
||||||
|
|
||||||
// c. Return result.
|
// c. Return result.
|
||||||
return result;
|
return result;
|
||||||
|
@ -380,7 +380,7 @@ ThrowCompletionOr<Value> regexp_exec(GlobalObject& global_object, Object& regexp
|
||||||
|
|
||||||
// 3. Perform ? RequireInternalSlot(R, [[RegExpMatcher]]).
|
// 3. Perform ? RequireInternalSlot(R, [[RegExpMatcher]]).
|
||||||
if (!is<RegExpObject>(regexp_object))
|
if (!is<RegExpObject>(regexp_object))
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::NotAnObjectOfType, "RegExp");
|
return vm.throw_completion<TypeError>(ErrorType::NotAnObjectOfType, "RegExp");
|
||||||
|
|
||||||
// 4. Return ? RegExpBuiltinExec(R, S).
|
// 4. Return ? RegExpBuiltinExec(R, S).
|
||||||
return regexp_builtin_exec(global_object, static_cast<RegExpObject&>(regexp_object), move(string));
|
return regexp_builtin_exec(global_object, static_cast<RegExpObject&>(regexp_object), move(string));
|
||||||
|
@ -415,24 +415,24 @@ size_t advance_string_index(Utf16View const& string, size_t index, bool unicode)
|
||||||
// 22.2.5.15 get RegExp.prototype.sticky, https://tc39.es/ecma262/#sec-get-regexp.prototype.sticky
|
// 22.2.5.15 get RegExp.prototype.sticky, https://tc39.es/ecma262/#sec-get-regexp.prototype.sticky
|
||||||
// 22.2.5.18 get RegExp.prototype.unicode, https://tc39.es/ecma262/#sec-get-regexp.prototype.unicode
|
// 22.2.5.18 get RegExp.prototype.unicode, https://tc39.es/ecma262/#sec-get-regexp.prototype.unicode
|
||||||
// 22.2.5.18 get RegExp.prototype.unicodeSets, https://arai-a.github.io/ecma262-compare/?pr=2418&id=sec-get-regexp.prototype.unicodeSets
|
// 22.2.5.18 get RegExp.prototype.unicodeSets, https://arai-a.github.io/ecma262-compare/?pr=2418&id=sec-get-regexp.prototype.unicodeSets
|
||||||
#define __JS_ENUMERATE(flagName, flag_name, flag_char) \
|
#define __JS_ENUMERATE(flagName, flag_name, flag_char) \
|
||||||
JS_DEFINE_NATIVE_FUNCTION(RegExpPrototype::flag_name) \
|
JS_DEFINE_NATIVE_FUNCTION(RegExpPrototype::flag_name) \
|
||||||
{ \
|
{ \
|
||||||
/* 1. If Type(R) is not Object, throw a TypeError exception. */ \
|
/* 1. If Type(R) is not Object, throw a TypeError exception. */ \
|
||||||
auto* regexp_object = TRY(this_object(global_object)); \
|
auto* regexp_object = TRY(this_object(global_object)); \
|
||||||
/* 2. If R does not have an [[OriginalFlags]] internal slot, then */ \
|
/* 2. If R does not have an [[OriginalFlags]] internal slot, then */ \
|
||||||
if (!is<RegExpObject>(regexp_object)) { \
|
if (!is<RegExpObject>(regexp_object)) { \
|
||||||
/* a. If SameValue(R, %RegExp.prototype%) is true, return undefined. */ \
|
/* a. If SameValue(R, %RegExp.prototype%) is true, return undefined. */ \
|
||||||
if (same_value(regexp_object, global_object.regexp_prototype())) \
|
if (same_value(regexp_object, global_object.regexp_prototype())) \
|
||||||
return js_undefined(); \
|
return js_undefined(); \
|
||||||
/* b. Otherwise, throw a TypeError exception. */ \
|
/* b. Otherwise, throw a TypeError exception. */ \
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::NotAnObjectOfType, "RegExp"); \
|
return vm.throw_completion<TypeError>(ErrorType::NotAnObjectOfType, "RegExp"); \
|
||||||
} \
|
} \
|
||||||
/* 3. Let flags be R.[[OriginalFlags]]. */ \
|
/* 3. Let flags be R.[[OriginalFlags]]. */ \
|
||||||
auto const& flags = static_cast<RegExpObject*>(regexp_object)->flags(); \
|
auto const& flags = static_cast<RegExpObject*>(regexp_object)->flags(); \
|
||||||
/* 4. If flags contains codeUnit, return true. */ \
|
/* 4. If flags contains codeUnit, return true. */ \
|
||||||
/* 5. Return false. */ \
|
/* 5. Return false. */ \
|
||||||
return Value(flags.contains(#flag_char##sv)); \
|
return Value(flags.contains(#flag_char##sv)); \
|
||||||
}
|
}
|
||||||
JS_ENUMERATE_REGEXP_FLAGS
|
JS_ENUMERATE_REGEXP_FLAGS
|
||||||
#undef __JS_ENUMERATE
|
#undef __JS_ENUMERATE
|
||||||
|
@ -856,7 +856,7 @@ JS_DEFINE_NATIVE_FUNCTION(RegExpPrototype::source)
|
||||||
return js_string(vm, "(?:)");
|
return js_string(vm, "(?:)");
|
||||||
|
|
||||||
// b. Otherwise, throw a TypeError exception.
|
// b. Otherwise, throw a TypeError exception.
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::NotAnObjectOfType, "RegExp");
|
return vm.throw_completion<TypeError>(ErrorType::NotAnObjectOfType, "RegExp");
|
||||||
}
|
}
|
||||||
|
|
||||||
// 4. Assert: R has an [[OriginalFlags]] internal slot.
|
// 4. Assert: R has an [[OriginalFlags]] internal slot.
|
||||||
|
@ -1073,7 +1073,7 @@ JS_DEFINE_NATIVE_FUNCTION(RegExpPrototype::compile)
|
||||||
if (pattern.is_object() && is<RegExpObject>(pattern.as_object())) {
|
if (pattern.is_object() && is<RegExpObject>(pattern.as_object())) {
|
||||||
// a. If flags is not undefined, throw a TypeError exception.
|
// a. If flags is not undefined, throw a TypeError exception.
|
||||||
if (!flags.is_undefined())
|
if (!flags.is_undefined())
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::NotUndefined, flags.to_string_without_side_effects());
|
return vm.throw_completion<TypeError>(ErrorType::NotUndefined, flags.to_string_without_side_effects());
|
||||||
|
|
||||||
auto& regexp_pattern = static_cast<RegExpObject&>(pattern.as_object());
|
auto& regexp_pattern = static_cast<RegExpObject&>(pattern.as_object());
|
||||||
|
|
||||||
|
|
|
@ -35,7 +35,7 @@ void SetConstructor::initialize(Realm& realm)
|
||||||
ThrowCompletionOr<Value> SetConstructor::call()
|
ThrowCompletionOr<Value> SetConstructor::call()
|
||||||
{
|
{
|
||||||
auto& vm = this->vm();
|
auto& vm = this->vm();
|
||||||
return vm.throw_completion<TypeError>(global_object(), ErrorType::ConstructorWithoutNew, vm.names.Set);
|
return vm.throw_completion<TypeError>(ErrorType::ConstructorWithoutNew, vm.names.Set);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 24.2.1.1 Set ( [ iterable ] ), https://tc39.es/ecma262/#sec-set-iterable
|
// 24.2.1.1 Set ( [ iterable ] ), https://tc39.es/ecma262/#sec-set-iterable
|
||||||
|
@ -51,7 +51,7 @@ ThrowCompletionOr<Object*> SetConstructor::construct(FunctionObject& new_target)
|
||||||
|
|
||||||
auto adder = TRY(set->get(vm.names.add));
|
auto adder = TRY(set->get(vm.names.add));
|
||||||
if (!adder.is_function())
|
if (!adder.is_function())
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::NotAFunction, "'add' property of Set");
|
return vm.throw_completion<TypeError>(ErrorType::NotAFunction, "'add' property of Set");
|
||||||
|
|
||||||
(void)TRY(get_iterator_values(global_object, vm.argument(0), [&](Value iterator_value) -> Optional<Completion> {
|
(void)TRY(get_iterator_values(global_object, vm.argument(0), [&](Value iterator_value) -> Optional<Completion> {
|
||||||
TRY(JS::call(global_object, adder.as_function(), set, iterator_value));
|
TRY(JS::call(global_object, adder.as_function(), set, iterator_value));
|
||||||
|
|
|
@ -82,7 +82,7 @@ JS_DEFINE_NATIVE_FUNCTION(SetPrototype::for_each)
|
||||||
{
|
{
|
||||||
auto* set = TRY(typed_this_object(global_object));
|
auto* set = TRY(typed_this_object(global_object));
|
||||||
if (!vm.argument(0).is_function())
|
if (!vm.argument(0).is_function())
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::NotAFunction, vm.argument(0).to_string_without_side_effects());
|
return vm.throw_completion<TypeError>(ErrorType::NotAFunction, vm.argument(0).to_string_without_side_effects());
|
||||||
auto this_value = vm.this_value(global_object);
|
auto this_value = vm.this_value(global_object);
|
||||||
for (auto& entry : *set)
|
for (auto& entry : *set)
|
||||||
TRY(call(global_object, vm.argument(0).as_function(), vm.argument(1), entry.key, entry.key, this_value));
|
TRY(call(global_object, vm.argument(0).as_function(), vm.argument(1), entry.key, entry.key, this_value));
|
||||||
|
|
|
@ -111,7 +111,7 @@ ThrowCompletionOr<Value> perform_shadow_realm_eval(GlobalObject& global_object,
|
||||||
// b. If script is a List of errors, throw a SyntaxError exception.
|
// b. If script is a List of errors, throw a SyntaxError exception.
|
||||||
if (parser.has_errors()) {
|
if (parser.has_errors()) {
|
||||||
auto& error = parser.errors()[0];
|
auto& error = parser.errors()[0];
|
||||||
return vm.throw_completion<SyntaxError>(global_object, error.to_string());
|
return vm.throw_completion<SyntaxError>(error.to_string());
|
||||||
}
|
}
|
||||||
|
|
||||||
// c. If script Contains ScriptBody is false, return undefined.
|
// c. If script Contains ScriptBody is false, return undefined.
|
||||||
|
@ -197,7 +197,7 @@ ThrowCompletionOr<Value> perform_shadow_realm_eval(GlobalObject& global_object,
|
||||||
|
|
||||||
// 21. If result.[[Type]] is not normal, throw a TypeError exception.
|
// 21. If result.[[Type]] is not normal, throw a TypeError exception.
|
||||||
if (result.type() != Completion::Type::Normal)
|
if (result.type() != Completion::Type::Normal)
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::ShadowRealmEvaluateAbruptCompletion);
|
return vm.throw_completion<TypeError>(ErrorType::ShadowRealmEvaluateAbruptCompletion);
|
||||||
|
|
||||||
// 22. Return ? GetWrappedValue(callerRealm, result.[[Value]]).
|
// 22. Return ? GetWrappedValue(callerRealm, result.[[Value]]).
|
||||||
return get_wrapped_value(global_object, caller_realm, *result.value());
|
return get_wrapped_value(global_object, caller_realm, *result.value());
|
||||||
|
@ -251,7 +251,7 @@ ThrowCompletionOr<Value> shadow_realm_import_value(GlobalObject& global_object,
|
||||||
|
|
||||||
// 6. If hasOwn is false, throw a TypeError exception.
|
// 6. If hasOwn is false, throw a TypeError exception.
|
||||||
if (!has_own)
|
if (!has_own)
|
||||||
return vm.template throw_completion<TypeError>(global_object, ErrorType::MissingRequiredProperty, string);
|
return vm.template throw_completion<TypeError>(ErrorType::MissingRequiredProperty, string);
|
||||||
|
|
||||||
// 7. Let value be ? Get(exports, string).
|
// 7. Let value be ? Get(exports, string).
|
||||||
auto value = TRY(exports.get(string));
|
auto value = TRY(exports.get(string));
|
||||||
|
@ -273,8 +273,8 @@ ThrowCompletionOr<Value> shadow_realm_import_value(GlobalObject& global_object,
|
||||||
|
|
||||||
// NOTE: Even though the spec tells us to use %ThrowTypeError%, it's not observable if we actually do.
|
// NOTE: Even though the spec tells us to use %ThrowTypeError%, it's not observable if we actually do.
|
||||||
// Throw a nicer TypeError forwarding the import error message instead (we know the argument is an Error object).
|
// Throw a nicer TypeError forwarding the import error message instead (we know the argument is an Error object).
|
||||||
auto* throw_type_error = NativeFunction::create(realm, {}, [](auto& vm, auto& global_object) -> ThrowCompletionOr<Value> {
|
auto* throw_type_error = NativeFunction::create(realm, {}, [](auto& vm, auto&) -> ThrowCompletionOr<Value> {
|
||||||
return vm.template throw_completion<TypeError>(global_object, vm.argument(0).as_object().get_without_side_effects(vm.names.message).as_string().string());
|
return vm.template throw_completion<TypeError>(vm.argument(0).as_object().get_without_side_effects(vm.names.message).as_string().string());
|
||||||
});
|
});
|
||||||
|
|
||||||
// 13. Return PerformPromiseThen(innerCapability.[[Promise]], onFulfilled, callerRealm.[[Intrinsics]].[[%ThrowTypeError%]], promiseCapability).
|
// 13. Return PerformPromiseThen(innerCapability.[[Promise]], onFulfilled, callerRealm.[[Intrinsics]].[[%ThrowTypeError%]], promiseCapability).
|
||||||
|
@ -291,7 +291,7 @@ ThrowCompletionOr<Value> get_wrapped_value(GlobalObject& global_object, Realm& c
|
||||||
if (value.is_object()) {
|
if (value.is_object()) {
|
||||||
// a. If IsCallable(value) is false, throw a TypeError exception.
|
// a. If IsCallable(value) is false, throw a TypeError exception.
|
||||||
if (!value.is_function())
|
if (!value.is_function())
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::ShadowRealmWrappedValueNonFunctionObject, value);
|
return vm.throw_completion<TypeError>(ErrorType::ShadowRealmWrappedValueNonFunctionObject, value);
|
||||||
|
|
||||||
// b. Return ? WrappedFunctionCreate(callerRealm, value).
|
// b. Return ? WrappedFunctionCreate(callerRealm, value).
|
||||||
return TRY(WrappedFunction::create(realm, caller_realm, value.as_function()));
|
return TRY(WrappedFunction::create(realm, caller_realm, value.as_function()));
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2021, Linus Groh <linusg@serenityos.org>
|
* Copyright (c) 2021-2022, Linus Groh <linusg@serenityos.org>
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: BSD-2-Clause
|
* SPDX-License-Identifier: BSD-2-Clause
|
||||||
*/
|
*/
|
||||||
|
@ -33,7 +33,7 @@ ThrowCompletionOr<Value> ShadowRealmConstructor::call()
|
||||||
auto& vm = this->vm();
|
auto& vm = this->vm();
|
||||||
|
|
||||||
// 1. If NewTarget is undefined, throw a TypeError exception.
|
// 1. If NewTarget is undefined, throw a TypeError exception.
|
||||||
return vm.throw_completion<TypeError>(global_object(), ErrorType::ConstructorWithoutNew, vm.names.ShadowRealm);
|
return vm.throw_completion<TypeError>(ErrorType::ConstructorWithoutNew, vm.names.ShadowRealm);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 3.2.1 ShadowRealm ( ), https://tc39.es/proposal-shadowrealm/#sec-shadowrealm
|
// 3.2.1 ShadowRealm ( ), https://tc39.es/proposal-shadowrealm/#sec-shadowrealm
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2021, Linus Groh <linusg@serenityos.org>
|
* Copyright (c) 2021-2022, Linus Groh <linusg@serenityos.org>
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: BSD-2-Clause
|
* SPDX-License-Identifier: BSD-2-Clause
|
||||||
*/
|
*/
|
||||||
|
@ -40,7 +40,7 @@ JS_DEFINE_NATIVE_FUNCTION(ShadowRealmPrototype::evaluate)
|
||||||
|
|
||||||
// 3. If Type(sourceText) is not String, throw a TypeError exception.
|
// 3. If Type(sourceText) is not String, throw a TypeError exception.
|
||||||
if (!source_text.is_string())
|
if (!source_text.is_string())
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::NotAString, source_text);
|
return vm.throw_completion<TypeError>(ErrorType::NotAString, source_text);
|
||||||
|
|
||||||
// 4. Let callerRealm be the current Realm Record.
|
// 4. Let callerRealm be the current Realm Record.
|
||||||
auto* caller_realm = vm.current_realm();
|
auto* caller_realm = vm.current_realm();
|
||||||
|
@ -67,7 +67,7 @@ JS_DEFINE_NATIVE_FUNCTION(ShadowRealmPrototype::import_value)
|
||||||
|
|
||||||
// 4. If Type(exportName) is not String, throw a TypeError exception.
|
// 4. If Type(exportName) is not String, throw a TypeError exception.
|
||||||
if (!export_name.is_string())
|
if (!export_name.is_string())
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::NotAString, export_name.to_string_without_side_effects());
|
return vm.throw_completion<TypeError>(ErrorType::NotAString, export_name.to_string_without_side_effects());
|
||||||
|
|
||||||
// 5. Let callerRealm be the current Realm Record.
|
// 5. Let callerRealm be the current Realm Record.
|
||||||
auto* caller_realm = vm.current_realm();
|
auto* caller_realm = vm.current_realm();
|
||||||
|
|
|
@ -118,10 +118,10 @@ JS_DEFINE_NATIVE_FUNCTION(StringConstructor::from_code_point)
|
||||||
for (size_t i = 0; i < vm.argument_count(); ++i) {
|
for (size_t i = 0; i < vm.argument_count(); ++i) {
|
||||||
auto next_code_point = TRY(vm.argument(i).to_number(global_object));
|
auto next_code_point = TRY(vm.argument(i).to_number(global_object));
|
||||||
if (!next_code_point.is_integral_number())
|
if (!next_code_point.is_integral_number())
|
||||||
return vm.throw_completion<RangeError>(global_object, ErrorType::InvalidCodePoint, next_code_point.to_string_without_side_effects());
|
return vm.throw_completion<RangeError>(ErrorType::InvalidCodePoint, next_code_point.to_string_without_side_effects());
|
||||||
auto code_point = TRY(next_code_point.to_i32(global_object));
|
auto code_point = TRY(next_code_point.to_i32(global_object));
|
||||||
if (code_point < 0 || code_point > 0x10FFFF)
|
if (code_point < 0 || code_point > 0x10FFFF)
|
||||||
return vm.throw_completion<RangeError>(global_object, ErrorType::InvalidCodePoint, next_code_point.to_string_without_side_effects());
|
return vm.throw_completion<RangeError>(ErrorType::InvalidCodePoint, next_code_point.to_string_without_side_effects());
|
||||||
|
|
||||||
AK::code_point_to_utf16(string, static_cast<u32>(code_point));
|
AK::code_point_to_utf16(string, static_cast<u32>(code_point));
|
||||||
}
|
}
|
||||||
|
|
|
@ -172,7 +172,7 @@ static ThrowCompletionOr<PrimitiveString*> this_string_value(GlobalObject& globa
|
||||||
if (value.is_object() && is<StringObject>(value.as_object()))
|
if (value.is_object() && is<StringObject>(value.as_object()))
|
||||||
return &static_cast<StringObject&>(value.as_object()).primitive_string();
|
return &static_cast<StringObject&>(value.as_object()).primitive_string();
|
||||||
auto& vm = global_object.vm();
|
auto& vm = global_object.vm();
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::NotAnObjectOfType, "String");
|
return vm.throw_completion<TypeError>(ErrorType::NotAnObjectOfType, "String");
|
||||||
}
|
}
|
||||||
|
|
||||||
// 22.1.3.2 String.prototype.charAt ( pos ), https://tc39.es/ecma262/#sec-string.prototype.charat
|
// 22.1.3.2 String.prototype.charAt ( pos ), https://tc39.es/ecma262/#sec-string.prototype.charat
|
||||||
|
@ -217,10 +217,10 @@ JS_DEFINE_NATIVE_FUNCTION(StringPrototype::repeat)
|
||||||
auto n = TRY(vm.argument(0).to_integer_or_infinity(global_object));
|
auto n = TRY(vm.argument(0).to_integer_or_infinity(global_object));
|
||||||
|
|
||||||
if (n < 0)
|
if (n < 0)
|
||||||
return vm.throw_completion<RangeError>(global_object, ErrorType::StringRepeatCountMustBe, "positive");
|
return vm.throw_completion<RangeError>(ErrorType::StringRepeatCountMustBe, "positive");
|
||||||
|
|
||||||
if (Value(n).is_positive_infinity())
|
if (Value(n).is_positive_infinity())
|
||||||
return vm.throw_completion<RangeError>(global_object, ErrorType::StringRepeatCountMustBe, "finite");
|
return vm.throw_completion<RangeError>(ErrorType::StringRepeatCountMustBe, "finite");
|
||||||
|
|
||||||
if (n == 0)
|
if (n == 0)
|
||||||
return js_string(vm, String::empty());
|
return js_string(vm, String::empty());
|
||||||
|
@ -244,7 +244,7 @@ JS_DEFINE_NATIVE_FUNCTION(StringPrototype::starts_with)
|
||||||
|
|
||||||
bool search_is_regexp = TRY(search_string_value.is_regexp(global_object));
|
bool search_is_regexp = TRY(search_string_value.is_regexp(global_object));
|
||||||
if (search_is_regexp)
|
if (search_is_regexp)
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::IsNotA, "searchString", "string, but a regular expression");
|
return vm.throw_completion<TypeError>(ErrorType::IsNotA, "searchString", "string, but a regular expression");
|
||||||
|
|
||||||
auto search_string = TRY(search_string_value.to_utf16_string(global_object));
|
auto search_string = TRY(search_string_value.to_utf16_string(global_object));
|
||||||
auto string_length = string.length_in_code_units();
|
auto string_length = string.length_in_code_units();
|
||||||
|
@ -276,7 +276,7 @@ JS_DEFINE_NATIVE_FUNCTION(StringPrototype::ends_with)
|
||||||
|
|
||||||
bool search_is_regexp = TRY(search_string_value.is_regexp(global_object));
|
bool search_is_regexp = TRY(search_string_value.is_regexp(global_object));
|
||||||
if (search_is_regexp)
|
if (search_is_regexp)
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::IsNotA, "searchString", "string, but a regular expression");
|
return vm.throw_completion<TypeError>(ErrorType::IsNotA, "searchString", "string, but a regular expression");
|
||||||
|
|
||||||
auto search_string = TRY(search_string_value.to_utf16_string(global_object));
|
auto search_string = TRY(search_string_value.to_utf16_string(global_object));
|
||||||
auto string_length = string.length_in_code_units();
|
auto string_length = string.length_in_code_units();
|
||||||
|
@ -602,7 +602,7 @@ JS_DEFINE_NATIVE_FUNCTION(StringPrototype::includes)
|
||||||
|
|
||||||
bool search_is_regexp = TRY(search_string_value.is_regexp(global_object));
|
bool search_is_regexp = TRY(search_string_value.is_regexp(global_object));
|
||||||
if (search_is_regexp)
|
if (search_is_regexp)
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::IsNotA, "searchString", "string, but a regular expression");
|
return vm.throw_completion<TypeError>(ErrorType::IsNotA, "searchString", "string, but a regular expression");
|
||||||
|
|
||||||
auto search_string = TRY(search_string_value.to_utf16_string(global_object));
|
auto search_string = TRY(search_string_value.to_utf16_string(global_object));
|
||||||
|
|
||||||
|
@ -808,7 +808,7 @@ JS_DEFINE_NATIVE_FUNCTION(StringPrototype::match_all)
|
||||||
auto flags_object = TRY(require_object_coercible(global_object, flags));
|
auto flags_object = TRY(require_object_coercible(global_object, flags));
|
||||||
auto flags_string = TRY(flags_object.to_string(global_object));
|
auto flags_string = TRY(flags_object.to_string(global_object));
|
||||||
if (!flags_string.contains('g'))
|
if (!flags_string.contains('g'))
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::StringNonGlobalRegExp);
|
return vm.throw_completion<TypeError>(ErrorType::StringNonGlobalRegExp);
|
||||||
}
|
}
|
||||||
if (auto* matcher = TRY(regexp.get_method(global_object, *vm.well_known_symbol_match_all())))
|
if (auto* matcher = TRY(regexp.get_method(global_object, *vm.well_known_symbol_match_all())))
|
||||||
return TRY(call(global_object, *matcher, regexp, this_object));
|
return TRY(call(global_object, *matcher, regexp, this_object));
|
||||||
|
@ -836,7 +836,7 @@ JS_DEFINE_NATIVE_FUNCTION(StringPrototype::normalize)
|
||||||
|
|
||||||
// 5. If f is not one of "NFC", "NFD", "NFKC", or "NFKD", throw a RangeError exception.
|
// 5. If f is not one of "NFC", "NFD", "NFKC", or "NFKD", throw a RangeError exception.
|
||||||
if (!form.is_one_of("NFC"sv, "NFD"sv, "NFKC"sv, "NFKD"sv))
|
if (!form.is_one_of("NFC"sv, "NFD"sv, "NFKC"sv, "NFKD"sv))
|
||||||
return vm.throw_completion<RangeError>(global_object, ErrorType::InvalidNormalizationForm, form);
|
return vm.throw_completion<RangeError>(ErrorType::InvalidNormalizationForm, form);
|
||||||
|
|
||||||
// FIXME: 6. Let ns be the String value that is the result of normalizing S into the normalization form named by f as specified in https://unicode.org/reports/tr15/.
|
// FIXME: 6. Let ns be the String value that is the result of normalizing S into the normalization form named by f as specified in https://unicode.org/reports/tr15/.
|
||||||
auto ns = string;
|
auto ns = string;
|
||||||
|
@ -902,7 +902,7 @@ JS_DEFINE_NATIVE_FUNCTION(StringPrototype::replace_all)
|
||||||
auto flags_object = TRY(require_object_coercible(global_object, flags));
|
auto flags_object = TRY(require_object_coercible(global_object, flags));
|
||||||
auto flags_string = TRY(flags_object.to_string(global_object));
|
auto flags_string = TRY(flags_object.to_string(global_object));
|
||||||
if (!flags_string.contains('g'))
|
if (!flags_string.contains('g'))
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::StringNonGlobalRegExp);
|
return vm.throw_completion<TypeError>(ErrorType::StringNonGlobalRegExp);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto* replacer = TRY(search_value.get_method(global_object, *vm.well_known_symbol_replace()));
|
auto* replacer = TRY(search_value.get_method(global_object, *vm.well_known_symbol_replace()));
|
||||||
|
|
|
@ -46,7 +46,7 @@ ThrowCompletionOr<Value> SymbolConstructor::call()
|
||||||
// 20.4.1.1 Symbol ( [ description ] ), https://tc39.es/ecma262/#sec-symbol-description
|
// 20.4.1.1 Symbol ( [ description ] ), https://tc39.es/ecma262/#sec-symbol-description
|
||||||
ThrowCompletionOr<Object*> SymbolConstructor::construct(FunctionObject&)
|
ThrowCompletionOr<Object*> SymbolConstructor::construct(FunctionObject&)
|
||||||
{
|
{
|
||||||
return vm().throw_completion<TypeError>(global_object(), ErrorType::NotAConstructor, "Symbol");
|
return vm().throw_completion<TypeError>(ErrorType::NotAConstructor, "Symbol");
|
||||||
}
|
}
|
||||||
|
|
||||||
// 20.4.2.2 Symbol.for ( key ), https://tc39.es/ecma262/#sec-symbol.for
|
// 20.4.2.2 Symbol.for ( key ), https://tc39.es/ecma262/#sec-symbol.for
|
||||||
|
@ -61,7 +61,7 @@ JS_DEFINE_NATIVE_FUNCTION(SymbolConstructor::key_for)
|
||||||
{
|
{
|
||||||
auto argument = vm.argument(0);
|
auto argument = vm.argument(0);
|
||||||
if (!argument.is_symbol())
|
if (!argument.is_symbol())
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::NotASymbol, argument.to_string_without_side_effects());
|
return vm.throw_completion<TypeError>(ErrorType::NotASymbol, argument.to_string_without_side_effects());
|
||||||
|
|
||||||
auto& symbol = argument.as_symbol();
|
auto& symbol = argument.as_symbol();
|
||||||
if (symbol.is_global())
|
if (symbol.is_global())
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2020, Matthew Olsson <mattco@serenityos.org>
|
* Copyright (c) 2020, Matthew Olsson <mattco@serenityos.org>
|
||||||
* Copyright (c) 2021, Linus Groh <linusg@serenityos.org>
|
* Copyright (c) 2021-2022, Linus Groh <linusg@serenityos.org>
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: BSD-2-Clause
|
* SPDX-License-Identifier: BSD-2-Clause
|
||||||
*/
|
*/
|
||||||
|
@ -45,7 +45,7 @@ static ThrowCompletionOr<Symbol*> this_symbol_value(GlobalObject& global_object,
|
||||||
if (value.is_object() && is<SymbolObject>(value.as_object()))
|
if (value.is_object() && is<SymbolObject>(value.as_object()))
|
||||||
return &static_cast<SymbolObject&>(value.as_object()).primitive_symbol();
|
return &static_cast<SymbolObject&>(value.as_object()).primitive_symbol();
|
||||||
auto& vm = global_object.vm();
|
auto& vm = global_object.vm();
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::NotAnObjectOfType, "Symbol");
|
return vm.throw_completion<TypeError>(ErrorType::NotAnObjectOfType, "Symbol");
|
||||||
}
|
}
|
||||||
|
|
||||||
// 20.4.3.2 get Symbol.prototype.description, https://tc39.es/ecma262/#sec-symbol.prototype.description
|
// 20.4.3.2 get Symbol.prototype.description, https://tc39.es/ecma262/#sec-symbol.prototype.description
|
||||||
|
|
|
@ -65,7 +65,7 @@ ThrowCompletionOr<MarkedVector<Value>> iterable_to_list_of_type(GlobalObject& gl
|
||||||
// ii. If Type(nextValue) is not an element of elementTypes, then
|
// ii. If Type(nextValue) is not an element of elementTypes, then
|
||||||
if (auto type = to_option_type(next_value); !type.has_value() || !element_types.contains_slow(*type)) {
|
if (auto type = to_option_type(next_value); !type.has_value() || !element_types.contains_slow(*type)) {
|
||||||
// 1. Let completion be ThrowCompletion(a newly created TypeError object).
|
// 1. Let completion be ThrowCompletion(a newly created TypeError object).
|
||||||
auto completion = vm.throw_completion<TypeError>(global_object, ErrorType::IterableToListOfTypeInvalidValue, next_value.to_string_without_side_effects());
|
auto completion = vm.throw_completion<TypeError>(ErrorType::IterableToListOfTypeInvalidValue, next_value.to_string_without_side_effects());
|
||||||
// 2. Return ? IteratorClose(iteratorRecord, completion).
|
// 2. Return ? IteratorClose(iteratorRecord, completion).
|
||||||
return iterator_close(global_object, iterator_record, move(completion));
|
return iterator_close(global_object, iterator_record, move(completion));
|
||||||
}
|
}
|
||||||
|
@ -97,7 +97,7 @@ ThrowCompletionOr<Object*> get_options_object(GlobalObject& global_object, Value
|
||||||
}
|
}
|
||||||
|
|
||||||
// 3. Throw a TypeError exception.
|
// 3. Throw a TypeError exception.
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::NotAnObject, "Options");
|
return vm.throw_completion<TypeError>(ErrorType::NotAnObject, "Options");
|
||||||
}
|
}
|
||||||
|
|
||||||
// 13.3 GetOption ( options, property, type, values, fallback ), https://tc39.es/proposal-temporal/#sec-getoption
|
// 13.3 GetOption ( options, property, type, values, fallback ), https://tc39.es/proposal-temporal/#sec-getoption
|
||||||
|
@ -114,7 +114,7 @@ ThrowCompletionOr<Value> get_option(GlobalObject& global_object, Object const& o
|
||||||
if (value.is_undefined()) {
|
if (value.is_undefined()) {
|
||||||
// a. If default is required, throw a RangeError exception.
|
// a. If default is required, throw a RangeError exception.
|
||||||
if (default_.has<GetOptionRequired>())
|
if (default_.has<GetOptionRequired>())
|
||||||
return vm.throw_completion<RangeError>(global_object, ErrorType::OptionIsNotValidValue, "undefined"sv, property.as_string());
|
return vm.throw_completion<RangeError>(ErrorType::OptionIsNotValidValue, "undefined"sv, property.as_string());
|
||||||
|
|
||||||
// b. Return default.
|
// b. Return default.
|
||||||
return default_.visit(
|
return default_.visit(
|
||||||
|
@ -137,7 +137,7 @@ ThrowCompletionOr<Value> get_option(GlobalObject& global_object, Object const& o
|
||||||
|
|
||||||
// b. If value is NaN, throw a RangeError exception.
|
// b. If value is NaN, throw a RangeError exception.
|
||||||
if (value.is_nan())
|
if (value.is_nan())
|
||||||
return vm.throw_completion<RangeError>(global_object, ErrorType::OptionIsNotValidValue, vm.names.NaN.as_string(), property.as_string());
|
return vm.throw_completion<RangeError>(ErrorType::OptionIsNotValidValue, vm.names.NaN.as_string(), property.as_string());
|
||||||
}
|
}
|
||||||
// 7. Else,
|
// 7. Else,
|
||||||
else {
|
else {
|
||||||
|
@ -153,7 +153,7 @@ ThrowCompletionOr<Value> get_option(GlobalObject& global_object, Object const& o
|
||||||
// NOTE: Every location in the spec that invokes GetOption with type=boolean also has values=undefined.
|
// NOTE: Every location in the spec that invokes GetOption with type=boolean also has values=undefined.
|
||||||
VERIFY(value.is_string());
|
VERIFY(value.is_string());
|
||||||
if (!values.contains_slow(value.as_string().string()))
|
if (!values.contains_slow(value.as_string().string()))
|
||||||
return vm.throw_completion<RangeError>(global_object, ErrorType::OptionIsNotValidValue, value.as_string().string(), property.as_string());
|
return vm.throw_completion<RangeError>(ErrorType::OptionIsNotValidValue, value.as_string().string(), property.as_string());
|
||||||
}
|
}
|
||||||
|
|
||||||
// 9. Return value.
|
// 9. Return value.
|
||||||
|
@ -305,7 +305,7 @@ ThrowCompletionOr<u64> to_temporal_rounding_increment(GlobalObject& global_objec
|
||||||
|
|
||||||
// 6. If increment < 1𝔽 or increment > maximum, throw a RangeError exception.
|
// 6. If increment < 1𝔽 or increment > maximum, throw a RangeError exception.
|
||||||
if (increment < 1 || increment > maximum)
|
if (increment < 1 || increment > maximum)
|
||||||
return vm.throw_completion<RangeError>(global_object, ErrorType::OptionIsNotValidValue, increment, "roundingIncrement");
|
return vm.throw_completion<RangeError>(ErrorType::OptionIsNotValidValue, increment, "roundingIncrement");
|
||||||
|
|
||||||
// 7. Set increment to floor(ℝ(increment)).
|
// 7. Set increment to floor(ℝ(increment)).
|
||||||
auto floored_increment = static_cast<u64>(increment);
|
auto floored_increment = static_cast<u64>(increment);
|
||||||
|
@ -313,7 +313,7 @@ ThrowCompletionOr<u64> to_temporal_rounding_increment(GlobalObject& global_objec
|
||||||
// 8. If dividend is not undefined and dividend modulo increment is not zero, then
|
// 8. If dividend is not undefined and dividend modulo increment is not zero, then
|
||||||
if (dividend.has_value() && static_cast<u64>(*dividend) % floored_increment != 0)
|
if (dividend.has_value() && static_cast<u64>(*dividend) % floored_increment != 0)
|
||||||
// a. Throw a RangeError exception.
|
// a. Throw a RangeError exception.
|
||||||
return vm.throw_completion<RangeError>(global_object, ErrorType::OptionIsNotValidValue, increment, "roundingIncrement");
|
return vm.throw_completion<RangeError>(ErrorType::OptionIsNotValidValue, increment, "roundingIncrement");
|
||||||
|
|
||||||
// 9. Return increment.
|
// 9. Return increment.
|
||||||
return floored_increment;
|
return floored_increment;
|
||||||
|
@ -350,7 +350,7 @@ ThrowCompletionOr<SecondsStringPrecision> to_seconds_string_precision(GlobalObje
|
||||||
|
|
||||||
// 2. If smallestUnit is "hour", throw a RangeError exception.
|
// 2. If smallestUnit is "hour", throw a RangeError exception.
|
||||||
if (smallest_unit == "hour"sv)
|
if (smallest_unit == "hour"sv)
|
||||||
return vm.throw_completion<RangeError>(global_object, ErrorType::OptionIsNotValidValue, *smallest_unit, "smallestUnit"sv);
|
return vm.throw_completion<RangeError>(ErrorType::OptionIsNotValidValue, *smallest_unit, "smallestUnit"sv);
|
||||||
|
|
||||||
// 3. If smallestUnit is "minute", then
|
// 3. If smallestUnit is "minute", then
|
||||||
if (smallest_unit == "minute"sv) {
|
if (smallest_unit == "minute"sv) {
|
||||||
|
@ -394,7 +394,7 @@ ThrowCompletionOr<SecondsStringPrecision> to_seconds_string_precision(GlobalObje
|
||||||
if (!fractional_digits_value.is_undefined()) {
|
if (!fractional_digits_value.is_undefined()) {
|
||||||
// i. If ? ToString(fractionalDigitsVal) is not "auto", throw a RangeError exception.
|
// i. If ? ToString(fractionalDigitsVal) is not "auto", throw a RangeError exception.
|
||||||
if (TRY(fractional_digits_value.to_string(global_object)) != "auto"sv)
|
if (TRY(fractional_digits_value.to_string(global_object)) != "auto"sv)
|
||||||
return vm.template throw_completion<RangeError>(global_object, ErrorType::OptionIsNotValidValue, fractional_digits_value, "fractionalSecondDigits"sv);
|
return vm.template throw_completion<RangeError>(ErrorType::OptionIsNotValidValue, fractional_digits_value, "fractionalSecondDigits"sv);
|
||||||
}
|
}
|
||||||
|
|
||||||
// b. Return the Record { [[Precision]]: "auto", [[Unit]]: "nanosecond", [[Increment]]: 1 }.
|
// b. Return the Record { [[Precision]]: "auto", [[Unit]]: "nanosecond", [[Increment]]: 1 }.
|
||||||
|
@ -403,14 +403,14 @@ ThrowCompletionOr<SecondsStringPrecision> to_seconds_string_precision(GlobalObje
|
||||||
|
|
||||||
// 11. If fractionalDigitsVal is NaN, +∞𝔽, or -∞𝔽, throw a RangeError exception.
|
// 11. If fractionalDigitsVal is NaN, +∞𝔽, or -∞𝔽, throw a RangeError exception.
|
||||||
if (fractional_digits_value.is_nan() || fractional_digits_value.is_infinity())
|
if (fractional_digits_value.is_nan() || fractional_digits_value.is_infinity())
|
||||||
return vm.template throw_completion<RangeError>(global_object, ErrorType::OptionIsNotValidValue, fractional_digits_value, "fractionalSecondDigits"sv);
|
return vm.template throw_completion<RangeError>(ErrorType::OptionIsNotValidValue, fractional_digits_value, "fractionalSecondDigits"sv);
|
||||||
|
|
||||||
// 12. Let fractionalDigitCount be RoundTowardsZero(ℝ(fractionalDigitsVal)).
|
// 12. Let fractionalDigitCount be RoundTowardsZero(ℝ(fractionalDigitsVal)).
|
||||||
auto fractional_digit_count_unchecked = trunc(fractional_digits_value.as_double());
|
auto fractional_digit_count_unchecked = trunc(fractional_digits_value.as_double());
|
||||||
|
|
||||||
// 13. If fractionalDigitCount < 0 or fractionalDigitCount > 9, throw a RangeError exception.
|
// 13. If fractionalDigitCount < 0 or fractionalDigitCount > 9, throw a RangeError exception.
|
||||||
if (fractional_digit_count_unchecked < 0 || fractional_digit_count_unchecked > 9)
|
if (fractional_digit_count_unchecked < 0 || fractional_digit_count_unchecked > 9)
|
||||||
return vm.template throw_completion<RangeError>(global_object, ErrorType::OptionIsNotValidValue, fractional_digits_value, "fractionalSecondDigits"sv);
|
return vm.template throw_completion<RangeError>(ErrorType::OptionIsNotValidValue, fractional_digits_value, "fractionalSecondDigits"sv);
|
||||||
|
|
||||||
auto fractional_digit_count = static_cast<u8>(fractional_digit_count_unchecked);
|
auto fractional_digit_count = static_cast<u8>(fractional_digit_count_unchecked);
|
||||||
|
|
||||||
|
@ -531,7 +531,7 @@ ThrowCompletionOr<Optional<String>> get_temporal_unit(GlobalObject& global_objec
|
||||||
|
|
||||||
// 10. If value is undefined and default is required, throw a RangeError exception.
|
// 10. If value is undefined and default is required, throw a RangeError exception.
|
||||||
if (option_value.is_undefined() && default_.has<TemporalUnitRequired>())
|
if (option_value.is_undefined() && default_.has<TemporalUnitRequired>())
|
||||||
return vm.throw_completion<RangeError>(global_object, ErrorType::IsUndefined, String::formatted("{} option value", key.as_string()));
|
return vm.throw_completion<RangeError>(ErrorType::IsUndefined, String::formatted("{} option value", key.as_string()));
|
||||||
|
|
||||||
Optional<String> value = option_value.is_undefined()
|
Optional<String> value = option_value.is_undefined()
|
||||||
? Optional<String> {}
|
? Optional<String> {}
|
||||||
|
@ -657,7 +657,7 @@ ThrowCompletionOr<Value> to_relative_temporal_object(GlobalObject& global_object
|
||||||
if (!is_valid_time_zone_numeric_utc_offset_syntax(*time_zone_name)) {
|
if (!is_valid_time_zone_numeric_utc_offset_syntax(*time_zone_name)) {
|
||||||
// 1. If IsValidTimeZoneName(timeZoneName) is false, throw a RangeError exception.
|
// 1. If IsValidTimeZoneName(timeZoneName) is false, throw a RangeError exception.
|
||||||
if (!is_valid_time_zone_name(*time_zone_name))
|
if (!is_valid_time_zone_name(*time_zone_name))
|
||||||
return vm.throw_completion<RangeError>(global_object, ErrorType::TemporalInvalidTimeZoneName, *time_zone_name);
|
return vm.throw_completion<RangeError>(ErrorType::TemporalInvalidTimeZoneName, *time_zone_name);
|
||||||
|
|
||||||
// 2. Set timeZoneName to ! CanonicalizeTimeZoneName(timeZoneName).
|
// 2. Set timeZoneName to ! CanonicalizeTimeZoneName(timeZoneName).
|
||||||
time_zone_name = canonicalize_time_zone_name(*time_zone_name);
|
time_zone_name = canonicalize_time_zone_name(*time_zone_name);
|
||||||
|
@ -809,7 +809,7 @@ ThrowCompletionOr<void> reject_object_with_calendar_or_time_zone(GlobalObject& g
|
||||||
// 2. If object has an [[InitializedTemporalDate]], [[InitializedTemporalDateTime]], [[InitializedTemporalMonthDay]], [[InitializedTemporalTime]], [[InitializedTemporalYearMonth]], or [[InitializedTemporalZonedDateTime]] internal slot, then
|
// 2. If object has an [[InitializedTemporalDate]], [[InitializedTemporalDateTime]], [[InitializedTemporalMonthDay]], [[InitializedTemporalTime]], [[InitializedTemporalYearMonth]], or [[InitializedTemporalZonedDateTime]] internal slot, then
|
||||||
if (is<PlainDate>(object) || is<PlainDateTime>(object) || is<PlainMonthDay>(object) || is<PlainTime>(object) || is<PlainYearMonth>(object) || is<ZonedDateTime>(object)) {
|
if (is<PlainDate>(object) || is<PlainDateTime>(object) || is<PlainMonthDay>(object) || is<PlainTime>(object) || is<PlainYearMonth>(object) || is<ZonedDateTime>(object)) {
|
||||||
// a. Throw a TypeError exception.
|
// a. Throw a TypeError exception.
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::TemporalObjectMustNotHave, "calendar or timeZone");
|
return vm.throw_completion<TypeError>(ErrorType::TemporalObjectMustNotHave, "calendar or timeZone");
|
||||||
}
|
}
|
||||||
|
|
||||||
// 3. Let calendarProperty be ? Get(object, "calendar").
|
// 3. Let calendarProperty be ? Get(object, "calendar").
|
||||||
|
@ -818,7 +818,7 @@ ThrowCompletionOr<void> reject_object_with_calendar_or_time_zone(GlobalObject& g
|
||||||
// 4. If calendarProperty is not undefined, then
|
// 4. If calendarProperty is not undefined, then
|
||||||
if (!calendar_property.is_undefined()) {
|
if (!calendar_property.is_undefined()) {
|
||||||
// a. Throw a TypeError exception.
|
// a. Throw a TypeError exception.
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::TemporalObjectMustNotHave, "calendar");
|
return vm.throw_completion<TypeError>(ErrorType::TemporalObjectMustNotHave, "calendar");
|
||||||
}
|
}
|
||||||
|
|
||||||
// 5. Let timeZoneProperty be ? Get(object, "timeZone").
|
// 5. Let timeZoneProperty be ? Get(object, "timeZone").
|
||||||
|
@ -827,7 +827,7 @@ ThrowCompletionOr<void> reject_object_with_calendar_or_time_zone(GlobalObject& g
|
||||||
// 6. If timeZoneProperty is not undefined, then
|
// 6. If timeZoneProperty is not undefined, then
|
||||||
if (!time_zone_property.is_undefined()) {
|
if (!time_zone_property.is_undefined()) {
|
||||||
// a. Throw a TypeError exception.
|
// a. Throw a TypeError exception.
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::TemporalObjectMustNotHave, "timeZone");
|
return vm.throw_completion<TypeError>(ErrorType::TemporalObjectMustNotHave, "timeZone");
|
||||||
}
|
}
|
||||||
|
|
||||||
return {};
|
return {};
|
||||||
|
@ -1315,11 +1315,11 @@ ThrowCompletionOr<ISODateTime> parse_iso_date_time(GlobalObject& global_object,
|
||||||
|
|
||||||
// 20. If IsValidISODate(yearMV, monthMV, dayMV) is false, throw a RangeError exception.
|
// 20. If IsValidISODate(yearMV, monthMV, dayMV) is false, throw a RangeError exception.
|
||||||
if (!is_valid_iso_date(year_mv, month_mv, day_mv))
|
if (!is_valid_iso_date(year_mv, month_mv, day_mv))
|
||||||
return vm.throw_completion<RangeError>(global_object, ErrorType::TemporalInvalidISODate);
|
return vm.throw_completion<RangeError>(ErrorType::TemporalInvalidISODate);
|
||||||
|
|
||||||
// 21. If IsValidTime(hourMV, minuteMV, secondMV, millisecondMV, microsecondMV, nanosecondMV) is false, throw a RangeError exception.
|
// 21. If IsValidTime(hourMV, minuteMV, secondMV, millisecondMV, microsecondMV, nanosecondMV) is false, throw a RangeError exception.
|
||||||
if (!is_valid_time(hour_mv, minute_mv, second_mv, millisecond_mv, microsecond_mv, nanosecond_mv))
|
if (!is_valid_time(hour_mv, minute_mv, second_mv, millisecond_mv, microsecond_mv, nanosecond_mv))
|
||||||
return vm.throw_completion<RangeError>(global_object, ErrorType::TemporalInvalidTime);
|
return vm.throw_completion<RangeError>(ErrorType::TemporalInvalidTime);
|
||||||
|
|
||||||
Optional<String> calendar_val;
|
Optional<String> calendar_val;
|
||||||
|
|
||||||
|
@ -1347,7 +1347,7 @@ ThrowCompletionOr<TemporalInstant> parse_temporal_instant_string(GlobalObject& g
|
||||||
// 1. If ParseText(StringToCodePoints(isoString), TemporalInstantString) is a List of errors, throw a RangeError exception.
|
// 1. If ParseText(StringToCodePoints(isoString), TemporalInstantString) is a List of errors, throw a RangeError exception.
|
||||||
auto parse_result = parse_iso8601(Production::TemporalInstantString, iso_string);
|
auto parse_result = parse_iso8601(Production::TemporalInstantString, iso_string);
|
||||||
if (!parse_result.has_value())
|
if (!parse_result.has_value())
|
||||||
return vm.throw_completion<RangeError>(global_object, ErrorType::TemporalInvalidInstantString, iso_string);
|
return vm.throw_completion<RangeError>(ErrorType::TemporalInvalidInstantString, iso_string);
|
||||||
|
|
||||||
// 2. Let result be ? ParseISODateTime(isoString).
|
// 2. Let result be ? ParseISODateTime(isoString).
|
||||||
auto result = TRY(parse_iso_date_time(global_object, *parse_result));
|
auto result = TRY(parse_iso_date_time(global_object, *parse_result));
|
||||||
|
@ -1379,7 +1379,7 @@ ThrowCompletionOr<TemporalZonedDateTime> parse_temporal_zoned_date_time_string(G
|
||||||
// 1. If ParseText(StringToCodePoints(isoString), TemporalZonedDateTimeString) is a List of errors, throw a RangeError exception.
|
// 1. If ParseText(StringToCodePoints(isoString), TemporalZonedDateTimeString) is a List of errors, throw a RangeError exception.
|
||||||
auto parse_result = parse_iso8601(Production::TemporalZonedDateTimeString, iso_string);
|
auto parse_result = parse_iso8601(Production::TemporalZonedDateTimeString, iso_string);
|
||||||
if (!parse_result.has_value())
|
if (!parse_result.has_value())
|
||||||
return vm.throw_completion<RangeError>(global_object, ErrorType::TemporalInvalidZonedDateTimeString, iso_string);
|
return vm.throw_completion<RangeError>(ErrorType::TemporalInvalidZonedDateTimeString, iso_string);
|
||||||
|
|
||||||
// 2. Let result be ? ParseISODateTime(isoString).
|
// 2. Let result be ? ParseISODateTime(isoString).
|
||||||
auto result = TRY(parse_iso_date_time(global_object, *parse_result));
|
auto result = TRY(parse_iso_date_time(global_object, *parse_result));
|
||||||
|
@ -1403,7 +1403,7 @@ ThrowCompletionOr<String> parse_temporal_calendar_string(GlobalObject& global_ob
|
||||||
|
|
||||||
// 2. If parseResult is a List of errors, throw a RangeError exception.
|
// 2. If parseResult is a List of errors, throw a RangeError exception.
|
||||||
if (!parse_result.has_value())
|
if (!parse_result.has_value())
|
||||||
return vm.throw_completion<RangeError>(global_object, ErrorType::TemporalInvalidCalendarString, iso_string);
|
return vm.throw_completion<RangeError>(ErrorType::TemporalInvalidCalendarString, iso_string);
|
||||||
|
|
||||||
// 3. Let id be the source text matched by the CalendarName Parse Node contained within parseResult, or an empty sequence of code points if not present.
|
// 3. Let id be the source text matched by the CalendarName Parse Node contained within parseResult, or an empty sequence of code points if not present.
|
||||||
auto id = parse_result->calendar_name;
|
auto id = parse_result->calendar_name;
|
||||||
|
@ -1438,11 +1438,11 @@ ThrowCompletionOr<ISODateTime> parse_temporal_date_time_string(GlobalObject& glo
|
||||||
|
|
||||||
// 2. If parseResult is a List of errors, throw a RangeError exception.
|
// 2. If parseResult is a List of errors, throw a RangeError exception.
|
||||||
if (!parse_result.has_value())
|
if (!parse_result.has_value())
|
||||||
return vm.throw_completion<RangeError>(global_object, ErrorType::TemporalInvalidDateTimeString, iso_string);
|
return vm.throw_completion<RangeError>(ErrorType::TemporalInvalidDateTimeString, iso_string);
|
||||||
|
|
||||||
// 3. If parseResult contains a UTCDesignator Parse Node, throw a RangeError exception.
|
// 3. If parseResult contains a UTCDesignator Parse Node, throw a RangeError exception.
|
||||||
if (parse_result->utc_designator.has_value())
|
if (parse_result->utc_designator.has_value())
|
||||||
return vm.throw_completion<RangeError>(global_object, ErrorType::TemporalInvalidDateTimeStringUTCDesignator, iso_string);
|
return vm.throw_completion<RangeError>(ErrorType::TemporalInvalidDateTimeStringUTCDesignator, iso_string);
|
||||||
|
|
||||||
// 4. Return ? ParseISODateTime(isoString).
|
// 4. Return ? ParseISODateTime(isoString).
|
||||||
return parse_iso_date_time(global_object, *parse_result);
|
return parse_iso_date_time(global_object, *parse_result);
|
||||||
|
@ -1458,7 +1458,7 @@ ThrowCompletionOr<DurationRecord> parse_temporal_duration_string(GlobalObject& g
|
||||||
|
|
||||||
// 2. If duration is a List of errors, throw a RangeError exception.
|
// 2. If duration is a List of errors, throw a RangeError exception.
|
||||||
if (!parse_result.has_value())
|
if (!parse_result.has_value())
|
||||||
return vm.throw_completion<RangeError>(global_object, ErrorType::TemporalInvalidDurationString, iso_string);
|
return vm.throw_completion<RangeError>(ErrorType::TemporalInvalidDurationString, iso_string);
|
||||||
|
|
||||||
// 3. Let each of sign, years, months, weeks, days, hours, fHours, minutes, fMinutes, seconds, and fSeconds be the source text matched by the respective Sign, DurationYears, DurationMonths, DurationWeeks, DurationDays, DurationWholeHours, DurationHoursFraction, DurationWholeMinutes, DurationMinutesFraction, DurationWholeSeconds, and DurationSecondsFraction Parse Node contained within duration, or an empty sequence of code points if not present.
|
// 3. Let each of sign, years, months, weeks, days, hours, fHours, minutes, fMinutes, seconds, and fSeconds be the source text matched by the respective Sign, DurationYears, DurationMonths, DurationWeeks, DurationDays, DurationWholeHours, DurationHoursFraction, DurationWholeMinutes, DurationMinutesFraction, DurationWholeSeconds, and DurationSecondsFraction Parse Node contained within duration, or an empty sequence of code points if not present.
|
||||||
auto sign_part = parse_result->sign;
|
auto sign_part = parse_result->sign;
|
||||||
|
@ -1496,7 +1496,7 @@ ThrowCompletionOr<DurationRecord> parse_temporal_duration_string(GlobalObject& g
|
||||||
if (f_hours_part.has_value()) {
|
if (f_hours_part.has_value()) {
|
||||||
// a. If any of minutes, fMinutes, seconds, fSeconds is not empty, throw a RangeError exception.
|
// a. If any of minutes, fMinutes, seconds, fSeconds is not empty, throw a RangeError exception.
|
||||||
if (minutes_part.has_value() || f_minutes_part.has_value() || seconds_part.has_value() || f_seconds_part.has_value())
|
if (minutes_part.has_value() || f_minutes_part.has_value() || seconds_part.has_value() || f_seconds_part.has_value())
|
||||||
return vm.throw_completion<RangeError>(global_object, ErrorType::TemporalInvalidDurationStringFractionNotLast, iso_string, "hours"sv, "minutes or seconds"sv);
|
return vm.throw_completion<RangeError>(ErrorType::TemporalInvalidDurationStringFractionNotLast, iso_string, "hours"sv, "minutes or seconds"sv);
|
||||||
|
|
||||||
// b. Let fHoursDigits be the substring of CodePointsToString(fHours) from 1.
|
// b. Let fHoursDigits be the substring of CodePointsToString(fHours) from 1.
|
||||||
auto f_hours_digits = f_hours_part->substring_view(1);
|
auto f_hours_digits = f_hours_part->substring_view(1);
|
||||||
|
@ -1519,7 +1519,7 @@ ThrowCompletionOr<DurationRecord> parse_temporal_duration_string(GlobalObject& g
|
||||||
if (f_minutes_part.has_value()) {
|
if (f_minutes_part.has_value()) {
|
||||||
// a. If any of seconds, fSeconds is not empty, throw a RangeError exception.
|
// a. If any of seconds, fSeconds is not empty, throw a RangeError exception.
|
||||||
if (seconds_part.has_value() || f_seconds_part.has_value())
|
if (seconds_part.has_value() || f_seconds_part.has_value())
|
||||||
return vm.throw_completion<RangeError>(global_object, ErrorType::TemporalInvalidDurationStringFractionNotLast, iso_string, "minutes"sv, "seconds"sv);
|
return vm.throw_completion<RangeError>(ErrorType::TemporalInvalidDurationStringFractionNotLast, iso_string, "minutes"sv, "seconds"sv);
|
||||||
|
|
||||||
// b. Let fMinutesDigits be the substring of CodePointsToString(fMinutes) from 1.
|
// b. Let fMinutesDigits be the substring of CodePointsToString(fMinutes) from 1.
|
||||||
auto f_minutes_digits = f_minutes_part->substring_view(1);
|
auto f_minutes_digits = f_minutes_part->substring_view(1);
|
||||||
|
@ -1598,11 +1598,11 @@ ThrowCompletionOr<TemporalMonthDay> parse_temporal_month_day_string(GlobalObject
|
||||||
|
|
||||||
// 2. If parseResult is a List of errors, throw a RangeError exception.
|
// 2. If parseResult is a List of errors, throw a RangeError exception.
|
||||||
if (!parse_result.has_value())
|
if (!parse_result.has_value())
|
||||||
return vm.throw_completion<RangeError>(global_object, ErrorType::TemporalInvalidMonthDayString, iso_string);
|
return vm.throw_completion<RangeError>(ErrorType::TemporalInvalidMonthDayString, iso_string);
|
||||||
|
|
||||||
// 3. If parseResult contains a UTCDesignator Parse Node, throw a RangeError exception.
|
// 3. If parseResult contains a UTCDesignator Parse Node, throw a RangeError exception.
|
||||||
if (parse_result->utc_designator.has_value())
|
if (parse_result->utc_designator.has_value())
|
||||||
return vm.throw_completion<RangeError>(global_object, ErrorType::TemporalInvalidMonthDayStringUTCDesignator, iso_string);
|
return vm.throw_completion<RangeError>(ErrorType::TemporalInvalidMonthDayStringUTCDesignator, iso_string);
|
||||||
|
|
||||||
// 4. Let result be ? ParseISODateTime(isoString).
|
// 4. Let result be ? ParseISODateTime(isoString).
|
||||||
auto result = TRY(parse_iso_date_time(global_object, *parse_result));
|
auto result = TRY(parse_iso_date_time(global_object, *parse_result));
|
||||||
|
@ -1628,7 +1628,7 @@ ThrowCompletionOr<TemporalZonedDateTime> parse_temporal_relative_to_string(Globa
|
||||||
// 1. If ParseText(StringToCodePoints(isoString), TemporalDateTimeString) is a List of errors, throw a RangeError exception.
|
// 1. If ParseText(StringToCodePoints(isoString), TemporalDateTimeString) is a List of errors, throw a RangeError exception.
|
||||||
auto parse_result = parse_iso8601(Production::TemporalDateTimeString, iso_string);
|
auto parse_result = parse_iso8601(Production::TemporalDateTimeString, iso_string);
|
||||||
if (!parse_result.has_value())
|
if (!parse_result.has_value())
|
||||||
return vm.throw_completion<RangeError>(global_object, ErrorType::TemporalInvalidDateTimeString, iso_string);
|
return vm.throw_completion<RangeError>(ErrorType::TemporalInvalidDateTimeString, iso_string);
|
||||||
|
|
||||||
// 2. Let result be ? ParseISODateTime(isoString).
|
// 2. Let result be ? ParseISODateTime(isoString).
|
||||||
auto result = TRY(parse_iso_date_time(global_object, *parse_result));
|
auto result = TRY(parse_iso_date_time(global_object, *parse_result));
|
||||||
|
@ -1675,11 +1675,11 @@ ThrowCompletionOr<TemporalTime> parse_temporal_time_string(GlobalObject& global_
|
||||||
|
|
||||||
// 2. If parseResult is a List of errors, throw a RangeError exception.
|
// 2. If parseResult is a List of errors, throw a RangeError exception.
|
||||||
if (!parse_result.has_value())
|
if (!parse_result.has_value())
|
||||||
return vm.throw_completion<RangeError>(global_object, ErrorType::TemporalInvalidTimeString, iso_string);
|
return vm.throw_completion<RangeError>(ErrorType::TemporalInvalidTimeString, iso_string);
|
||||||
|
|
||||||
// 3. If parseResult contains a UTCDesignator Parse Node, throw a RangeError exception.
|
// 3. If parseResult contains a UTCDesignator Parse Node, throw a RangeError exception.
|
||||||
if (parse_result->utc_designator.has_value())
|
if (parse_result->utc_designator.has_value())
|
||||||
return vm.throw_completion<RangeError>(global_object, ErrorType::TemporalInvalidTimeStringUTCDesignator, iso_string);
|
return vm.throw_completion<RangeError>(ErrorType::TemporalInvalidTimeStringUTCDesignator, iso_string);
|
||||||
|
|
||||||
// 4. Let result be ? ParseISODateTime(isoString).
|
// 4. Let result be ? ParseISODateTime(isoString).
|
||||||
auto result = TRY(parse_iso_date_time(global_object, *parse_result));
|
auto result = TRY(parse_iso_date_time(global_object, *parse_result));
|
||||||
|
@ -1698,7 +1698,7 @@ ThrowCompletionOr<TemporalTimeZone> parse_temporal_time_zone_string(GlobalObject
|
||||||
|
|
||||||
// 2. If parseResult is a List of errors, throw a RangeError exception.
|
// 2. If parseResult is a List of errors, throw a RangeError exception.
|
||||||
if (!parse_result.has_value())
|
if (!parse_result.has_value())
|
||||||
return vm.throw_completion<RangeError>(global_object, ErrorType::TemporalInvalidTimeZoneString, iso_string);
|
return vm.throw_completion<RangeError>(ErrorType::TemporalInvalidTimeZoneString, iso_string);
|
||||||
|
|
||||||
// 3. Let each of z, offsetString, and name be the source text matched by the respective UTCDesignator, TimeZoneNumericUTCOffset, and TimeZoneIdentifier Parse Nodes contained within parseResult, or an empty sequence of code points if not present.
|
// 3. Let each of z, offsetString, and name be the source text matched by the respective UTCDesignator, TimeZoneNumericUTCOffset, and TimeZoneIdentifier Parse Nodes contained within parseResult, or an empty sequence of code points if not present.
|
||||||
auto z = parse_result->utc_designator;
|
auto z = parse_result->utc_designator;
|
||||||
|
@ -1737,11 +1737,11 @@ ThrowCompletionOr<TemporalYearMonth> parse_temporal_year_month_string(GlobalObje
|
||||||
|
|
||||||
// 2. If parseResult is a List of errors, throw a RangeError exception.
|
// 2. If parseResult is a List of errors, throw a RangeError exception.
|
||||||
if (!parse_result.has_value())
|
if (!parse_result.has_value())
|
||||||
return vm.throw_completion<RangeError>(global_object, ErrorType::TemporalInvalidYearMonthString, iso_string);
|
return vm.throw_completion<RangeError>(ErrorType::TemporalInvalidYearMonthString, iso_string);
|
||||||
|
|
||||||
// 3. If parseResult contains a UTCDesignator Parse Node, throw a RangeError exception.
|
// 3. If parseResult contains a UTCDesignator Parse Node, throw a RangeError exception.
|
||||||
if (parse_result->utc_designator.has_value())
|
if (parse_result->utc_designator.has_value())
|
||||||
return vm.throw_completion<RangeError>(global_object, ErrorType::TemporalInvalidYearMonthStringUTCDesignator, iso_string);
|
return vm.throw_completion<RangeError>(ErrorType::TemporalInvalidYearMonthStringUTCDesignator, iso_string);
|
||||||
|
|
||||||
// 4. Let result be ? ParseISODateTime(isoString).
|
// 4. Let result be ? ParseISODateTime(isoString).
|
||||||
auto result = TRY(parse_iso_date_time(global_object, *parse_result));
|
auto result = TRY(parse_iso_date_time(global_object, *parse_result));
|
||||||
|
@ -1761,7 +1761,7 @@ ThrowCompletionOr<double> to_positive_integer(GlobalObject& global_object, Value
|
||||||
// 2. If integer ≤ 0, then
|
// 2. If integer ≤ 0, then
|
||||||
if (integer <= 0) {
|
if (integer <= 0) {
|
||||||
// a. Throw a RangeError exception.
|
// a. Throw a RangeError exception.
|
||||||
return vm.throw_completion<RangeError>(global_object, ErrorType::TemporalPropertyMustBePositiveInteger);
|
return vm.throw_completion<RangeError>(ErrorType::TemporalPropertyMustBePositiveInteger);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 3. Return integer.
|
// 3. Return integer.
|
||||||
|
@ -1820,7 +1820,7 @@ ThrowCompletionOr<Object*> prepare_temporal_fields(GlobalObject& global_object,
|
||||||
// i. If requiredFields contains property, then
|
// i. If requiredFields contains property, then
|
||||||
if (required_fields.get<Vector<StringView>>().contains_slow(property)) {
|
if (required_fields.get<Vector<StringView>>().contains_slow(property)) {
|
||||||
// 1. Throw a TypeError exception.
|
// 1. Throw a TypeError exception.
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::MissingRequiredProperty, property);
|
return vm.throw_completion<TypeError>(ErrorType::MissingRequiredProperty, property);
|
||||||
}
|
}
|
||||||
// ii. If property is in the Property column of Table 13, then
|
// ii. If property is in the Property column of Table 13, then
|
||||||
// NOTE: The other properties in the table are automatically handled as their default value is undefined
|
// NOTE: The other properties in the table are automatically handled as their default value is undefined
|
||||||
|
@ -1837,7 +1837,7 @@ ThrowCompletionOr<Object*> prepare_temporal_fields(GlobalObject& global_object,
|
||||||
// 4. If requiredFields is partial and any is false, then
|
// 4. If requiredFields is partial and any is false, then
|
||||||
if (required_fields.has<PrepareTemporalFieldsPartial>() && !any) {
|
if (required_fields.has<PrepareTemporalFieldsPartial>() && !any) {
|
||||||
// a. Throw a TypeError exception.
|
// a. Throw a TypeError exception.
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::TemporalObjectMustHaveOneOf, String::join(", "sv, field_names));
|
return vm.throw_completion<TypeError>(ErrorType::TemporalObjectMustHaveOneOf, String::join(", "sv, field_names));
|
||||||
}
|
}
|
||||||
|
|
||||||
// 5. Return result.
|
// 5. Return result.
|
||||||
|
@ -1857,7 +1857,7 @@ ThrowCompletionOr<DifferenceSettings> get_difference_settings(GlobalObject& glob
|
||||||
|
|
||||||
// 3. If disallowedUnits contains smallestUnit, throw a RangeError exception.
|
// 3. If disallowedUnits contains smallestUnit, throw a RangeError exception.
|
||||||
if (disallowed_units.contains_slow(*smallest_unit))
|
if (disallowed_units.contains_slow(*smallest_unit))
|
||||||
return vm.throw_completion<RangeError>(global_object, ErrorType::OptionIsNotValidValue, *smallest_unit, "smallestUnit"sv);
|
return vm.throw_completion<RangeError>(ErrorType::OptionIsNotValidValue, *smallest_unit, "smallestUnit"sv);
|
||||||
|
|
||||||
// 4. Let defaultLargestUnit be ! LargerOfTwoTemporalUnits(smallestLargestDefaultUnit, smallestUnit).
|
// 4. Let defaultLargestUnit be ! LargerOfTwoTemporalUnits(smallestLargestDefaultUnit, smallestUnit).
|
||||||
auto default_largest_unit = larger_of_two_temporal_units(smallest_largest_default_unit, *smallest_unit);
|
auto default_largest_unit = larger_of_two_temporal_units(smallest_largest_default_unit, *smallest_unit);
|
||||||
|
@ -1867,7 +1867,7 @@ ThrowCompletionOr<DifferenceSettings> get_difference_settings(GlobalObject& glob
|
||||||
|
|
||||||
// 6. If disallowedUnits contains largestUnit, throw a RangeError exception.
|
// 6. If disallowedUnits contains largestUnit, throw a RangeError exception.
|
||||||
if (disallowed_units.contains_slow(*largest_unit))
|
if (disallowed_units.contains_slow(*largest_unit))
|
||||||
return vm.throw_completion<RangeError>(global_object, ErrorType::OptionIsNotValidValue, *largest_unit, "largestUnit"sv);
|
return vm.throw_completion<RangeError>(ErrorType::OptionIsNotValidValue, *largest_unit, "largestUnit"sv);
|
||||||
|
|
||||||
// 7. If largestUnit is "auto", set largestUnit to defaultLargestUnit.
|
// 7. If largestUnit is "auto", set largestUnit to defaultLargestUnit.
|
||||||
if (largest_unit == "auto"sv)
|
if (largest_unit == "auto"sv)
|
||||||
|
@ -1875,7 +1875,7 @@ ThrowCompletionOr<DifferenceSettings> get_difference_settings(GlobalObject& glob
|
||||||
|
|
||||||
// 8. If LargerOfTwoTemporalUnits(largestUnit, smallestUnit) is not largestUnit, throw a RangeError exception.
|
// 8. If LargerOfTwoTemporalUnits(largestUnit, smallestUnit) is not largestUnit, throw a RangeError exception.
|
||||||
if (larger_of_two_temporal_units(*largest_unit, *smallest_unit) != largest_unit)
|
if (larger_of_two_temporal_units(*largest_unit, *smallest_unit) != largest_unit)
|
||||||
return vm.throw_completion<RangeError>(global_object, ErrorType::TemporalInvalidUnitRange, *smallest_unit, *largest_unit);
|
return vm.throw_completion<RangeError>(ErrorType::TemporalInvalidUnitRange, *smallest_unit, *largest_unit);
|
||||||
|
|
||||||
// 9. Let roundingMode be ? ToTemporalRoundingMode(options, "trunc").
|
// 9. Let roundingMode be ? ToTemporalRoundingMode(options, "trunc").
|
||||||
auto rounding_mode = TRY(to_temporal_rounding_mode(global_object, *options, "trunc"sv));
|
auto rounding_mode = TRY(to_temporal_rounding_mode(global_object, *options, "trunc"sv));
|
||||||
|
|
|
@ -199,7 +199,7 @@ ThrowCompletionOr<double> to_integer_throw_on_infinity(GlobalObject& global_obje
|
||||||
// 2. If integer is -∞ or +∞ , then
|
// 2. If integer is -∞ or +∞ , then
|
||||||
if (Value(integer).is_infinity()) {
|
if (Value(integer).is_infinity()) {
|
||||||
// a. Throw a RangeError exception.
|
// a. Throw a RangeError exception.
|
||||||
return vm.template throw_completion<RangeError>(global_object, error_type, args...);
|
return vm.template throw_completion<RangeError>(error_type, args...);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 3. Return integer.
|
// 3. Return integer.
|
||||||
|
@ -221,7 +221,7 @@ ThrowCompletionOr<double> to_integer_without_rounding(GlobalObject& global_objec
|
||||||
|
|
||||||
// 3. If IsIntegralNumber(number) is false, throw a RangeError exception.
|
// 3. If IsIntegralNumber(number) is false, throw a RangeError exception.
|
||||||
if (!number.is_integral_number())
|
if (!number.is_integral_number())
|
||||||
return vm.template throw_completion<RangeError>(global_object, error_type, args...);
|
return vm.template throw_completion<RangeError>(error_type, args...);
|
||||||
|
|
||||||
// 4. Return ℝ(number).
|
// 4. Return ℝ(number).
|
||||||
return number.as_double();
|
return number.as_double();
|
||||||
|
|
|
@ -85,7 +85,7 @@ ThrowCompletionOr<Calendar*> get_builtin_calendar(GlobalObject& global_object, S
|
||||||
|
|
||||||
// 1. If IsBuiltinCalendar(id) is false, throw a RangeError exception.
|
// 1. If IsBuiltinCalendar(id) is false, throw a RangeError exception.
|
||||||
if (!is_builtin_calendar(identifier))
|
if (!is_builtin_calendar(identifier))
|
||||||
return vm.throw_completion<RangeError>(global_object, ErrorType::TemporalInvalidCalendarIdentifier, identifier);
|
return vm.throw_completion<RangeError>(ErrorType::TemporalInvalidCalendarIdentifier, identifier);
|
||||||
|
|
||||||
// 2. Return ! CreateTemporalCalendar(id).
|
// 2. Return ! CreateTemporalCalendar(id).
|
||||||
return MUST(create_temporal_calendar(global_object, identifier));
|
return MUST(create_temporal_calendar(global_object, identifier));
|
||||||
|
@ -147,7 +147,7 @@ ThrowCompletionOr<Object*> calendar_merge_fields(GlobalObject& global_object, Ob
|
||||||
|
|
||||||
// 4. If Type(result) is not Object, throw a TypeError exception.
|
// 4. If Type(result) is not Object, throw a TypeError exception.
|
||||||
if (!result.is_object())
|
if (!result.is_object())
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::NotAnObject, result.to_string_without_side_effects());
|
return vm.throw_completion<TypeError>(ErrorType::NotAnObject, result.to_string_without_side_effects());
|
||||||
|
|
||||||
// 5. Return result.
|
// 5. Return result.
|
||||||
return &result.as_object();
|
return &result.as_object();
|
||||||
|
@ -173,7 +173,7 @@ ThrowCompletionOr<PlainDate*> calendar_date_add(GlobalObject& global_object, Obj
|
||||||
// 6. Perform ? RequireInternalSlot(addedDate, [[InitializedTemporalDate]]).
|
// 6. Perform ? RequireInternalSlot(addedDate, [[InitializedTemporalDate]]).
|
||||||
auto* added_date_object = TRY(added_date.to_object(global_object));
|
auto* added_date_object = TRY(added_date.to_object(global_object));
|
||||||
if (!is<PlainDate>(added_date_object))
|
if (!is<PlainDate>(added_date_object))
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::NotAnObjectOfType, "Temporal.PlainDate");
|
return vm.throw_completion<TypeError>(ErrorType::NotAnObjectOfType, "Temporal.PlainDate");
|
||||||
|
|
||||||
// 7. Return addedDate.
|
// 7. Return addedDate.
|
||||||
return static_cast<PlainDate*>(added_date_object);
|
return static_cast<PlainDate*>(added_date_object);
|
||||||
|
@ -196,7 +196,7 @@ ThrowCompletionOr<Duration*> calendar_date_until(GlobalObject& global_object, Ob
|
||||||
// 4. Perform ? RequireInternalSlot(duration, [[InitializedTemporalDuration]]).
|
// 4. Perform ? RequireInternalSlot(duration, [[InitializedTemporalDuration]]).
|
||||||
auto* duration_object = TRY(duration.to_object(global_object));
|
auto* duration_object = TRY(duration.to_object(global_object));
|
||||||
if (!is<Duration>(duration_object))
|
if (!is<Duration>(duration_object))
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::NotAnObjectOfType, "Temporal.Duration");
|
return vm.throw_completion<TypeError>(ErrorType::NotAnObjectOfType, "Temporal.Duration");
|
||||||
|
|
||||||
// 5. Return duration.
|
// 5. Return duration.
|
||||||
return static_cast<Duration*>(duration_object);
|
return static_cast<Duration*>(duration_object);
|
||||||
|
@ -213,7 +213,7 @@ ThrowCompletionOr<double> calendar_year(GlobalObject& global_object, Object& cal
|
||||||
|
|
||||||
// 3. If result is undefined, throw a RangeError exception.
|
// 3. If result is undefined, throw a RangeError exception.
|
||||||
if (result.is_undefined())
|
if (result.is_undefined())
|
||||||
return vm.throw_completion<RangeError>(global_object, ErrorType::TemporalInvalidCalendarFunctionResult, vm.names.year.as_string(), vm.names.undefined.as_string());
|
return vm.throw_completion<RangeError>(ErrorType::TemporalInvalidCalendarFunctionResult, vm.names.year.as_string(), vm.names.undefined.as_string());
|
||||||
|
|
||||||
// 4. Return ? ToIntegerThrowOnInfinity(result).
|
// 4. Return ? ToIntegerThrowOnInfinity(result).
|
||||||
return TRY(to_integer_throw_on_infinity(global_object, result, ErrorType::TemporalInvalidCalendarFunctionResult, vm.names.year.as_string(), vm.names.Infinity.as_string()));
|
return TRY(to_integer_throw_on_infinity(global_object, result, ErrorType::TemporalInvalidCalendarFunctionResult, vm.names.year.as_string(), vm.names.Infinity.as_string()));
|
||||||
|
@ -230,7 +230,7 @@ ThrowCompletionOr<double> calendar_month(GlobalObject& global_object, Object& ca
|
||||||
|
|
||||||
// NOTE: Explicitly handled for a better error message similar to the other calendar property AOs
|
// NOTE: Explicitly handled for a better error message similar to the other calendar property AOs
|
||||||
if (result.is_undefined())
|
if (result.is_undefined())
|
||||||
return vm.throw_completion<RangeError>(global_object, ErrorType::TemporalInvalidCalendarFunctionResult, vm.names.month.as_string(), vm.names.undefined.as_string());
|
return vm.throw_completion<RangeError>(ErrorType::TemporalInvalidCalendarFunctionResult, vm.names.month.as_string(), vm.names.undefined.as_string());
|
||||||
|
|
||||||
// 3. Return ? ToPositiveInteger(result).
|
// 3. Return ? ToPositiveInteger(result).
|
||||||
return TRY(to_positive_integer(global_object, result));
|
return TRY(to_positive_integer(global_object, result));
|
||||||
|
@ -247,7 +247,7 @@ ThrowCompletionOr<String> calendar_month_code(GlobalObject& global_object, Objec
|
||||||
|
|
||||||
// 3. If result is undefined, throw a RangeError exception.
|
// 3. If result is undefined, throw a RangeError exception.
|
||||||
if (result.is_undefined())
|
if (result.is_undefined())
|
||||||
return vm.throw_completion<RangeError>(global_object, ErrorType::TemporalInvalidCalendarFunctionResult, vm.names.monthCode.as_string(), vm.names.undefined.as_string());
|
return vm.throw_completion<RangeError>(ErrorType::TemporalInvalidCalendarFunctionResult, vm.names.monthCode.as_string(), vm.names.undefined.as_string());
|
||||||
|
|
||||||
// 4. Return ? ToString(result).
|
// 4. Return ? ToString(result).
|
||||||
return result.to_string(global_object);
|
return result.to_string(global_object);
|
||||||
|
@ -264,7 +264,7 @@ ThrowCompletionOr<double> calendar_day(GlobalObject& global_object, Object& cale
|
||||||
|
|
||||||
// NOTE: Explicitly handled for a better error message similar to the other calendar property AOs
|
// NOTE: Explicitly handled for a better error message similar to the other calendar property AOs
|
||||||
if (result.is_undefined())
|
if (result.is_undefined())
|
||||||
return vm.throw_completion<RangeError>(global_object, ErrorType::TemporalInvalidCalendarFunctionResult, vm.names.day.as_string(), vm.names.undefined.as_string());
|
return vm.throw_completion<RangeError>(ErrorType::TemporalInvalidCalendarFunctionResult, vm.names.day.as_string(), vm.names.undefined.as_string());
|
||||||
|
|
||||||
// 3. Return ? ToPositiveInteger(result).
|
// 3. Return ? ToPositiveInteger(result).
|
||||||
return TRY(to_positive_integer(global_object, result));
|
return TRY(to_positive_integer(global_object, result));
|
||||||
|
@ -431,7 +431,7 @@ ThrowCompletionOr<Object*> to_temporal_calendar(GlobalObject& global_object, Val
|
||||||
|
|
||||||
// b. If IsBuiltinCalendar(identifier) is false, throw a RangeError exception.
|
// b. If IsBuiltinCalendar(identifier) is false, throw a RangeError exception.
|
||||||
if (!is_builtin_calendar(identifier))
|
if (!is_builtin_calendar(identifier))
|
||||||
return vm.throw_completion<RangeError>(global_object, ErrorType::TemporalInvalidCalendarIdentifier, identifier);
|
return vm.throw_completion<RangeError>(ErrorType::TemporalInvalidCalendarIdentifier, identifier);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 4. Return ! CreateTemporalCalendar(identifier).
|
// 4. Return ! CreateTemporalCalendar(identifier).
|
||||||
|
@ -490,7 +490,7 @@ ThrowCompletionOr<PlainDate*> calendar_date_from_fields(GlobalObject& global_obj
|
||||||
// 3. Perform ? RequireInternalSlot(date, [[InitializedTemporalDate]]).
|
// 3. Perform ? RequireInternalSlot(date, [[InitializedTemporalDate]]).
|
||||||
auto* date_object = TRY(date.to_object(global_object));
|
auto* date_object = TRY(date.to_object(global_object));
|
||||||
if (!is<PlainDate>(date_object))
|
if (!is<PlainDate>(date_object))
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::NotAnObjectOfType, "Temporal.PlainDate");
|
return vm.throw_completion<TypeError>(ErrorType::NotAnObjectOfType, "Temporal.PlainDate");
|
||||||
|
|
||||||
// 4. Return date.
|
// 4. Return date.
|
||||||
return static_cast<PlainDate*>(date_object);
|
return static_cast<PlainDate*>(date_object);
|
||||||
|
@ -509,7 +509,7 @@ ThrowCompletionOr<PlainYearMonth*> calendar_year_month_from_fields(GlobalObject&
|
||||||
// 3. Perform ? RequireInternalSlot(yearMonth, [[InitializedTemporalYearMonth]]).
|
// 3. Perform ? RequireInternalSlot(yearMonth, [[InitializedTemporalYearMonth]]).
|
||||||
auto* year_month_object = TRY(year_month.to_object(global_object));
|
auto* year_month_object = TRY(year_month.to_object(global_object));
|
||||||
if (!is<PlainYearMonth>(year_month_object))
|
if (!is<PlainYearMonth>(year_month_object))
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::NotAnObjectOfType, "Temporal.PlainYearMonth");
|
return vm.throw_completion<TypeError>(ErrorType::NotAnObjectOfType, "Temporal.PlainYearMonth");
|
||||||
|
|
||||||
// 4. Return yearMonth.
|
// 4. Return yearMonth.
|
||||||
return static_cast<PlainYearMonth*>(year_month_object);
|
return static_cast<PlainYearMonth*>(year_month_object);
|
||||||
|
@ -528,7 +528,7 @@ ThrowCompletionOr<PlainMonthDay*> calendar_month_day_from_fields(GlobalObject& g
|
||||||
// 3. Perform ? RequireInternalSlot(monthDay, [[InitializedTemporalMonthDay]]).
|
// 3. Perform ? RequireInternalSlot(monthDay, [[InitializedTemporalMonthDay]]).
|
||||||
auto* month_day_object = TRY(month_day.to_object(global_object));
|
auto* month_day_object = TRY(month_day.to_object(global_object));
|
||||||
if (!is<PlainMonthDay>(month_day_object))
|
if (!is<PlainMonthDay>(month_day_object))
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::NotAnObjectOfType, "Temporal.PlainMonthDay");
|
return vm.throw_completion<TypeError>(ErrorType::NotAnObjectOfType, "Temporal.PlainMonthDay");
|
||||||
|
|
||||||
// 4. Return monthDay.
|
// 4. Return monthDay.
|
||||||
return static_cast<PlainMonthDay*>(month_day_object);
|
return static_cast<PlainMonthDay*>(month_day_object);
|
||||||
|
@ -600,7 +600,7 @@ ThrowCompletionOr<Object*> consolidate_calendars(GlobalObject& global_object, Ob
|
||||||
return &one;
|
return &one;
|
||||||
|
|
||||||
// 7. Throw a RangeError exception.
|
// 7. Throw a RangeError exception.
|
||||||
return vm.throw_completion<RangeError>(global_object, ErrorType::TemporalInvalidCalendar);
|
return vm.throw_completion<RangeError>(ErrorType::TemporalInvalidCalendar);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 12.2.29 ISODaysInMonth ( year, month ), https://tc39.es/proposal-temporal/#sec-temporal-isodaysinmonth
|
// 12.2.29 ISODaysInMonth ( year, month ), https://tc39.es/proposal-temporal/#sec-temporal-isodaysinmonth
|
||||||
|
@ -683,7 +683,7 @@ ThrowCompletionOr<double> resolve_iso_month(GlobalObject& global_object, Object
|
||||||
if (month_code.is_undefined()) {
|
if (month_code.is_undefined()) {
|
||||||
// a. If month is undefined, throw a TypeError exception.
|
// a. If month is undefined, throw a TypeError exception.
|
||||||
if (month.is_undefined())
|
if (month.is_undefined())
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::MissingRequiredProperty, vm.names.month.as_string());
|
return vm.throw_completion<TypeError>(ErrorType::MissingRequiredProperty, vm.names.month.as_string());
|
||||||
|
|
||||||
// b. Assert: Type(month) is Number.
|
// b. Assert: Type(month) is Number.
|
||||||
VERIFY(month.is_number());
|
VERIFY(month.is_number());
|
||||||
|
@ -701,7 +701,7 @@ ThrowCompletionOr<double> resolve_iso_month(GlobalObject& global_object, Object
|
||||||
|
|
||||||
// 7. If monthLength is not 3, throw a RangeError exception.
|
// 7. If monthLength is not 3, throw a RangeError exception.
|
||||||
if (month_length != 3)
|
if (month_length != 3)
|
||||||
return vm.throw_completion<RangeError>(global_object, ErrorType::TemporalInvalidMonthCode);
|
return vm.throw_completion<RangeError>(ErrorType::TemporalInvalidMonthCode);
|
||||||
|
|
||||||
// 8. Let numberPart be the substring of monthCode from 1.
|
// 8. Let numberPart be the substring of monthCode from 1.
|
||||||
auto number_part = month_code_string.substring(1);
|
auto number_part = month_code_string.substring(1);
|
||||||
|
@ -711,18 +711,18 @@ ThrowCompletionOr<double> resolve_iso_month(GlobalObject& global_object, Object
|
||||||
|
|
||||||
// 10. If numberPart < 1 or numberPart > 12, throw a RangeError exception.
|
// 10. If numberPart < 1 or numberPart > 12, throw a RangeError exception.
|
||||||
if (number_part_integer < 1 || number_part_integer > 12)
|
if (number_part_integer < 1 || number_part_integer > 12)
|
||||||
return vm.throw_completion<RangeError>(global_object, ErrorType::TemporalInvalidMonthCode);
|
return vm.throw_completion<RangeError>(ErrorType::TemporalInvalidMonthCode);
|
||||||
|
|
||||||
// 11. If month is not undefined and month ≠ numberPart, then
|
// 11. If month is not undefined and month ≠ numberPart, then
|
||||||
if (!month.is_undefined() && month.as_double() != number_part_integer) {
|
if (!month.is_undefined() && month.as_double() != number_part_integer) {
|
||||||
// a. Throw a RangeError exception.
|
// a. Throw a RangeError exception.
|
||||||
return vm.throw_completion<RangeError>(global_object, ErrorType::TemporalInvalidMonthCode);
|
return vm.throw_completion<RangeError>(ErrorType::TemporalInvalidMonthCode);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 12. If SameValueNonNumeric(monthCode, ! BuildISOMonthCode(numberPart)) is false, then
|
// 12. If SameValueNonNumeric(monthCode, ! BuildISOMonthCode(numberPart)) is false, then
|
||||||
if (month_code_string != build_iso_month_code(number_part_integer)) {
|
if (month_code_string != build_iso_month_code(number_part_integer)) {
|
||||||
// a. Throw a RangeError exception.
|
// a. Throw a RangeError exception.
|
||||||
return vm.throw_completion<RangeError>(global_object, ErrorType::TemporalInvalidMonthCode);
|
return vm.throw_completion<RangeError>(ErrorType::TemporalInvalidMonthCode);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 13. Return numberPart.
|
// 13. Return numberPart.
|
||||||
|
@ -815,7 +815,7 @@ ThrowCompletionOr<ISOMonthDay> iso_month_day_from_fields(GlobalObject& global_ob
|
||||||
// 7. If month is not undefined, and monthCode and year are both undefined, then
|
// 7. If month is not undefined, and monthCode and year are both undefined, then
|
||||||
if (!month_value.is_undefined() && month_code.is_undefined() && year.is_undefined()) {
|
if (!month_value.is_undefined() && month_code.is_undefined() && year.is_undefined()) {
|
||||||
// a. Throw a TypeError exception.
|
// a. Throw a TypeError exception.
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::MissingRequiredProperty, "monthCode or year");
|
return vm.throw_completion<TypeError>(ErrorType::MissingRequiredProperty, "monthCode or year");
|
||||||
}
|
}
|
||||||
|
|
||||||
// 8. Set month to ? ResolveISOMonth(fields).
|
// 8. Set month to ? ResolveISOMonth(fields).
|
||||||
|
|
|
@ -38,7 +38,7 @@ ThrowCompletionOr<Value> CalendarConstructor::call()
|
||||||
|
|
||||||
// 1. If NewTarget is undefined, then
|
// 1. If NewTarget is undefined, then
|
||||||
// a. Throw a TypeError exception.
|
// a. Throw a TypeError exception.
|
||||||
return vm.throw_completion<TypeError>(global_object(), ErrorType::ConstructorWithoutNew, "Temporal.Calendar");
|
return vm.throw_completion<TypeError>(ErrorType::ConstructorWithoutNew, "Temporal.Calendar");
|
||||||
}
|
}
|
||||||
|
|
||||||
// 12.2.1 Temporal.Calendar ( id ), https://tc39.es/proposal-temporal/#sec-temporal.calendar
|
// 12.2.1 Temporal.Calendar ( id ), https://tc39.es/proposal-temporal/#sec-temporal.calendar
|
||||||
|
@ -53,7 +53,7 @@ ThrowCompletionOr<Object*> CalendarConstructor::construct(FunctionObject& new_ta
|
||||||
// 3. If IsBuiltinCalendar(id) is false, then
|
// 3. If IsBuiltinCalendar(id) is false, then
|
||||||
if (!is_builtin_calendar(identifier)) {
|
if (!is_builtin_calendar(identifier)) {
|
||||||
// a. Throw a RangeError exception.
|
// a. Throw a RangeError exception.
|
||||||
return vm.throw_completion<RangeError>(global_object, ErrorType::TemporalInvalidCalendarIdentifier, identifier);
|
return vm.throw_completion<RangeError>(ErrorType::TemporalInvalidCalendarIdentifier, identifier);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 4. Return ? CreateTemporalCalendar(id, NewTarget).
|
// 4. Return ? CreateTemporalCalendar(id, NewTarget).
|
||||||
|
|
|
@ -87,7 +87,7 @@ JS_DEFINE_NATIVE_FUNCTION(CalendarPrototype::date_from_fields)
|
||||||
// 4. If Type(fields) is not Object, throw a TypeError exception.
|
// 4. If Type(fields) is not Object, throw a TypeError exception.
|
||||||
auto fields = vm.argument(0);
|
auto fields = vm.argument(0);
|
||||||
if (!fields.is_object())
|
if (!fields.is_object())
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::NotAnObject, fields.to_string_without_side_effects());
|
return vm.throw_completion<TypeError>(ErrorType::NotAnObject, fields.to_string_without_side_effects());
|
||||||
|
|
||||||
// 5. Set options to ? GetOptionsObject(options).
|
// 5. Set options to ? GetOptionsObject(options).
|
||||||
auto const* options = TRY(get_options_object(global_object, vm.argument(1)));
|
auto const* options = TRY(get_options_object(global_object, vm.argument(1)));
|
||||||
|
@ -113,7 +113,7 @@ JS_DEFINE_NATIVE_FUNCTION(CalendarPrototype::year_month_from_fields)
|
||||||
// 4. If Type(fields) is not Object, throw a TypeError exception.
|
// 4. If Type(fields) is not Object, throw a TypeError exception.
|
||||||
auto fields = vm.argument(0);
|
auto fields = vm.argument(0);
|
||||||
if (!fields.is_object())
|
if (!fields.is_object())
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::NotAnObject, fields.to_string_without_side_effects());
|
return vm.throw_completion<TypeError>(ErrorType::NotAnObject, fields.to_string_without_side_effects());
|
||||||
|
|
||||||
// 5. Set options to ? GetOptionsObject(options).
|
// 5. Set options to ? GetOptionsObject(options).
|
||||||
auto const* options = TRY(get_options_object(global_object, vm.argument(1)));
|
auto const* options = TRY(get_options_object(global_object, vm.argument(1)));
|
||||||
|
@ -139,7 +139,7 @@ JS_DEFINE_NATIVE_FUNCTION(CalendarPrototype::month_day_from_fields)
|
||||||
// 4. If Type(fields) is not Object, throw a TypeError exception.
|
// 4. If Type(fields) is not Object, throw a TypeError exception.
|
||||||
auto fields = vm.argument(0);
|
auto fields = vm.argument(0);
|
||||||
if (!fields.is_object())
|
if (!fields.is_object())
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::NotAnObject, fields.to_string_without_side_effects());
|
return vm.throw_completion<TypeError>(ErrorType::NotAnObject, fields.to_string_without_side_effects());
|
||||||
|
|
||||||
// 5. Set options to ? GetOptionsObject(options).
|
// 5. Set options to ? GetOptionsObject(options).
|
||||||
auto const* options = TRY(get_options_object(global_object, vm.argument(1)));
|
auto const* options = TRY(get_options_object(global_object, vm.argument(1)));
|
||||||
|
@ -257,7 +257,7 @@ JS_DEFINE_NATIVE_FUNCTION(CalendarPrototype::month)
|
||||||
// 4. If Type(temporalDateLike) is Object and temporalDateLike has an [[InitializedTemporalMonthDay]] internal slot, then
|
// 4. If Type(temporalDateLike) is Object and temporalDateLike has an [[InitializedTemporalMonthDay]] internal slot, then
|
||||||
if (temporal_date_like.is_object() && is<PlainMonthDay>(temporal_date_like.as_object())) {
|
if (temporal_date_like.is_object() && is<PlainMonthDay>(temporal_date_like.as_object())) {
|
||||||
// a. Throw a TypeError exception.
|
// a. Throw a TypeError exception.
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::TemporalAmbiguousMonthOfPlainMonthDay);
|
return vm.throw_completion<TypeError>(ErrorType::TemporalAmbiguousMonthOfPlainMonthDay);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 5. If Type(temporalDateLike) is not Object or temporalDateLike does not have an [[InitializedTemporalDate]], [[InitializedTemporalDateTime]], or [[InitializedTemporalYearMonth]] internal slot, then
|
// 5. If Type(temporalDateLike) is not Object or temporalDateLike does not have an [[InitializedTemporalDate]], [[InitializedTemporalDateTime]], or [[InitializedTemporalYearMonth]] internal slot, then
|
||||||
|
@ -534,7 +534,7 @@ JS_DEFINE_NATIVE_FUNCTION(CalendarPrototype::fields)
|
||||||
// ii. If Type(nextValue) is not String, then
|
// ii. If Type(nextValue) is not String, then
|
||||||
if (!next_value.is_string()) {
|
if (!next_value.is_string()) {
|
||||||
// 1. Let completion be ThrowCompletion(a newly created TypeError object).
|
// 1. Let completion be ThrowCompletion(a newly created TypeError object).
|
||||||
auto completion = vm.throw_completion<TypeError>(global_object, ErrorType::TemporalInvalidCalendarFieldValue, next_value.to_string_without_side_effects());
|
auto completion = vm.throw_completion<TypeError>(ErrorType::TemporalInvalidCalendarFieldValue, next_value.to_string_without_side_effects());
|
||||||
|
|
||||||
// 2. Return ? IteratorClose(iteratorRecord, completion).
|
// 2. Return ? IteratorClose(iteratorRecord, completion).
|
||||||
return TRY(iterator_close(global_object, iterator_record, move(completion)));
|
return TRY(iterator_close(global_object, iterator_record, move(completion)));
|
||||||
|
@ -543,7 +543,7 @@ JS_DEFINE_NATIVE_FUNCTION(CalendarPrototype::fields)
|
||||||
// iii. If fieldNames contains nextValue, then
|
// iii. If fieldNames contains nextValue, then
|
||||||
if (field_names.contains_slow(next_value)) {
|
if (field_names.contains_slow(next_value)) {
|
||||||
// 1. Let completion be ThrowCompletion(a newly created RangeError object).
|
// 1. Let completion be ThrowCompletion(a newly created RangeError object).
|
||||||
auto completion = vm.throw_completion<RangeError>(global_object, ErrorType::TemporalDuplicateCalendarField, next_value.as_string().string());
|
auto completion = vm.throw_completion<RangeError>(ErrorType::TemporalDuplicateCalendarField, next_value.as_string().string());
|
||||||
|
|
||||||
// 2. Return ? IteratorClose(iteratorRecord, completion).
|
// 2. Return ? IteratorClose(iteratorRecord, completion).
|
||||||
return TRY(iterator_close(global_object, iterator_record, move(completion)));
|
return TRY(iterator_close(global_object, iterator_record, move(completion)));
|
||||||
|
@ -552,7 +552,7 @@ JS_DEFINE_NATIVE_FUNCTION(CalendarPrototype::fields)
|
||||||
// iv. If nextValue is not one of "year", "month", "monthCode", "day", "hour", "minute", "second", "millisecond", "microsecond", "nanosecond", then
|
// iv. If nextValue is not one of "year", "month", "monthCode", "day", "hour", "minute", "second", "millisecond", "microsecond", "nanosecond", then
|
||||||
if (!next_value.as_string().string().is_one_of("year"sv, "month"sv, "monthCode"sv, "day"sv, "hour"sv, "minute"sv, "second"sv, "millisecond"sv, "microsecond"sv, "nanosecond"sv)) {
|
if (!next_value.as_string().string().is_one_of("year"sv, "month"sv, "monthCode"sv, "day"sv, "hour"sv, "minute"sv, "second"sv, "millisecond"sv, "microsecond"sv, "nanosecond"sv)) {
|
||||||
// 1. Let completion be ThrowCompletion(a newly created RangeError object).
|
// 1. Let completion be ThrowCompletion(a newly created RangeError object).
|
||||||
auto completion = vm.throw_completion<RangeError>(global_object, ErrorType::TemporalInvalidCalendarFieldName, next_value.as_string().string());
|
auto completion = vm.throw_completion<RangeError>(ErrorType::TemporalInvalidCalendarFieldName, next_value.as_string().string());
|
||||||
|
|
||||||
// 2. Return ? IteratorClose(iteratorRecord, completion).
|
// 2. Return ? IteratorClose(iteratorRecord, completion).
|
||||||
return TRY(iterator_close(global_object, iterator_record, move(completion)));
|
return TRY(iterator_close(global_object, iterator_record, move(completion)));
|
||||||
|
|
|
@ -84,7 +84,7 @@ ThrowCompletionOr<DurationRecord> create_duration_record(GlobalObject& global_ob
|
||||||
|
|
||||||
// 1. If ! IsValidDuration(years, months, weeks, days, hours, minutes, seconds, milliseconds, microseconds, nanoseconds) is false, throw a RangeError exception.
|
// 1. If ! IsValidDuration(years, months, weeks, days, hours, minutes, seconds, milliseconds, microseconds, nanoseconds) is false, throw a RangeError exception.
|
||||||
if (!is_valid_duration(years, months, weeks, days, hours, minutes, seconds, milliseconds, microseconds, nanoseconds))
|
if (!is_valid_duration(years, months, weeks, days, hours, minutes, seconds, milliseconds, microseconds, nanoseconds))
|
||||||
return vm.throw_completion<RangeError>(global_object, ErrorType::TemporalInvalidDuration);
|
return vm.throw_completion<RangeError>(ErrorType::TemporalInvalidDuration);
|
||||||
|
|
||||||
// 2. Return the Record { [[Years]]: ℝ(𝔽(years)), [[Months]]: ℝ(𝔽(months)), [[Weeks]]: ℝ(𝔽(weeks)), [[Days]]: ℝ(𝔽(days)), [[Hours]]: ℝ(𝔽(hours)), [[Minutes]]: ℝ(𝔽(minutes)), [[Seconds]]: ℝ(𝔽(seconds)), [[Milliseconds]]: ℝ(𝔽(milliseconds)), [[Microseconds]]: ℝ(𝔽(microseconds)), [[Nanoseconds]]: ℝ(𝔽(nanoseconds)) }.
|
// 2. Return the Record { [[Years]]: ℝ(𝔽(years)), [[Months]]: ℝ(𝔽(months)), [[Weeks]]: ℝ(𝔽(weeks)), [[Days]]: ℝ(𝔽(days)), [[Hours]]: ℝ(𝔽(hours)), [[Minutes]]: ℝ(𝔽(minutes)), [[Seconds]]: ℝ(𝔽(seconds)), [[Milliseconds]]: ℝ(𝔽(milliseconds)), [[Microseconds]]: ℝ(𝔽(microseconds)), [[Nanoseconds]]: ℝ(𝔽(nanoseconds)) }.
|
||||||
return DurationRecord { .years = years, .months = months, .weeks = weeks, .days = days, .hours = hours, .minutes = minutes, .seconds = seconds, .milliseconds = milliseconds, .microseconds = microseconds, .nanoseconds = nanoseconds };
|
return DurationRecord { .years = years, .months = months, .weeks = weeks, .days = days, .hours = hours, .minutes = minutes, .seconds = seconds, .milliseconds = milliseconds, .microseconds = microseconds, .nanoseconds = nanoseconds };
|
||||||
|
@ -107,7 +107,7 @@ ThrowCompletionOr<DateDurationRecord> create_date_duration_record(GlobalObject&
|
||||||
|
|
||||||
// 1. If ! IsValidDuration(years, months, weeks, days, 0, 0, 0, 0, 0, 0) is false, throw a RangeError exception.
|
// 1. If ! IsValidDuration(years, months, weeks, days, 0, 0, 0, 0, 0, 0) is false, throw a RangeError exception.
|
||||||
if (!is_valid_duration(years, months, weeks, days, 0, 0, 0, 0, 0, 0))
|
if (!is_valid_duration(years, months, weeks, days, 0, 0, 0, 0, 0, 0))
|
||||||
return vm.throw_completion<RangeError>(global_object, ErrorType::TemporalInvalidDuration);
|
return vm.throw_completion<RangeError>(ErrorType::TemporalInvalidDuration);
|
||||||
|
|
||||||
// 2. Return the Record { [[Years]]: ℝ(𝔽(years)), [[Months]]: ℝ(𝔽(months)), [[Weeks]]: ℝ(𝔽(weeks)), [[Days]]: ℝ(𝔽(days)) }.
|
// 2. Return the Record { [[Years]]: ℝ(𝔽(years)), [[Months]]: ℝ(𝔽(months)), [[Weeks]]: ℝ(𝔽(weeks)), [[Days]]: ℝ(𝔽(days)) }.
|
||||||
return DateDurationRecord { .years = years, .months = months, .weeks = weeks, .days = days };
|
return DateDurationRecord { .years = years, .months = months, .weeks = weeks, .days = days };
|
||||||
|
@ -120,7 +120,7 @@ ThrowCompletionOr<TimeDurationRecord> create_time_duration_record(GlobalObject&
|
||||||
|
|
||||||
// 1. If ! IsValidDuration(0, 0, 0, days, hours, minutes, seconds, milliseconds, microseconds, nanoseconds) is false, throw a RangeError exception.
|
// 1. If ! IsValidDuration(0, 0, 0, days, hours, minutes, seconds, milliseconds, microseconds, nanoseconds) is false, throw a RangeError exception.
|
||||||
if (!is_valid_duration(0, 0, 0, days, hours, minutes, seconds, milliseconds, microseconds, nanoseconds))
|
if (!is_valid_duration(0, 0, 0, days, hours, minutes, seconds, milliseconds, microseconds, nanoseconds))
|
||||||
return vm.throw_completion<RangeError>(global_object, ErrorType::TemporalInvalidDuration);
|
return vm.throw_completion<RangeError>(ErrorType::TemporalInvalidDuration);
|
||||||
|
|
||||||
// 2. Return the Record { [[Days]]: ℝ(𝔽(days)), [[Hours]]: ℝ(𝔽(hours)), [[Minutes]]: ℝ(𝔽(minutes)), [[Seconds]]: ℝ(𝔽(seconds)), [[Milliseconds]]: ℝ(𝔽(milliseconds)), [[Microseconds]]: ℝ(𝔽(microseconds)), [[Nanoseconds]]: ℝ(𝔽(nanoseconds)) }.
|
// 2. Return the Record { [[Days]]: ℝ(𝔽(days)), [[Hours]]: ℝ(𝔽(hours)), [[Minutes]]: ℝ(𝔽(minutes)), [[Seconds]]: ℝ(𝔽(seconds)), [[Milliseconds]]: ℝ(𝔽(milliseconds)), [[Microseconds]]: ℝ(𝔽(microseconds)), [[Nanoseconds]]: ℝ(𝔽(nanoseconds)) }.
|
||||||
return TimeDurationRecord { .days = days, .hours = hours, .minutes = minutes, .seconds = seconds, .milliseconds = milliseconds, .microseconds = microseconds, .nanoseconds = nanoseconds };
|
return TimeDurationRecord { .days = days, .hours = hours, .minutes = minutes, .seconds = seconds, .milliseconds = milliseconds, .microseconds = microseconds, .nanoseconds = nanoseconds };
|
||||||
|
@ -192,7 +192,7 @@ ThrowCompletionOr<DurationRecord> to_temporal_duration_record(GlobalObject& glob
|
||||||
// 6. If ! IsValidDuration(result.[[Years]], result.[[Months]], result.[[Weeks]], result.[[Days]], result.[[Hours]], result.[[Minutes]], result.[[Seconds]], result.[[Milliseconds]], result.[[Microseconds]], result.[[Nanoseconds]]) is false, then
|
// 6. If ! IsValidDuration(result.[[Years]], result.[[Months]], result.[[Weeks]], result.[[Days]], result.[[Hours]], result.[[Minutes]], result.[[Seconds]], result.[[Milliseconds]], result.[[Microseconds]], result.[[Nanoseconds]]) is false, then
|
||||||
if (!is_valid_duration(result.years, result.months, result.weeks, result.days, result.hours, result.minutes, result.seconds, result.milliseconds, result.microseconds, result.nanoseconds)) {
|
if (!is_valid_duration(result.years, result.months, result.weeks, result.days, result.hours, result.minutes, result.seconds, result.milliseconds, result.microseconds, result.nanoseconds)) {
|
||||||
// a. Throw a RangeError exception.
|
// a. Throw a RangeError exception.
|
||||||
return vm.throw_completion<RangeError>(global_object, ErrorType::TemporalInvalidDuration);
|
return vm.throw_completion<RangeError>(ErrorType::TemporalInvalidDuration);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 7. Return result.
|
// 7. Return result.
|
||||||
|
@ -293,7 +293,7 @@ ThrowCompletionOr<PartialDurationRecord> to_temporal_partial_duration_record(Glo
|
||||||
// 1. If Type(temporalDurationLike) is not Object, then
|
// 1. If Type(temporalDurationLike) is not Object, then
|
||||||
if (!temporal_duration_like.is_object()) {
|
if (!temporal_duration_like.is_object()) {
|
||||||
// a. Throw a TypeError exception.
|
// a. Throw a TypeError exception.
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::NotAnObject, temporal_duration_like.to_string_without_side_effects());
|
return vm.throw_completion<TypeError>(ErrorType::NotAnObject, temporal_duration_like.to_string_without_side_effects());
|
||||||
}
|
}
|
||||||
|
|
||||||
// 2. Let result be a new partial Duration Record with each field set to undefined.
|
// 2. Let result be a new partial Duration Record with each field set to undefined.
|
||||||
|
@ -326,7 +326,7 @@ ThrowCompletionOr<PartialDurationRecord> to_temporal_partial_duration_record(Glo
|
||||||
// 5. If any is false, then
|
// 5. If any is false, then
|
||||||
if (!any) {
|
if (!any) {
|
||||||
// a. Throw a TypeError exception.
|
// a. Throw a TypeError exception.
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::TemporalInvalidDurationLikeObject);
|
return vm.throw_completion<TypeError>(ErrorType::TemporalInvalidDurationLikeObject);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 6. Return result.
|
// 6. Return result.
|
||||||
|
@ -340,7 +340,7 @@ ThrowCompletionOr<Duration*> create_temporal_duration(GlobalObject& global_objec
|
||||||
|
|
||||||
// 1. If ! IsValidDuration(years, months, weeks, days, hours, minutes, seconds, milliseconds, microseconds, nanoseconds) is false, throw a RangeError exception.
|
// 1. If ! IsValidDuration(years, months, weeks, days, hours, minutes, seconds, milliseconds, microseconds, nanoseconds) is false, throw a RangeError exception.
|
||||||
if (!is_valid_duration(years, months, weeks, days, hours, minutes, seconds, milliseconds, microseconds, nanoseconds))
|
if (!is_valid_duration(years, months, weeks, days, hours, minutes, seconds, milliseconds, microseconds, nanoseconds))
|
||||||
return vm.throw_completion<RangeError>(global_object, ErrorType::TemporalInvalidDuration);
|
return vm.throw_completion<RangeError>(ErrorType::TemporalInvalidDuration);
|
||||||
|
|
||||||
// 2. If newTarget is not present, set newTarget to %Temporal.Duration%.
|
// 2. If newTarget is not present, set newTarget to %Temporal.Duration%.
|
||||||
if (!new_target)
|
if (!new_target)
|
||||||
|
@ -617,7 +617,7 @@ ThrowCompletionOr<DateDurationRecord> unbalance_duration_relative(GlobalObject&
|
||||||
// a. If calendar is undefined, then
|
// a. If calendar is undefined, then
|
||||||
if (!calendar) {
|
if (!calendar) {
|
||||||
// i. Throw a RangeError exception.
|
// i. Throw a RangeError exception.
|
||||||
return vm.throw_completion<RangeError>(global_object, ErrorType::TemporalMissingStartingPoint, "months");
|
return vm.throw_completion<RangeError>(ErrorType::TemporalMissingStartingPoint, "months");
|
||||||
}
|
}
|
||||||
|
|
||||||
// b. Let dateAdd be ? GetMethod(calendar, "dateAdd").
|
// b. Let dateAdd be ? GetMethod(calendar, "dateAdd").
|
||||||
|
@ -658,7 +658,7 @@ ThrowCompletionOr<DateDurationRecord> unbalance_duration_relative(GlobalObject&
|
||||||
// a. If calendar is undefined, then
|
// a. If calendar is undefined, then
|
||||||
if (!calendar) {
|
if (!calendar) {
|
||||||
// i. Throw a RangeError exception.
|
// i. Throw a RangeError exception.
|
||||||
return vm.throw_completion<RangeError>(global_object, ErrorType::TemporalMissingStartingPoint, "weeks");
|
return vm.throw_completion<RangeError>(ErrorType::TemporalMissingStartingPoint, "weeks");
|
||||||
}
|
}
|
||||||
|
|
||||||
// b. Repeat, while years ≠ 0,
|
// b. Repeat, while years ≠ 0,
|
||||||
|
@ -698,7 +698,7 @@ ThrowCompletionOr<DateDurationRecord> unbalance_duration_relative(GlobalObject&
|
||||||
// i. If calendar is undefined, then
|
// i. If calendar is undefined, then
|
||||||
if (!calendar) {
|
if (!calendar) {
|
||||||
// i. Throw a RangeError exception.
|
// i. Throw a RangeError exception.
|
||||||
return vm.throw_completion<RangeError>(global_object, ErrorType::TemporalMissingStartingPoint, "calendar units");
|
return vm.throw_completion<RangeError>(ErrorType::TemporalMissingStartingPoint, "calendar units");
|
||||||
}
|
}
|
||||||
|
|
||||||
// ii. Repeat, while years ≠ 0,
|
// ii. Repeat, while years ≠ 0,
|
||||||
|
@ -767,7 +767,7 @@ ThrowCompletionOr<DateDurationRecord> balance_duration_relative(GlobalObject& gl
|
||||||
// 2. If relativeTo is undefined, then
|
// 2. If relativeTo is undefined, then
|
||||||
if (relative_to_value.is_undefined()) {
|
if (relative_to_value.is_undefined()) {
|
||||||
// a. Throw a RangeError exception.
|
// a. Throw a RangeError exception.
|
||||||
return vm.throw_completion<RangeError>(global_object, ErrorType::TemporalMissingStartingPoint, "calendar units");
|
return vm.throw_completion<RangeError>(ErrorType::TemporalMissingStartingPoint, "calendar units");
|
||||||
}
|
}
|
||||||
|
|
||||||
// 3. Let sign be ! DurationSign(years, months, weeks, days, 0, 0, 0, 0, 0, 0).
|
// 3. Let sign be ! DurationSign(years, months, weeks, days, 0, 0, 0, 0, 0, 0).
|
||||||
|
@ -995,7 +995,7 @@ ThrowCompletionOr<DurationRecord> add_duration(GlobalObject& global_object, doub
|
||||||
// a. If largestUnit is one of "year", "month", or "week", then
|
// a. If largestUnit is one of "year", "month", or "week", then
|
||||||
if (largest_unit.is_one_of("year"sv, "month"sv, "week"sv)) {
|
if (largest_unit.is_one_of("year"sv, "month"sv, "week"sv)) {
|
||||||
// i. Throw a RangeError exception.
|
// i. Throw a RangeError exception.
|
||||||
return vm.throw_completion<RangeError>(global_object, ErrorType::TemporalMissingStartingPoint, "year, month or week");
|
return vm.throw_completion<RangeError>(ErrorType::TemporalMissingStartingPoint, "year, month or week");
|
||||||
}
|
}
|
||||||
|
|
||||||
// b. Let result be ? BalanceDuration(d1 + d2, h1 + h2, min1 + min2, s1 + s2, ms1 + ms2, mus1 + mus2, ns1 + ns2, largestUnit).
|
// b. Let result be ? BalanceDuration(d1 + d2, h1 + h2, min1 + min2, s1 + s2, ms1 + ms2, mus1 + mus2, ns1 + ns2, largestUnit).
|
||||||
|
@ -1124,7 +1124,7 @@ ThrowCompletionOr<RoundedDuration> round_duration(GlobalObject& global_object, d
|
||||||
// 2. If unit is "year", "month", or "week", and relativeTo is undefined, then
|
// 2. If unit is "year", "month", or "week", and relativeTo is undefined, then
|
||||||
if (unit.is_one_of("year"sv, "month"sv, "week"sv) && !relative_to_object) {
|
if (unit.is_one_of("year"sv, "month"sv, "week"sv) && !relative_to_object) {
|
||||||
// a. Throw a RangeError exception.
|
// a. Throw a RangeError exception.
|
||||||
return vm.throw_completion<RangeError>(global_object, ErrorType::OptionIsNotValidValue, unit, "smallestUnit"sv);
|
return vm.throw_completion<RangeError>(ErrorType::OptionIsNotValidValue, unit, "smallestUnit"sv);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 3. Let zonedRelativeTo be undefined.
|
// 3. Let zonedRelativeTo be undefined.
|
||||||
|
|
|
@ -42,7 +42,7 @@ ThrowCompletionOr<Value> DurationConstructor::call()
|
||||||
|
|
||||||
// 1. If NewTarget is undefined, then
|
// 1. If NewTarget is undefined, then
|
||||||
// a. Throw a TypeError exception.
|
// a. Throw a TypeError exception.
|
||||||
return vm.throw_completion<TypeError>(global_object(), ErrorType::ConstructorWithoutNew, "Temporal.Duration");
|
return vm.throw_completion<TypeError>(ErrorType::ConstructorWithoutNew, "Temporal.Duration");
|
||||||
}
|
}
|
||||||
|
|
||||||
// 7.1.1 Temporal.Duration ( [ years [ , months [ , weeks [ , days [ , hours [ , minutes [ , seconds [ , milliseconds [ , microseconds [ , nanoseconds ] ] ] ] ] ] ] ] ] ] ), https://tc39.es/proposal-temporal/#sec-temporal.duration
|
// 7.1.1 Temporal.Duration ( [ years [ , months [ , weeks [ , days [ , hours [ , minutes [ , seconds [ , milliseconds [ , microseconds [ , nanoseconds ] ] ] ] ] ] ] ] ] ] ), https://tc39.es/proposal-temporal/#sec-temporal.duration
|
||||||
|
|
|
@ -331,7 +331,7 @@ JS_DEFINE_NATIVE_FUNCTION(DurationPrototype::round)
|
||||||
// 3. If roundTo is undefined, then
|
// 3. If roundTo is undefined, then
|
||||||
if (vm.argument(0).is_undefined()) {
|
if (vm.argument(0).is_undefined()) {
|
||||||
// a. Throw a TypeError exception.
|
// a. Throw a TypeError exception.
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::TemporalMissingOptionsObject);
|
return vm.throw_completion<TypeError>(ErrorType::TemporalMissingOptionsObject);
|
||||||
}
|
}
|
||||||
|
|
||||||
Object* round_to;
|
Object* round_to;
|
||||||
|
@ -396,12 +396,12 @@ JS_DEFINE_NATIVE_FUNCTION(DurationPrototype::round)
|
||||||
// 15. If smallestUnitPresent is false and largestUnitPresent is false, then
|
// 15. If smallestUnitPresent is false and largestUnitPresent is false, then
|
||||||
if (!smallest_unit_present && !largest_unit_present) {
|
if (!smallest_unit_present && !largest_unit_present) {
|
||||||
// a. Throw a RangeError exception.
|
// a. Throw a RangeError exception.
|
||||||
return vm.throw_completion<RangeError>(global_object, ErrorType::TemporalMissingUnits);
|
return vm.throw_completion<RangeError>(ErrorType::TemporalMissingUnits);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 16. If LargerOfTwoTemporalUnits(largestUnit, smallestUnit) is not largestUnit, throw a RangeError exception.
|
// 16. If LargerOfTwoTemporalUnits(largestUnit, smallestUnit) is not largestUnit, throw a RangeError exception.
|
||||||
if (larger_of_two_temporal_units(*largest_unit, *smallest_unit) != largest_unit)
|
if (larger_of_two_temporal_units(*largest_unit, *smallest_unit) != largest_unit)
|
||||||
return vm.throw_completion<RangeError>(global_object, ErrorType::TemporalInvalidUnitRange, *smallest_unit, *largest_unit);
|
return vm.throw_completion<RangeError>(ErrorType::TemporalInvalidUnitRange, *smallest_unit, *largest_unit);
|
||||||
|
|
||||||
// 17. Let roundingMode be ? ToTemporalRoundingMode(roundTo, "halfExpand").
|
// 17. Let roundingMode be ? ToTemporalRoundingMode(roundTo, "halfExpand").
|
||||||
auto rounding_mode = TRY(to_temporal_rounding_mode(global_object, *round_to, "halfExpand"sv));
|
auto rounding_mode = TRY(to_temporal_rounding_mode(global_object, *round_to, "halfExpand"sv));
|
||||||
|
@ -454,7 +454,7 @@ JS_DEFINE_NATIVE_FUNCTION(DurationPrototype::total)
|
||||||
|
|
||||||
// 3. If totalOf is undefined, throw a TypeError exception.
|
// 3. If totalOf is undefined, throw a TypeError exception.
|
||||||
if (vm.argument(0).is_undefined())
|
if (vm.argument(0).is_undefined())
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::TemporalMissingOptionsObject);
|
return vm.throw_completion<TypeError>(ErrorType::TemporalMissingOptionsObject);
|
||||||
|
|
||||||
Object* total_of;
|
Object* total_of;
|
||||||
|
|
||||||
|
@ -578,7 +578,7 @@ JS_DEFINE_NATIVE_FUNCTION(DurationPrototype::to_string)
|
||||||
|
|
||||||
// 5. If precision.[[Unit]] is "minute", throw a RangeError exception.
|
// 5. If precision.[[Unit]] is "minute", throw a RangeError exception.
|
||||||
if (precision.unit == "minute"sv)
|
if (precision.unit == "minute"sv)
|
||||||
return vm.throw_completion<RangeError>(global_object, ErrorType::OptionIsNotValidValue, "minute"sv, "smallestUnit"sv);
|
return vm.throw_completion<RangeError>(ErrorType::OptionIsNotValidValue, "minute"sv, "smallestUnit"sv);
|
||||||
|
|
||||||
// 6. Let roundingMode be ? ToTemporalRoundingMode(options, "trunc").
|
// 6. Let roundingMode be ? ToTemporalRoundingMode(options, "trunc").
|
||||||
auto rounding_mode = TRY(to_temporal_rounding_mode(global_object, *options, "trunc"sv));
|
auto rounding_mode = TRY(to_temporal_rounding_mode(global_object, *options, "trunc"sv));
|
||||||
|
@ -617,7 +617,7 @@ JS_DEFINE_NATIVE_FUNCTION(DurationPrototype::to_locale_string)
|
||||||
JS_DEFINE_NATIVE_FUNCTION(DurationPrototype::value_of)
|
JS_DEFINE_NATIVE_FUNCTION(DurationPrototype::value_of)
|
||||||
{
|
{
|
||||||
// 1. Throw a TypeError exception.
|
// 1. Throw a TypeError exception.
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::Convert, "Temporal.Duration", "a primitive value");
|
return vm.throw_completion<TypeError>(ErrorType::Convert, "Temporal.Duration", "a primitive value");
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -127,7 +127,7 @@ ThrowCompletionOr<BigInt*> parse_temporal_instant(GlobalObject& global_object, S
|
||||||
// 8. If ! IsValidEpochNanoseconds(result) is false, then
|
// 8. If ! IsValidEpochNanoseconds(result) is false, then
|
||||||
if (!is_valid_epoch_nanoseconds(*result_ns)) {
|
if (!is_valid_epoch_nanoseconds(*result_ns)) {
|
||||||
// a. Throw a RangeError exception.
|
// a. Throw a RangeError exception.
|
||||||
return vm.throw_completion<RangeError>(global_object, ErrorType::TemporalInvalidEpochNanoseconds);
|
return vm.throw_completion<RangeError>(ErrorType::TemporalInvalidEpochNanoseconds);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 9. Return result.
|
// 9. Return result.
|
||||||
|
@ -169,7 +169,7 @@ ThrowCompletionOr<BigInt*> add_instant(GlobalObject& global_object, BigInt const
|
||||||
|
|
||||||
// 2. If ! IsValidEpochNanoseconds(result) is false, throw a RangeError exception.
|
// 2. If ! IsValidEpochNanoseconds(result) is false, throw a RangeError exception.
|
||||||
if (!is_valid_epoch_nanoseconds(*result))
|
if (!is_valid_epoch_nanoseconds(*result))
|
||||||
return vm.throw_completion<RangeError>(global_object, ErrorType::TemporalInvalidEpochNanoseconds);
|
return vm.throw_completion<RangeError>(ErrorType::TemporalInvalidEpochNanoseconds);
|
||||||
|
|
||||||
// 3. Return result.
|
// 3. Return result.
|
||||||
return result;
|
return result;
|
||||||
|
@ -314,19 +314,19 @@ ThrowCompletionOr<Instant*> add_duration_to_or_subtract_duration_from_instant(Gl
|
||||||
|
|
||||||
// 3. If duration.[[Days]] is not 0, throw a RangeError exception.
|
// 3. If duration.[[Days]] is not 0, throw a RangeError exception.
|
||||||
if (duration.days != 0)
|
if (duration.days != 0)
|
||||||
return vm.throw_completion<RangeError>(global_object, ErrorType::TemporalInvalidDurationPropertyValueNonZero, "days", duration.days);
|
return vm.throw_completion<RangeError>(ErrorType::TemporalInvalidDurationPropertyValueNonZero, "days", duration.days);
|
||||||
|
|
||||||
// 4. If duration.[[Months]] is not 0, throw a RangeError exception.
|
// 4. If duration.[[Months]] is not 0, throw a RangeError exception.
|
||||||
if (duration.months != 0)
|
if (duration.months != 0)
|
||||||
return vm.throw_completion<RangeError>(global_object, ErrorType::TemporalInvalidDurationPropertyValueNonZero, "months", duration.months);
|
return vm.throw_completion<RangeError>(ErrorType::TemporalInvalidDurationPropertyValueNonZero, "months", duration.months);
|
||||||
|
|
||||||
// 5. If duration.[[Weeks]] is not 0, throw a RangeError exception.
|
// 5. If duration.[[Weeks]] is not 0, throw a RangeError exception.
|
||||||
if (duration.weeks != 0)
|
if (duration.weeks != 0)
|
||||||
return vm.throw_completion<RangeError>(global_object, ErrorType::TemporalInvalidDurationPropertyValueNonZero, "weeks", duration.weeks);
|
return vm.throw_completion<RangeError>(ErrorType::TemporalInvalidDurationPropertyValueNonZero, "weeks", duration.weeks);
|
||||||
|
|
||||||
// 6. If duration.[[Years]] is not 0, throw a RangeError exception.
|
// 6. If duration.[[Years]] is not 0, throw a RangeError exception.
|
||||||
if (duration.years != 0)
|
if (duration.years != 0)
|
||||||
return vm.throw_completion<RangeError>(global_object, ErrorType::TemporalInvalidDurationPropertyValueNonZero, "years", duration.years);
|
return vm.throw_completion<RangeError>(ErrorType::TemporalInvalidDurationPropertyValueNonZero, "years", duration.years);
|
||||||
|
|
||||||
// 7. Let ns be ? AddInstant(instant.[[Nanoseconds]], sign × duration.[[Hours]], sign × duration.[[Minutes]], sign × duration.[[Seconds]], sign × duration.[[Milliseconds]], sign × duration.[[Microseconds]], sign × duration.[[Nanoseconds]]).
|
// 7. Let ns be ? AddInstant(instant.[[Nanoseconds]], sign × duration.[[Hours]], sign × duration.[[Minutes]], sign × duration.[[Seconds]], sign × duration.[[Milliseconds]], sign × duration.[[Microseconds]], sign × duration.[[Nanoseconds]]).
|
||||||
auto* ns = TRY(add_instant(global_object, instant.nanoseconds(), sign * duration.hours, sign * duration.minutes, sign * duration.seconds, sign * duration.milliseconds, sign * duration.microseconds, sign * duration.nanoseconds));
|
auto* ns = TRY(add_instant(global_object, instant.nanoseconds(), sign * duration.hours, sign * duration.minutes, sign * duration.seconds, sign * duration.milliseconds, sign * duration.microseconds, sign * duration.nanoseconds));
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue