LibJS+LibWeb: Replace GlobalObject with Realm in create() functions
This is a continuation of the previous two commits. As allocating a JS cell already primarily involves a realm instead of a global object, and we'll need to pass one to the allocate() function itself eventually (it's bridged via the global object right now), the create() functions need to receive a realm as well. The plan is for this to be the highest-level function that actually receives a realm and passes it around, AOs on an even higher level will use the "current realm" concept via VM::current_realm() as that's what the spec assumes; passing around realms (or global objects, for that matter) on higher AO levels is pointless and unlike for allocating individual objects, which may happen outside of regular JS execution, we don't need control over the specific realm that is being used there.
This commit is contained in:
parent
5dd5896588
commit
b99cc7d050
Notes:
sideshowbarker
2024-07-19 01:59:31 +09:00
Author: https://github.com/linusg Commit: https://github.com/SerenityOS/serenity/commit/b99cc7d050 Pull-request: https://github.com/SerenityOS/serenity/pull/14973 Reviewed-by: https://github.com/davidot ✅
178 changed files with 883 additions and 609 deletions
|
@ -557,7 +557,7 @@ static void generate_to_cpp(SourceGenerator& generator, ParameterType& parameter
|
||||||
// anything of this sort. Both Gecko and Blink do it, however, so I'm sure it's correct.
|
// anything of this sort. Both Gecko and Blink do it, however, so I'm sure it's correct.
|
||||||
scoped_generator.append(R"~~~(
|
scoped_generator.append(R"~~~(
|
||||||
if (!@js_name@@js_suffix@.is_object() || !is<JS::Promise>(@js_name@@js_suffix@.as_object())) {
|
if (!@js_name@@js_suffix@.is_object() || !is<JS::Promise>(@js_name@@js_suffix@.as_object())) {
|
||||||
auto* new_promise = JS::Promise::create(global_object);
|
auto* new_promise = JS::Promise::create(realm);
|
||||||
new_promise->fulfill(@js_name@@js_suffix@);
|
new_promise->fulfill(@js_name@@js_suffix@);
|
||||||
@js_name@@js_suffix@ = new_promise;
|
@js_name@@js_suffix@ = new_promise;
|
||||||
}
|
}
|
||||||
|
@ -1444,7 +1444,7 @@ static void generate_wrap_statement(SourceGenerator& generator, String const& va
|
||||||
auto& sequence_generic_type = verify_cast<IDL::ParameterizedType>(type);
|
auto& sequence_generic_type = verify_cast<IDL::ParameterizedType>(type);
|
||||||
|
|
||||||
scoped_generator.append(R"~~~(
|
scoped_generator.append(R"~~~(
|
||||||
auto* new_array@recursion_depth@ = MUST(JS::Array::create(global_object, 0));
|
auto* new_array@recursion_depth@ = MUST(JS::Array::create(realm, 0));
|
||||||
)~~~");
|
)~~~");
|
||||||
|
|
||||||
if (!type.nullable) {
|
if (!type.nullable) {
|
||||||
|
@ -1572,7 +1572,7 @@ static void generate_wrap_statement(SourceGenerator& generator, String const& va
|
||||||
auto dictionary_generator = scoped_generator.fork();
|
auto dictionary_generator = scoped_generator.fork();
|
||||||
|
|
||||||
dictionary_generator.append(R"~~~(
|
dictionary_generator.append(R"~~~(
|
||||||
auto* dictionary_object@recursion_depth@ = JS::Object::create(global_object, global_object.object_prototype());
|
auto* dictionary_object@recursion_depth@ = JS::Object::create(realm, global_object.object_prototype());
|
||||||
)~~~");
|
)~~~");
|
||||||
|
|
||||||
auto* current_dictionary = &interface.dictionaries.find(type.name)->value;
|
auto* current_dictionary = &interface.dictionaries.find(type.name)->value;
|
||||||
|
@ -1664,6 +1664,7 @@ static void generate_function(SourceGenerator& generator, IDL::Function const& f
|
||||||
function_generator.append(R"~~~(
|
function_generator.append(R"~~~(
|
||||||
JS_DEFINE_NATIVE_FUNCTION(@class_name@::@function.name:snakecase@@overload_suffix@)
|
JS_DEFINE_NATIVE_FUNCTION(@class_name@::@function.name:snakecase@@overload_suffix@)
|
||||||
{
|
{
|
||||||
|
[[maybe_unused]] auto& realm = *global_object.associated_realm();
|
||||||
)~~~");
|
)~~~");
|
||||||
|
|
||||||
if (is_static_function == StaticFunction::No) {
|
if (is_static_function == StaticFunction::No) {
|
||||||
|
@ -1748,6 +1749,7 @@ static void generate_overload_arbiter(SourceGenerator& generator, auto const& ov
|
||||||
function_generator.append(R"~~~(
|
function_generator.append(R"~~~(
|
||||||
JS_DEFINE_NATIVE_FUNCTION(@class_name@::@function.name:snakecase@)
|
JS_DEFINE_NATIVE_FUNCTION(@class_name@::@function.name:snakecase@)
|
||||||
{
|
{
|
||||||
|
[[maybe_unused]] auto& realm = *global_object.associated_realm();
|
||||||
)~~~");
|
)~~~");
|
||||||
|
|
||||||
auto minimum_argument_count = get_shortest_function_length(overload_set.value);
|
auto minimum_argument_count = get_shortest_function_length(overload_set.value);
|
||||||
|
@ -1835,7 +1837,7 @@ namespace Web::Bindings {
|
||||||
class @wrapper_class@ : public @wrapper_base_class@ {
|
class @wrapper_class@ : public @wrapper_base_class@ {
|
||||||
JS_OBJECT(@name@, @wrapper_base_class@);
|
JS_OBJECT(@name@, @wrapper_base_class@);
|
||||||
public:
|
public:
|
||||||
static @wrapper_class@* create(JS::GlobalObject&, @fully_qualified_name@&);
|
static @wrapper_class@* create(JS::Realm&, @fully_qualified_name@&);
|
||||||
|
|
||||||
@wrapper_class@(JS::Realm&, @fully_qualified_name@&);
|
@wrapper_class@(JS::Realm&, @fully_qualified_name@&);
|
||||||
virtual void initialize(JS::Realm&) override;
|
virtual void initialize(JS::Realm&) override;
|
||||||
|
@ -2002,10 +2004,9 @@ using namespace Web::WebGL;
|
||||||
|
|
||||||
namespace Web::Bindings {
|
namespace Web::Bindings {
|
||||||
|
|
||||||
@wrapper_class@* @wrapper_class@::create(JS::GlobalObject& global_object, @fully_qualified_name@& impl)
|
@wrapper_class@* @wrapper_class@::create(JS::Realm& realm, @fully_qualified_name@& impl)
|
||||||
{
|
{
|
||||||
auto& realm = *global_object.associated_realm();
|
return realm.heap().allocate<@wrapper_class@>(realm.global_object(), realm, impl);
|
||||||
return global_object.heap().allocate<@wrapper_class@>(global_object, realm, impl);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
)~~~");
|
)~~~");
|
||||||
|
@ -2164,6 +2165,7 @@ JS::ThrowCompletionOr<Optional<JS::PropertyDescriptor>> @class_name@::legacy_pla
|
||||||
|
|
||||||
get_own_property_generator.append(R"~~~(
|
get_own_property_generator.append(R"~~~(
|
||||||
[[maybe_unused]] auto& global_object = this->global_object();
|
[[maybe_unused]] auto& global_object = this->global_object();
|
||||||
|
[[maybe_unused]] auto& realm = *global_object.associated_realm();
|
||||||
)~~~");
|
)~~~");
|
||||||
|
|
||||||
// 1. If O supports indexed properties...
|
// 1. If O supports indexed properties...
|
||||||
|
@ -2432,6 +2434,7 @@ JS::ThrowCompletionOr<Optional<JS::PropertyDescriptor>> @class_name@::internal_g
|
||||||
JS::ThrowCompletionOr<bool> @class_name@::internal_set(JS::PropertyKey const& property_name, JS::Value value, JS::Value receiver)
|
JS::ThrowCompletionOr<bool> @class_name@::internal_set(JS::PropertyKey const& property_name, JS::Value value, JS::Value receiver)
|
||||||
{
|
{
|
||||||
[[maybe_unused]] auto& global_object = this->global_object();
|
[[maybe_unused]] auto& global_object = this->global_object();
|
||||||
|
[[maybe_unused]] auto& realm = *global_object.associated_realm();
|
||||||
)~~~");
|
)~~~");
|
||||||
|
|
||||||
// The step 1 if statement will be empty if the interface has no setters, so don't generate the if statement if there's no setters.
|
// The step 1 if statement will be empty if the interface has no setters, so don't generate the if statement if there's no setters.
|
||||||
|
@ -2491,6 +2494,7 @@ JS::ThrowCompletionOr<bool> @class_name@::internal_define_own_property(JS::Prope
|
||||||
{
|
{
|
||||||
[[maybe_unused]] auto& vm = this->vm();
|
[[maybe_unused]] auto& vm = this->vm();
|
||||||
[[maybe_unused]] auto& global_object = this->global_object();
|
[[maybe_unused]] auto& global_object = this->global_object();
|
||||||
|
[[maybe_unused]] auto& realm = *global_object.associated_realm();
|
||||||
)~~~");
|
)~~~");
|
||||||
|
|
||||||
// 1. If O supports indexed properties...
|
// 1. If O supports indexed properties...
|
||||||
|
@ -2610,6 +2614,7 @@ JS::ThrowCompletionOr<bool> @class_name@::internal_define_own_property(JS::Prope
|
||||||
JS::ThrowCompletionOr<bool> @class_name@::internal_delete(JS::PropertyKey const& property_name)
|
JS::ThrowCompletionOr<bool> @class_name@::internal_delete(JS::PropertyKey const& property_name)
|
||||||
{
|
{
|
||||||
[[maybe_unused]] auto& global_object = this->global_object();
|
[[maybe_unused]] auto& global_object = this->global_object();
|
||||||
|
[[maybe_unused]] auto& realm = *global_object.associated_realm();
|
||||||
)~~~");
|
)~~~");
|
||||||
|
|
||||||
// 1. If O supports indexed properties...
|
// 1. If O supports indexed properties...
|
||||||
|
@ -2961,6 +2966,7 @@ JS::ThrowCompletionOr<JS::Object*> @constructor_class@::construct(FunctionObject
|
||||||
generator.append(R"~~~(
|
generator.append(R"~~~(
|
||||||
[[maybe_unused]] auto& vm = this->vm();
|
[[maybe_unused]] auto& vm = this->vm();
|
||||||
[[maybe_unused]] auto& global_object = this->global_object();
|
[[maybe_unused]] auto& global_object = this->global_object();
|
||||||
|
[[maybe_unused]] auto& realm = *global_object.associated_realm();
|
||||||
|
|
||||||
auto& window = static_cast<WindowObject&>(global_object);
|
auto& window = static_cast<WindowObject&>(global_object);
|
||||||
)~~~");
|
)~~~");
|
||||||
|
@ -3247,7 +3253,7 @@ void @prototype_class@::initialize(JS::Realm& realm)
|
||||||
|
|
||||||
if (interface.has_unscopable_member) {
|
if (interface.has_unscopable_member) {
|
||||||
generator.append(R"~~~(
|
generator.append(R"~~~(
|
||||||
auto* unscopable_object = JS::Object::create(realm.global_object(), nullptr);
|
auto* unscopable_object = JS::Object::create(realm, nullptr);
|
||||||
)~~~");
|
)~~~");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3413,6 +3419,7 @@ static JS::ThrowCompletionOr<@fully_qualified_name@*> impl_from(JS::VM& vm, JS::
|
||||||
attribute_generator.append(R"~~~(
|
attribute_generator.append(R"~~~(
|
||||||
JS_DEFINE_NATIVE_FUNCTION(@prototype_class@::@attribute.getter_callback@)
|
JS_DEFINE_NATIVE_FUNCTION(@prototype_class@::@attribute.getter_callback@)
|
||||||
{
|
{
|
||||||
|
[[maybe_unused]] auto& realm = *global_object.associated_realm();
|
||||||
auto* impl = TRY(impl_from(vm, global_object));
|
auto* impl = TRY(impl_from(vm, global_object));
|
||||||
)~~~");
|
)~~~");
|
||||||
|
|
||||||
|
@ -3442,6 +3449,7 @@ JS_DEFINE_NATIVE_FUNCTION(@prototype_class@::@attribute.getter_callback@)
|
||||||
attribute_generator.append(R"~~~(
|
attribute_generator.append(R"~~~(
|
||||||
JS_DEFINE_NATIVE_FUNCTION(@prototype_class@::@attribute.setter_callback@)
|
JS_DEFINE_NATIVE_FUNCTION(@prototype_class@::@attribute.setter_callback@)
|
||||||
{
|
{
|
||||||
|
[[maybe_unused]] auto& realm = *global_object.associated_realm();
|
||||||
auto* impl = TRY(impl_from(vm, global_object));
|
auto* impl = TRY(impl_from(vm, global_object));
|
||||||
|
|
||||||
auto value = vm.argument(0);
|
auto value = vm.argument(0);
|
||||||
|
@ -3493,6 +3501,7 @@ JS_DEFINE_NATIVE_FUNCTION(@prototype_class@::@attribute.setter_callback@)
|
||||||
stringifier_generator.append(R"~~~(
|
stringifier_generator.append(R"~~~(
|
||||||
JS_DEFINE_NATIVE_FUNCTION(@class_name@::to_string)
|
JS_DEFINE_NATIVE_FUNCTION(@class_name@::to_string)
|
||||||
{
|
{
|
||||||
|
[[maybe_unused]] auto& realm = *global_object.associated_realm();
|
||||||
auto* impl = TRY(impl_from(vm, global_object));
|
auto* impl = TRY(impl_from(vm, global_object));
|
||||||
|
|
||||||
)~~~");
|
)~~~");
|
||||||
|
@ -3524,6 +3533,7 @@ JS_DEFINE_NATIVE_FUNCTION(@prototype_class@::entries)
|
||||||
|
|
||||||
JS_DEFINE_NATIVE_FUNCTION(@prototype_class@::for_each)
|
JS_DEFINE_NATIVE_FUNCTION(@prototype_class@::for_each)
|
||||||
{
|
{
|
||||||
|
[[maybe_unused]] auto& realm = *global_object.associated_realm();
|
||||||
auto* impl = TRY(impl_from(vm, global_object));
|
auto* impl = TRY(impl_from(vm, global_object));
|
||||||
|
|
||||||
auto callback = vm.argument(0);
|
auto callback = vm.argument(0);
|
||||||
|
@ -3586,7 +3596,7 @@ namespace Web::Bindings {
|
||||||
class @wrapper_class@ : public Wrapper {
|
class @wrapper_class@ : public Wrapper {
|
||||||
JS_OBJECT(@name@, Wrapper);
|
JS_OBJECT(@name@, Wrapper);
|
||||||
public:
|
public:
|
||||||
static @wrapper_class@* create(JS::GlobalObject&, @fully_qualified_name@&);
|
static @wrapper_class@* create(JS::Realm&, @fully_qualified_name@&);
|
||||||
|
|
||||||
@wrapper_class@(JS::Realm&, @fully_qualified_name@&);
|
@wrapper_class@(JS::Realm&, @fully_qualified_name@&);
|
||||||
virtual void initialize(JS::Realm&) override;
|
virtual void initialize(JS::Realm&) override;
|
||||||
|
@ -3658,10 +3668,9 @@ using namespace Web::WebGL;
|
||||||
|
|
||||||
namespace Web::Bindings {
|
namespace Web::Bindings {
|
||||||
|
|
||||||
@wrapper_class@* @wrapper_class@::create(JS::GlobalObject& global_object, @fully_qualified_name@& impl)
|
@wrapper_class@* @wrapper_class@::create(JS::Realm& realm, @fully_qualified_name@& impl)
|
||||||
{
|
{
|
||||||
auto& realm = *global_object.associated_realm();
|
return realm.heap().allocate<@wrapper_class@>(realm.global_object(), realm, impl);
|
||||||
return global_object.heap().allocate<@wrapper_class@>(global_object, realm, impl);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@wrapper_class@::@wrapper_class@(JS::Realm& realm, @fully_qualified_name@& impl)
|
@wrapper_class@::@wrapper_class@(JS::Realm& realm, @fully_qualified_name@& impl)
|
||||||
|
|
|
@ -14,6 +14,7 @@ TEST_ROOT("Userland/Libraries/LibWasm/Tests");
|
||||||
|
|
||||||
TESTJS_GLOBAL_FUNCTION(read_binary_wasm_file, readBinaryWasmFile)
|
TESTJS_GLOBAL_FUNCTION(read_binary_wasm_file, readBinaryWasmFile)
|
||||||
{
|
{
|
||||||
|
auto& realm = *global_object.associated_realm();
|
||||||
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())
|
||||||
|
@ -23,7 +24,7 @@ TESTJS_GLOBAL_FUNCTION(read_binary_wasm_file, readBinaryWasmFile)
|
||||||
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>(global_object, strerror(file_size.error().code()));
|
||||||
|
|
||||||
auto* array = TRY(JS::Uint8Array::create(global_object, 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())
|
||||||
|
@ -46,20 +47,20 @@ public:
|
||||||
Wasm::Module& module() { return *m_module; }
|
Wasm::Module& module() { return *m_module; }
|
||||||
Wasm::ModuleInstance& module_instance() { return *m_module_instance; }
|
Wasm::ModuleInstance& module_instance() { return *m_module_instance; }
|
||||||
|
|
||||||
static JS::ThrowCompletionOr<WebAssemblyModule*> create(JS::GlobalObject& global_object, Wasm::Module module, HashMap<Wasm::Linker::Name, Wasm::ExternValue> const& imports)
|
static JS::ThrowCompletionOr<WebAssemblyModule*> create(JS::Realm& realm, Wasm::Module module, HashMap<Wasm::Linker::Name, Wasm::ExternValue> const& imports)
|
||||||
{
|
{
|
||||||
auto& vm = global_object.vm();
|
auto& vm = realm.vm();
|
||||||
auto* instance = global_object.heap().allocate<WebAssemblyModule>(global_object, *global_object.object_prototype());
|
auto* instance = realm.heap().allocate<WebAssemblyModule>(realm.global_object(), *realm.global_object().object_prototype());
|
||||||
instance->m_module = move(module);
|
instance->m_module = move(module);
|
||||||
Wasm::Linker linker(*instance->m_module);
|
Wasm::Linker linker(*instance->m_module);
|
||||||
linker.link(imports);
|
linker.link(imports);
|
||||||
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>(global_object, "Link failed");
|
return vm.throw_completion<JS::TypeError>(realm.global_object(), "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>(global_object, result.release_error().error);
|
return vm.throw_completion<JS::TypeError>(realm.global_object(), result.release_error().error);
|
||||||
instance->m_module_instance = result.release_value();
|
instance->m_module_instance = result.release_value();
|
||||||
return instance;
|
return instance;
|
||||||
}
|
}
|
||||||
|
@ -99,6 +100,7 @@ HashMap<Wasm::Linker::Name, Wasm::ExternValue> WebAssemblyModule::s_spec_test_na
|
||||||
|
|
||||||
TESTJS_GLOBAL_FUNCTION(parse_webassembly_module, parseWebAssemblyModule)
|
TESTJS_GLOBAL_FUNCTION(parse_webassembly_module, parseWebAssemblyModule)
|
||||||
{
|
{
|
||||||
|
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>(global_object, "Expected a Uint8Array argument to parse_webassembly_module");
|
||||||
|
@ -132,7 +134,7 @@ TESTJS_GLOBAL_FUNCTION(parse_webassembly_module, parseWebAssemblyModule)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return JS::Value(TRY(WebAssemblyModule::create(global_object, result.release_value(), imports)));
|
return JS::Value(TRY(WebAssemblyModule::create(realm, result.release_value(), imports)));
|
||||||
}
|
}
|
||||||
|
|
||||||
TESTJS_GLOBAL_FUNCTION(compare_typed_arrays, compareTypedArrays)
|
TESTJS_GLOBAL_FUNCTION(compare_typed_arrays, compareTypedArrays)
|
||||||
|
|
|
@ -240,6 +240,8 @@ JS_DEFINE_NATIVE_FUNCTION(SheetGlobalObject::set_real_cell_contents)
|
||||||
|
|
||||||
JS_DEFINE_NATIVE_FUNCTION(SheetGlobalObject::parse_cell_name)
|
JS_DEFINE_NATIVE_FUNCTION(SheetGlobalObject::parse_cell_name)
|
||||||
{
|
{
|
||||||
|
auto& realm = *global_object.associated_realm();
|
||||||
|
|
||||||
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))
|
||||||
|
@ -256,7 +258,7 @@ JS_DEFINE_NATIVE_FUNCTION(SheetGlobalObject::parse_cell_name)
|
||||||
if (!position.has_value())
|
if (!position.has_value())
|
||||||
return JS::js_undefined();
|
return JS::js_undefined();
|
||||||
|
|
||||||
auto object = JS::Object::create(global_object, global_object.object_prototype());
|
auto object = JS::Object::create(realm, global_object.object_prototype());
|
||||||
object->define_direct_property("column", JS::js_string(vm, sheet_object->m_sheet.column(position.value().column)), JS::default_attributes);
|
object->define_direct_property("column", JS::js_string(vm, sheet_object->m_sheet.column(position.value().column)), JS::default_attributes);
|
||||||
object->define_direct_property("row", JS::Value((unsigned)position.value().row), JS::default_attributes);
|
object->define_direct_property("row", JS::Value((unsigned)position.value().row), JS::default_attributes);
|
||||||
|
|
||||||
|
@ -265,6 +267,8 @@ JS_DEFINE_NATIVE_FUNCTION(SheetGlobalObject::parse_cell_name)
|
||||||
|
|
||||||
JS_DEFINE_NATIVE_FUNCTION(SheetGlobalObject::current_cell_position)
|
JS_DEFINE_NATIVE_FUNCTION(SheetGlobalObject::current_cell_position)
|
||||||
{
|
{
|
||||||
|
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>(global_object, "Expected no arguments to current_cell_position()");
|
||||||
|
|
||||||
|
@ -280,7 +284,7 @@ JS_DEFINE_NATIVE_FUNCTION(SheetGlobalObject::current_cell_position)
|
||||||
|
|
||||||
auto position = current_cell->position();
|
auto position = current_cell->position();
|
||||||
|
|
||||||
auto object = JS::Object::create(global_object, global_object.object_prototype());
|
auto object = JS::Object::create(realm, global_object.object_prototype());
|
||||||
object->define_direct_property("column", JS::js_string(vm, sheet_object->m_sheet.column(position.column)), JS::default_attributes);
|
object->define_direct_property("column", JS::js_string(vm, sheet_object->m_sheet.column(position.column)), JS::default_attributes);
|
||||||
object->define_direct_property("row", JS::Value((unsigned)position.row), JS::default_attributes);
|
object->define_direct_property("row", JS::Value((unsigned)position.row), JS::default_attributes);
|
||||||
|
|
||||||
|
|
|
@ -231,7 +231,7 @@ Completion BlockStatement::execute(Interpreter& interpreter, GlobalObject& globa
|
||||||
if (has_lexical_declarations()) {
|
if (has_lexical_declarations()) {
|
||||||
old_environment = vm.running_execution_context().lexical_environment;
|
old_environment = vm.running_execution_context().lexical_environment;
|
||||||
auto* block_environment = new_declarative_environment(*old_environment);
|
auto* block_environment = new_declarative_environment(*old_environment);
|
||||||
block_declaration_instantiation(global_object, block_environment);
|
block_declaration_instantiation(interpreter, global_object, block_environment);
|
||||||
vm.running_execution_context().lexical_environment = block_environment;
|
vm.running_execution_context().lexical_environment = block_environment;
|
||||||
} else {
|
} else {
|
||||||
restore_environment.disarm();
|
restore_environment.disarm();
|
||||||
|
@ -287,6 +287,8 @@ Completion FunctionExpression::execute(Interpreter& interpreter, GlobalObject& g
|
||||||
// 15.2.5 Runtime Semantics: InstantiateOrdinaryFunctionExpression, https://tc39.es/ecma262/#sec-runtime-semantics-instantiateordinaryfunctionexpression
|
// 15.2.5 Runtime Semantics: InstantiateOrdinaryFunctionExpression, https://tc39.es/ecma262/#sec-runtime-semantics-instantiateordinaryfunctionexpression
|
||||||
Value FunctionExpression::instantiate_ordinary_function_expression(Interpreter& interpreter, GlobalObject& global_object, FlyString given_name) const
|
Value FunctionExpression::instantiate_ordinary_function_expression(Interpreter& interpreter, GlobalObject& global_object, FlyString given_name) const
|
||||||
{
|
{
|
||||||
|
auto& realm = *global_object.associated_realm();
|
||||||
|
|
||||||
if (given_name.is_empty())
|
if (given_name.is_empty())
|
||||||
given_name = "";
|
given_name = "";
|
||||||
auto has_own_name = !name().is_empty();
|
auto has_own_name = !name().is_empty();
|
||||||
|
@ -301,7 +303,7 @@ Value FunctionExpression::instantiate_ordinary_function_expression(Interpreter&
|
||||||
|
|
||||||
auto* private_environment = interpreter.vm().running_execution_context().private_environment;
|
auto* private_environment = interpreter.vm().running_execution_context().private_environment;
|
||||||
|
|
||||||
auto closure = ECMAScriptFunctionObject::create(global_object, used_name, source_text(), body(), parameters(), function_length(), environment, private_environment, kind(), is_strict_mode(), might_need_arguments_object(), contains_direct_call_to_eval(), is_arrow_function());
|
auto closure = ECMAScriptFunctionObject::create(realm, used_name, source_text(), body(), parameters(), function_length(), environment, private_environment, kind(), is_strict_mode(), might_need_arguments_object(), contains_direct_call_to_eval(), is_arrow_function());
|
||||||
|
|
||||||
// FIXME: 6. Perform SetFunctionName(closure, name).
|
// FIXME: 6. Perform SetFunctionName(closure, name).
|
||||||
// FIXME: 7. Perform MakeConstructor(closure).
|
// FIXME: 7. Perform MakeConstructor(closure).
|
||||||
|
@ -1639,6 +1641,8 @@ private:
|
||||||
// 15.7.10 Runtime Semantics: ClassFieldDefinitionEvaluation, https://tc39.es/ecma262/#sec-runtime-semantics-classfielddefinitionevaluation
|
// 15.7.10 Runtime Semantics: ClassFieldDefinitionEvaluation, https://tc39.es/ecma262/#sec-runtime-semantics-classfielddefinitionevaluation
|
||||||
ThrowCompletionOr<ClassElement::ClassValue> ClassField::class_element_evaluation(Interpreter& interpreter, GlobalObject& global_object, Object& target) const
|
ThrowCompletionOr<ClassElement::ClassValue> ClassField::class_element_evaluation(Interpreter& interpreter, GlobalObject& global_object, Object& target) const
|
||||||
{
|
{
|
||||||
|
auto& realm = *global_object.associated_realm();
|
||||||
|
|
||||||
auto property_key_or_private_name = TRY(class_key_to_property_name(interpreter, global_object, *m_key));
|
auto property_key_or_private_name = TRY(class_key_to_property_name(interpreter, global_object, *m_key));
|
||||||
Handle<ECMAScriptFunctionObject> initializer {};
|
Handle<ECMAScriptFunctionObject> initializer {};
|
||||||
if (m_initializer) {
|
if (m_initializer) {
|
||||||
|
@ -1653,7 +1657,7 @@ ThrowCompletionOr<ClassElement::ClassValue> ClassField::class_element_evaluation
|
||||||
|
|
||||||
// FIXME: A potential optimization is not creating the functions here since these are never directly accessible.
|
// FIXME: A potential optimization is not creating the functions here since these are never directly accessible.
|
||||||
auto function_code = create_ast_node<ClassFieldInitializerStatement>(m_initializer->source_range(), copy_initializer.release_nonnull(), name);
|
auto function_code = create_ast_node<ClassFieldInitializerStatement>(m_initializer->source_range(), copy_initializer.release_nonnull(), name);
|
||||||
initializer = make_handle(ECMAScriptFunctionObject::create(interpreter.global_object(), String::empty(), String::empty(), *function_code, {}, 0, interpreter.lexical_environment(), interpreter.vm().running_execution_context().private_environment, FunctionKind::Normal, true, false, m_contains_direct_call_to_eval, false, property_key_or_private_name));
|
initializer = make_handle(ECMAScriptFunctionObject::create(realm, String::empty(), String::empty(), *function_code, {}, 0, interpreter.lexical_environment(), interpreter.vm().running_execution_context().private_environment, FunctionKind::Normal, true, false, m_contains_direct_call_to_eval, false, property_key_or_private_name));
|
||||||
initializer->make_method(target);
|
initializer->make_method(target);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1685,6 +1689,8 @@ Optional<FlyString> ClassMethod::private_bound_identifier() const
|
||||||
// 15.7.11 Runtime Semantics: ClassStaticBlockDefinitionEvaluation, https://tc39.es/ecma262/#sec-runtime-semantics-classstaticblockdefinitionevaluation
|
// 15.7.11 Runtime Semantics: ClassStaticBlockDefinitionEvaluation, https://tc39.es/ecma262/#sec-runtime-semantics-classstaticblockdefinitionevaluation
|
||||||
ThrowCompletionOr<ClassElement::ClassValue> StaticInitializer::class_element_evaluation(Interpreter& interpreter, GlobalObject& global_object, Object& home_object) const
|
ThrowCompletionOr<ClassElement::ClassValue> StaticInitializer::class_element_evaluation(Interpreter& interpreter, GlobalObject& global_object, Object& home_object) const
|
||||||
{
|
{
|
||||||
|
auto& realm = *global_object.associated_realm();
|
||||||
|
|
||||||
// 1. Let lex be the running execution context's LexicalEnvironment.
|
// 1. Let lex be the running execution context's LexicalEnvironment.
|
||||||
auto* lexical_environment = interpreter.vm().running_execution_context().lexical_environment;
|
auto* lexical_environment = interpreter.vm().running_execution_context().lexical_environment;
|
||||||
|
|
||||||
|
@ -1695,7 +1701,7 @@ ThrowCompletionOr<ClassElement::ClassValue> StaticInitializer::class_element_eva
|
||||||
// 4. Let formalParameters be an instance of the production FormalParameters : [empty] .
|
// 4. Let formalParameters be an instance of the production FormalParameters : [empty] .
|
||||||
// 5. Let bodyFunction be OrdinaryFunctionCreate(%Function.prototype%, sourceText, formalParameters, ClassStaticBlockBody, non-lexical-this, lex, privateEnv).
|
// 5. Let bodyFunction be OrdinaryFunctionCreate(%Function.prototype%, sourceText, formalParameters, ClassStaticBlockBody, non-lexical-this, lex, privateEnv).
|
||||||
// Note: The function bodyFunction is never directly accessible to ECMAScript code.
|
// Note: The function bodyFunction is never directly accessible to ECMAScript code.
|
||||||
auto* body_function = ECMAScriptFunctionObject::create(global_object, String::empty(), String::empty(), *m_function_body, {}, 0, lexical_environment, private_environment, FunctionKind::Normal, true, false, m_contains_direct_call_to_eval, false);
|
auto* body_function = ECMAScriptFunctionObject::create(realm, String::empty(), String::empty(), *m_function_body, {}, 0, lexical_environment, private_environment, FunctionKind::Normal, true, false, m_contains_direct_call_to_eval, false);
|
||||||
|
|
||||||
// 6. Perform MakeMethod(bodyFunction, homeObject).
|
// 6. Perform MakeMethod(bodyFunction, homeObject).
|
||||||
body_function->make_method(home_object);
|
body_function->make_method(home_object);
|
||||||
|
@ -1775,6 +1781,8 @@ Completion ClassDeclaration::execute(Interpreter& interpreter, GlobalObject& glo
|
||||||
ThrowCompletionOr<ECMAScriptFunctionObject*> ClassExpression::class_definition_evaluation(Interpreter& interpreter, GlobalObject& global_object, FlyString const& binding_name, FlyString const& class_name) const
|
ThrowCompletionOr<ECMAScriptFunctionObject*> ClassExpression::class_definition_evaluation(Interpreter& interpreter, GlobalObject& global_object, FlyString const& binding_name, FlyString const& class_name) const
|
||||||
{
|
{
|
||||||
auto& vm = interpreter.vm();
|
auto& vm = interpreter.vm();
|
||||||
|
auto& realm = *global_object.associated_realm();
|
||||||
|
|
||||||
auto* environment = vm.lexical_environment();
|
auto* environment = vm.lexical_environment();
|
||||||
VERIFY(environment);
|
VERIFY(environment);
|
||||||
auto* class_environment = new_declarative_environment(*environment);
|
auto* class_environment = new_declarative_environment(*environment);
|
||||||
|
@ -1833,7 +1841,7 @@ ThrowCompletionOr<ECMAScriptFunctionObject*> ClassExpression::class_definition_e
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
auto* prototype = Object::create(global_object, proto_parent);
|
auto* prototype = Object::create(realm, proto_parent);
|
||||||
VERIFY(prototype);
|
VERIFY(prototype);
|
||||||
|
|
||||||
vm.running_execution_context().lexical_environment = class_environment;
|
vm.running_execution_context().lexical_environment = class_environment;
|
||||||
|
@ -2994,9 +3002,10 @@ Completion ObjectProperty::execute(Interpreter& interpreter, GlobalObject&) cons
|
||||||
Completion ObjectExpression::execute(Interpreter& interpreter, GlobalObject& global_object) const
|
Completion ObjectExpression::execute(Interpreter& interpreter, GlobalObject& global_object) const
|
||||||
{
|
{
|
||||||
InterpreterNodeScope node_scope { interpreter, *this };
|
InterpreterNodeScope node_scope { interpreter, *this };
|
||||||
|
auto& realm = *global_object.associated_realm();
|
||||||
|
|
||||||
// 1. Let obj be OrdinaryObjectCreate(%Object.prototype%).
|
// 1. Let obj be OrdinaryObjectCreate(%Object.prototype%).
|
||||||
auto* object = Object::create(global_object, global_object.object_prototype());
|
auto* object = Object::create(realm, global_object.object_prototype());
|
||||||
|
|
||||||
// 2. Perform ? PropertyDefinitionEvaluation of PropertyDefinitionList with argument obj.
|
// 2. Perform ? PropertyDefinitionEvaluation of PropertyDefinitionList with argument obj.
|
||||||
for (auto& property : m_properties) {
|
for (auto& property : m_properties) {
|
||||||
|
@ -3205,6 +3214,7 @@ void MetaProperty::dump(int indent) const
|
||||||
Completion MetaProperty::execute(Interpreter& interpreter, GlobalObject& global_object) const
|
Completion MetaProperty::execute(Interpreter& interpreter, GlobalObject& global_object) const
|
||||||
{
|
{
|
||||||
InterpreterNodeScope node_scope { interpreter, *this };
|
InterpreterNodeScope node_scope { interpreter, *this };
|
||||||
|
auto& realm = *global_object.associated_realm();
|
||||||
|
|
||||||
// NewTarget : new . target
|
// NewTarget : new . target
|
||||||
if (m_type == MetaProperty::Type::NewTarget) {
|
if (m_type == MetaProperty::Type::NewTarget) {
|
||||||
|
@ -3229,7 +3239,7 @@ Completion MetaProperty::execute(Interpreter& interpreter, GlobalObject& global_
|
||||||
// 4. If importMeta is empty, then
|
// 4. If importMeta is empty, then
|
||||||
if (import_meta == nullptr) {
|
if (import_meta == nullptr) {
|
||||||
// a. Set importMeta to OrdinaryObjectCreate(null).
|
// a. Set importMeta to OrdinaryObjectCreate(null).
|
||||||
import_meta = Object::create(global_object, nullptr);
|
import_meta = Object::create(realm, nullptr);
|
||||||
|
|
||||||
// b. Let importMetaValues be HostGetImportMetaProperties(module).
|
// b. Let importMetaValues be HostGetImportMetaProperties(module).
|
||||||
auto import_meta_values = interpreter.vm().host_get_import_meta_properties(module);
|
auto import_meta_values = interpreter.vm().host_get_import_meta_properties(module);
|
||||||
|
@ -3279,6 +3289,7 @@ void ImportCall::dump(int indent) const
|
||||||
Completion ImportCall::execute(Interpreter& interpreter, GlobalObject& global_object) const
|
Completion ImportCall::execute(Interpreter& interpreter, GlobalObject& global_object) const
|
||||||
{
|
{
|
||||||
InterpreterNodeScope node_scope { interpreter, *this };
|
InterpreterNodeScope node_scope { interpreter, *this };
|
||||||
|
auto& realm = *global_object.associated_realm();
|
||||||
|
|
||||||
// 2.1.1.1 EvaluateImportCall ( specifierExpression [ , optionsExpression ] ), https://tc39.es/proposal-import-assertions/#sec-evaluate-import-call
|
// 2.1.1.1 EvaluateImportCall ( specifierExpression [ , optionsExpression ] ), https://tc39.es/proposal-import-assertions/#sec-evaluate-import-call
|
||||||
// 1. Let referencingScriptOrModule be GetActiveScriptOrModule().
|
// 1. Let referencingScriptOrModule be GetActiveScriptOrModule().
|
||||||
|
@ -3313,7 +3324,7 @@ Completion ImportCall::execute(Interpreter& interpreter, GlobalObject& global_ob
|
||||||
if (!options_value.is_undefined()) {
|
if (!options_value.is_undefined()) {
|
||||||
// a. If Type(options) is not Object,
|
// a. If Type(options) is not Object,
|
||||||
if (!options_value.is_object()) {
|
if (!options_value.is_object()) {
|
||||||
auto* error = TypeError::create(global_object, String::formatted(ErrorType::NotAnObject.message(), "ImportOptions"));
|
auto* error = TypeError::create(realm, String::formatted(ErrorType::NotAnObject.message(), "ImportOptions"));
|
||||||
// i. Perform ! Call(promiseCapability.[[Reject]], undefined, « a newly created TypeError object »).
|
// i. Perform ! Call(promiseCapability.[[Reject]], undefined, « a newly created TypeError object »).
|
||||||
MUST(call(global_object, *promise_capability.reject, js_undefined(), error));
|
MUST(call(global_object, *promise_capability.reject, js_undefined(), error));
|
||||||
|
|
||||||
|
@ -3329,7 +3340,7 @@ Completion ImportCall::execute(Interpreter& interpreter, GlobalObject& global_ob
|
||||||
if (!assertion_object.is_undefined()) {
|
if (!assertion_object.is_undefined()) {
|
||||||
// i. If Type(assertionsObj) is not Object,
|
// i. If Type(assertionsObj) is not Object,
|
||||||
if (!assertion_object.is_object()) {
|
if (!assertion_object.is_object()) {
|
||||||
auto* error = TypeError::create(global_object, String::formatted(ErrorType::NotAnObject.message(), "ImportOptionsAssertions"));
|
auto* error = TypeError::create(realm, String::formatted(ErrorType::NotAnObject.message(), "ImportOptionsAssertions"));
|
||||||
// 1. Perform ! Call(promiseCapability.[[Reject]], undefined, « a newly created TypeError object »).
|
// 1. Perform ! Call(promiseCapability.[[Reject]], undefined, « a newly created TypeError object »).
|
||||||
MUST(call(global_object, *promise_capability.reject, js_undefined(), error));
|
MUST(call(global_object, *promise_capability.reject, js_undefined(), error));
|
||||||
|
|
||||||
|
@ -3354,7 +3365,7 @@ Completion ImportCall::execute(Interpreter& interpreter, GlobalObject& global_ob
|
||||||
|
|
||||||
// 3. If Type(value) is not String, then
|
// 3. If Type(value) is not String, then
|
||||||
if (!value.is_string()) {
|
if (!value.is_string()) {
|
||||||
auto* error = TypeError::create(global_object, String::formatted(ErrorType::NotAString.message(), "Import Assertion option value"));
|
auto* error = TypeError::create(realm, String::formatted(ErrorType::NotAString.message(), "Import Assertion option value"));
|
||||||
// a. Perform ! Call(promiseCapability.[[Reject]], undefined, « a newly created TypeError object »).
|
// a. Perform ! Call(promiseCapability.[[Reject]], undefined, « a newly created TypeError object »).
|
||||||
MUST(call(global_object, *promise_capability.reject, js_undefined(), error));
|
MUST(call(global_object, *promise_capability.reject, js_undefined(), error));
|
||||||
|
|
||||||
|
@ -3449,6 +3460,7 @@ void RegExpLiteral::dump(int indent) const
|
||||||
Completion RegExpLiteral::execute(Interpreter& interpreter, GlobalObject& global_object) const
|
Completion RegExpLiteral::execute(Interpreter& interpreter, GlobalObject& global_object) const
|
||||||
{
|
{
|
||||||
InterpreterNodeScope node_scope { interpreter, *this };
|
InterpreterNodeScope node_scope { interpreter, *this };
|
||||||
|
auto& realm = *global_object.associated_realm();
|
||||||
|
|
||||||
// 1. Let pattern be CodePointsToString(BodyText of RegularExpressionLiteral).
|
// 1. Let pattern be CodePointsToString(BodyText of RegularExpressionLiteral).
|
||||||
auto pattern = this->pattern();
|
auto pattern = this->pattern();
|
||||||
|
@ -3458,7 +3470,7 @@ Completion RegExpLiteral::execute(Interpreter& interpreter, GlobalObject& global
|
||||||
|
|
||||||
// 3. Return ! RegExpCreate(pattern, flags).
|
// 3. Return ! RegExpCreate(pattern, flags).
|
||||||
Regex<ECMA262> regex(parsed_regex(), parsed_pattern(), parsed_flags());
|
Regex<ECMA262> regex(parsed_regex(), parsed_pattern(), parsed_flags());
|
||||||
return Value { RegExpObject::create(global_object, move(regex), move(pattern), move(flags)) };
|
return Value { RegExpObject::create(realm, move(regex), move(pattern), move(flags)) };
|
||||||
}
|
}
|
||||||
|
|
||||||
void ArrayExpression::dump(int indent) const
|
void ArrayExpression::dump(int indent) const
|
||||||
|
@ -3478,9 +3490,10 @@ void ArrayExpression::dump(int indent) const
|
||||||
Completion ArrayExpression::execute(Interpreter& interpreter, GlobalObject& global_object) const
|
Completion ArrayExpression::execute(Interpreter& interpreter, GlobalObject& global_object) const
|
||||||
{
|
{
|
||||||
InterpreterNodeScope node_scope { interpreter, *this };
|
InterpreterNodeScope node_scope { interpreter, *this };
|
||||||
|
auto& realm = *global_object.associated_realm();
|
||||||
|
|
||||||
// 1. Let array be ! ArrayCreate(0).
|
// 1. Let array be ! ArrayCreate(0).
|
||||||
auto* array = MUST(Array::create(global_object, 0));
|
auto* array = MUST(Array::create(realm, 0));
|
||||||
|
|
||||||
// 2. Perform ? ArrayAccumulation of ElementList with arguments array and 0.
|
// 2. Perform ? ArrayAccumulation of ElementList with arguments array and 0.
|
||||||
|
|
||||||
|
@ -3593,7 +3606,7 @@ Completion TaggedTemplateLiteral::execute(Interpreter& interpreter, GlobalObject
|
||||||
ThrowCompletionOr<Value> TaggedTemplateLiteral::get_template_object(Interpreter& interpreter, GlobalObject& global_object) const
|
ThrowCompletionOr<Value> TaggedTemplateLiteral::get_template_object(Interpreter& interpreter, GlobalObject& global_object) const
|
||||||
{
|
{
|
||||||
// 1. Let realm be the current Realm Record.
|
// 1. Let realm be the current Realm Record.
|
||||||
auto* realm = global_object.associated_realm();
|
auto& realm = *global_object.associated_realm();
|
||||||
|
|
||||||
// 2. Let templateRegistry be realm.[[TemplateMap]].
|
// 2. Let templateRegistry be realm.[[TemplateMap]].
|
||||||
// 3. For each element e of templateRegistry, do
|
// 3. For each element e of templateRegistry, do
|
||||||
|
@ -3601,7 +3614,7 @@ ThrowCompletionOr<Value> TaggedTemplateLiteral::get_template_object(Interpreter&
|
||||||
// i. Return e.[[Array]].
|
// i. Return e.[[Array]].
|
||||||
// NOTE: Instead of caching on the realm we cache on the Parse Node side as
|
// NOTE: Instead of caching on the realm we cache on the Parse Node side as
|
||||||
// this makes it easier to track whether it is the same parse node.
|
// this makes it easier to track whether it is the same parse node.
|
||||||
if (auto cached_value_or_end = m_cached_values.find(realm); cached_value_or_end != m_cached_values.end())
|
if (auto cached_value_or_end = m_cached_values.find(&realm); cached_value_or_end != m_cached_values.end())
|
||||||
return Value { cached_value_or_end->value.cell() };
|
return Value { cached_value_or_end->value.cell() };
|
||||||
|
|
||||||
// 4. Let rawStrings be TemplateStrings of templateLiteral with argument true.
|
// 4. Let rawStrings be TemplateStrings of templateLiteral with argument true.
|
||||||
|
@ -3622,10 +3635,10 @@ ThrowCompletionOr<Value> TaggedTemplateLiteral::get_template_object(Interpreter&
|
||||||
// 8. Let template be ! ArrayCreate(count).
|
// 8. Let template be ! ArrayCreate(count).
|
||||||
// NOTE: We don't set count since we push the values using append which
|
// NOTE: We don't set count since we push the values using append which
|
||||||
// would then append after count. Same for 9.
|
// would then append after count. Same for 9.
|
||||||
auto* template_ = MUST(Array::create(global_object, 0));
|
auto* template_ = MUST(Array::create(realm, 0));
|
||||||
|
|
||||||
// 9. Let rawObj be ! ArrayCreate(count).
|
// 9. Let rawObj be ! ArrayCreate(count).
|
||||||
auto* raw_obj = MUST(Array::create(global_object, 0));
|
auto* raw_obj = MUST(Array::create(realm, 0));
|
||||||
|
|
||||||
// 10. Let index be 0.
|
// 10. Let index be 0.
|
||||||
// 11. Repeat, while index < count,
|
// 11. Repeat, while index < count,
|
||||||
|
@ -3661,7 +3674,7 @@ ThrowCompletionOr<Value> TaggedTemplateLiteral::get_template_object(Interpreter&
|
||||||
MUST(template_->set_integrity_level(Object::IntegrityLevel::Frozen));
|
MUST(template_->set_integrity_level(Object::IntegrityLevel::Frozen));
|
||||||
|
|
||||||
// 15. Append the Record { [[Site]]: templateLiteral, [[Array]]: template } to templateRegistry.
|
// 15. Append the Record { [[Site]]: templateLiteral, [[Array]]: template } to templateRegistry.
|
||||||
m_cached_values.set(realm, make_handle(template_));
|
m_cached_values.set(&realm, make_handle(template_));
|
||||||
|
|
||||||
// 16. Return template.
|
// 16. Return template.
|
||||||
return template_;
|
return template_;
|
||||||
|
@ -4047,7 +4060,7 @@ Completion SwitchStatement::execute_impl(Interpreter& interpreter, GlobalObject&
|
||||||
auto* block_environment = new_declarative_environment(*old_environment);
|
auto* block_environment = new_declarative_environment(*old_environment);
|
||||||
|
|
||||||
// 5. Perform BlockDeclarationInstantiation(CaseBlock, blockEnv).
|
// 5. Perform BlockDeclarationInstantiation(CaseBlock, blockEnv).
|
||||||
block_declaration_instantiation(global_object, block_environment);
|
block_declaration_instantiation(interpreter, global_object, block_environment);
|
||||||
|
|
||||||
// 6. Set the running execution context's LexicalEnvironment to blockEnv.
|
// 6. Set the running execution context's LexicalEnvironment to blockEnv.
|
||||||
vm.running_execution_context().lexical_environment = block_environment;
|
vm.running_execution_context().lexical_environment = block_environment;
|
||||||
|
@ -4455,9 +4468,11 @@ bool ImportStatement::has_bound_name(FlyString const& name) const
|
||||||
}
|
}
|
||||||
|
|
||||||
// 14.2.3 BlockDeclarationInstantiation ( code, env ), https://tc39.es/ecma262/#sec-blockdeclarationinstantiation
|
// 14.2.3 BlockDeclarationInstantiation ( code, env ), https://tc39.es/ecma262/#sec-blockdeclarationinstantiation
|
||||||
void ScopeNode::block_declaration_instantiation(GlobalObject& global_object, Environment* environment) const
|
void ScopeNode::block_declaration_instantiation(Interpreter&, GlobalObject& global_object, Environment* environment) const
|
||||||
{
|
{
|
||||||
// See also B.3.2.6 Changes to BlockDeclarationInstantiation, https://tc39.es/ecma262/#sec-web-compat-blockdeclarationinstantiation
|
// See also B.3.2.6 Changes to BlockDeclarationInstantiation, https://tc39.es/ecma262/#sec-web-compat-blockdeclarationinstantiation
|
||||||
|
auto& realm = *global_object.associated_realm();
|
||||||
|
|
||||||
VERIFY(environment);
|
VERIFY(environment);
|
||||||
auto* private_environment = global_object.vm().running_execution_context().private_environment;
|
auto* private_environment = global_object.vm().running_execution_context().private_environment;
|
||||||
// Note: All the calls here are ! and thus we do not need to TRY this callback.
|
// Note: All the calls here are ! and thus we do not need to TRY this callback.
|
||||||
|
@ -4474,7 +4489,7 @@ void ScopeNode::block_declaration_instantiation(GlobalObject& global_object, Env
|
||||||
|
|
||||||
if (is<FunctionDeclaration>(declaration)) {
|
if (is<FunctionDeclaration>(declaration)) {
|
||||||
auto& function_declaration = static_cast<FunctionDeclaration const&>(declaration);
|
auto& function_declaration = static_cast<FunctionDeclaration const&>(declaration);
|
||||||
auto* function = ECMAScriptFunctionObject::create(global_object, function_declaration.name(), function_declaration.source_text(), function_declaration.body(), function_declaration.parameters(), function_declaration.function_length(), environment, private_environment, function_declaration.kind(), function_declaration.is_strict_mode(), function_declaration.might_need_arguments_object(), function_declaration.contains_direct_call_to_eval());
|
auto* function = ECMAScriptFunctionObject::create(realm, function_declaration.name(), function_declaration.source_text(), function_declaration.body(), function_declaration.parameters(), function_declaration.function_length(), environment, private_environment, function_declaration.kind(), function_declaration.is_strict_mode(), function_declaration.might_need_arguments_object(), function_declaration.contains_direct_call_to_eval());
|
||||||
VERIFY(is<DeclarativeEnvironment>(*environment));
|
VERIFY(is<DeclarativeEnvironment>(*environment));
|
||||||
static_cast<DeclarativeEnvironment&>(*environment).initialize_or_set_mutable_binding({}, global_object, function_declaration.name(), function);
|
static_cast<DeclarativeEnvironment&>(*environment).initialize_or_set_mutable_binding({}, global_object, function_declaration.name(), function);
|
||||||
}
|
}
|
||||||
|
@ -4484,6 +4499,8 @@ void ScopeNode::block_declaration_instantiation(GlobalObject& global_object, Env
|
||||||
// 16.1.7 GlobalDeclarationInstantiation ( script, env ), https://tc39.es/ecma262/#sec-globaldeclarationinstantiation
|
// 16.1.7 GlobalDeclarationInstantiation ( script, env ), https://tc39.es/ecma262/#sec-globaldeclarationinstantiation
|
||||||
ThrowCompletionOr<void> Program::global_declaration_instantiation(Interpreter& interpreter, GlobalObject& global_object, GlobalEnvironment& global_environment) const
|
ThrowCompletionOr<void> Program::global_declaration_instantiation(Interpreter& interpreter, GlobalObject& global_object, GlobalEnvironment& global_environment) const
|
||||||
{
|
{
|
||||||
|
auto& realm = *global_object.associated_realm();
|
||||||
|
|
||||||
// 1. Let lexNames be the LexicallyDeclaredNames of script.
|
// 1. Let lexNames be the LexicallyDeclaredNames of script.
|
||||||
// 2. Let varNames be the VarDeclaredNames of script.
|
// 2. Let varNames be the VarDeclaredNames of script.
|
||||||
// 3. For each element name of lexNames, do
|
// 3. For each element name of lexNames, do
|
||||||
|
@ -4661,7 +4678,7 @@ ThrowCompletionOr<void> Program::global_declaration_instantiation(Interpreter& i
|
||||||
for (auto& declaration : functions_to_initialize) {
|
for (auto& declaration : functions_to_initialize) {
|
||||||
// a. Let fn be the sole element of the BoundNames of f.
|
// a. Let fn be the sole element of the BoundNames of f.
|
||||||
// b. Let fo be InstantiateFunctionObject of f with arguments env and privateEnv.
|
// b. Let fo be InstantiateFunctionObject of f with arguments env and privateEnv.
|
||||||
auto* function = ECMAScriptFunctionObject::create(global_object, declaration.name(), declaration.source_text(), declaration.body(), declaration.parameters(), declaration.function_length(), &global_environment, private_environment, declaration.kind(), declaration.is_strict_mode(), declaration.might_need_arguments_object(), declaration.contains_direct_call_to_eval());
|
auto* function = ECMAScriptFunctionObject::create(realm, declaration.name(), declaration.source_text(), declaration.body(), declaration.parameters(), declaration.function_length(), &global_environment, private_environment, declaration.kind(), declaration.is_strict_mode(), declaration.might_need_arguments_object(), declaration.contains_direct_call_to_eval());
|
||||||
|
|
||||||
// c. Perform ? env.CreateGlobalFunctionBinding(fn, fo, false).
|
// c. Perform ? env.CreateGlobalFunctionBinding(fn, fo, false).
|
||||||
TRY(global_environment.create_global_function_binding(declaration.name(), function, false));
|
TRY(global_environment.create_global_function_binding(declaration.name(), function, false));
|
||||||
|
|
|
@ -255,7 +255,7 @@ public:
|
||||||
ThrowCompletionOr<void> for_each_var_function_declaration_in_reverse_order(ThrowCompletionOrVoidCallback<FunctionDeclaration const&>&& callback) const;
|
ThrowCompletionOr<void> for_each_var_function_declaration_in_reverse_order(ThrowCompletionOrVoidCallback<FunctionDeclaration const&>&& callback) const;
|
||||||
ThrowCompletionOr<void> for_each_var_scoped_variable_declaration(ThrowCompletionOrVoidCallback<VariableDeclaration const&>&& callback) const;
|
ThrowCompletionOr<void> for_each_var_scoped_variable_declaration(ThrowCompletionOrVoidCallback<VariableDeclaration const&>&& callback) const;
|
||||||
|
|
||||||
void block_declaration_instantiation(GlobalObject& global_object, Environment* environment) const;
|
void block_declaration_instantiation(Interpreter&, GlobalObject&, Environment*) const;
|
||||||
|
|
||||||
ThrowCompletionOr<void> for_each_function_hoistable_with_annexB_extension(ThrowCompletionOrVoidCallback<FunctionDeclaration&>&& callback) const;
|
ThrowCompletionOr<void> for_each_function_hoistable_with_annexB_extension(ThrowCompletionOrVoidCallback<FunctionDeclaration&>&& callback) const;
|
||||||
|
|
||||||
|
@ -495,7 +495,7 @@ public:
|
||||||
bool has_top_level_await() const { return m_has_top_level_await; }
|
bool has_top_level_await() const { return m_has_top_level_await; }
|
||||||
void set_has_top_level_await() { m_has_top_level_await = true; }
|
void set_has_top_level_await() { m_has_top_level_await = true; }
|
||||||
|
|
||||||
ThrowCompletionOr<void> global_declaration_instantiation(Interpreter& interpreter, GlobalObject& global_object, GlobalEnvironment& global_environment) const;
|
ThrowCompletionOr<void> global_declaration_instantiation(Interpreter&, GlobalObject&, GlobalEnvironment&) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
virtual bool is_program() const override { return true; }
|
virtual bool is_program() const override { return true; }
|
||||||
|
|
|
@ -168,7 +168,7 @@ ThrowCompletionOr<void> NewBigInt::execute_impl(Bytecode::Interpreter& interpret
|
||||||
|
|
||||||
ThrowCompletionOr<void> NewArray::execute_impl(Bytecode::Interpreter& interpreter) const
|
ThrowCompletionOr<void> NewArray::execute_impl(Bytecode::Interpreter& interpreter) const
|
||||||
{
|
{
|
||||||
auto* array = MUST(Array::create(interpreter.global_object(), 0));
|
auto* array = MUST(Array::create(interpreter.realm(), 0));
|
||||||
for (size_t i = 0; i < m_element_count; i++) {
|
for (size_t i = 0; i < m_element_count; i++) {
|
||||||
auto& value = interpreter.reg(Register(m_elements[0].index() + i));
|
auto& value = interpreter.reg(Register(m_elements[0].index() + i));
|
||||||
array->indexed_properties().put(i, value, default_attributes);
|
array->indexed_properties().put(i, value, default_attributes);
|
||||||
|
@ -182,7 +182,8 @@ ThrowCompletionOr<void> NewArray::execute_impl(Bytecode::Interpreter& interprete
|
||||||
static Object* iterator_to_object(GlobalObject& global_object, Iterator iterator)
|
static Object* iterator_to_object(GlobalObject& global_object, Iterator iterator)
|
||||||
{
|
{
|
||||||
auto& vm = global_object.vm();
|
auto& vm = global_object.vm();
|
||||||
auto* object = Object::create(global_object, nullptr);
|
auto& realm = *global_object.associated_realm();
|
||||||
|
auto* object = Object::create(realm, nullptr);
|
||||||
object->define_direct_property(vm.names.iterator, iterator.iterator, 0);
|
object->define_direct_property(vm.names.iterator, iterator.iterator, 0);
|
||||||
object->define_direct_property(vm.names.next, iterator.next_method, 0);
|
object->define_direct_property(vm.names.next, iterator.next_method, 0);
|
||||||
object->define_direct_property(vm.names.done, Value(iterator.done), 0);
|
object->define_direct_property(vm.names.done, Value(iterator.done), 0);
|
||||||
|
@ -205,7 +206,7 @@ ThrowCompletionOr<void> IteratorToArray::execute_impl(Bytecode::Interpreter& int
|
||||||
auto iterator_object = TRY(interpreter.accumulator().to_object(global_object));
|
auto iterator_object = TRY(interpreter.accumulator().to_object(global_object));
|
||||||
auto iterator = object_to_iterator(global_object, *iterator_object);
|
auto iterator = object_to_iterator(global_object, *iterator_object);
|
||||||
|
|
||||||
auto* array = MUST(Array::create(global_object, 0));
|
auto* array = MUST(Array::create(interpreter.realm(), 0));
|
||||||
size_t index = 0;
|
size_t index = 0;
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
|
@ -234,7 +235,7 @@ ThrowCompletionOr<void> NewString::execute_impl(Bytecode::Interpreter& interpret
|
||||||
|
|
||||||
ThrowCompletionOr<void> NewObject::execute_impl(Bytecode::Interpreter& interpreter) const
|
ThrowCompletionOr<void> NewObject::execute_impl(Bytecode::Interpreter& interpreter) const
|
||||||
{
|
{
|
||||||
interpreter.accumulator() = Object::create(interpreter.global_object(), interpreter.global_object().object_prototype());
|
interpreter.accumulator() = Object::create(interpreter.realm(), interpreter.global_object().object_prototype());
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -251,7 +252,7 @@ ThrowCompletionOr<void> CopyObjectExcludingProperties::execute_impl(Bytecode::In
|
||||||
{
|
{
|
||||||
auto* from_object = TRY(interpreter.reg(m_from_object).to_object(interpreter.global_object()));
|
auto* from_object = TRY(interpreter.reg(m_from_object).to_object(interpreter.global_object()));
|
||||||
|
|
||||||
auto* to_object = Object::create(interpreter.global_object(), interpreter.global_object().object_prototype());
|
auto* to_object = Object::create(interpreter.realm(), interpreter.global_object().object_prototype());
|
||||||
|
|
||||||
HashTable<Value, ValueTraits> excluded_names;
|
HashTable<Value, ValueTraits> excluded_names;
|
||||||
for (size_t i = 0; i < m_excluded_names_count; ++i)
|
for (size_t i = 0; i < m_excluded_names_count; ++i)
|
||||||
|
@ -506,7 +507,7 @@ ThrowCompletionOr<void> Call::execute_impl(Bytecode::Interpreter& interpreter) c
|
||||||
ThrowCompletionOr<void> NewFunction::execute_impl(Bytecode::Interpreter& interpreter) const
|
ThrowCompletionOr<void> NewFunction::execute_impl(Bytecode::Interpreter& interpreter) const
|
||||||
{
|
{
|
||||||
auto& vm = interpreter.vm();
|
auto& vm = interpreter.vm();
|
||||||
interpreter.accumulator() = ECMAScriptFunctionObject::create(interpreter.global_object(), m_function_node.name(), m_function_node.source_text(), m_function_node.body(), m_function_node.parameters(), m_function_node.function_length(), vm.lexical_environment(), vm.running_execution_context().private_environment, m_function_node.kind(), m_function_node.is_strict_mode(), m_function_node.might_need_arguments_object(), m_function_node.contains_direct_call_to_eval(), m_function_node.is_arrow_function());
|
interpreter.accumulator() = ECMAScriptFunctionObject::create(interpreter.realm(), m_function_node.name(), m_function_node.source_text(), m_function_node.body(), m_function_node.parameters(), m_function_node.function_length(), vm.lexical_environment(), vm.running_execution_context().private_environment, m_function_node.kind(), m_function_node.is_strict_mode(), m_function_node.might_need_arguments_object(), m_function_node.contains_direct_call_to_eval(), m_function_node.is_arrow_function());
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -610,7 +611,7 @@ ThrowCompletionOr<void> PushDeclarativeEnvironment::execute_impl(Bytecode::Inter
|
||||||
ThrowCompletionOr<void> Yield::execute_impl(Bytecode::Interpreter& interpreter) const
|
ThrowCompletionOr<void> Yield::execute_impl(Bytecode::Interpreter& interpreter) const
|
||||||
{
|
{
|
||||||
auto yielded_value = interpreter.accumulator().value_or(js_undefined());
|
auto yielded_value = interpreter.accumulator().value_or(js_undefined());
|
||||||
auto object = JS::Object::create(interpreter.global_object(), nullptr);
|
auto object = Object::create(interpreter.realm(), nullptr);
|
||||||
object->define_direct_property("result", yielded_value, JS::default_attributes);
|
object->define_direct_property("result", yielded_value, JS::default_attributes);
|
||||||
if (m_continuation_label.has_value())
|
if (m_continuation_label.has_value())
|
||||||
object->define_direct_property("continuation", Value(static_cast<double>(reinterpret_cast<u64>(&m_continuation_label->block()))), JS::default_attributes);
|
object->define_direct_property("continuation", Value(static_cast<double>(reinterpret_cast<u64>(&m_continuation_label->block()))), JS::default_attributes);
|
||||||
|
@ -693,14 +694,15 @@ ThrowCompletionOr<void> GetObjectPropertyIterator::execute_impl(Bytecode::Interp
|
||||||
Iterator iterator {
|
Iterator iterator {
|
||||||
.iterator = object,
|
.iterator = object,
|
||||||
.next_method = NativeFunction::create(
|
.next_method = NativeFunction::create(
|
||||||
interpreter.global_object(),
|
interpreter.realm(),
|
||||||
[seen_items = HashTable<PropertyKey>(), items = move(properties)](VM& vm, GlobalObject& global_object) mutable -> ThrowCompletionOr<Value> {
|
[seen_items = HashTable<PropertyKey>(), items = move(properties)](VM& vm, GlobalObject& global_object) mutable -> ThrowCompletionOr<Value> {
|
||||||
|
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>(global_object, "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(global_object, nullptr);
|
auto* result_object = Object::create(realm, nullptr);
|
||||||
while (true) {
|
while (true) {
|
||||||
if (items.is_empty()) {
|
if (items.is_empty()) {
|
||||||
result_object->define_direct_property(vm.names.done, JS::Value(true), default_attributes);
|
result_object->define_direct_property(vm.names.done, JS::Value(true), default_attributes);
|
||||||
|
|
|
@ -433,14 +433,15 @@ ThrowCompletionOr<void> CyclicModule::execute_module(VM&, Optional<PromiseCapabi
|
||||||
// 16.2.1.5.2.2 ExecuteAsyncModule ( module ), https://tc39.es/ecma262/#sec-execute-async-module
|
// 16.2.1.5.2.2 ExecuteAsyncModule ( module ), https://tc39.es/ecma262/#sec-execute-async-module
|
||||||
void CyclicModule::execute_async_module(VM& vm)
|
void CyclicModule::execute_async_module(VM& vm)
|
||||||
{
|
{
|
||||||
|
auto& global_object = realm().global_object();
|
||||||
|
auto& realm = *global_object.associated_realm();
|
||||||
|
|
||||||
dbgln_if(JS_MODULE_DEBUG, "[JS MODULE] executing async module {}", filename());
|
dbgln_if(JS_MODULE_DEBUG, "[JS MODULE] executing async module {}", filename());
|
||||||
// 1. Assert: module.[[Status]] is evaluating or evaluating-async.
|
// 1. Assert: module.[[Status]] is evaluating or evaluating-async.
|
||||||
VERIFY(m_status == ModuleStatus::Evaluating || m_status == ModuleStatus::EvaluatingAsync);
|
VERIFY(m_status == ModuleStatus::Evaluating || m_status == ModuleStatus::EvaluatingAsync);
|
||||||
// 2. Assert: module.[[HasTLA]] is true.
|
// 2. Assert: module.[[HasTLA]] is true.
|
||||||
VERIFY(m_has_top_level_await);
|
VERIFY(m_has_top_level_await);
|
||||||
|
|
||||||
auto& global_object = realm().global_object();
|
|
||||||
|
|
||||||
// 3. Let capability be ! NewPromiseCapability(%Promise%).
|
// 3. Let capability be ! NewPromiseCapability(%Promise%).
|
||||||
auto capability = MUST(new_promise_capability(global_object, global_object.promise_constructor()));
|
auto capability = MUST(new_promise_capability(global_object, global_object.promise_constructor()));
|
||||||
|
|
||||||
|
@ -454,7 +455,7 @@ void CyclicModule::execute_async_module(VM& vm)
|
||||||
};
|
};
|
||||||
|
|
||||||
// 5. Let onFulfilled be CreateBuiltinFunction(fulfilledClosure, 0, "", « »).
|
// 5. Let onFulfilled be CreateBuiltinFunction(fulfilledClosure, 0, "", « »).
|
||||||
auto* on_fulfilled = NativeFunction::create(global_object, move(fulfilled_closure), 0, "");
|
auto* on_fulfilled = NativeFunction::create(realm, move(fulfilled_closure), 0, "");
|
||||||
|
|
||||||
// 6. Let rejectedClosure be a new Abstract Closure with parameters (error) that captures module and performs the following steps when called:
|
// 6. Let rejectedClosure be a new Abstract Closure with parameters (error) that captures module and performs the following steps when called:
|
||||||
auto rejected_closure = [&](VM& vm, GlobalObject&) -> ThrowCompletionOr<Value> {
|
auto rejected_closure = [&](VM& vm, GlobalObject&) -> ThrowCompletionOr<Value> {
|
||||||
|
@ -468,7 +469,7 @@ void CyclicModule::execute_async_module(VM& vm)
|
||||||
};
|
};
|
||||||
|
|
||||||
// 7. Let onRejected be CreateBuiltinFunction(rejectedClosure, 0, "", « »).
|
// 7. Let onRejected be CreateBuiltinFunction(rejectedClosure, 0, "", « »).
|
||||||
auto* on_rejected = NativeFunction::create(global_object, move(rejected_closure), 0, "");
|
auto* on_rejected = NativeFunction::create(realm, move(rejected_closure), 0, "");
|
||||||
|
|
||||||
VERIFY(is<Promise>(*capability.promise));
|
VERIFY(is<Promise>(*capability.promise));
|
||||||
|
|
||||||
|
|
|
@ -349,8 +349,8 @@ 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>() receives one.
|
// Temporary helper function as we can't pass a realm directly until Heap::allocate<T>() and VM::throw_completion<T>() receive one.
|
||||||
// Heap.h only has a forward declaration of the GlobalObject, so no inlined member access possible.
|
// 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)
|
Realm& realm_from_global_object(GlobalObject& global_object)
|
||||||
{
|
{
|
||||||
return *global_object.associated_realm();
|
return *global_object.associated_realm();
|
||||||
|
|
|
@ -726,6 +726,7 @@ ThrowCompletionOr<Value> perform_eval(GlobalObject& global_object, Value x, Call
|
||||||
// 19.2.1.3 EvalDeclarationInstantiation ( body, varEnv, lexEnv, privateEnv, strict ), https://tc39.es/ecma262/#sec-evaldeclarationinstantiation
|
// 19.2.1.3 EvalDeclarationInstantiation ( body, varEnv, lexEnv, privateEnv, strict ), https://tc39.es/ecma262/#sec-evaldeclarationinstantiation
|
||||||
ThrowCompletionOr<void> eval_declaration_instantiation(VM& vm, GlobalObject& global_object, Program const& program, Environment* variable_environment, Environment* lexical_environment, PrivateEnvironment* private_environment, bool strict)
|
ThrowCompletionOr<void> eval_declaration_instantiation(VM& vm, GlobalObject& global_object, Program const& program, Environment* variable_environment, Environment* lexical_environment, PrivateEnvironment* private_environment, bool strict)
|
||||||
{
|
{
|
||||||
|
auto& realm = *global_object.associated_realm();
|
||||||
GlobalEnvironment* global_var_environment = variable_environment->is_global_environment() ? static_cast<GlobalEnvironment*>(variable_environment) : nullptr;
|
GlobalEnvironment* global_var_environment = variable_environment->is_global_environment() ? static_cast<GlobalEnvironment*>(variable_environment) : nullptr;
|
||||||
|
|
||||||
// 1. Let varNames be the VarDeclaredNames of body.
|
// 1. Let varNames be the VarDeclaredNames of body.
|
||||||
|
@ -974,7 +975,7 @@ ThrowCompletionOr<void> eval_declaration_instantiation(VM& vm, GlobalObject& glo
|
||||||
for (auto& declaration : functions_to_initialize) {
|
for (auto& declaration : functions_to_initialize) {
|
||||||
// a. Let fn be the sole element of the BoundNames of f.
|
// a. Let fn be the sole element of the BoundNames of f.
|
||||||
// b. Let fo be InstantiateFunctionObject of f with arguments lexEnv and privateEnv.
|
// b. Let fo be InstantiateFunctionObject of f with arguments lexEnv and privateEnv.
|
||||||
auto* function = ECMAScriptFunctionObject::create(global_object, declaration.name(), declaration.source_text(), declaration.body(), declaration.parameters(), declaration.function_length(), lexical_environment, private_environment, declaration.kind(), declaration.is_strict_mode(), declaration.might_need_arguments_object());
|
auto* function = ECMAScriptFunctionObject::create(realm, declaration.name(), declaration.source_text(), declaration.body(), declaration.parameters(), declaration.function_length(), lexical_environment, private_environment, declaration.kind(), declaration.is_strict_mode(), declaration.might_need_arguments_object());
|
||||||
|
|
||||||
// c. If varEnv is a global Environment Record, then
|
// c. If varEnv is a global Environment Record, then
|
||||||
if (global_var_environment) {
|
if (global_var_environment) {
|
||||||
|
@ -1036,13 +1037,14 @@ ThrowCompletionOr<void> eval_declaration_instantiation(VM& vm, GlobalObject& glo
|
||||||
Object* create_unmapped_arguments_object(GlobalObject& global_object, Span<Value> arguments)
|
Object* create_unmapped_arguments_object(GlobalObject& global_object, Span<Value> arguments)
|
||||||
{
|
{
|
||||||
auto& vm = global_object.vm();
|
auto& vm = global_object.vm();
|
||||||
|
auto& realm = *global_object.associated_realm();
|
||||||
|
|
||||||
// 1. Let len be the number of elements in argumentsList.
|
// 1. Let len be the number of elements in argumentsList.
|
||||||
auto length = arguments.size();
|
auto length = arguments.size();
|
||||||
|
|
||||||
// 2. Let obj be OrdinaryObjectCreate(%Object.prototype%, « [[ParameterMap]] »).
|
// 2. Let obj be OrdinaryObjectCreate(%Object.prototype%, « [[ParameterMap]] »).
|
||||||
// 3. Set obj.[[ParameterMap]] to undefined.
|
// 3. Set obj.[[ParameterMap]] to undefined.
|
||||||
auto* object = Object::create(global_object, global_object.object_prototype());
|
auto* object = Object::create(realm, global_object.object_prototype());
|
||||||
object->set_has_parameter_map();
|
object->set_has_parameter_map();
|
||||||
|
|
||||||
// 4. Perform ! DefinePropertyOrThrow(obj, "length", PropertyDescriptor { [[Value]]: 𝔽(len), [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: true }).
|
// 4. Perform ! DefinePropertyOrThrow(obj, "length", PropertyDescriptor { [[Value]]: 𝔽(len), [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: true }).
|
||||||
|
|
|
@ -133,8 +133,9 @@ ALWAYS_INLINE ThrowCompletionOr<Object*> construct(GlobalObject& global_object,
|
||||||
template<typename T, typename... Args>
|
template<typename T, typename... Args>
|
||||||
ThrowCompletionOr<T*> ordinary_create_from_constructor(GlobalObject& global_object, FunctionObject const& constructor, Object* (GlobalObject::*intrinsic_default_prototype)(), Args&&... args)
|
ThrowCompletionOr<T*> ordinary_create_from_constructor(GlobalObject& global_object, FunctionObject const& constructor, Object* (GlobalObject::*intrinsic_default_prototype)(), Args&&... args)
|
||||||
{
|
{
|
||||||
|
auto& realm = *global_object.associated_realm();
|
||||||
auto* prototype = TRY(get_prototype_from_constructor(global_object, constructor, intrinsic_default_prototype));
|
auto* prototype = TRY(get_prototype_from_constructor(global_object, constructor, intrinsic_default_prototype));
|
||||||
return global_object.heap().allocate<T>(global_object, forward<Args>(args)..., *prototype);
|
return realm.heap().allocate<T>(realm.global_object(), forward<Args>(args)..., *prototype);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 14.1 MergeLists ( a, b ), https://tc39.es/proposal-temporal/#sec-temporal-mergelists
|
// 14.1 MergeLists ( a, b ), https://tc39.es/proposal-temporal/#sec-temporal-mergelists
|
||||||
|
|
|
@ -10,9 +10,9 @@
|
||||||
|
|
||||||
namespace JS {
|
namespace JS {
|
||||||
|
|
||||||
AggregateError* AggregateError::create(GlobalObject& global_object)
|
AggregateError* AggregateError::create(Realm& realm)
|
||||||
{
|
{
|
||||||
return global_object.heap().allocate<AggregateError>(global_object, *global_object.aggregate_error_prototype());
|
return realm.heap().allocate<AggregateError>(realm.global_object(), *realm.global_object().aggregate_error_prototype());
|
||||||
}
|
}
|
||||||
|
|
||||||
AggregateError::AggregateError(Object& prototype)
|
AggregateError::AggregateError(Object& prototype)
|
||||||
|
|
|
@ -15,7 +15,7 @@ class AggregateError : public Error {
|
||||||
JS_OBJECT(AggregateError, Error);
|
JS_OBJECT(AggregateError, Error);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static AggregateError* create(GlobalObject&);
|
static AggregateError* create(Realm&);
|
||||||
|
|
||||||
explicit AggregateError(Object& prototype);
|
explicit AggregateError(Object& prototype);
|
||||||
virtual ~AggregateError() override = default;
|
virtual ~AggregateError() override = default;
|
||||||
|
|
|
@ -41,6 +41,7 @@ ThrowCompletionOr<Object*> AggregateErrorConstructor::construct(FunctionObject&
|
||||||
{
|
{
|
||||||
auto& vm = this->vm();
|
auto& vm = this->vm();
|
||||||
auto& global_object = this->global_object();
|
auto& global_object = this->global_object();
|
||||||
|
auto& realm = *global_object.associated_realm();
|
||||||
|
|
||||||
auto* aggregate_error = TRY(ordinary_create_from_constructor<AggregateError>(global_object, new_target, &GlobalObject::aggregate_error_prototype));
|
auto* aggregate_error = TRY(ordinary_create_from_constructor<AggregateError>(global_object, new_target, &GlobalObject::aggregate_error_prototype));
|
||||||
|
|
||||||
|
@ -53,7 +54,7 @@ ThrowCompletionOr<Object*> AggregateErrorConstructor::construct(FunctionObject&
|
||||||
|
|
||||||
auto errors_list = TRY(iterable_to_list(global_object, vm.argument(0)));
|
auto errors_list = TRY(iterable_to_list(global_object, vm.argument(0)));
|
||||||
|
|
||||||
MUST(aggregate_error->define_property_or_throw(vm.names.errors, { .value = Array::create_from(global_object, errors_list), .writable = true, .enumerable = false, .configurable = true }));
|
MUST(aggregate_error->define_property_or_throw(vm.names.errors, { .value = Array::create_from(realm, errors_list), .writable = true, .enumerable = false, .configurable = true }));
|
||||||
|
|
||||||
return aggregate_error;
|
return aggregate_error;
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,7 +20,7 @@ void ArgumentsObject::initialize(Realm& realm)
|
||||||
{
|
{
|
||||||
Base::initialize(realm);
|
Base::initialize(realm);
|
||||||
set_has_parameter_map();
|
set_has_parameter_map();
|
||||||
m_parameter_map = Object::create(realm.global_object(), nullptr);
|
m_parameter_map = Object::create(realm, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ArgumentsObject::visit_edges(Cell::Visitor& visitor)
|
void ArgumentsObject::visit_edges(Cell::Visitor& visitor)
|
||||||
|
|
|
@ -17,22 +17,22 @@
|
||||||
namespace JS {
|
namespace JS {
|
||||||
|
|
||||||
// 10.4.2.2 ArrayCreate ( length [ , proto ] ), https://tc39.es/ecma262/#sec-arraycreate
|
// 10.4.2.2 ArrayCreate ( length [ , proto ] ), https://tc39.es/ecma262/#sec-arraycreate
|
||||||
ThrowCompletionOr<Array*> Array::create(GlobalObject& global_object, u64 length, Object* prototype)
|
ThrowCompletionOr<Array*> Array::create(Realm& realm, u64 length, Object* prototype)
|
||||||
{
|
{
|
||||||
auto& vm = global_object.vm();
|
auto& vm = realm.vm();
|
||||||
|
|
||||||
// 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>(global_object, ErrorType::InvalidLength, "array");
|
return vm.throw_completion<RangeError>(realm.global_object(), 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)
|
||||||
prototype = global_object.array_prototype();
|
prototype = realm.global_object().array_prototype();
|
||||||
|
|
||||||
// 3. Let A be MakeBasicObject(« [[Prototype]], [[Extensible]] »).
|
// 3. Let A be MakeBasicObject(« [[Prototype]], [[Extensible]] »).
|
||||||
// 4. Set A.[[Prototype]] to proto.
|
// 4. Set A.[[Prototype]] to proto.
|
||||||
// 5. Set A.[[DefineOwnProperty]] as specified in 10.4.2.1.
|
// 5. Set A.[[DefineOwnProperty]] as specified in 10.4.2.1.
|
||||||
auto* array = global_object.heap().allocate<Array>(global_object, *prototype);
|
auto* array = realm.heap().allocate<Array>(realm.global_object(), *prototype);
|
||||||
|
|
||||||
// 6. Perform ! OrdinaryDefineOwnProperty(A, "length", PropertyDescriptor { [[Value]]: 𝔽(length), [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: false }).
|
// 6. Perform ! OrdinaryDefineOwnProperty(A, "length", PropertyDescriptor { [[Value]]: 𝔽(length), [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: false }).
|
||||||
MUST(array->internal_define_own_property(vm.names.length, { .value = Value(length), .writable = true, .enumerable = false, .configurable = false }));
|
MUST(array->internal_define_own_property(vm.names.length, { .value = Value(length), .writable = true, .enumerable = false, .configurable = false }));
|
||||||
|
@ -42,10 +42,10 @@ ThrowCompletionOr<Array*> Array::create(GlobalObject& global_object, u64 length,
|
||||||
}
|
}
|
||||||
|
|
||||||
// 7.3.18 CreateArrayFromList ( elements ), https://tc39.es/ecma262/#sec-createarrayfromlist
|
// 7.3.18 CreateArrayFromList ( elements ), https://tc39.es/ecma262/#sec-createarrayfromlist
|
||||||
Array* Array::create_from(GlobalObject& global_object, Vector<Value> const& elements)
|
Array* Array::create_from(Realm& realm, Vector<Value> const& elements)
|
||||||
{
|
{
|
||||||
// 1. Let array be ! ArrayCreate(0).
|
// 1. Let array be ! ArrayCreate(0).
|
||||||
auto* array = MUST(Array::create(global_object, 0));
|
auto* array = MUST(Array::create(realm, 0));
|
||||||
|
|
||||||
// 2. Let n be 0.
|
// 2. Let n be 0.
|
||||||
// 3. For each element e of elements, do
|
// 3. For each element e of elements, do
|
||||||
|
|
|
@ -21,18 +21,18 @@ class Array : public Object {
|
||||||
JS_OBJECT(Array, Object);
|
JS_OBJECT(Array, Object);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static ThrowCompletionOr<Array*> create(GlobalObject&, u64 length, Object* prototype = nullptr);
|
static ThrowCompletionOr<Array*> create(Realm&, u64 length, Object* prototype = nullptr);
|
||||||
static Array* create_from(GlobalObject&, Vector<Value> const&);
|
static Array* create_from(Realm&, Vector<Value> const&);
|
||||||
// Non-standard but equivalent to CreateArrayFromList.
|
// Non-standard but equivalent to CreateArrayFromList.
|
||||||
template<typename T>
|
template<typename T>
|
||||||
static Array* create_from(GlobalObject& global_object, Span<T const> elements, Function<Value(T const&)> map_fn)
|
static Array* create_from(Realm& realm, Span<T const> elements, Function<Value(T const&)> map_fn)
|
||||||
{
|
{
|
||||||
auto values = MarkedVector<Value> { global_object.heap() };
|
auto values = MarkedVector<Value> { realm.heap() };
|
||||||
values.ensure_capacity(elements.size());
|
values.ensure_capacity(elements.size());
|
||||||
for (auto const& element : elements)
|
for (auto const& element : elements)
|
||||||
values.append(map_fn(element));
|
values.append(map_fn(element));
|
||||||
|
|
||||||
return Array::create_from(global_object, values);
|
return Array::create_from(realm, values);
|
||||||
}
|
}
|
||||||
|
|
||||||
explicit Array(Object& prototype);
|
explicit Array(Object& prototype);
|
||||||
|
|
|
@ -11,23 +11,23 @@
|
||||||
|
|
||||||
namespace JS {
|
namespace JS {
|
||||||
|
|
||||||
ThrowCompletionOr<ArrayBuffer*> ArrayBuffer::create(GlobalObject& global_object, size_t byte_length)
|
ThrowCompletionOr<ArrayBuffer*> ArrayBuffer::create(Realm& realm, size_t byte_length)
|
||||||
{
|
{
|
||||||
auto buffer = ByteBuffer::create_zeroed(byte_length);
|
auto buffer = ByteBuffer::create_zeroed(byte_length);
|
||||||
if (buffer.is_error())
|
if (buffer.is_error())
|
||||||
return global_object.vm().throw_completion<RangeError>(global_object, ErrorType::NotEnoughMemoryToAllocate, byte_length);
|
return realm.vm().throw_completion<RangeError>(realm.global_object(), ErrorType::NotEnoughMemoryToAllocate, byte_length);
|
||||||
|
|
||||||
return global_object.heap().allocate<ArrayBuffer>(global_object, buffer.release_value(), *global_object.array_buffer_prototype());
|
return realm.heap().allocate<ArrayBuffer>(realm.global_object(), buffer.release_value(), *realm.global_object().array_buffer_prototype());
|
||||||
}
|
}
|
||||||
|
|
||||||
ArrayBuffer* ArrayBuffer::create(GlobalObject& global_object, ByteBuffer buffer)
|
ArrayBuffer* ArrayBuffer::create(Realm& realm, ByteBuffer buffer)
|
||||||
{
|
{
|
||||||
return global_object.heap().allocate<ArrayBuffer>(global_object, move(buffer), *global_object.array_buffer_prototype());
|
return realm.heap().allocate<ArrayBuffer>(realm.global_object(), move(buffer), *realm.global_object().array_buffer_prototype());
|
||||||
}
|
}
|
||||||
|
|
||||||
ArrayBuffer* ArrayBuffer::create(GlobalObject& global_object, ByteBuffer* buffer)
|
ArrayBuffer* ArrayBuffer::create(Realm& realm, ByteBuffer* buffer)
|
||||||
{
|
{
|
||||||
return global_object.heap().allocate<ArrayBuffer>(global_object, buffer, *global_object.array_buffer_prototype());
|
return realm.heap().allocate<ArrayBuffer>(realm.global_object(), buffer, *realm.global_object().array_buffer_prototype());
|
||||||
}
|
}
|
||||||
|
|
||||||
ArrayBuffer::ArrayBuffer(ByteBuffer buffer, Object& prototype)
|
ArrayBuffer::ArrayBuffer(ByteBuffer buffer, Object& prototype)
|
||||||
|
|
|
@ -25,9 +25,9 @@ class ArrayBuffer : public Object {
|
||||||
JS_OBJECT(ArrayBuffer, Object);
|
JS_OBJECT(ArrayBuffer, Object);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static ThrowCompletionOr<ArrayBuffer*> create(GlobalObject&, size_t);
|
static ThrowCompletionOr<ArrayBuffer*> create(Realm&, size_t);
|
||||||
static ArrayBuffer* create(GlobalObject&, ByteBuffer);
|
static ArrayBuffer* create(Realm&, ByteBuffer);
|
||||||
static ArrayBuffer* create(GlobalObject&, ByteBuffer*);
|
static ArrayBuffer* create(Realm&, ByteBuffer*);
|
||||||
|
|
||||||
ArrayBuffer(ByteBuffer buffer, Object& prototype);
|
ArrayBuffer(ByteBuffer buffer, Object& prototype);
|
||||||
ArrayBuffer(ByteBuffer* buffer, Object& prototype);
|
ArrayBuffer(ByteBuffer* buffer, Object& prototype);
|
||||||
|
|
|
@ -50,29 +50,31 @@ ThrowCompletionOr<Value> ArrayConstructor::call()
|
||||||
ThrowCompletionOr<Object*> ArrayConstructor::construct(FunctionObject& new_target)
|
ThrowCompletionOr<Object*> ArrayConstructor::construct(FunctionObject& new_target)
|
||||||
{
|
{
|
||||||
auto& vm = this->vm();
|
auto& vm = this->vm();
|
||||||
|
auto& global_object = this->global_object();
|
||||||
|
auto& realm = *global_object.associated_realm();
|
||||||
|
|
||||||
auto* proto = TRY(get_prototype_from_constructor(global_object(), new_target, &GlobalObject::array_prototype));
|
auto* proto = TRY(get_prototype_from_constructor(global_object, new_target, &GlobalObject::array_prototype));
|
||||||
|
|
||||||
if (vm.argument_count() == 0)
|
if (vm.argument_count() == 0)
|
||||||
return MUST(Array::create(global_object(), 0, proto));
|
return MUST(Array::create(realm, 0, proto));
|
||||||
|
|
||||||
if (vm.argument_count() == 1) {
|
if (vm.argument_count() == 1) {
|
||||||
auto length = vm.argument(0);
|
auto length = vm.argument(0);
|
||||||
auto* array = MUST(Array::create(global_object(), 0, proto));
|
auto* array = MUST(Array::create(realm, 0, proto));
|
||||||
size_t int_length;
|
size_t int_length;
|
||||||
if (!length.is_number()) {
|
if (!length.is_number()) {
|
||||||
MUST(array->create_data_property_or_throw(0, length));
|
MUST(array->create_data_property_or_throw(0, length));
|
||||||
int_length = 1;
|
int_length = 1;
|
||||||
} 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>(global_object, 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;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto* array = TRY(Array::create(global_object(), vm.argument_count(), proto));
|
auto* array = TRY(Array::create(realm, vm.argument_count(), proto));
|
||||||
|
|
||||||
for (size_t k = 0; k < vm.argument_count(); ++k)
|
for (size_t k = 0; k < vm.argument_count(); ++k)
|
||||||
MUST(array->create_data_property_or_throw(k, vm.argument(k)));
|
MUST(array->create_data_property_or_throw(k, vm.argument(k)));
|
||||||
|
@ -83,6 +85,7 @@ ThrowCompletionOr<Object*> ArrayConstructor::construct(FunctionObject& new_targe
|
||||||
// 23.1.2.1 Array.from ( items [ , mapfn [ , thisArg ] ] ), https://tc39.es/ecma262/#sec-array.from
|
// 23.1.2.1 Array.from ( items [ , mapfn [ , thisArg ] ] ), https://tc39.es/ecma262/#sec-array.from
|
||||||
JS_DEFINE_NATIVE_FUNCTION(ArrayConstructor::from)
|
JS_DEFINE_NATIVE_FUNCTION(ArrayConstructor::from)
|
||||||
{
|
{
|
||||||
|
auto& realm = *global_object.associated_realm();
|
||||||
auto constructor = vm.this_value(global_object);
|
auto constructor = vm.this_value(global_object);
|
||||||
|
|
||||||
FunctionObject* map_fn = nullptr;
|
FunctionObject* map_fn = nullptr;
|
||||||
|
@ -102,7 +105,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayConstructor::from)
|
||||||
if (constructor.is_constructor())
|
if (constructor.is_constructor())
|
||||||
array = TRY(JS::construct(global_object, constructor.as_function(), {}));
|
array = TRY(JS::construct(global_object, constructor.as_function(), {}));
|
||||||
else
|
else
|
||||||
array = MUST(Array::create(global_object, 0));
|
array = MUST(Array::create(realm, 0));
|
||||||
|
|
||||||
auto iterator = TRY(get_iterator(global_object, items, IteratorHint::Sync, using_iterator));
|
auto iterator = TRY(get_iterator(global_object, items, IteratorHint::Sync, using_iterator));
|
||||||
|
|
||||||
|
@ -147,7 +150,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayConstructor::from)
|
||||||
if (constructor.is_constructor())
|
if (constructor.is_constructor())
|
||||||
array = TRY(JS::construct(global_object, constructor.as_function(), Value(length)));
|
array = TRY(JS::construct(global_object, constructor.as_function(), Value(length)));
|
||||||
else
|
else
|
||||||
array = TRY(Array::create(global_object, length));
|
array = TRY(Array::create(realm, length));
|
||||||
|
|
||||||
for (size_t k = 0; k < length; ++k) {
|
for (size_t k = 0; k < length; ++k) {
|
||||||
auto k_value = TRY(array_like->get(k));
|
auto k_value = TRY(array_like->get(k));
|
||||||
|
@ -174,12 +177,13 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayConstructor::is_array)
|
||||||
// 23.1.2.3 Array.of ( ...items ), https://tc39.es/ecma262/#sec-array.of
|
// 23.1.2.3 Array.of ( ...items ), https://tc39.es/ecma262/#sec-array.of
|
||||||
JS_DEFINE_NATIVE_FUNCTION(ArrayConstructor::of)
|
JS_DEFINE_NATIVE_FUNCTION(ArrayConstructor::of)
|
||||||
{
|
{
|
||||||
|
auto& realm = *global_object.associated_realm();
|
||||||
auto this_value = vm.this_value(global_object);
|
auto this_value = vm.this_value(global_object);
|
||||||
Object* array;
|
Object* array;
|
||||||
if (this_value.is_constructor())
|
if (this_value.is_constructor())
|
||||||
array = TRY(JS::construct(global_object, this_value.as_function(), Value(vm.argument_count())));
|
array = TRY(JS::construct(global_object, this_value.as_function(), Value(vm.argument_count())));
|
||||||
else
|
else
|
||||||
array = TRY(Array::create(global_object, vm.argument_count()));
|
array = TRY(Array::create(realm, vm.argument_count()));
|
||||||
for (size_t k = 0; k < vm.argument_count(); ++k)
|
for (size_t k = 0; k < vm.argument_count(); ++k)
|
||||||
TRY(array->create_data_property_or_throw(k, vm.argument(k)));
|
TRY(array->create_data_property_or_throw(k, vm.argument(k)));
|
||||||
TRY(array->set(vm.names.length, Value(vm.argument_count()), Object::ShouldThrowExceptions::Yes));
|
TRY(array->set(vm.names.length, Value(vm.argument_count()), Object::ShouldThrowExceptions::Yes));
|
||||||
|
|
|
@ -9,9 +9,9 @@
|
||||||
|
|
||||||
namespace JS {
|
namespace JS {
|
||||||
|
|
||||||
ArrayIterator* ArrayIterator::create(GlobalObject& global_object, Value array, Object::PropertyKind iteration_kind)
|
ArrayIterator* ArrayIterator::create(Realm& realm, Value array, Object::PropertyKind iteration_kind)
|
||||||
{
|
{
|
||||||
return global_object.heap().allocate<ArrayIterator>(global_object, array, iteration_kind, *global_object.array_iterator_prototype());
|
return realm.heap().allocate<ArrayIterator>(realm.global_object(), array, iteration_kind, *realm.global_object().array_iterator_prototype());
|
||||||
}
|
}
|
||||||
|
|
||||||
ArrayIterator::ArrayIterator(Value array, Object::PropertyKind iteration_kind, Object& prototype)
|
ArrayIterator::ArrayIterator(Value array, Object::PropertyKind iteration_kind, Object& prototype)
|
||||||
|
|
|
@ -14,7 +14,7 @@ class ArrayIterator final : public Object {
|
||||||
JS_OBJECT(ArrayIterator, Object);
|
JS_OBJECT(ArrayIterator, Object);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static ArrayIterator* create(GlobalObject&, Value array, Object::PropertyKind iteration_kind);
|
static ArrayIterator* create(Realm&, Value array, Object::PropertyKind iteration_kind);
|
||||||
|
|
||||||
explicit ArrayIterator(Value array, Object::PropertyKind iteration_kind, Object& prototype);
|
explicit ArrayIterator(Value array, Object::PropertyKind iteration_kind, Object& prototype);
|
||||||
virtual ~ArrayIterator() override = default;
|
virtual ~ArrayIterator() override = default;
|
||||||
|
|
|
@ -34,6 +34,8 @@ void ArrayIteratorPrototype::initialize(Realm& realm)
|
||||||
// FIXME: This seems to be CreateArrayIterator (https://tc39.es/ecma262/#sec-createarrayiterator) instead of %ArrayIteratorPrototype%.next.
|
// FIXME: This seems to be CreateArrayIterator (https://tc39.es/ecma262/#sec-createarrayiterator) instead of %ArrayIteratorPrototype%.next.
|
||||||
JS_DEFINE_NATIVE_FUNCTION(ArrayIteratorPrototype::next)
|
JS_DEFINE_NATIVE_FUNCTION(ArrayIteratorPrototype::next)
|
||||||
{
|
{
|
||||||
|
auto& realm = *global_object.associated_realm();
|
||||||
|
|
||||||
auto* iterator = TRY(typed_this_value(global_object));
|
auto* iterator = TRY(typed_this_value(global_object));
|
||||||
auto target_array = iterator->array();
|
auto target_array = iterator->array();
|
||||||
if (target_array.is_undefined())
|
if (target_array.is_undefined())
|
||||||
|
@ -71,7 +73,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayIteratorPrototype::next)
|
||||||
if (iteration_kind == Object::PropertyKind::Value)
|
if (iteration_kind == Object::PropertyKind::Value)
|
||||||
return create_iterator_result_object(global_object, value, false);
|
return create_iterator_result_object(global_object, value, false);
|
||||||
|
|
||||||
return create_iterator_result_object(global_object, Array::create_from(global_object, { Value(static_cast<i32>(index)), value }), false);
|
return create_iterator_result_object(global_object, Array::create_from(realm, { Value(static_cast<i32>(index)), value }), false);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -89,7 +89,7 @@ void ArrayPrototype::initialize(Realm& realm)
|
||||||
// 23.1.3.37 Array.prototype [ @@unscopables ], https://tc39.es/ecma262/#sec-array.prototype-@@unscopables
|
// 23.1.3.37 Array.prototype [ @@unscopables ], https://tc39.es/ecma262/#sec-array.prototype-@@unscopables
|
||||||
// With array grouping proposal, https://tc39.es/proposal-array-grouping/#sec-array.prototype-@@unscopables
|
// With array grouping proposal, https://tc39.es/proposal-array-grouping/#sec-array.prototype-@@unscopables
|
||||||
// With change array by copy proposal, https://tc39.es/proposal-change-array-by-copy/#sec-array.prototype-@@unscopables
|
// With change array by copy proposal, https://tc39.es/proposal-change-array-by-copy/#sec-array.prototype-@@unscopables
|
||||||
auto* unscopable_list = Object::create(realm.global_object(), nullptr);
|
auto* unscopable_list = Object::create(realm, nullptr);
|
||||||
MUST(unscopable_list->create_data_property_or_throw(vm.names.at, Value(true)));
|
MUST(unscopable_list->create_data_property_or_throw(vm.names.at, Value(true)));
|
||||||
MUST(unscopable_list->create_data_property_or_throw(vm.names.copyWithin, Value(true)));
|
MUST(unscopable_list->create_data_property_or_throw(vm.names.copyWithin, Value(true)));
|
||||||
MUST(unscopable_list->create_data_property_or_throw(vm.names.entries, Value(true)));
|
MUST(unscopable_list->create_data_property_or_throw(vm.names.entries, Value(true)));
|
||||||
|
@ -116,11 +116,12 @@ void ArrayPrototype::initialize(Realm& realm)
|
||||||
static ThrowCompletionOr<Object*> array_species_create(GlobalObject& global_object, Object& original_array, size_t length)
|
static ThrowCompletionOr<Object*> array_species_create(GlobalObject& global_object, Object& original_array, size_t length)
|
||||||
{
|
{
|
||||||
auto& vm = global_object.vm();
|
auto& vm = global_object.vm();
|
||||||
|
auto& realm = *global_object.associated_realm();
|
||||||
|
|
||||||
auto is_array = TRY(Value(&original_array).is_array(global_object));
|
auto is_array = TRY(Value(&original_array).is_array(global_object));
|
||||||
|
|
||||||
if (!is_array)
|
if (!is_array)
|
||||||
return TRY(Array::create(global_object, length));
|
return TRY(Array::create(realm, length));
|
||||||
|
|
||||||
auto constructor = TRY(original_array.get(vm.names.constructor));
|
auto constructor = TRY(original_array.get(vm.names.constructor));
|
||||||
if (constructor.is_constructor()) {
|
if (constructor.is_constructor()) {
|
||||||
|
@ -140,7 +141,7 @@ static ThrowCompletionOr<Object*> array_species_create(GlobalObject& global_obje
|
||||||
}
|
}
|
||||||
|
|
||||||
if (constructor.is_undefined())
|
if (constructor.is_undefined())
|
||||||
return TRY(Array::create(global_object, 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>(global_object, ErrorType::NotAConstructor, constructor.to_string_without_side_effects());
|
||||||
|
@ -295,9 +296,11 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::copy_within)
|
||||||
// 23.1.3.5 Array.prototype.entries ( ), https://tc39.es/ecma262/#sec-array.prototype.entries
|
// 23.1.3.5 Array.prototype.entries ( ), https://tc39.es/ecma262/#sec-array.prototype.entries
|
||||||
JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::entries)
|
JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::entries)
|
||||||
{
|
{
|
||||||
|
auto& realm = *global_object.associated_realm();
|
||||||
|
|
||||||
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));
|
||||||
|
|
||||||
return ArrayIterator::create(global_object, this_object, Object::PropertyKind::KeyAndValue);
|
return ArrayIterator::create(realm, this_object, Object::PropertyKind::KeyAndValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 23.1.3.6 Array.prototype.every ( callbackfn [ , thisArg ] ), https://tc39.es/ecma262/#sec-array.prototype.every
|
// 23.1.3.6 Array.prototype.every ( callbackfn [ , thisArg ] ), https://tc39.es/ecma262/#sec-array.prototype.every
|
||||||
|
@ -752,6 +755,8 @@ static void add_value_to_keyed_group(GlobalObject& global_object, GroupsType& gr
|
||||||
// 2.1 Array.prototype.group ( callbackfn [ , thisArg ] ), https://tc39.es/proposal-array-grouping/#sec-array.prototype.group
|
// 2.1 Array.prototype.group ( callbackfn [ , thisArg ] ), https://tc39.es/proposal-array-grouping/#sec-array.prototype.group
|
||||||
JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::group)
|
JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::group)
|
||||||
{
|
{
|
||||||
|
auto& realm = *global_object.associated_realm();
|
||||||
|
|
||||||
auto callback_function = vm.argument(0);
|
auto callback_function = vm.argument(0);
|
||||||
auto this_arg = vm.argument(1);
|
auto this_arg = vm.argument(1);
|
||||||
|
|
||||||
|
@ -788,12 +793,12 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::group)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 7. Let obj be OrdinaryObjectCreate(null).
|
// 7. Let obj be OrdinaryObjectCreate(null).
|
||||||
auto* object = Object::create(global_object, nullptr);
|
auto* object = Object::create(realm, nullptr);
|
||||||
|
|
||||||
// 8. For each Record { [[Key]], [[Elements]] } g of groups, do
|
// 8. For each Record { [[Key]], [[Elements]] } g of groups, do
|
||||||
for (auto& group : groups) {
|
for (auto& group : groups) {
|
||||||
// a. Let elements be CreateArrayFromList(g.[[Elements]]).
|
// a. Let elements be CreateArrayFromList(g.[[Elements]]).
|
||||||
auto* elements = Array::create_from(global_object, group.value);
|
auto* elements = Array::create_from(realm, group.value);
|
||||||
|
|
||||||
// b. Perform ! CreateDataPropertyOrThrow(obj, g.[[Key]], elements).
|
// b. Perform ! CreateDataPropertyOrThrow(obj, g.[[Key]], elements).
|
||||||
MUST(object->create_data_property_or_throw(group.key, elements));
|
MUST(object->create_data_property_or_throw(group.key, elements));
|
||||||
|
@ -806,6 +811,8 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::group)
|
||||||
// 2.2 Array.prototype.groupToMap ( callbackfn [ , thisArg ] ), https://tc39.es/proposal-array-grouping/#sec-array.prototype.grouptomap
|
// 2.2 Array.prototype.groupToMap ( callbackfn [ , thisArg ] ), https://tc39.es/proposal-array-grouping/#sec-array.prototype.grouptomap
|
||||||
JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::group_to_map)
|
JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::group_to_map)
|
||||||
{
|
{
|
||||||
|
auto& realm = *global_object.associated_realm();
|
||||||
|
|
||||||
auto callback_function = vm.argument(0);
|
auto callback_function = vm.argument(0);
|
||||||
auto this_arg = vm.argument(1);
|
auto this_arg = vm.argument(1);
|
||||||
|
|
||||||
|
@ -858,12 +865,12 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::group_to_map)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 7. Let map be ! Construct(%Map%).
|
// 7. Let map be ! Construct(%Map%).
|
||||||
auto* map = Map::create(global_object);
|
auto* map = Map::create(realm);
|
||||||
|
|
||||||
// 8. For each Record { [[Key]], [[Elements]] } g of groups, do
|
// 8. For each Record { [[Key]], [[Elements]] } g of groups, do
|
||||||
for (auto& group : groups) {
|
for (auto& group : groups) {
|
||||||
// a. Let elements be CreateArrayFromList(g.[[Elements]]).
|
// a. Let elements be CreateArrayFromList(g.[[Elements]]).
|
||||||
auto* elements = Array::create_from(global_object, group.value);
|
auto* elements = Array::create_from(realm, group.value);
|
||||||
|
|
||||||
// b. Let entry be the Record { [[Key]]: g.[[Key]], [[Value]]: elements }.
|
// b. Let entry be the Record { [[Key]]: g.[[Key]], [[Value]]: elements }.
|
||||||
// c. Append entry as the last element of map.[[MapData]].
|
// c. Append entry as the last element of map.[[MapData]].
|
||||||
|
@ -1013,9 +1020,11 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::join)
|
||||||
// 23.1.3.19 Array.prototype.keys ( ), https://tc39.es/ecma262/#sec-array.prototype.keys
|
// 23.1.3.19 Array.prototype.keys ( ), https://tc39.es/ecma262/#sec-array.prototype.keys
|
||||||
JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::keys)
|
JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::keys)
|
||||||
{
|
{
|
||||||
|
auto& realm = *global_object.associated_realm();
|
||||||
|
|
||||||
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));
|
||||||
|
|
||||||
return ArrayIterator::create(global_object, this_object, Object::PropertyKind::Key);
|
return ArrayIterator::create(realm, this_object, Object::PropertyKind::Key);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 23.1.3.20 Array.prototype.lastIndexOf ( searchElement [ , fromIndex ] ), https://tc39.es/ecma262/#sec-array.prototype.lastindexof
|
// 23.1.3.20 Array.prototype.lastIndexOf ( searchElement [ , fromIndex ] ), https://tc39.es/ecma262/#sec-array.prototype.lastindexof
|
||||||
|
@ -1744,6 +1753,8 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::to_locale_string)
|
||||||
// 1.1.1.4 Array.prototype.toReversed ( ), https://tc39.es/proposal-change-array-by-copy/#sec-array.prototype.toReversed
|
// 1.1.1.4 Array.prototype.toReversed ( ), https://tc39.es/proposal-change-array-by-copy/#sec-array.prototype.toReversed
|
||||||
JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::to_reversed)
|
JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::to_reversed)
|
||||||
{
|
{
|
||||||
|
auto& realm = *global_object.associated_realm();
|
||||||
|
|
||||||
// 1. Let O be ? ToObject(this value).
|
// 1. 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));
|
||||||
|
|
||||||
|
@ -1751,7 +1762,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::to_reversed)
|
||||||
auto length = TRY(length_of_array_like(global_object, *object));
|
auto length = TRY(length_of_array_like(global_object, *object));
|
||||||
|
|
||||||
// 3. Let A be ? ArrayCreate(𝔽(len)).
|
// 3. Let A be ? ArrayCreate(𝔽(len)).
|
||||||
auto* array = TRY(Array::create(global_object, length));
|
auto* array = TRY(Array::create(realm, length));
|
||||||
|
|
||||||
// 4. Let k be 0.
|
// 4. Let k be 0.
|
||||||
// 5. Repeat, while k < len,
|
// 5. Repeat, while k < len,
|
||||||
|
@ -1778,6 +1789,8 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::to_reversed)
|
||||||
// 1.1.1.5 Array.prototype.toSorted ( comparefn ), https://tc39.es/proposal-change-array-by-copy/#sec-array.prototype.toSorted
|
// 1.1.1.5 Array.prototype.toSorted ( comparefn ), https://tc39.es/proposal-change-array-by-copy/#sec-array.prototype.toSorted
|
||||||
JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::to_sorted)
|
JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::to_sorted)
|
||||||
{
|
{
|
||||||
|
auto& realm = *global_object.associated_realm();
|
||||||
|
|
||||||
auto comparefn = vm.argument(0);
|
auto comparefn = vm.argument(0);
|
||||||
|
|
||||||
// 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.
|
||||||
|
@ -1791,7 +1804,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::to_sorted)
|
||||||
auto length = TRY(length_of_array_like(global_object, *object));
|
auto length = TRY(length_of_array_like(global_object, *object));
|
||||||
|
|
||||||
// 4. Let A be ? ArrayCreate(𝔽(len)).
|
// 4. Let A be ? ArrayCreate(𝔽(len)).
|
||||||
auto* array = TRY(Array::create(global_object, length));
|
auto* array = TRY(Array::create(realm, length));
|
||||||
|
|
||||||
// 5. Let SortCompare be a new Abstract Closure with parameters (x, y) that captures comparefn and performs the following steps when called:
|
// 5. Let SortCompare be a new Abstract Closure with parameters (x, y) that captures comparefn and performs the following steps when called:
|
||||||
Function<ThrowCompletionOr<double>(Value, Value)> sort_compare = [&](auto x, auto y) -> ThrowCompletionOr<double> {
|
Function<ThrowCompletionOr<double>(Value, Value)> sort_compare = [&](auto x, auto y) -> ThrowCompletionOr<double> {
|
||||||
|
@ -1818,6 +1831,8 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::to_sorted)
|
||||||
// 1.1.1.6 Array.prototype.toSpliced ( start, deleteCount, ...items ), https://tc39.es/proposal-change-array-by-copy/#sec-array.prototype.toSpliced
|
// 1.1.1.6 Array.prototype.toSpliced ( start, deleteCount, ...items ), https://tc39.es/proposal-change-array-by-copy/#sec-array.prototype.toSpliced
|
||||||
JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::to_spliced)
|
JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::to_spliced)
|
||||||
{
|
{
|
||||||
|
auto& realm = *global_object.associated_realm();
|
||||||
|
|
||||||
auto start = vm.argument(0);
|
auto start = vm.argument(0);
|
||||||
auto delete_count = vm.argument(1);
|
auto delete_count = vm.argument(1);
|
||||||
|
|
||||||
|
@ -1882,7 +1897,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::to_spliced)
|
||||||
auto new_length = static_cast<u64>(new_length_double);
|
auto new_length = static_cast<u64>(new_length_double);
|
||||||
|
|
||||||
// 13. Let A be ? ArrayCreate(𝔽(newLen)).
|
// 13. Let A be ? ArrayCreate(𝔽(newLen)).
|
||||||
auto* array = TRY(Array::create(global_object, new_length));
|
auto* array = TRY(Array::create(realm, new_length));
|
||||||
|
|
||||||
// 14. Let i be 0.
|
// 14. Let i be 0.
|
||||||
size_t i = 0;
|
size_t i = 0;
|
||||||
|
@ -1996,14 +2011,18 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::unshift)
|
||||||
// 23.1.3.35 Array.prototype.values ( ), https://tc39.es/ecma262/#sec-array.prototype.values
|
// 23.1.3.35 Array.prototype.values ( ), https://tc39.es/ecma262/#sec-array.prototype.values
|
||||||
JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::values)
|
JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::values)
|
||||||
{
|
{
|
||||||
|
auto& realm = *global_object.associated_realm();
|
||||||
|
|
||||||
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));
|
||||||
|
|
||||||
return ArrayIterator::create(global_object, this_object, Object::PropertyKind::Value);
|
return ArrayIterator::create(realm, this_object, Object::PropertyKind::Value);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 1.1.1.7 Array.prototype.with ( index, value ), https://tc39.es/proposal-change-array-by-copy/#sec-array.prototype.with
|
// 1.1.1.7 Array.prototype.with ( index, value ), https://tc39.es/proposal-change-array-by-copy/#sec-array.prototype.with
|
||||||
JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::with)
|
JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::with)
|
||||||
{
|
{
|
||||||
|
auto& realm = *global_object.associated_realm();
|
||||||
|
|
||||||
auto index = vm.argument(0);
|
auto index = vm.argument(0);
|
||||||
auto value = vm.argument(1);
|
auto value = vm.argument(1);
|
||||||
|
|
||||||
|
@ -2030,7 +2049,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::with)
|
||||||
return vm.throw_completion<RangeError>(global_object, ErrorType::IndexOutOfRange, actual_index, length);
|
return vm.throw_completion<RangeError>(global_object, ErrorType::IndexOutOfRange, actual_index, length);
|
||||||
|
|
||||||
// 7. Let A be ? ArrayCreate(𝔽(len)).
|
// 7. Let A be ? ArrayCreate(𝔽(len)).
|
||||||
auto* array = TRY(Array::create(global_object, length));
|
auto* array = TRY(Array::create(realm, length));
|
||||||
|
|
||||||
// 8. Let k be 0.
|
// 8. Let k be 0.
|
||||||
// 9. Repeat, while k < len,
|
// 9. Repeat, while k < len,
|
||||||
|
|
|
@ -11,10 +11,9 @@
|
||||||
|
|
||||||
namespace JS {
|
namespace JS {
|
||||||
|
|
||||||
AsyncFromSyncIterator* AsyncFromSyncIterator::create(GlobalObject& global_object, Iterator sync_iterator_record)
|
AsyncFromSyncIterator* AsyncFromSyncIterator::create(Realm& realm, Iterator sync_iterator_record)
|
||||||
{
|
{
|
||||||
auto& realm = *global_object.associated_realm();
|
return realm.heap().allocate<AsyncFromSyncIterator>(realm.global_object(), realm, sync_iterator_record);
|
||||||
return global_object.heap().allocate<AsyncFromSyncIterator>(global_object, realm, sync_iterator_record);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
AsyncFromSyncIterator::AsyncFromSyncIterator(Realm& realm, Iterator sync_iterator_record)
|
AsyncFromSyncIterator::AsyncFromSyncIterator(Realm& realm, Iterator sync_iterator_record)
|
||||||
|
|
|
@ -17,7 +17,7 @@ class AsyncFromSyncIterator final : public Object {
|
||||||
JS_OBJECT(AsyncFromSyncIterator, Object);
|
JS_OBJECT(AsyncFromSyncIterator, Object);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static AsyncFromSyncIterator* create(GlobalObject&, Iterator sync_iterator_record);
|
static AsyncFromSyncIterator* create(Realm&, Iterator sync_iterator_record);
|
||||||
|
|
||||||
explicit AsyncFromSyncIterator(Realm&, Iterator sync_iterator_record);
|
explicit AsyncFromSyncIterator(Realm&, Iterator sync_iterator_record);
|
||||||
virtual void initialize(Realm&) override;
|
virtual void initialize(Realm&) override;
|
||||||
|
|
|
@ -33,6 +33,8 @@ void AsyncFromSyncIteratorPrototype::initialize(Realm& realm)
|
||||||
// 27.1.4.4 AsyncFromSyncIteratorContinuation ( result, promiseCapability ), https://tc39.es/ecma262/#sec-asyncfromsynciteratorcontinuation
|
// 27.1.4.4 AsyncFromSyncIteratorContinuation ( result, promiseCapability ), https://tc39.es/ecma262/#sec-asyncfromsynciteratorcontinuation
|
||||||
static Object* async_from_sync_iterator_continuation(GlobalObject& global_object, Object& result, PromiseCapability& promise_capability)
|
static Object* async_from_sync_iterator_continuation(GlobalObject& global_object, Object& result, PromiseCapability& promise_capability)
|
||||||
{
|
{
|
||||||
|
auto& realm = *global_object.associated_realm();
|
||||||
|
|
||||||
// 1. NOTE: Because promiseCapability is derived from the intrinsic %Promise%, the calls to promiseCapability.[[Reject]] entailed by the use IfAbruptRejectPromise below are guaranteed not to throw.
|
// 1. NOTE: Because promiseCapability is derived from the intrinsic %Promise%, the calls to promiseCapability.[[Reject]] entailed by the use IfAbruptRejectPromise below are guaranteed not to throw.
|
||||||
// 2. Let done be Completion(IteratorComplete(result)).
|
// 2. Let done be Completion(IteratorComplete(result)).
|
||||||
// 3. IfAbruptRejectPromise(done, promiseCapability).
|
// 3. IfAbruptRejectPromise(done, promiseCapability).
|
||||||
|
@ -54,7 +56,7 @@ static Object* async_from_sync_iterator_continuation(GlobalObject& global_object
|
||||||
|
|
||||||
// 9. Let onFulfilled be CreateBuiltinFunction(unwrap, 1, "", « »).
|
// 9. Let onFulfilled be CreateBuiltinFunction(unwrap, 1, "", « »).
|
||||||
// 10. NOTE: onFulfilled is used when processing the "value" property of an IteratorResult object in order to wait for its value if it is a promise and re-package the result in a new "unwrapped" IteratorResult object.
|
// 10. NOTE: onFulfilled is used when processing the "value" property of an IteratorResult object in order to wait for its value if it is a promise and re-package the result in a new "unwrapped" IteratorResult object.
|
||||||
auto* on_fulfilled = NativeFunction::create(global_object, move(unwrap), 1, "");
|
auto* on_fulfilled = NativeFunction::create(realm, move(unwrap), 1, "");
|
||||||
|
|
||||||
// 11. Perform PerformPromiseThen(valueWrapper, onFulfilled, undefined, promiseCapability).
|
// 11. Perform PerformPromiseThen(valueWrapper, onFulfilled, undefined, promiseCapability).
|
||||||
verify_cast<Promise>(value_wrapper)->perform_then(move(on_fulfilled), js_undefined(), promise_capability);
|
verify_cast<Promise>(value_wrapper)->perform_then(move(on_fulfilled), js_undefined(), promise_capability);
|
||||||
|
@ -92,6 +94,8 @@ JS_DEFINE_NATIVE_FUNCTION(AsyncFromSyncIteratorPrototype::next)
|
||||||
// 27.1.4.2.2 %AsyncFromSyncIteratorPrototype%.return ( [ value ] ), https://tc39.es/ecma262/#sec-%asyncfromsynciteratorprototype%.return
|
// 27.1.4.2.2 %AsyncFromSyncIteratorPrototype%.return ( [ value ] ), https://tc39.es/ecma262/#sec-%asyncfromsynciteratorprototype%.return
|
||||||
JS_DEFINE_NATIVE_FUNCTION(AsyncFromSyncIteratorPrototype::return_)
|
JS_DEFINE_NATIVE_FUNCTION(AsyncFromSyncIteratorPrototype::return_)
|
||||||
{
|
{
|
||||||
|
auto& realm = *global_object.associated_realm();
|
||||||
|
|
||||||
// 1. Let O be the this value.
|
// 1. Let O be the this value.
|
||||||
// 2. Assert: O is an Object that has a [[SyncIteratorRecord]] internal slot.
|
// 2. Assert: O is an Object that has a [[SyncIteratorRecord]] internal slot.
|
||||||
auto* this_object = MUST(typed_this_object(global_object));
|
auto* this_object = MUST(typed_this_object(global_object));
|
||||||
|
@ -129,7 +133,7 @@ JS_DEFINE_NATIVE_FUNCTION(AsyncFromSyncIteratorPrototype::return_)
|
||||||
|
|
||||||
// 11. If Type(result) is not Object, then
|
// 11. If Type(result) is not Object, then
|
||||||
if (!result.is_object()) {
|
if (!result.is_object()) {
|
||||||
auto* error = TypeError::create(global_object, String::formatted(ErrorType::NotAnObject.message(), "SyncIteratorReturnResult"));
|
auto* error = TypeError::create(realm, String::formatted(ErrorType::NotAnObject.message(), "SyncIteratorReturnResult"));
|
||||||
// a. Perform ! Call(promiseCapability.[[Reject]], undefined, « a newly created TypeError object »).
|
// a. Perform ! Call(promiseCapability.[[Reject]], undefined, « a newly created TypeError object »).
|
||||||
MUST(call(global_object, *promise_capability.reject, js_undefined(), error));
|
MUST(call(global_object, *promise_capability.reject, js_undefined(), error));
|
||||||
// b. Return promiseCapability.[[Promise]].
|
// b. Return promiseCapability.[[Promise]].
|
||||||
|
@ -143,6 +147,8 @@ JS_DEFINE_NATIVE_FUNCTION(AsyncFromSyncIteratorPrototype::return_)
|
||||||
// 27.1.4.2.3 %AsyncFromSyncIteratorPrototype%.throw ( [ value ] ), https://tc39.es/ecma262/#sec-%asyncfromsynciteratorprototype%.throw
|
// 27.1.4.2.3 %AsyncFromSyncIteratorPrototype%.throw ( [ value ] ), https://tc39.es/ecma262/#sec-%asyncfromsynciteratorprototype%.throw
|
||||||
JS_DEFINE_NATIVE_FUNCTION(AsyncFromSyncIteratorPrototype::throw_)
|
JS_DEFINE_NATIVE_FUNCTION(AsyncFromSyncIteratorPrototype::throw_)
|
||||||
{
|
{
|
||||||
|
auto& realm = *global_object.associated_realm();
|
||||||
|
|
||||||
// 1. Let O be the this value.
|
// 1. Let O be the this value.
|
||||||
// 2. Assert: O is an Object that has a [[SyncIteratorRecord]] internal slot.
|
// 2. Assert: O is an Object that has a [[SyncIteratorRecord]] internal slot.
|
||||||
auto* this_object = MUST(typed_this_object(global_object));
|
auto* this_object = MUST(typed_this_object(global_object));
|
||||||
|
@ -175,7 +181,7 @@ JS_DEFINE_NATIVE_FUNCTION(AsyncFromSyncIteratorPrototype::throw_)
|
||||||
|
|
||||||
// 11. If Type(result) is not Object, then
|
// 11. If Type(result) is not Object, then
|
||||||
if (!result.is_object()) {
|
if (!result.is_object()) {
|
||||||
auto* error = TypeError::create(global_object, String::formatted(ErrorType::NotAnObject.message(), "SyncIteratorThrowResult"));
|
auto* error = TypeError::create(realm, String::formatted(ErrorType::NotAnObject.message(), "SyncIteratorThrowResult"));
|
||||||
// a. Perform ! Call(promiseCapability.[[Reject]], undefined, « a newly created TypeError object »).
|
// a. Perform ! Call(promiseCapability.[[Reject]], undefined, « a newly created TypeError object »).
|
||||||
MUST(call(global_object, *promise_capability.reject, js_undefined(), error));
|
MUST(call(global_object, *promise_capability.reject, js_undefined(), error));
|
||||||
|
|
||||||
|
@ -191,10 +197,11 @@ JS_DEFINE_NATIVE_FUNCTION(AsyncFromSyncIteratorPrototype::throw_)
|
||||||
Iterator create_async_from_sync_iterator(GlobalObject& global_object, Iterator sync_iterator_record)
|
Iterator create_async_from_sync_iterator(GlobalObject& global_object, Iterator sync_iterator_record)
|
||||||
{
|
{
|
||||||
auto& vm = global_object.vm();
|
auto& vm = global_object.vm();
|
||||||
|
auto& realm = *global_object.associated_realm();
|
||||||
|
|
||||||
// 1. Let asyncIterator be OrdinaryObjectCreate(%AsyncFromSyncIteratorPrototype%, « [[SyncIteratorRecord]] »).
|
// 1. Let asyncIterator be OrdinaryObjectCreate(%AsyncFromSyncIteratorPrototype%, « [[SyncIteratorRecord]] »).
|
||||||
// 2. Set asyncIterator.[[SyncIteratorRecord]] to syncIteratorRecord.
|
// 2. Set asyncIterator.[[SyncIteratorRecord]] to syncIteratorRecord.
|
||||||
auto* async_iterator = AsyncFromSyncIterator::create(global_object, sync_iterator_record);
|
auto* async_iterator = AsyncFromSyncIterator::create(realm, sync_iterator_record);
|
||||||
|
|
||||||
// 3. Let nextMethod be ! Get(asyncIterator, "next").
|
// 3. Let nextMethod be ! Get(asyncIterator, "next").
|
||||||
auto next_method = MUST(async_iterator->get(vm.names.next));
|
auto next_method = MUST(async_iterator->get(vm.names.next));
|
||||||
|
|
|
@ -12,20 +12,19 @@
|
||||||
|
|
||||||
namespace JS {
|
namespace JS {
|
||||||
|
|
||||||
ThrowCompletionOr<Value> AsyncFunctionDriverWrapper::create(GlobalObject& global_object, GeneratorObject* generator_object)
|
ThrowCompletionOr<Value> AsyncFunctionDriverWrapper::create(Realm& realm, GeneratorObject* generator_object)
|
||||||
{
|
{
|
||||||
auto& realm = *global_object.associated_realm();
|
auto wrapper = realm.heap().allocate<AsyncFunctionDriverWrapper>(realm.global_object(), realm, generator_object);
|
||||||
auto wrapper = global_object.heap().allocate<AsyncFunctionDriverWrapper>(global_object, realm, generator_object);
|
return wrapper->react_to_async_task_completion(realm.vm(), realm.global_object(), js_undefined(), true);
|
||||||
return wrapper->react_to_async_task_completion(global_object.vm(), global_object, js_undefined(), true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
AsyncFunctionDriverWrapper::AsyncFunctionDriverWrapper(Realm& realm, GeneratorObject* generator_object)
|
AsyncFunctionDriverWrapper::AsyncFunctionDriverWrapper(Realm& realm, GeneratorObject* generator_object)
|
||||||
: Promise(*realm.global_object().promise_prototype())
|
: Promise(*realm.global_object().promise_prototype())
|
||||||
, m_generator_object(generator_object)
|
, m_generator_object(generator_object)
|
||||||
, m_on_fulfillment(NativeFunction::create(realm.global_object(), "async.on_fulfillment"sv, [this](VM& vm, GlobalObject& global_object) {
|
, m_on_fulfillment(NativeFunction::create(realm, "async.on_fulfillment"sv, [this](VM& vm, GlobalObject& global_object) {
|
||||||
return react_to_async_task_completion(vm, global_object, vm.argument(0), true);
|
return react_to_async_task_completion(vm, global_object, vm.argument(0), true);
|
||||||
}))
|
}))
|
||||||
, m_on_rejection(NativeFunction::create(realm.global_object(), "async.on_rejection"sv, [this](VM& vm, GlobalObject& global_object) {
|
, m_on_rejection(NativeFunction::create(realm, "async.on_rejection"sv, [this](VM& vm, GlobalObject& global_object) {
|
||||||
return react_to_async_task_completion(vm, global_object, vm.argument(0), false);
|
return react_to_async_task_completion(vm, global_object, vm.argument(0), false);
|
||||||
}))
|
}))
|
||||||
{
|
{
|
||||||
|
@ -33,13 +32,15 @@ AsyncFunctionDriverWrapper::AsyncFunctionDriverWrapper(Realm& realm, GeneratorOb
|
||||||
|
|
||||||
ThrowCompletionOr<Value> AsyncFunctionDriverWrapper::react_to_async_task_completion(VM& vm, GlobalObject& global_object, Value value, bool is_successful)
|
ThrowCompletionOr<Value> AsyncFunctionDriverWrapper::react_to_async_task_completion(VM& vm, GlobalObject& global_object, Value value, bool is_successful)
|
||||||
{
|
{
|
||||||
|
auto& realm = *global_object.associated_realm();
|
||||||
|
|
||||||
auto generator_result = is_successful
|
auto generator_result = is_successful
|
||||||
? m_generator_object->next_impl(vm, global_object, value, {})
|
? m_generator_object->next_impl(vm, global_object, value, {})
|
||||||
: m_generator_object->next_impl(vm, global_object, {}, value);
|
: m_generator_object->next_impl(vm, global_object, {}, value);
|
||||||
|
|
||||||
if (generator_result.is_throw_completion()) {
|
if (generator_result.is_throw_completion()) {
|
||||||
VERIFY(generator_result.throw_completion().type() == Completion::Type::Throw);
|
VERIFY(generator_result.throw_completion().type() == Completion::Type::Throw);
|
||||||
auto promise = Promise::create(global_object);
|
auto promise = Promise::create(realm);
|
||||||
promise->reject(*generator_result.throw_completion().value());
|
promise->reject(*generator_result.throw_completion().value());
|
||||||
return promise;
|
return promise;
|
||||||
}
|
}
|
||||||
|
@ -49,7 +50,7 @@ ThrowCompletionOr<Value> AsyncFunctionDriverWrapper::react_to_async_task_complet
|
||||||
|
|
||||||
auto promise_value = TRY(result.get(global_object, vm.names.value));
|
auto promise_value = TRY(result.get(global_object, vm.names.value));
|
||||||
if (!promise_value.is_object() || !is<Promise>(promise_value.as_object())) {
|
if (!promise_value.is_object() || !is<Promise>(promise_value.as_object())) {
|
||||||
auto promise = Promise::create(global_object);
|
auto promise = Promise::create(realm);
|
||||||
promise->fulfill(promise_value);
|
promise->fulfill(promise_value);
|
||||||
return promise;
|
return promise;
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,7 +18,7 @@ class AsyncFunctionDriverWrapper final : public Promise {
|
||||||
JS_OBJECT(AsyncFunctionDriverWrapper, Promise);
|
JS_OBJECT(AsyncFunctionDriverWrapper, Promise);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static ThrowCompletionOr<Value> create(GlobalObject&, GeneratorObject*);
|
static ThrowCompletionOr<Value> create(Realm&, GeneratorObject*);
|
||||||
explicit AsyncFunctionDriverWrapper(Realm&, GeneratorObject*);
|
explicit AsyncFunctionDriverWrapper(Realm&, GeneratorObject*);
|
||||||
|
|
||||||
virtual ~AsyncFunctionDriverWrapper() override = default;
|
virtual ~AsyncFunctionDriverWrapper() override = default;
|
||||||
|
|
|
@ -9,9 +9,9 @@
|
||||||
|
|
||||||
namespace JS {
|
namespace JS {
|
||||||
|
|
||||||
BigIntObject* BigIntObject::create(GlobalObject& global_object, BigInt& bigint)
|
BigIntObject* BigIntObject::create(Realm& realm, BigInt& bigint)
|
||||||
{
|
{
|
||||||
return global_object.heap().allocate<BigIntObject>(global_object, bigint, *global_object.bigint_prototype());
|
return realm.heap().allocate<BigIntObject>(realm.global_object(), bigint, *realm.global_object().bigint_prototype());
|
||||||
}
|
}
|
||||||
|
|
||||||
BigIntObject::BigIntObject(BigInt& bigint, Object& prototype)
|
BigIntObject::BigIntObject(BigInt& bigint, Object& prototype)
|
||||||
|
|
|
@ -15,7 +15,7 @@ class BigIntObject final : public Object {
|
||||||
JS_OBJECT(BigIntObject, Object);
|
JS_OBJECT(BigIntObject, Object);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static BigIntObject* create(GlobalObject&, BigInt&);
|
static BigIntObject* create(Realm&, BigInt&);
|
||||||
|
|
||||||
BigIntObject(BigInt&, Object& prototype);
|
BigIntObject(BigInt&, Object& prototype);
|
||||||
virtual ~BigIntObject() override = default;
|
virtual ~BigIntObject() override = default;
|
||||||
|
|
|
@ -9,9 +9,9 @@
|
||||||
|
|
||||||
namespace JS {
|
namespace JS {
|
||||||
|
|
||||||
BooleanObject* BooleanObject::create(GlobalObject& global_object, bool value)
|
BooleanObject* BooleanObject::create(Realm& realm, bool value)
|
||||||
{
|
{
|
||||||
return global_object.heap().allocate<BooleanObject>(global_object, value, *global_object.boolean_prototype());
|
return realm.heap().allocate<BooleanObject>(realm.global_object(), value, *realm.global_object().boolean_prototype());
|
||||||
}
|
}
|
||||||
|
|
||||||
BooleanObject::BooleanObject(bool value, Object& prototype)
|
BooleanObject::BooleanObject(bool value, Object& prototype)
|
||||||
|
|
|
@ -14,7 +14,7 @@ class BooleanObject : public Object {
|
||||||
JS_OBJECT(BooleanObject, Object);
|
JS_OBJECT(BooleanObject, Object);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static BooleanObject* create(GlobalObject&, bool);
|
static BooleanObject* create(Realm&, bool);
|
||||||
|
|
||||||
BooleanObject(bool, Object& prototype);
|
BooleanObject(bool, Object& prototype);
|
||||||
virtual ~BooleanObject() override = default;
|
virtual ~BooleanObject() override = default;
|
||||||
|
|
|
@ -12,10 +12,8 @@
|
||||||
namespace JS {
|
namespace JS {
|
||||||
|
|
||||||
// 10.4.1.3 BoundFunctionCreate ( targetFunction, boundThis, boundArgs ), https://tc39.es/ecma262/#sec-boundfunctioncreate
|
// 10.4.1.3 BoundFunctionCreate ( targetFunction, boundThis, boundArgs ), https://tc39.es/ecma262/#sec-boundfunctioncreate
|
||||||
ThrowCompletionOr<BoundFunction*> BoundFunction::create(GlobalObject& global_object, FunctionObject& target_function, Value bound_this, Vector<Value> bound_arguments)
|
ThrowCompletionOr<BoundFunction*> BoundFunction::create(Realm& realm, FunctionObject& target_function, Value bound_this, Vector<Value> bound_arguments)
|
||||||
{
|
{
|
||||||
auto& realm = *global_object.associated_realm();
|
|
||||||
|
|
||||||
// 1. Let proto be ? targetFunction.[[GetPrototypeOf]]().
|
// 1. Let proto be ? targetFunction.[[GetPrototypeOf]]().
|
||||||
auto* prototype = TRY(target_function.internal_get_prototype_of());
|
auto* prototype = TRY(target_function.internal_get_prototype_of());
|
||||||
|
|
||||||
|
@ -28,7 +26,7 @@ ThrowCompletionOr<BoundFunction*> BoundFunction::create(GlobalObject& global_obj
|
||||||
// 7. Set obj.[[BoundTargetFunction]] to targetFunction.
|
// 7. Set obj.[[BoundTargetFunction]] to targetFunction.
|
||||||
// 8. Set obj.[[BoundThis]] to boundThis.
|
// 8. Set obj.[[BoundThis]] to boundThis.
|
||||||
// 9. Set obj.[[BoundArguments]] to boundArgs.
|
// 9. Set obj.[[BoundArguments]] to boundArgs.
|
||||||
auto* object = global_object.heap().allocate<BoundFunction>(global_object, realm, target_function, bound_this, move(bound_arguments), prototype);
|
auto* object = realm.heap().allocate<BoundFunction>(realm.global_object(), realm, target_function, bound_this, move(bound_arguments), prototype);
|
||||||
|
|
||||||
// 10. Return obj.
|
// 10. Return obj.
|
||||||
return object;
|
return object;
|
||||||
|
|
|
@ -15,7 +15,7 @@ class BoundFunction final : public FunctionObject {
|
||||||
JS_OBJECT(BoundFunction, FunctionObject);
|
JS_OBJECT(BoundFunction, FunctionObject);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static ThrowCompletionOr<BoundFunction*> create(GlobalObject&, FunctionObject& target_function, Value bound_this, Vector<Value> bound_arguments);
|
static ThrowCompletionOr<BoundFunction*> create(Realm&, FunctionObject& target_function, Value bound_this, Vector<Value> bound_arguments);
|
||||||
|
|
||||||
BoundFunction(Realm&, FunctionObject& target_function, Value bound_this, Vector<Value> bound_arguments, Object* prototype);
|
BoundFunction(Realm&, FunctionObject& target_function, Value bound_this, Vector<Value> bound_arguments, Object* prototype);
|
||||||
virtual ~BoundFunction() override = default;
|
virtual ~BoundFunction() override = default;
|
||||||
|
|
|
@ -32,6 +32,7 @@ Completion::Completion(ThrowCompletionOr<Value> const& throw_completion_or_value
|
||||||
ThrowCompletionOr<Value> await(GlobalObject& global_object, Value value)
|
ThrowCompletionOr<Value> await(GlobalObject& global_object, Value value)
|
||||||
{
|
{
|
||||||
auto& vm = global_object.vm();
|
auto& vm = global_object.vm();
|
||||||
|
auto& realm = *global_object.associated_realm();
|
||||||
|
|
||||||
// 1. Let asyncContext be the running execution context.
|
// 1. Let asyncContext be the running execution context.
|
||||||
// NOTE: This is not needed, as we don't suspend anything.
|
// NOTE: This is not needed, as we don't suspend anything.
|
||||||
|
@ -63,7 +64,7 @@ ThrowCompletionOr<Value> await(GlobalObject& global_object, Value value)
|
||||||
};
|
};
|
||||||
|
|
||||||
// 4. Let onFulfilled be CreateBuiltinFunction(fulfilledClosure, 1, "", « »).
|
// 4. Let onFulfilled be CreateBuiltinFunction(fulfilledClosure, 1, "", « »).
|
||||||
auto* on_fulfilled = NativeFunction::create(global_object, move(fulfilled_closure), 1, "");
|
auto* on_fulfilled = NativeFunction::create(realm, move(fulfilled_closure), 1, "");
|
||||||
|
|
||||||
// 5. Let rejectedClosure be a new Abstract Closure with parameters (reason) that captures asyncContext and performs the following steps when called:
|
// 5. Let rejectedClosure be a new Abstract Closure with parameters (reason) that captures asyncContext and performs the following steps when called:
|
||||||
auto rejected_closure = [&success, &result](VM& vm, GlobalObject&) -> ThrowCompletionOr<Value> {
|
auto rejected_closure = [&success, &result](VM& vm, GlobalObject&) -> ThrowCompletionOr<Value> {
|
||||||
|
@ -87,7 +88,7 @@ ThrowCompletionOr<Value> await(GlobalObject& global_object, Value value)
|
||||||
};
|
};
|
||||||
|
|
||||||
// 6. Let onRejected be CreateBuiltinFunction(rejectedClosure, 1, "", « »).
|
// 6. Let onRejected be CreateBuiltinFunction(rejectedClosure, 1, "", « »).
|
||||||
auto* on_rejected = NativeFunction::create(global_object, move(rejected_closure), 1, "");
|
auto* on_rejected = NativeFunction::create(realm, move(rejected_closure), 1, "");
|
||||||
|
|
||||||
// 7. Perform PerformPromiseThen(promise, onFulfilled, onRejected).
|
// 7. Perform PerformPromiseThen(promise, onFulfilled, onRejected).
|
||||||
auto* promise = verify_cast<Promise>(promise_object);
|
auto* promise = verify_cast<Promise>(promise_object);
|
||||||
|
|
|
@ -8,9 +8,9 @@
|
||||||
|
|
||||||
namespace JS {
|
namespace JS {
|
||||||
|
|
||||||
DataView* DataView::create(GlobalObject& global_object, ArrayBuffer* viewed_buffer, size_t byte_length, size_t byte_offset)
|
DataView* DataView::create(Realm& realm, ArrayBuffer* viewed_buffer, size_t byte_length, size_t byte_offset)
|
||||||
{
|
{
|
||||||
return global_object.heap().allocate<DataView>(global_object, viewed_buffer, byte_length, byte_offset, *global_object.data_view_prototype());
|
return realm.heap().allocate<DataView>(realm.global_object(), viewed_buffer, byte_length, byte_offset, *realm.global_object().data_view_prototype());
|
||||||
}
|
}
|
||||||
|
|
||||||
DataView::DataView(ArrayBuffer* viewed_buffer, size_t byte_length, size_t byte_offset, Object& prototype)
|
DataView::DataView(ArrayBuffer* viewed_buffer, size_t byte_length, size_t byte_offset, Object& prototype)
|
||||||
|
|
|
@ -16,7 +16,7 @@ class DataView : public Object {
|
||||||
JS_OBJECT(DataView, Object);
|
JS_OBJECT(DataView, Object);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static DataView* create(GlobalObject&, ArrayBuffer*, size_t byte_length, size_t byte_offset);
|
static DataView* create(Realm&, ArrayBuffer*, size_t byte_length, size_t byte_offset);
|
||||||
|
|
||||||
explicit DataView(ArrayBuffer*, size_t byte_length, size_t byte_offset, Object& prototype);
|
explicit DataView(ArrayBuffer*, size_t byte_length, size_t byte_offset, Object& prototype);
|
||||||
virtual ~DataView() override = default;
|
virtual ~DataView() override = default;
|
||||||
|
|
|
@ -16,9 +16,9 @@
|
||||||
|
|
||||||
namespace JS {
|
namespace JS {
|
||||||
|
|
||||||
Date* Date::create(GlobalObject& global_object, double date_value)
|
Date* Date::create(Realm& realm, double date_value)
|
||||||
{
|
{
|
||||||
return global_object.heap().allocate<Date>(global_object, date_value, *global_object.date_prototype());
|
return realm.heap().allocate<Date>(realm.global_object(), date_value, *realm.global_object().date_prototype());
|
||||||
}
|
}
|
||||||
|
|
||||||
Date::Date(double date_value, Object& prototype)
|
Date::Date(double date_value, Object& prototype)
|
||||||
|
|
|
@ -15,7 +15,7 @@ class Date final : public Object {
|
||||||
JS_OBJECT(Date, Object);
|
JS_OBJECT(Date, Object);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static Date* create(GlobalObject&, double date_value);
|
static Date* create(Realm&, double date_value);
|
||||||
static Date* now(GlobalObject&);
|
static Date* now(GlobalObject&);
|
||||||
|
|
||||||
Date(double date_value, Object& prototype);
|
Date(double date_value, Object& prototype);
|
||||||
|
|
|
@ -28,29 +28,29 @@
|
||||||
|
|
||||||
namespace JS {
|
namespace JS {
|
||||||
|
|
||||||
ECMAScriptFunctionObject* ECMAScriptFunctionObject::create(GlobalObject& global_object, FlyString name, String source_text, Statement const& ecmascript_code, Vector<FunctionNode::Parameter> parameters, i32 m_function_length, Environment* parent_environment, PrivateEnvironment* private_environment, FunctionKind kind, bool is_strict, bool might_need_arguments_object, bool contains_direct_call_to_eval, bool is_arrow_function, Variant<PropertyKey, PrivateName, Empty> class_field_initializer_name)
|
ECMAScriptFunctionObject* ECMAScriptFunctionObject::create(Realm& realm, FlyString name, String source_text, Statement const& ecmascript_code, Vector<FunctionNode::Parameter> parameters, i32 m_function_length, Environment* parent_environment, PrivateEnvironment* private_environment, FunctionKind kind, bool is_strict, bool might_need_arguments_object, bool contains_direct_call_to_eval, bool is_arrow_function, Variant<PropertyKey, PrivateName, Empty> class_field_initializer_name)
|
||||||
{
|
{
|
||||||
Object* prototype = nullptr;
|
Object* prototype = nullptr;
|
||||||
switch (kind) {
|
switch (kind) {
|
||||||
case FunctionKind::Normal:
|
case FunctionKind::Normal:
|
||||||
prototype = global_object.function_prototype();
|
prototype = realm.global_object().function_prototype();
|
||||||
break;
|
break;
|
||||||
case FunctionKind::Generator:
|
case FunctionKind::Generator:
|
||||||
prototype = global_object.generator_function_prototype();
|
prototype = realm.global_object().generator_function_prototype();
|
||||||
break;
|
break;
|
||||||
case FunctionKind::Async:
|
case FunctionKind::Async:
|
||||||
prototype = global_object.async_function_prototype();
|
prototype = realm.global_object().async_function_prototype();
|
||||||
break;
|
break;
|
||||||
case FunctionKind::AsyncGenerator:
|
case FunctionKind::AsyncGenerator:
|
||||||
prototype = global_object.async_generator_function_prototype();
|
prototype = realm.global_object().async_generator_function_prototype();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return global_object.heap().allocate<ECMAScriptFunctionObject>(global_object, move(name), move(source_text), ecmascript_code, move(parameters), m_function_length, parent_environment, private_environment, *prototype, kind, is_strict, might_need_arguments_object, contains_direct_call_to_eval, is_arrow_function, move(class_field_initializer_name));
|
return realm.heap().allocate<ECMAScriptFunctionObject>(realm.global_object(), move(name), move(source_text), ecmascript_code, move(parameters), m_function_length, parent_environment, private_environment, *prototype, kind, is_strict, might_need_arguments_object, contains_direct_call_to_eval, is_arrow_function, move(class_field_initializer_name));
|
||||||
}
|
}
|
||||||
|
|
||||||
ECMAScriptFunctionObject* ECMAScriptFunctionObject::create(GlobalObject& global_object, FlyString name, Object& prototype, String source_text, Statement const& ecmascript_code, Vector<FunctionNode::Parameter> parameters, i32 m_function_length, Environment* parent_environment, PrivateEnvironment* private_environment, FunctionKind kind, bool is_strict, bool might_need_arguments_object, bool contains_direct_call_to_eval, bool is_arrow_function, Variant<PropertyKey, PrivateName, Empty> class_field_initializer_name)
|
ECMAScriptFunctionObject* ECMAScriptFunctionObject::create(Realm& realm, FlyString name, Object& prototype, String source_text, Statement const& ecmascript_code, Vector<FunctionNode::Parameter> parameters, i32 m_function_length, Environment* parent_environment, PrivateEnvironment* private_environment, FunctionKind kind, bool is_strict, bool might_need_arguments_object, bool contains_direct_call_to_eval, bool is_arrow_function, Variant<PropertyKey, PrivateName, Empty> class_field_initializer_name)
|
||||||
{
|
{
|
||||||
return global_object.heap().allocate<ECMAScriptFunctionObject>(global_object, move(name), move(source_text), ecmascript_code, move(parameters), m_function_length, parent_environment, private_environment, prototype, kind, is_strict, might_need_arguments_object, contains_direct_call_to_eval, is_arrow_function, move(class_field_initializer_name));
|
return realm.heap().allocate<ECMAScriptFunctionObject>(realm.global_object(), move(name), move(source_text), ecmascript_code, move(parameters), m_function_length, parent_environment, private_environment, prototype, kind, is_strict, might_need_arguments_object, contains_direct_call_to_eval, is_arrow_function, move(class_field_initializer_name));
|
||||||
}
|
}
|
||||||
|
|
||||||
ECMAScriptFunctionObject::ECMAScriptFunctionObject(FlyString name, String source_text, Statement const& ecmascript_code, Vector<FunctionNode::Parameter> formal_parameters, i32 function_length, Environment* parent_environment, PrivateEnvironment* private_environment, Object& prototype, FunctionKind kind, bool strict, bool might_need_arguments_object, bool contains_direct_call_to_eval, bool is_arrow_function, Variant<PropertyKey, PrivateName, Empty> class_field_initializer_name)
|
ECMAScriptFunctionObject::ECMAScriptFunctionObject(FlyString name, String source_text, Statement const& ecmascript_code, Vector<FunctionNode::Parameter> formal_parameters, i32 function_length, Environment* parent_environment, PrivateEnvironment* private_environment, Object& prototype, FunctionKind kind, bool strict, bool might_need_arguments_object, bool contains_direct_call_to_eval, bool is_arrow_function, Variant<PropertyKey, PrivateName, Empty> class_field_initializer_name)
|
||||||
|
@ -119,12 +119,12 @@ void ECMAScriptFunctionObject::initialize(Realm& realm)
|
||||||
break;
|
break;
|
||||||
case FunctionKind::Generator:
|
case FunctionKind::Generator:
|
||||||
// prototype is "g1.prototype" in figure-2 (https://tc39.es/ecma262/img/figure-2.png)
|
// prototype is "g1.prototype" in figure-2 (https://tc39.es/ecma262/img/figure-2.png)
|
||||||
prototype = Object::create(realm.global_object(), realm.global_object().generator_function_prototype_prototype());
|
prototype = Object::create(realm, realm.global_object().generator_function_prototype_prototype());
|
||||||
break;
|
break;
|
||||||
case FunctionKind::Async:
|
case FunctionKind::Async:
|
||||||
break;
|
break;
|
||||||
case FunctionKind::AsyncGenerator:
|
case FunctionKind::AsyncGenerator:
|
||||||
prototype = Object::create(realm.global_object(), realm.global_object().async_generator_function_prototype_prototype());
|
prototype = Object::create(realm, realm.global_object().async_generator_function_prototype_prototype());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
// 27.7.4 AsyncFunction Instances, https://tc39.es/ecma262/#sec-async-function-instances
|
// 27.7.4 AsyncFunction Instances, https://tc39.es/ecma262/#sec-async-function-instances
|
||||||
|
@ -319,6 +319,8 @@ void ECMAScriptFunctionObject::make_method(Object& home_object)
|
||||||
ThrowCompletionOr<void> ECMAScriptFunctionObject::function_declaration_instantiation(Interpreter* interpreter)
|
ThrowCompletionOr<void> ECMAScriptFunctionObject::function_declaration_instantiation(Interpreter* interpreter)
|
||||||
{
|
{
|
||||||
auto& vm = this->vm();
|
auto& vm = this->vm();
|
||||||
|
auto& global_object = this->global_object();
|
||||||
|
auto& realm = *global_object.associated_realm();
|
||||||
|
|
||||||
auto& callee_context = vm.running_execution_context();
|
auto& callee_context = vm.running_execution_context();
|
||||||
|
|
||||||
|
@ -399,24 +401,24 @@ ThrowCompletionOr<void> ECMAScriptFunctionObject::function_declaration_instantia
|
||||||
if (MUST(environment->has_binding(parameter_name)))
|
if (MUST(environment->has_binding(parameter_name)))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
MUST(environment->create_mutable_binding(global_object(), parameter_name, false));
|
MUST(environment->create_mutable_binding(global_object, parameter_name, false));
|
||||||
if (has_duplicates)
|
if (has_duplicates)
|
||||||
MUST(environment->initialize_binding(global_object(), parameter_name, js_undefined()));
|
MUST(environment->initialize_binding(global_object, parameter_name, js_undefined()));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (arguments_object_needed) {
|
if (arguments_object_needed) {
|
||||||
Object* arguments_object;
|
Object* arguments_object;
|
||||||
if (is_strict_mode() || !has_simple_parameter_list())
|
if (is_strict_mode() || !has_simple_parameter_list())
|
||||||
arguments_object = create_unmapped_arguments_object(global_object(), vm.running_execution_context().arguments);
|
arguments_object = create_unmapped_arguments_object(global_object, vm.running_execution_context().arguments);
|
||||||
else
|
else
|
||||||
arguments_object = create_mapped_arguments_object(global_object(), *this, formal_parameters(), vm.running_execution_context().arguments, *environment);
|
arguments_object = create_mapped_arguments_object(global_object, *this, formal_parameters(), vm.running_execution_context().arguments, *environment);
|
||||||
|
|
||||||
if (is_strict_mode())
|
if (is_strict_mode())
|
||||||
MUST(environment->create_immutable_binding(global_object(), vm.names.arguments.as_string(), false));
|
MUST(environment->create_immutable_binding(global_object, vm.names.arguments.as_string(), false));
|
||||||
else
|
else
|
||||||
MUST(environment->create_mutable_binding(global_object(), vm.names.arguments.as_string(), false));
|
MUST(environment->create_mutable_binding(global_object, vm.names.arguments.as_string(), false));
|
||||||
|
|
||||||
MUST(environment->initialize_binding(global_object(), vm.names.arguments.as_string(), arguments_object));
|
MUST(environment->initialize_binding(global_object, vm.names.arguments.as_string(), arguments_object));
|
||||||
parameter_names.set(vm.names.arguments.as_string());
|
parameter_names.set(vm.names.arguments.as_string());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -435,7 +437,7 @@ ThrowCompletionOr<void> ECMAScriptFunctionObject::function_declaration_instantia
|
||||||
[&](auto const& param) -> ThrowCompletionOr<void> {
|
[&](auto const& param) -> ThrowCompletionOr<void> {
|
||||||
Value argument_value;
|
Value argument_value;
|
||||||
if (parameter.is_rest) {
|
if (parameter.is_rest) {
|
||||||
auto* array = MUST(Array::create(global_object(), 0));
|
auto* array = MUST(Array::create(realm, 0));
|
||||||
for (size_t rest_index = i; rest_index < execution_context_arguments.size(); ++rest_index)
|
for (size_t rest_index = i; rest_index < execution_context_arguments.size(); ++rest_index)
|
||||||
array->indexed_properties().append(execution_context_arguments[rest_index]);
|
array->indexed_properties().append(execution_context_arguments[rest_index]);
|
||||||
argument_value = array;
|
argument_value = array;
|
||||||
|
@ -449,7 +451,7 @@ ThrowCompletionOr<void> ECMAScriptFunctionObject::function_declaration_instantia
|
||||||
// Resulting value is in the accumulator.
|
// Resulting value is in the accumulator.
|
||||||
argument_value = value_and_frame.frame->registers.at(0);
|
argument_value = value_and_frame.frame->registers.at(0);
|
||||||
} else if (interpreter) {
|
} else if (interpreter) {
|
||||||
argument_value = TRY(parameter.default_value->execute(*interpreter, global_object())).release_value();
|
argument_value = TRY(parameter.default_value->execute(*interpreter, global_object)).release_value();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
argument_value = js_undefined();
|
argument_value = js_undefined();
|
||||||
|
@ -461,12 +463,12 @@ ThrowCompletionOr<void> ECMAScriptFunctionObject::function_declaration_instantia
|
||||||
Reference reference = TRY(vm.resolve_binding(param, used_environment));
|
Reference reference = TRY(vm.resolve_binding(param, used_environment));
|
||||||
// Here the difference from hasDuplicates is important
|
// Here the difference from hasDuplicates is important
|
||||||
if (has_duplicates)
|
if (has_duplicates)
|
||||||
return reference.put_value(global_object(), argument_value);
|
return reference.put_value(global_object, argument_value);
|
||||||
else
|
else
|
||||||
return reference.initialize_referenced_binding(global_object(), argument_value);
|
return reference.initialize_referenced_binding(global_object, argument_value);
|
||||||
} else if (IsSame<NonnullRefPtr<BindingPattern> const&, decltype(param)>) {
|
} else if (IsSame<NonnullRefPtr<BindingPattern> const&, decltype(param)>) {
|
||||||
// Here the difference from hasDuplicates is important
|
// Here the difference from hasDuplicates is important
|
||||||
return vm.binding_initialization(param, argument_value, used_environment, global_object());
|
return vm.binding_initialization(param, argument_value, used_environment, global_object);
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
@ -481,8 +483,8 @@ ThrowCompletionOr<void> ECMAScriptFunctionObject::function_declaration_instantia
|
||||||
if (scope_body) {
|
if (scope_body) {
|
||||||
scope_body->for_each_var_declared_name([&](auto const& name) {
|
scope_body->for_each_var_declared_name([&](auto const& name) {
|
||||||
if (!parameter_names.contains(name) && instantiated_var_names.set(name) == AK::HashSetResult::InsertedNewEntry) {
|
if (!parameter_names.contains(name) && instantiated_var_names.set(name) == AK::HashSetResult::InsertedNewEntry) {
|
||||||
MUST(environment->create_mutable_binding(global_object(), name, false));
|
MUST(environment->create_mutable_binding(global_object, name, false));
|
||||||
MUST(environment->initialize_binding(global_object(), name, js_undefined()));
|
MUST(environment->initialize_binding(global_object, name, js_undefined()));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -495,15 +497,15 @@ ThrowCompletionOr<void> ECMAScriptFunctionObject::function_declaration_instantia
|
||||||
scope_body->for_each_var_declared_name([&](auto const& name) {
|
scope_body->for_each_var_declared_name([&](auto const& name) {
|
||||||
if (instantiated_var_names.set(name) != AK::HashSetResult::InsertedNewEntry)
|
if (instantiated_var_names.set(name) != AK::HashSetResult::InsertedNewEntry)
|
||||||
return;
|
return;
|
||||||
MUST(var_environment->create_mutable_binding(global_object(), name, false));
|
MUST(var_environment->create_mutable_binding(global_object, name, false));
|
||||||
|
|
||||||
Value initial_value;
|
Value initial_value;
|
||||||
if (!parameter_names.contains(name) || function_names.contains(name))
|
if (!parameter_names.contains(name) || function_names.contains(name))
|
||||||
initial_value = js_undefined();
|
initial_value = js_undefined();
|
||||||
else
|
else
|
||||||
initial_value = MUST(environment->get_binding_value(global_object(), name, false));
|
initial_value = MUST(environment->get_binding_value(global_object, name, false));
|
||||||
|
|
||||||
MUST(var_environment->initialize_binding(global_object(), name, initial_value));
|
MUST(var_environment->initialize_binding(global_object, name, initial_value));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -516,8 +518,8 @@ ThrowCompletionOr<void> ECMAScriptFunctionObject::function_declaration_instantia
|
||||||
return;
|
return;
|
||||||
// The spec says 'initializedBindings' here but that does not exist and it then adds it to 'instantiatedVarNames' so it probably means 'instantiatedVarNames'.
|
// The spec says 'initializedBindings' here but that does not exist and it then adds it to 'instantiatedVarNames' so it probably means 'instantiatedVarNames'.
|
||||||
if (!instantiated_var_names.contains(function_name) && function_name != vm.names.arguments.as_string()) {
|
if (!instantiated_var_names.contains(function_name) && function_name != vm.names.arguments.as_string()) {
|
||||||
MUST(var_environment->create_mutable_binding(global_object(), function_name, false));
|
MUST(var_environment->create_mutable_binding(global_object, function_name, false));
|
||||||
MUST(var_environment->initialize_binding(global_object(), function_name, js_undefined()));
|
MUST(var_environment->initialize_binding(global_object, function_name, js_undefined()));
|
||||||
instantiated_var_names.set(function_name);
|
instantiated_var_names.set(function_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -558,17 +560,17 @@ ThrowCompletionOr<void> ECMAScriptFunctionObject::function_declaration_instantia
|
||||||
scope_body->for_each_lexically_scoped_declaration([&](Declaration const& declaration) {
|
scope_body->for_each_lexically_scoped_declaration([&](Declaration const& declaration) {
|
||||||
declaration.for_each_bound_name([&](auto const& name) {
|
declaration.for_each_bound_name([&](auto const& name) {
|
||||||
if (declaration.is_constant_declaration())
|
if (declaration.is_constant_declaration())
|
||||||
MUST(lex_environment->create_immutable_binding(global_object(), name, true));
|
MUST(lex_environment->create_immutable_binding(global_object, name, true));
|
||||||
else
|
else
|
||||||
MUST(lex_environment->create_mutable_binding(global_object(), name, false));
|
MUST(lex_environment->create_mutable_binding(global_object, name, false));
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
auto* private_environment = callee_context.private_environment;
|
auto* private_environment = callee_context.private_environment;
|
||||||
for (auto& declaration : functions_to_initialize) {
|
for (auto& declaration : functions_to_initialize) {
|
||||||
auto* function = ECMAScriptFunctionObject::create(global_object(), declaration.name(), declaration.source_text(), declaration.body(), declaration.parameters(), declaration.function_length(), lex_environment, private_environment, declaration.kind(), declaration.is_strict_mode(), declaration.might_need_arguments_object(), declaration.contains_direct_call_to_eval());
|
auto* function = ECMAScriptFunctionObject::create(realm, declaration.name(), declaration.source_text(), declaration.body(), declaration.parameters(), declaration.function_length(), lex_environment, private_environment, declaration.kind(), declaration.is_strict_mode(), declaration.might_need_arguments_object(), declaration.contains_direct_call_to_eval());
|
||||||
MUST(var_environment->set_mutable_binding(global_object(), declaration.name(), function, false));
|
MUST(var_environment->set_mutable_binding(global_object, declaration.name(), function, false));
|
||||||
}
|
}
|
||||||
|
|
||||||
return {};
|
return {};
|
||||||
|
@ -717,14 +719,16 @@ void ECMAScriptFunctionObject::async_function_start(PromiseCapability const& pro
|
||||||
// 27.7.5.2 AsyncBlockStart ( promiseCapability, asyncBody, asyncContext ), https://tc39.es/ecma262/#sec-asyncblockstart
|
// 27.7.5.2 AsyncBlockStart ( promiseCapability, asyncBody, asyncContext ), https://tc39.es/ecma262/#sec-asyncblockstart
|
||||||
void async_block_start(VM& vm, NonnullRefPtr<Statement> const& async_body, PromiseCapability const& promise_capability, ExecutionContext& async_context)
|
void async_block_start(VM& vm, NonnullRefPtr<Statement> const& async_body, PromiseCapability const& promise_capability, ExecutionContext& async_context)
|
||||||
{
|
{
|
||||||
auto& global_object = vm.current_realm()->global_object();
|
auto& realm = *vm.current_realm();
|
||||||
|
auto& global_object = realm.global_object();
|
||||||
|
|
||||||
// 1. Assert: promiseCapability is a PromiseCapability Record.
|
// 1. Assert: promiseCapability is a PromiseCapability Record.
|
||||||
|
|
||||||
// 2. Let runningContext be the running execution context.
|
// 2. Let runningContext be the running execution context.
|
||||||
auto& running_context = vm.running_execution_context();
|
auto& running_context = vm.running_execution_context();
|
||||||
|
|
||||||
// 3. Set the code evaluation state of asyncContext such that when evaluation is resumed for that execution context the following steps will be performed:
|
// 3. Set the code evaluation state of asyncContext such that when evaluation is resumed for that execution context the following steps will be performed:
|
||||||
auto* execution_steps = NativeFunction::create(global_object, "", [&async_body, &promise_capability](auto& vm, auto& global_object) -> ThrowCompletionOr<Value> {
|
auto* execution_steps = NativeFunction::create(realm, "", [&async_body, &promise_capability](auto& vm, auto& global_object) -> ThrowCompletionOr<Value> {
|
||||||
// a. Let result be the result of evaluating asyncBody.
|
// a. Let result be the result of evaluating asyncBody.
|
||||||
auto result = async_body->execute(vm.interpreter(), global_object);
|
auto result = async_body->execute(vm.interpreter(), global_object);
|
||||||
|
|
||||||
|
@ -778,10 +782,12 @@ void async_block_start(VM& vm, NonnullRefPtr<Statement> const& async_body, Promi
|
||||||
Completion ECMAScriptFunctionObject::ordinary_call_evaluate_body()
|
Completion ECMAScriptFunctionObject::ordinary_call_evaluate_body()
|
||||||
{
|
{
|
||||||
auto& vm = this->vm();
|
auto& vm = this->vm();
|
||||||
|
auto& global_object = this->global_object();
|
||||||
|
auto& realm = *global_object.associated_realm();
|
||||||
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>(global_object, ErrorType::NotImplemented, "Async Generator function execution");
|
||||||
|
|
||||||
if (bytecode_interpreter) {
|
if (bytecode_interpreter) {
|
||||||
if (!m_bytecode_executable) {
|
if (!m_bytecode_executable) {
|
||||||
|
@ -828,23 +834,23 @@ Completion ECMAScriptFunctionObject::ordinary_call_evaluate_body()
|
||||||
if (m_kind == FunctionKind::Normal)
|
if (m_kind == FunctionKind::Normal)
|
||||||
return { Completion::Type::Return, result.value_or(js_undefined()), {} };
|
return { Completion::Type::Return, result.value_or(js_undefined()), {} };
|
||||||
|
|
||||||
auto generator_object = TRY(GeneratorObject::create(global_object(), result, this, vm.running_execution_context().copy(), move(*result_and_frame.frame)));
|
auto generator_object = TRY(GeneratorObject::create(realm, result, this, vm.running_execution_context().copy(), move(*result_and_frame.frame)));
|
||||||
|
|
||||||
// NOTE: Async functions are entirely transformed to generator functions, and wrapped in a custom driver that returns a promise
|
// NOTE: Async functions are entirely transformed to generator functions, and wrapped in a custom driver that returns a promise
|
||||||
// See AwaitExpression::generate_bytecode() for the transformation.
|
// See AwaitExpression::generate_bytecode() for the transformation.
|
||||||
if (m_kind == FunctionKind::Async)
|
if (m_kind == FunctionKind::Async)
|
||||||
return { Completion::Type::Return, TRY(AsyncFunctionDriverWrapper::create(global_object(), generator_object)), {} };
|
return { Completion::Type::Return, TRY(AsyncFunctionDriverWrapper::create(realm, generator_object)), {} };
|
||||||
|
|
||||||
VERIFY(m_kind == FunctionKind::Generator);
|
VERIFY(m_kind == FunctionKind::Generator);
|
||||||
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>(global_object, 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();
|
||||||
|
|
||||||
if (!ast_interpreter) {
|
if (!ast_interpreter) {
|
||||||
local_interpreter = Interpreter::create_with_existing_realm(*realm());
|
local_interpreter = Interpreter::create_with_existing_realm(realm);
|
||||||
ast_interpreter = local_interpreter.ptr();
|
ast_interpreter = local_interpreter.ptr();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -856,12 +862,12 @@ Completion ECMAScriptFunctionObject::ordinary_call_evaluate_body()
|
||||||
TRY(function_declaration_instantiation(ast_interpreter));
|
TRY(function_declaration_instantiation(ast_interpreter));
|
||||||
|
|
||||||
// 2. Return the result of evaluating FunctionStatementList.
|
// 2. Return the result of evaluating FunctionStatementList.
|
||||||
return m_ecmascript_code->execute(*ast_interpreter, global_object());
|
return m_ecmascript_code->execute(*ast_interpreter, global_object);
|
||||||
}
|
}
|
||||||
// AsyncFunctionBody : FunctionBody
|
// AsyncFunctionBody : FunctionBody
|
||||||
else if (m_kind == FunctionKind::Async) {
|
else if (m_kind == FunctionKind::Async) {
|
||||||
// 1. Let promiseCapability be ! NewPromiseCapability(%Promise%).
|
// 1. Let promiseCapability be ! NewPromiseCapability(%Promise%).
|
||||||
auto promise_capability = MUST(new_promise_capability(global_object(), global_object().promise_constructor()));
|
auto promise_capability = MUST(new_promise_capability(global_object, global_object.promise_constructor()));
|
||||||
|
|
||||||
// 2. Let declResult be Completion(FunctionDeclarationInstantiation(functionObject, argumentsList)).
|
// 2. Let declResult be Completion(FunctionDeclarationInstantiation(functionObject, argumentsList)).
|
||||||
auto declaration_result = function_declaration_instantiation(ast_interpreter);
|
auto declaration_result = function_declaration_instantiation(ast_interpreter);
|
||||||
|
@ -869,7 +875,7 @@ Completion ECMAScriptFunctionObject::ordinary_call_evaluate_body()
|
||||||
// 3. If declResult is an abrupt completion, then
|
// 3. If declResult is an abrupt completion, then
|
||||||
if (declaration_result.is_throw_completion()) {
|
if (declaration_result.is_throw_completion()) {
|
||||||
// a. Perform ! Call(promiseCapability.[[Reject]], undefined, « declResult.[[Value]] »).
|
// a. Perform ! Call(promiseCapability.[[Reject]], undefined, « declResult.[[Value]] »).
|
||||||
MUST(call(global_object(), promise_capability.reject, js_undefined(), *declaration_result.throw_completion().value()));
|
MUST(call(global_object, promise_capability.reject, js_undefined(), *declaration_result.throw_completion().value()));
|
||||||
}
|
}
|
||||||
// 4. Else,
|
// 4. Else,
|
||||||
else {
|
else {
|
||||||
|
|
|
@ -32,8 +32,8 @@ public:
|
||||||
Global,
|
Global,
|
||||||
};
|
};
|
||||||
|
|
||||||
static ECMAScriptFunctionObject* create(GlobalObject&, FlyString name, String source_text, Statement const& ecmascript_code, Vector<FunctionNode::Parameter> parameters, i32 m_function_length, Environment* parent_environment, PrivateEnvironment* private_environment, FunctionKind, bool is_strict, bool might_need_arguments_object = true, bool contains_direct_call_to_eval = true, bool is_arrow_function = false, Variant<PropertyKey, PrivateName, Empty> class_field_initializer_name = {});
|
static ECMAScriptFunctionObject* create(Realm&, FlyString name, String source_text, Statement const& ecmascript_code, Vector<FunctionNode::Parameter> parameters, i32 m_function_length, Environment* parent_environment, PrivateEnvironment* private_environment, FunctionKind, bool is_strict, bool might_need_arguments_object = true, bool contains_direct_call_to_eval = true, bool is_arrow_function = false, Variant<PropertyKey, PrivateName, Empty> class_field_initializer_name = {});
|
||||||
static ECMAScriptFunctionObject* create(GlobalObject&, FlyString name, Object& prototype, String source_text, Statement const& ecmascript_code, Vector<FunctionNode::Parameter> parameters, i32 m_function_length, Environment* parent_environment, PrivateEnvironment* private_environment, FunctionKind, bool is_strict, bool might_need_arguments_object = true, bool contains_direct_call_to_eval = true, bool is_arrow_function = false, Variant<PropertyKey, PrivateName, Empty> class_field_initializer_name = {});
|
static ECMAScriptFunctionObject* create(Realm&, FlyString name, Object& prototype, String source_text, Statement const& ecmascript_code, Vector<FunctionNode::Parameter> parameters, i32 m_function_length, Environment* parent_environment, PrivateEnvironment* private_environment, FunctionKind, bool is_strict, bool might_need_arguments_object = true, bool contains_direct_call_to_eval = true, bool is_arrow_function = false, Variant<PropertyKey, PrivateName, Empty> class_field_initializer_name = {});
|
||||||
|
|
||||||
ECMAScriptFunctionObject(FlyString name, String source_text, Statement const& ecmascript_code, Vector<FunctionNode::Parameter> parameters, i32 m_function_length, Environment* parent_environment, PrivateEnvironment* private_environment, Object& prototype, FunctionKind, bool is_strict, bool might_need_arguments_object, bool contains_direct_call_to_eval, bool is_arrow_function, Variant<PropertyKey, PrivateName, Empty> class_field_initializer_name);
|
ECMAScriptFunctionObject(FlyString name, String source_text, Statement const& ecmascript_code, Vector<FunctionNode::Parameter> parameters, i32 m_function_length, Environment* parent_environment, PrivateEnvironment* private_environment, Object& prototype, FunctionKind, bool is_strict, bool might_need_arguments_object, bool contains_direct_call_to_eval, bool is_arrow_function, Variant<PropertyKey, PrivateName, Empty> class_field_initializer_name);
|
||||||
virtual void initialize(Realm&) override;
|
virtual void initialize(Realm&) override;
|
||||||
|
|
|
@ -14,15 +14,15 @@
|
||||||
|
|
||||||
namespace JS {
|
namespace JS {
|
||||||
|
|
||||||
Error* Error::create(GlobalObject& global_object)
|
Error* Error::create(Realm& realm)
|
||||||
{
|
{
|
||||||
return global_object.heap().allocate<Error>(global_object, *global_object.error_prototype());
|
return realm.heap().allocate<Error>(realm.global_object(), *realm.global_object().error_prototype());
|
||||||
}
|
}
|
||||||
|
|
||||||
Error* Error::create(GlobalObject& global_object, String const& message)
|
Error* Error::create(Realm& realm, String const& message)
|
||||||
{
|
{
|
||||||
auto& vm = global_object.vm();
|
auto& vm = realm.vm();
|
||||||
auto* error = Error::create(global_object);
|
auto* error = Error::create(realm);
|
||||||
u8 attr = Attribute::Writable | Attribute::Configurable;
|
u8 attr = Attribute::Writable | Attribute::Configurable;
|
||||||
error->define_direct_property(vm.names.message, js_string(vm, message), attr);
|
error->define_direct_property(vm.names.message, js_string(vm, message), attr);
|
||||||
return error;
|
return error;
|
||||||
|
@ -97,15 +97,16 @@ String Error::stack_string() const
|
||||||
}
|
}
|
||||||
|
|
||||||
#define __JS_ENUMERATE(ClassName, snake_name, PrototypeName, ConstructorName, ArrayType) \
|
#define __JS_ENUMERATE(ClassName, snake_name, PrototypeName, ConstructorName, ArrayType) \
|
||||||
ClassName* ClassName::create(GlobalObject& global_object) \
|
ClassName* ClassName::create(Realm& realm) \
|
||||||
{ \
|
{ \
|
||||||
return global_object.heap().allocate<ClassName>(global_object, *global_object.snake_name##_prototype()); \
|
return realm.heap().allocate<ClassName>( \
|
||||||
|
realm.global_object(), *realm.global_object().snake_name##_prototype()); /* */ \
|
||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
ClassName* ClassName::create(GlobalObject& global_object, String const& message) \
|
ClassName* ClassName::create(Realm& realm, String const& message) \
|
||||||
{ \
|
{ \
|
||||||
auto& vm = global_object.vm(); \
|
auto& vm = realm.vm(); \
|
||||||
auto* error = ClassName::create(global_object); \
|
auto* error = ClassName::create(realm); \
|
||||||
u8 attr = Attribute::Writable | Attribute::Configurable; \
|
u8 attr = Attribute::Writable | Attribute::Configurable; \
|
||||||
error->define_direct_property(vm.names.message, js_string(vm, message), attr); \
|
error->define_direct_property(vm.names.message, js_string(vm, message), attr); \
|
||||||
return error; \
|
return error; \
|
||||||
|
|
|
@ -23,8 +23,8 @@ class Error : public Object {
|
||||||
JS_OBJECT(Error, Object);
|
JS_OBJECT(Error, Object);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static Error* create(GlobalObject&);
|
static Error* create(Realm&);
|
||||||
static Error* create(GlobalObject&, String const& message);
|
static Error* create(Realm&, String const& message);
|
||||||
|
|
||||||
explicit Error(Object& prototype);
|
explicit Error(Object& prototype);
|
||||||
virtual ~Error() override = default;
|
virtual ~Error() override = default;
|
||||||
|
@ -48,8 +48,8 @@ private:
|
||||||
JS_OBJECT(ClassName, Error); \
|
JS_OBJECT(ClassName, Error); \
|
||||||
\
|
\
|
||||||
public: \
|
public: \
|
||||||
static ClassName* create(GlobalObject&); \
|
static ClassName* create(Realm&); \
|
||||||
static ClassName* create(GlobalObject&, String const& message); \
|
static ClassName* create(Realm&, String const& message); \
|
||||||
\
|
\
|
||||||
explicit ClassName(Object& prototype); \
|
explicit ClassName(Object& prototype); \
|
||||||
virtual ~ClassName() override = default; \
|
virtual ~ClassName() override = default; \
|
||||||
|
|
|
@ -217,16 +217,16 @@ ThrowCompletionOr<ECMAScriptFunctionObject*> FunctionConstructor::create_dynamic
|
||||||
auto* prototype = TRY(get_prototype_from_constructor(global_object, *new_target, fallback_prototype));
|
auto* prototype = TRY(get_prototype_from_constructor(global_object, *new_target, fallback_prototype));
|
||||||
|
|
||||||
// 25. Let realmF be the current Realm Record.
|
// 25. Let realmF be the current Realm Record.
|
||||||
auto* realm = vm.current_realm();
|
auto& realm = *vm.current_realm();
|
||||||
|
|
||||||
// 26. Let env be realmF.[[GlobalEnv]].
|
// 26. Let env be realmF.[[GlobalEnv]].
|
||||||
auto* environment = &realm->global_environment();
|
auto& environment = realm.global_environment();
|
||||||
|
|
||||||
// 27. Let privateEnv be null.
|
// 27. Let privateEnv be null.
|
||||||
PrivateEnvironment* private_environment = nullptr;
|
PrivateEnvironment* private_environment = nullptr;
|
||||||
|
|
||||||
// 28. Let F be OrdinaryFunctionCreate(proto, sourceText, parameters, body, non-lexical-this, env, privateEnv).
|
// 28. Let F be OrdinaryFunctionCreate(proto, sourceText, parameters, body, non-lexical-this, env, privateEnv).
|
||||||
auto* function = ECMAScriptFunctionObject::create(global_object, "anonymous", *prototype, move(source_text), expr->body(), expr->parameters(), expr->function_length(), environment, private_environment, expr->kind(), expr->is_strict_mode(), expr->might_need_arguments_object(), contains_direct_call_to_eval);
|
auto* function = ECMAScriptFunctionObject::create(realm, "anonymous", *prototype, move(source_text), expr->body(), expr->parameters(), expr->function_length(), &environment, private_environment, expr->kind(), expr->is_strict_mode(), expr->might_need_arguments_object(), contains_direct_call_to_eval);
|
||||||
|
|
||||||
// FIXME: Remove the name argument from create() and do this instead.
|
// FIXME: Remove the name argument from create() and do this instead.
|
||||||
// 29. Perform SetFunctionName(F, "anonymous").
|
// 29. Perform SetFunctionName(F, "anonymous").
|
||||||
|
@ -234,7 +234,7 @@ ThrowCompletionOr<ECMAScriptFunctionObject*> FunctionConstructor::create_dynamic
|
||||||
// 30. If kind is generator, then
|
// 30. If kind is generator, then
|
||||||
if (kind == FunctionKind::Generator) {
|
if (kind == FunctionKind::Generator) {
|
||||||
// a. Let prototype be OrdinaryObjectCreate(%GeneratorFunction.prototype.prototype%).
|
// a. Let prototype be OrdinaryObjectCreate(%GeneratorFunction.prototype.prototype%).
|
||||||
prototype = Object::create(global_object, global_object.generator_function_prototype_prototype());
|
prototype = Object::create(realm, global_object.generator_function_prototype_prototype());
|
||||||
|
|
||||||
// b. Perform ! DefinePropertyOrThrow(F, "prototype", PropertyDescriptor { [[Value]]: prototype, [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: false }).
|
// b. Perform ! DefinePropertyOrThrow(F, "prototype", PropertyDescriptor { [[Value]]: prototype, [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: false }).
|
||||||
function->define_direct_property(vm.names.prototype, prototype, Attribute::Writable);
|
function->define_direct_property(vm.names.prototype, prototype, Attribute::Writable);
|
||||||
|
@ -242,7 +242,7 @@ ThrowCompletionOr<ECMAScriptFunctionObject*> FunctionConstructor::create_dynamic
|
||||||
// 31. Else if kind is asyncGenerator, then
|
// 31. Else if kind is asyncGenerator, then
|
||||||
else if (kind == FunctionKind::AsyncGenerator) {
|
else if (kind == FunctionKind::AsyncGenerator) {
|
||||||
// a. Let prototype be OrdinaryObjectCreate(%AsyncGeneratorFunction.prototype.prototype%).
|
// a. Let prototype be OrdinaryObjectCreate(%AsyncGeneratorFunction.prototype.prototype%).
|
||||||
prototype = Object::create(global_object, global_object.async_generator_function_prototype_prototype());
|
prototype = Object::create(realm, global_object.async_generator_function_prototype_prototype());
|
||||||
|
|
||||||
// b. Perform ! DefinePropertyOrThrow(F, "prototype", PropertyDescriptor { [[Value]]: prototype, [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: false }).
|
// b. Perform ! DefinePropertyOrThrow(F, "prototype", PropertyDescriptor { [[Value]]: prototype, [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: false }).
|
||||||
function->define_direct_property(vm.names.prototype, prototype, Attribute::Writable);
|
function->define_direct_property(vm.names.prototype, prototype, Attribute::Writable);
|
||||||
|
@ -250,7 +250,7 @@ ThrowCompletionOr<ECMAScriptFunctionObject*> FunctionConstructor::create_dynamic
|
||||||
// 32. Else if kind is normal, perform MakeConstructor(F).
|
// 32. Else if kind is normal, perform MakeConstructor(F).
|
||||||
else if (kind == FunctionKind::Normal) {
|
else if (kind == FunctionKind::Normal) {
|
||||||
// FIXME: Implement MakeConstructor
|
// FIXME: Implement MakeConstructor
|
||||||
prototype = Object::create(global_object, global_object.object_prototype());
|
prototype = Object::create(realm, global_object.object_prototype());
|
||||||
prototype->define_direct_property(vm.names.constructor, function, Attribute::Writable | Attribute::Configurable);
|
prototype->define_direct_property(vm.names.constructor, function, Attribute::Writable | Attribute::Configurable);
|
||||||
function->define_direct_property(vm.names.prototype, prototype, Attribute::Writable);
|
function->define_direct_property(vm.names.prototype, prototype, Attribute::Writable);
|
||||||
}
|
}
|
||||||
|
|
|
@ -82,6 +82,8 @@ JS_DEFINE_NATIVE_FUNCTION(FunctionPrototype::apply)
|
||||||
// 3.1.2.1 Function.prototype.bind ( thisArg, ...args ), https://tc39.es/proposal-shadowrealm/#sec-function.prototype.bind
|
// 3.1.2.1 Function.prototype.bind ( thisArg, ...args ), https://tc39.es/proposal-shadowrealm/#sec-function.prototype.bind
|
||||||
JS_DEFINE_NATIVE_FUNCTION(FunctionPrototype::bind)
|
JS_DEFINE_NATIVE_FUNCTION(FunctionPrototype::bind)
|
||||||
{
|
{
|
||||||
|
auto& realm = *global_object.associated_realm();
|
||||||
|
|
||||||
auto this_argument = vm.argument(0);
|
auto this_argument = vm.argument(0);
|
||||||
|
|
||||||
// 1. Let Target be the this value.
|
// 1. Let Target be the this value.
|
||||||
|
@ -100,7 +102,7 @@ JS_DEFINE_NATIVE_FUNCTION(FunctionPrototype::bind)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 3. Let F be ? BoundFunctionCreate(Target, thisArg, args).
|
// 3. Let F be ? BoundFunctionCreate(Target, thisArg, args).
|
||||||
auto* function = TRY(BoundFunction::create(global_object, target, this_argument, move(arguments)));
|
auto* function = TRY(BoundFunction::create(realm, target, this_argument, move(arguments)));
|
||||||
|
|
||||||
// 4. Let argCount be the number of elements in args.
|
// 4. Let argCount be the number of elements in args.
|
||||||
auto arg_count = vm.argument_count() > 0 ? vm.argument_count() - 1 : 0;
|
auto arg_count = vm.argument_count() > 0 ? vm.argument_count() - 1 : 0;
|
||||||
|
|
|
@ -13,22 +13,21 @@
|
||||||
|
|
||||||
namespace JS {
|
namespace JS {
|
||||||
|
|
||||||
ThrowCompletionOr<GeneratorObject*> GeneratorObject::create(GlobalObject& global_object, Value initial_value, ECMAScriptFunctionObject* generating_function, ExecutionContext execution_context, Bytecode::RegisterWindow frame)
|
ThrowCompletionOr<GeneratorObject*> GeneratorObject::create(Realm& realm, Value initial_value, ECMAScriptFunctionObject* generating_function, ExecutionContext execution_context, Bytecode::RegisterWindow frame)
|
||||||
{
|
{
|
||||||
auto& realm = *global_object.associated_realm();
|
auto& vm = realm.vm();
|
||||||
|
|
||||||
// This is "g1.prototype" in figure-2 (https://tc39.es/ecma262/img/figure-2.png)
|
// This is "g1.prototype" in figure-2 (https://tc39.es/ecma262/img/figure-2.png)
|
||||||
Value generating_function_prototype;
|
Value generating_function_prototype;
|
||||||
if (generating_function->kind() == FunctionKind::Async) {
|
if (generating_function->kind() == FunctionKind::Async) {
|
||||||
// We implement async functions by transforming them to generator function in the bytecode
|
// We implement async functions by transforming them to generator function in the bytecode
|
||||||
// interpreter. However an async function does not have a prototype and should not be
|
// interpreter. However an async function does not have a prototype and should not be
|
||||||
// changed thus we hardcode the prototype.
|
// changed thus we hardcode the prototype.
|
||||||
generating_function_prototype = global_object.generator_prototype();
|
generating_function_prototype = realm.global_object().generator_prototype();
|
||||||
} else {
|
} else {
|
||||||
generating_function_prototype = TRY(generating_function->get(global_object.vm().names.prototype));
|
generating_function_prototype = TRY(generating_function->get(vm.names.prototype));
|
||||||
}
|
}
|
||||||
auto* generating_function_prototype_object = TRY(generating_function_prototype.to_object(global_object));
|
auto* generating_function_prototype_object = TRY(generating_function_prototype.to_object(realm.global_object()));
|
||||||
auto object = global_object.heap().allocate<GeneratorObject>(global_object, realm, *generating_function_prototype_object, move(execution_context));
|
auto object = realm.heap().allocate<GeneratorObject>(realm.global_object(), realm, *generating_function_prototype_object, move(execution_context));
|
||||||
object->m_generating_function = generating_function;
|
object->m_generating_function = generating_function;
|
||||||
object->m_frame = move(frame);
|
object->m_frame = move(frame);
|
||||||
object->m_previous_value = initial_value;
|
object->m_previous_value = initial_value;
|
||||||
|
@ -54,6 +53,7 @@ void GeneratorObject::visit_edges(Cell::Visitor& visitor)
|
||||||
|
|
||||||
ThrowCompletionOr<Value> GeneratorObject::next_impl(VM& vm, GlobalObject& global_object, Optional<Value> next_argument, Optional<Value> value_to_throw)
|
ThrowCompletionOr<Value> GeneratorObject::next_impl(VM& vm, GlobalObject& global_object, Optional<Value> next_argument, Optional<Value> value_to_throw)
|
||||||
{
|
{
|
||||||
|
auto& realm = *global_object.associated_realm();
|
||||||
auto bytecode_interpreter = Bytecode::Interpreter::current();
|
auto bytecode_interpreter = Bytecode::Interpreter::current();
|
||||||
VERIFY(bytecode_interpreter);
|
VERIFY(bytecode_interpreter);
|
||||||
|
|
||||||
|
@ -73,7 +73,7 @@ ThrowCompletionOr<Value> GeneratorObject::next_impl(VM& vm, GlobalObject& global
|
||||||
|
|
||||||
auto previous_generated_value = TRY(generated_value(m_previous_value));
|
auto previous_generated_value = TRY(generated_value(m_previous_value));
|
||||||
|
|
||||||
auto result = Object::create(global_object, global_object.object_prototype());
|
auto result = Object::create(realm, global_object.object_prototype());
|
||||||
result->define_direct_property("value", previous_generated_value, default_attributes);
|
result->define_direct_property("value", previous_generated_value, default_attributes);
|
||||||
|
|
||||||
if (m_done) {
|
if (m_done) {
|
||||||
|
|
|
@ -16,7 +16,7 @@ class GeneratorObject final : public Object {
|
||||||
JS_OBJECT(GeneratorObject, Object);
|
JS_OBJECT(GeneratorObject, Object);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static ThrowCompletionOr<GeneratorObject*> create(GlobalObject&, Value, ECMAScriptFunctionObject*, ExecutionContext, Bytecode::RegisterWindow);
|
static ThrowCompletionOr<GeneratorObject*> create(Realm&, Value, ECMAScriptFunctionObject*, ExecutionContext, Bytecode::RegisterWindow);
|
||||||
GeneratorObject(Realm&, Object& prototype, ExecutionContext);
|
GeneratorObject(Realm&, Object& prototype, ExecutionContext);
|
||||||
virtual void initialize(Realm&) override;
|
virtual void initialize(Realm&) override;
|
||||||
virtual ~GeneratorObject() override = default;
|
virtual ~GeneratorObject() override = default;
|
||||||
|
|
|
@ -225,9 +225,11 @@ void GlobalObject::initialize_global_object()
|
||||||
define_native_function(vm.names.eval, eval, 1, attr);
|
define_native_function(vm.names.eval, eval, 1, attr);
|
||||||
|
|
||||||
// 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(global_object(), {}, [](VM& vm, GlobalObject& global_object) {
|
m_throw_type_error_function = NativeFunction::create(
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::RestrictedFunctionPropertiesAccess);
|
realm, [](VM& vm, GlobalObject& global_object) {
|
||||||
});
|
return vm.throw_completion<TypeError>(global_object, ErrorType::RestrictedFunctionPropertiesAccess);
|
||||||
|
},
|
||||||
|
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);
|
||||||
m_throw_type_error_function->define_direct_property(vm.names.name, js_string(vm, ""), 0);
|
m_throw_type_error_function->define_direct_property(vm.names.name, js_string(vm, ""), 0);
|
||||||
MUST(m_throw_type_error_function->internal_prevent_extensions());
|
MUST(m_throw_type_error_function->internal_prevent_extensions());
|
||||||
|
|
|
@ -186,6 +186,7 @@ bool is_well_formed_unit_identifier(StringView unit_identifier)
|
||||||
ThrowCompletionOr<Vector<String>> canonicalize_locale_list(GlobalObject& global_object, Value locales)
|
ThrowCompletionOr<Vector<String>> canonicalize_locale_list(GlobalObject& global_object, Value locales)
|
||||||
{
|
{
|
||||||
auto& vm = global_object.vm();
|
auto& vm = global_object.vm();
|
||||||
|
auto& realm = *global_object.associated_realm();
|
||||||
|
|
||||||
// 1. If locales is undefined, then
|
// 1. If locales is undefined, then
|
||||||
if (locales.is_undefined()) {
|
if (locales.is_undefined()) {
|
||||||
|
@ -200,7 +201,7 @@ ThrowCompletionOr<Vector<String>> canonicalize_locale_list(GlobalObject& global_
|
||||||
// 3. If Type(locales) is String or Type(locales) is Object and locales has an [[InitializedLocale]] internal slot, then
|
// 3. If Type(locales) is String or Type(locales) is Object and locales has an [[InitializedLocale]] internal slot, then
|
||||||
if (locales.is_string() || (locales.is_object() && is<Locale>(locales.as_object()))) {
|
if (locales.is_string() || (locales.is_object() && is<Locale>(locales.as_object()))) {
|
||||||
// a. Let O be CreateArrayFromList(« locales »).
|
// a. Let O be CreateArrayFromList(« locales »).
|
||||||
object = Array::create_from(global_object, { locales });
|
object = Array::create_from(realm, { locales });
|
||||||
}
|
}
|
||||||
// 4. Else,
|
// 4. Else,
|
||||||
else {
|
else {
|
||||||
|
@ -568,6 +569,7 @@ Vector<String> best_fit_supported_locales(Vector<String> const& requested_locale
|
||||||
ThrowCompletionOr<Array*> supported_locales(GlobalObject& global_object, Vector<String> const& requested_locales, Value options)
|
ThrowCompletionOr<Array*> supported_locales(GlobalObject& global_object, Vector<String> const& requested_locales, Value options)
|
||||||
{
|
{
|
||||||
auto& vm = global_object.vm();
|
auto& vm = global_object.vm();
|
||||||
|
auto& realm = *global_object.associated_realm();
|
||||||
|
|
||||||
// 1. Set options to ? CoerceOptionsToObject(options).
|
// 1. Set options to ? CoerceOptionsToObject(options).
|
||||||
auto* options_object = TRY(coerce_options_to_object(global_object, options));
|
auto* options_object = TRY(coerce_options_to_object(global_object, options));
|
||||||
|
@ -589,16 +591,18 @@ ThrowCompletionOr<Array*> supported_locales(GlobalObject& global_object, Vector<
|
||||||
}
|
}
|
||||||
|
|
||||||
// 5. Return CreateArrayFromList(supportedLocales).
|
// 5. Return CreateArrayFromList(supportedLocales).
|
||||||
return Array::create_from<String>(global_object, supported_locales, [&vm](auto& locale) { return js_string(vm, locale); });
|
return Array::create_from<String>(realm, supported_locales, [&vm](auto& locale) { return js_string(vm, locale); });
|
||||||
}
|
}
|
||||||
|
|
||||||
// 9.2.12 CoerceOptionsToObject ( options ), https://tc39.es/ecma402/#sec-coerceoptionstoobject
|
// 9.2.12 CoerceOptionsToObject ( options ), https://tc39.es/ecma402/#sec-coerceoptionstoobject
|
||||||
ThrowCompletionOr<Object*> coerce_options_to_object(GlobalObject& global_object, Value options)
|
ThrowCompletionOr<Object*> coerce_options_to_object(GlobalObject& global_object, Value options)
|
||||||
{
|
{
|
||||||
|
auto& realm = *global_object.associated_realm();
|
||||||
|
|
||||||
// 1. If options is undefined, then
|
// 1. If options is undefined, then
|
||||||
if (options.is_undefined()) {
|
if (options.is_undefined()) {
|
||||||
// a. Return OrdinaryObjectCreate(null).
|
// a. Return OrdinaryObjectCreate(null).
|
||||||
return Object::create(global_object, nullptr);
|
return Object::create(realm, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 2. Return ? ToObject(options).
|
// 2. Return ? ToObject(options).
|
||||||
|
|
|
@ -11,10 +11,9 @@
|
||||||
|
|
||||||
namespace JS::Intl {
|
namespace JS::Intl {
|
||||||
|
|
||||||
CollatorCompareFunction* CollatorCompareFunction::create(GlobalObject& global_object, Collator& collator)
|
CollatorCompareFunction* CollatorCompareFunction::create(Realm& realm, Collator& collator)
|
||||||
{
|
{
|
||||||
auto& realm = *global_object.associated_realm();
|
return realm.heap().allocate<CollatorCompareFunction>(realm.global_object(), realm, collator);
|
||||||
return global_object.heap().allocate<CollatorCompareFunction>(global_object, realm, collator);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CollatorCompareFunction::CollatorCompareFunction(Realm& realm, Collator& collator)
|
CollatorCompareFunction::CollatorCompareFunction(Realm& realm, Collator& collator)
|
||||||
|
|
|
@ -14,7 +14,7 @@ class CollatorCompareFunction : public NativeFunction {
|
||||||
JS_OBJECT(CollatorCompareFunction, NativeFunction);
|
JS_OBJECT(CollatorCompareFunction, NativeFunction);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static CollatorCompareFunction* create(GlobalObject&, Collator&);
|
static CollatorCompareFunction* create(Realm&, Collator&);
|
||||||
|
|
||||||
CollatorCompareFunction(Realm&, Collator&);
|
CollatorCompareFunction(Realm&, Collator&);
|
||||||
virtual void initialize(Realm&) override;
|
virtual void initialize(Realm&) override;
|
||||||
|
|
|
@ -34,6 +34,8 @@ void CollatorPrototype::initialize(Realm& realm)
|
||||||
// 10.3.3 get Intl.Collator.prototype.compare, https://tc39.es/ecma402/#sec-intl.collator.prototype.compare
|
// 10.3.3 get Intl.Collator.prototype.compare, https://tc39.es/ecma402/#sec-intl.collator.prototype.compare
|
||||||
JS_DEFINE_NATIVE_FUNCTION(CollatorPrototype::compare_getter)
|
JS_DEFINE_NATIVE_FUNCTION(CollatorPrototype::compare_getter)
|
||||||
{
|
{
|
||||||
|
auto& realm = *global_object.associated_realm();
|
||||||
|
|
||||||
// 1. Let collator be the this value.
|
// 1. Let collator be the this value.
|
||||||
// 2. Perform ? RequireInternalSlot(collator, [[InitializedCollator]]).
|
// 2. Perform ? RequireInternalSlot(collator, [[InitializedCollator]]).
|
||||||
auto* collator = TRY(typed_this_object(global_object));
|
auto* collator = TRY(typed_this_object(global_object));
|
||||||
|
@ -42,7 +44,7 @@ JS_DEFINE_NATIVE_FUNCTION(CollatorPrototype::compare_getter)
|
||||||
if (!collator->bound_compare()) {
|
if (!collator->bound_compare()) {
|
||||||
// a. Let F be a new built-in function object as defined in 10.3.3.1.
|
// a. Let F be a new built-in function object as defined in 10.3.3.1.
|
||||||
// b. Set F.[[Collator]] to collator.
|
// b. Set F.[[Collator]] to collator.
|
||||||
auto* function = CollatorCompareFunction::create(global_object, *collator);
|
auto* function = CollatorCompareFunction::create(realm, *collator);
|
||||||
|
|
||||||
// c. Set collator.[[BoundCompare]] to F.
|
// c. Set collator.[[BoundCompare]] to F.
|
||||||
collator->set_bound_compare(function);
|
collator->set_bound_compare(function);
|
||||||
|
@ -55,12 +57,14 @@ JS_DEFINE_NATIVE_FUNCTION(CollatorPrototype::compare_getter)
|
||||||
// 10.3.4 Intl.Collator.prototype.resolvedOptions ( ), https://tc39.es/ecma402/#sec-intl.collator.prototype.resolvedoptions
|
// 10.3.4 Intl.Collator.prototype.resolvedOptions ( ), https://tc39.es/ecma402/#sec-intl.collator.prototype.resolvedoptions
|
||||||
JS_DEFINE_NATIVE_FUNCTION(CollatorPrototype::resolved_options)
|
JS_DEFINE_NATIVE_FUNCTION(CollatorPrototype::resolved_options)
|
||||||
{
|
{
|
||||||
|
auto& realm = *global_object.associated_realm();
|
||||||
|
|
||||||
// 1. Let collator be the this value.
|
// 1. Let collator be the this value.
|
||||||
// 2. Perform ? RequireInternalSlot(collator, [[InitializedCollator]]).
|
// 2. Perform ? RequireInternalSlot(collator, [[InitializedCollator]]).
|
||||||
auto* collator = TRY(typed_this_object(global_object));
|
auto* collator = TRY(typed_this_object(global_object));
|
||||||
|
|
||||||
// 3. Let options be OrdinaryObjectCreate(%Object.prototype%).
|
// 3. Let options be OrdinaryObjectCreate(%Object.prototype%).
|
||||||
auto* options = Object::create(global_object, global_object.object_prototype());
|
auto* options = Object::create(realm, global_object.object_prototype());
|
||||||
|
|
||||||
// 4. For each row of Table 3, except the header row, in table order, do
|
// 4. For each row of Table 3, except the header row, in table order, do
|
||||||
// a. Let p be the Property value of the current row.
|
// a. Let p be the Property value of the current row.
|
||||||
|
|
|
@ -67,6 +67,7 @@ StringView DateTimeFormat::style_to_string(Style style)
|
||||||
ThrowCompletionOr<Object*> to_date_time_options(GlobalObject& global_object, Value options_value, OptionRequired required, OptionDefaults defaults)
|
ThrowCompletionOr<Object*> to_date_time_options(GlobalObject& global_object, Value options_value, OptionRequired required, OptionDefaults defaults)
|
||||||
{
|
{
|
||||||
auto& vm = global_object.vm();
|
auto& vm = global_object.vm();
|
||||||
|
auto& realm = *global_object.associated_realm();
|
||||||
|
|
||||||
// 1. If options is undefined, let options be null; otherwise let options be ? ToObject(options).
|
// 1. If options is undefined, let options be null; otherwise let options be ? ToObject(options).
|
||||||
Object* options = nullptr;
|
Object* options = nullptr;
|
||||||
|
@ -74,7 +75,7 @@ ThrowCompletionOr<Object*> to_date_time_options(GlobalObject& global_object, Val
|
||||||
options = TRY(options_value.to_object(global_object));
|
options = TRY(options_value.to_object(global_object));
|
||||||
|
|
||||||
// 2. Let options be OrdinaryObjectCreate(options).
|
// 2. Let options be OrdinaryObjectCreate(options).
|
||||||
options = Object::create(global_object, options);
|
options = Object::create(realm, options);
|
||||||
|
|
||||||
// 3. Let needDefaults be true.
|
// 3. Let needDefaults be true.
|
||||||
bool needs_defaults = true;
|
bool needs_defaults = true;
|
||||||
|
@ -532,6 +533,7 @@ static Optional<StringView> resolve_day_period(StringView locale, StringView cal
|
||||||
ThrowCompletionOr<Vector<PatternPartition>> format_date_time_pattern(GlobalObject& global_object, DateTimeFormat& date_time_format, Vector<PatternPartition> pattern_parts, double time, Unicode::CalendarPattern const* range_format_options)
|
ThrowCompletionOr<Vector<PatternPartition>> format_date_time_pattern(GlobalObject& global_object, DateTimeFormat& date_time_format, Vector<PatternPartition> pattern_parts, double time, Unicode::CalendarPattern const* range_format_options)
|
||||||
{
|
{
|
||||||
auto& vm = global_object.vm();
|
auto& vm = global_object.vm();
|
||||||
|
auto& realm = *global_object.associated_realm();
|
||||||
|
|
||||||
// 1. Let x be TimeClip(x).
|
// 1. Let x be TimeClip(x).
|
||||||
time = time_clip(time);
|
time = time_clip(time);
|
||||||
|
@ -550,7 +552,7 @@ ThrowCompletionOr<Vector<PatternPartition>> format_date_time_pattern(GlobalObjec
|
||||||
};
|
};
|
||||||
|
|
||||||
// 4. Let nfOptions be OrdinaryObjectCreate(null).
|
// 4. Let nfOptions be OrdinaryObjectCreate(null).
|
||||||
auto* number_format_options = Object::create(global_object, nullptr);
|
auto* number_format_options = Object::create(realm, nullptr);
|
||||||
|
|
||||||
// 5. Perform ! CreateDataPropertyOrThrow(nfOptions, "useGrouping", false).
|
// 5. Perform ! CreateDataPropertyOrThrow(nfOptions, "useGrouping", false).
|
||||||
MUST(number_format_options->create_data_property_or_throw(vm.names.useGrouping, Value(false)));
|
MUST(number_format_options->create_data_property_or_throw(vm.names.useGrouping, Value(false)));
|
||||||
|
@ -559,7 +561,7 @@ ThrowCompletionOr<Vector<PatternPartition>> format_date_time_pattern(GlobalObjec
|
||||||
auto* number_format = TRY(construct_number_format(number_format_options));
|
auto* number_format = TRY(construct_number_format(number_format_options));
|
||||||
|
|
||||||
// 7. Let nf2Options be OrdinaryObjectCreate(null).
|
// 7. Let nf2Options be OrdinaryObjectCreate(null).
|
||||||
auto* number_format_options2 = Object::create(global_object, nullptr);
|
auto* number_format_options2 = Object::create(realm, nullptr);
|
||||||
|
|
||||||
// 8. Perform ! CreateDataPropertyOrThrow(nf2Options, "minimumIntegerDigits", 2).
|
// 8. Perform ! CreateDataPropertyOrThrow(nf2Options, "minimumIntegerDigits", 2).
|
||||||
MUST(number_format_options2->create_data_property_or_throw(vm.names.minimumIntegerDigits, Value(2)));
|
MUST(number_format_options2->create_data_property_or_throw(vm.names.minimumIntegerDigits, Value(2)));
|
||||||
|
@ -579,7 +581,7 @@ ThrowCompletionOr<Vector<PatternPartition>> format_date_time_pattern(GlobalObjec
|
||||||
fractional_second_digits = date_time_format.fractional_second_digits();
|
fractional_second_digits = date_time_format.fractional_second_digits();
|
||||||
|
|
||||||
// a. Let nf3Options be OrdinaryObjectCreate(null).
|
// a. Let nf3Options be OrdinaryObjectCreate(null).
|
||||||
auto* number_format_options3 = Object::create(global_object, nullptr);
|
auto* number_format_options3 = Object::create(realm, nullptr);
|
||||||
|
|
||||||
// b. Perform ! CreateDataPropertyOrThrow(nf3Options, "minimumIntegerDigits", fractionalSecondDigits).
|
// b. Perform ! CreateDataPropertyOrThrow(nf3Options, "minimumIntegerDigits", fractionalSecondDigits).
|
||||||
MUST(number_format_options3->create_data_property_or_throw(vm.names.minimumIntegerDigits, Value(*fractional_second_digits)));
|
MUST(number_format_options3->create_data_property_or_throw(vm.names.minimumIntegerDigits, Value(*fractional_second_digits)));
|
||||||
|
@ -848,12 +850,13 @@ ThrowCompletionOr<String> format_date_time(GlobalObject& global_object, DateTime
|
||||||
ThrowCompletionOr<Array*> format_date_time_to_parts(GlobalObject& global_object, DateTimeFormat& date_time_format, double time)
|
ThrowCompletionOr<Array*> format_date_time_to_parts(GlobalObject& global_object, DateTimeFormat& date_time_format, double time)
|
||||||
{
|
{
|
||||||
auto& vm = global_object.vm();
|
auto& vm = global_object.vm();
|
||||||
|
auto& realm = *global_object.associated_realm();
|
||||||
|
|
||||||
// 1. Let parts be ? PartitionDateTimePattern(dateTimeFormat, x).
|
// 1. Let parts be ? PartitionDateTimePattern(dateTimeFormat, x).
|
||||||
auto parts = TRY(partition_date_time_pattern(global_object, date_time_format, time));
|
auto parts = TRY(partition_date_time_pattern(global_object, date_time_format, time));
|
||||||
|
|
||||||
// 2. Let result be ! ArrayCreate(0).
|
// 2. Let result be ! ArrayCreate(0).
|
||||||
auto* result = MUST(Array::create(global_object, 0));
|
auto* result = MUST(Array::create(realm, 0));
|
||||||
|
|
||||||
// 3. Let n be 0.
|
// 3. Let n be 0.
|
||||||
size_t n = 0;
|
size_t n = 0;
|
||||||
|
@ -861,7 +864,7 @@ ThrowCompletionOr<Array*> format_date_time_to_parts(GlobalObject& global_object,
|
||||||
// 4. For each Record { [[Type]], [[Value]] } part in parts, do
|
// 4. For each Record { [[Type]], [[Value]] } part in parts, do
|
||||||
for (auto& part : parts) {
|
for (auto& part : parts) {
|
||||||
// a. Let O be OrdinaryObjectCreate(%Object.prototype%).
|
// a. Let O be OrdinaryObjectCreate(%Object.prototype%).
|
||||||
auto* object = Object::create(global_object, global_object.object_prototype());
|
auto* object = Object::create(realm, global_object.object_prototype());
|
||||||
|
|
||||||
// b. Perform ! CreateDataPropertyOrThrow(O, "type", part.[[Type]]).
|
// b. Perform ! CreateDataPropertyOrThrow(O, "type", part.[[Type]]).
|
||||||
MUST(object->create_data_property_or_throw(vm.names.type, js_string(vm, part.type)));
|
MUST(object->create_data_property_or_throw(vm.names.type, js_string(vm, part.type)));
|
||||||
|
@ -1164,12 +1167,13 @@ ThrowCompletionOr<String> format_date_time_range(GlobalObject& global_object, Da
|
||||||
ThrowCompletionOr<Array*> format_date_time_range_to_parts(GlobalObject& global_object, DateTimeFormat& date_time_format, double start, double end)
|
ThrowCompletionOr<Array*> format_date_time_range_to_parts(GlobalObject& global_object, DateTimeFormat& date_time_format, double start, double end)
|
||||||
{
|
{
|
||||||
auto& vm = global_object.vm();
|
auto& vm = global_object.vm();
|
||||||
|
auto& realm = *global_object.associated_realm();
|
||||||
|
|
||||||
// 1. Let parts be ? PartitionDateTimeRangePattern(dateTimeFormat, x, y).
|
// 1. Let parts be ? PartitionDateTimeRangePattern(dateTimeFormat, x, y).
|
||||||
auto parts = TRY(partition_date_time_range_pattern(global_object, date_time_format, start, end));
|
auto parts = TRY(partition_date_time_range_pattern(global_object, date_time_format, start, end));
|
||||||
|
|
||||||
// 2. Let result be ! ArrayCreate(0).
|
// 2. Let result be ! ArrayCreate(0).
|
||||||
auto* result = MUST(Array::create(global_object, 0));
|
auto* result = MUST(Array::create(realm, 0));
|
||||||
|
|
||||||
// 3. Let n be 0.
|
// 3. Let n be 0.
|
||||||
size_t n = 0;
|
size_t n = 0;
|
||||||
|
@ -1177,7 +1181,7 @@ ThrowCompletionOr<Array*> format_date_time_range_to_parts(GlobalObject& global_o
|
||||||
// 4. For each Record { [[Type]], [[Value]], [[Source]] } part in parts, do
|
// 4. For each Record { [[Type]], [[Value]], [[Source]] } part in parts, do
|
||||||
for (auto& part : parts) {
|
for (auto& part : parts) {
|
||||||
// a. Let O be OrdinaryObjectCreate(%ObjectPrototype%).
|
// a. Let O be OrdinaryObjectCreate(%ObjectPrototype%).
|
||||||
auto* object = Object::create(global_object, global_object.object_prototype());
|
auto* object = Object::create(realm, global_object.object_prototype());
|
||||||
|
|
||||||
// b. Perform ! CreateDataPropertyOrThrow(O, "type", part.[[Type]]).
|
// b. Perform ! CreateDataPropertyOrThrow(O, "type", part.[[Type]]).
|
||||||
MUST(object->create_data_property_or_throw(vm.names.type, js_string(vm, part.type)));
|
MUST(object->create_data_property_or_throw(vm.names.type, js_string(vm, part.type)));
|
||||||
|
|
|
@ -14,9 +14,9 @@
|
||||||
namespace JS::Intl {
|
namespace JS::Intl {
|
||||||
|
|
||||||
// 11.5.5 DateTime Format Functions, https://tc39.es/ecma402/#sec-datetime-format-functions
|
// 11.5.5 DateTime Format Functions, https://tc39.es/ecma402/#sec-datetime-format-functions
|
||||||
DateTimeFormatFunction* DateTimeFormatFunction::create(GlobalObject& global_object, DateTimeFormat& date_time_format)
|
DateTimeFormatFunction* DateTimeFormatFunction::create(Realm& realm, DateTimeFormat& date_time_format)
|
||||||
{
|
{
|
||||||
return global_object.heap().allocate<DateTimeFormatFunction>(global_object, date_time_format, *global_object.function_prototype());
|
return realm.heap().allocate<DateTimeFormatFunction>(realm.global_object(), date_time_format, *realm.global_object().function_prototype());
|
||||||
}
|
}
|
||||||
|
|
||||||
DateTimeFormatFunction::DateTimeFormatFunction(DateTimeFormat& date_time_format, Object& prototype)
|
DateTimeFormatFunction::DateTimeFormatFunction(DateTimeFormat& date_time_format, Object& prototype)
|
||||||
|
|
|
@ -16,7 +16,7 @@ class DateTimeFormatFunction final : public NativeFunction {
|
||||||
JS_OBJECT(DateTimeFormatFunction, NativeFunction);
|
JS_OBJECT(DateTimeFormatFunction, NativeFunction);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static DateTimeFormatFunction* create(GlobalObject&, DateTimeFormat&);
|
static DateTimeFormatFunction* create(Realm&, DateTimeFormat&);
|
||||||
|
|
||||||
explicit DateTimeFormatFunction(DateTimeFormat&, Object& prototype);
|
explicit DateTimeFormatFunction(DateTimeFormat&, Object& prototype);
|
||||||
virtual ~DateTimeFormatFunction() override = default;
|
virtual ~DateTimeFormatFunction() override = default;
|
||||||
|
|
|
@ -40,6 +40,8 @@ void DateTimeFormatPrototype::initialize(Realm& realm)
|
||||||
// 11.3.3 get Intl.DateTimeFormat.prototype.format, https://tc39.es/ecma402/#sec-intl.datetimeformat.prototype.format
|
// 11.3.3 get Intl.DateTimeFormat.prototype.format, https://tc39.es/ecma402/#sec-intl.datetimeformat.prototype.format
|
||||||
JS_DEFINE_NATIVE_FUNCTION(DateTimeFormatPrototype::format)
|
JS_DEFINE_NATIVE_FUNCTION(DateTimeFormatPrototype::format)
|
||||||
{
|
{
|
||||||
|
auto& realm = *global_object.associated_realm();
|
||||||
|
|
||||||
// 1. Let dtf be the this value.
|
// 1. Let dtf be the this value.
|
||||||
// 2. If the implementation supports the normative optional constructor mode of 4.3 Note 1, then
|
// 2. If the implementation supports the normative optional constructor mode of 4.3 Note 1, then
|
||||||
// a. Set dtf to ? UnwrapDateTimeFormat(dtf).
|
// a. Set dtf to ? UnwrapDateTimeFormat(dtf).
|
||||||
|
@ -50,7 +52,7 @@ JS_DEFINE_NATIVE_FUNCTION(DateTimeFormatPrototype::format)
|
||||||
if (!date_time_format->bound_format()) {
|
if (!date_time_format->bound_format()) {
|
||||||
// a. Let F be a new built-in function object as defined in DateTime Format Functions (11.1.6).
|
// a. Let F be a new built-in function object as defined in DateTime Format Functions (11.1.6).
|
||||||
// b. Set F.[[DateTimeFormat]] to dtf.
|
// b. Set F.[[DateTimeFormat]] to dtf.
|
||||||
auto* bound_format = DateTimeFormatFunction::create(global_object, *date_time_format);
|
auto* bound_format = DateTimeFormatFunction::create(realm, *date_time_format);
|
||||||
|
|
||||||
// c. Set dtf.[[BoundFormat]] to F.
|
// c. Set dtf.[[BoundFormat]] to F.
|
||||||
date_time_format->set_bound_format(bound_format);
|
date_time_format->set_bound_format(bound_format);
|
||||||
|
@ -142,6 +144,8 @@ JS_DEFINE_NATIVE_FUNCTION(DateTimeFormatPrototype::format_range_to_parts)
|
||||||
// 11.3.7 Intl.DateTimeFormat.prototype.resolvedOptions ( ), https://tc39.es/ecma402/#sec-intl.datetimeformat.prototype.resolvedoptions
|
// 11.3.7 Intl.DateTimeFormat.prototype.resolvedOptions ( ), https://tc39.es/ecma402/#sec-intl.datetimeformat.prototype.resolvedoptions
|
||||||
JS_DEFINE_NATIVE_FUNCTION(DateTimeFormatPrototype::resolved_options)
|
JS_DEFINE_NATIVE_FUNCTION(DateTimeFormatPrototype::resolved_options)
|
||||||
{
|
{
|
||||||
|
auto& realm = *global_object.associated_realm();
|
||||||
|
|
||||||
// 1. Let dtf be the this value.
|
// 1. Let dtf be the this value.
|
||||||
// 2. If the implementation supports the normative optional constructor mode of 4.3 Note 1, then
|
// 2. If the implementation supports the normative optional constructor mode of 4.3 Note 1, then
|
||||||
// a. Set dtf to ? UnwrapDateTimeFormat(dtf).
|
// a. Set dtf to ? UnwrapDateTimeFormat(dtf).
|
||||||
|
@ -149,7 +153,7 @@ JS_DEFINE_NATIVE_FUNCTION(DateTimeFormatPrototype::resolved_options)
|
||||||
auto* date_time_format = TRY(typed_this_object(global_object));
|
auto* date_time_format = TRY(typed_this_object(global_object));
|
||||||
|
|
||||||
// 4. Let options be OrdinaryObjectCreate(%Object.prototype%).
|
// 4. Let options be OrdinaryObjectCreate(%Object.prototype%).
|
||||||
auto* options = Object::create(global_object, global_object.object_prototype());
|
auto* options = Object::create(realm, global_object.object_prototype());
|
||||||
|
|
||||||
// 5. For each row of Table 5, except the header row, in table order, do
|
// 5. For each row of Table 5, except the header row, in table order, do
|
||||||
// a. Let p be the Property value of the current row.
|
// a. Let p be the Property value of the current row.
|
||||||
|
|
|
@ -124,12 +124,14 @@ JS_DEFINE_NATIVE_FUNCTION(DisplayNamesPrototype::of)
|
||||||
// 12.3.4 Intl.DisplayNames.prototype.resolvedOptions ( ), https://tc39.es/ecma402/#sec-Intl.DisplayNames.prototype.resolvedOptions
|
// 12.3.4 Intl.DisplayNames.prototype.resolvedOptions ( ), https://tc39.es/ecma402/#sec-Intl.DisplayNames.prototype.resolvedOptions
|
||||||
JS_DEFINE_NATIVE_FUNCTION(DisplayNamesPrototype::resolved_options)
|
JS_DEFINE_NATIVE_FUNCTION(DisplayNamesPrototype::resolved_options)
|
||||||
{
|
{
|
||||||
|
auto& realm = *global_object.associated_realm();
|
||||||
|
|
||||||
// 1. Let displayNames be this value.
|
// 1. Let displayNames be this value.
|
||||||
// 2. Perform ? RequireInternalSlot(displayNames, [[InitializedDisplayNames]]).
|
// 2. Perform ? RequireInternalSlot(displayNames, [[InitializedDisplayNames]]).
|
||||||
auto* display_names = TRY(typed_this_object(global_object));
|
auto* display_names = TRY(typed_this_object(global_object));
|
||||||
|
|
||||||
// 3. Let options be OrdinaryObjectCreate(%Object.prototype%).
|
// 3. Let options be OrdinaryObjectCreate(%Object.prototype%).
|
||||||
auto* options = Object::create(global_object, global_object.object_prototype());
|
auto* options = Object::create(realm, global_object.object_prototype());
|
||||||
|
|
||||||
// 4. For each row of Table 8, except the header row, in table order, do
|
// 4. For each row of Table 8, except the header row, in table order, do
|
||||||
// a. Let p be the Property value of the current row.
|
// a. Let p be the Property value of the current row.
|
||||||
|
|
|
@ -311,6 +311,7 @@ static String convert_number_format_pattern_to_duration_format_template(Unicode:
|
||||||
ThrowCompletionOr<Vector<PatternPartition>> partition_duration_format_pattern(GlobalObject& global_object, DurationFormat const& duration_format, Temporal::DurationRecord const& duration)
|
ThrowCompletionOr<Vector<PatternPartition>> partition_duration_format_pattern(GlobalObject& global_object, DurationFormat const& duration_format, Temporal::DurationRecord const& duration)
|
||||||
{
|
{
|
||||||
auto& vm = global_object.vm();
|
auto& vm = global_object.vm();
|
||||||
|
auto& realm = *global_object.associated_realm();
|
||||||
|
|
||||||
// 1. Let result be a new empty List.
|
// 1. Let result be a new empty List.
|
||||||
Vector<PatternPartition> result;
|
Vector<PatternPartition> result;
|
||||||
|
@ -349,7 +350,7 @@ ThrowCompletionOr<Vector<PatternPartition>> partition_duration_format_pattern(Gl
|
||||||
}
|
}
|
||||||
|
|
||||||
// h. Let nfOpts be ! OrdinaryObjectCreate(null).
|
// h. Let nfOpts be ! OrdinaryObjectCreate(null).
|
||||||
auto* number_format_options = Object::create(global_object, nullptr);
|
auto* number_format_options = Object::create(realm, nullptr);
|
||||||
|
|
||||||
// i. Let value be 0.
|
// i. Let value be 0.
|
||||||
auto value = Value(0);
|
auto value = Value(0);
|
||||||
|
|
|
@ -64,6 +64,8 @@ JS_DEFINE_NATIVE_FUNCTION(DurationFormatPrototype::format)
|
||||||
// 1.4.4 Intl.DurationFormat.prototype.formatToParts ( duration ), https://tc39.es/proposal-intl-duration-format/#sec-Intl.DurationFormat.prototype.formatToParts
|
// 1.4.4 Intl.DurationFormat.prototype.formatToParts ( duration ), https://tc39.es/proposal-intl-duration-format/#sec-Intl.DurationFormat.prototype.formatToParts
|
||||||
JS_DEFINE_NATIVE_FUNCTION(DurationFormatPrototype::format_to_parts)
|
JS_DEFINE_NATIVE_FUNCTION(DurationFormatPrototype::format_to_parts)
|
||||||
{
|
{
|
||||||
|
auto& realm = *global_object.associated_realm();
|
||||||
|
|
||||||
// 1. Let df be this value.
|
// 1. Let df be this value.
|
||||||
// 2. Perform ? RequireInternalSlot(df, [[InitializedDurationFormat]]).
|
// 2. Perform ? RequireInternalSlot(df, [[InitializedDurationFormat]]).
|
||||||
auto* duration_format = TRY(typed_this_object(global_object));
|
auto* duration_format = TRY(typed_this_object(global_object));
|
||||||
|
@ -79,7 +81,7 @@ JS_DEFINE_NATIVE_FUNCTION(DurationFormatPrototype::format_to_parts)
|
||||||
auto formatted = TRY(partition_duration_format_pattern(global_object, *duration_format, record));
|
auto formatted = TRY(partition_duration_format_pattern(global_object, *duration_format, record));
|
||||||
|
|
||||||
// 6. Let result be ! ArrayCreate(0).
|
// 6. Let result be ! ArrayCreate(0).
|
||||||
auto* result = MUST(Array::create(global_object, 0));
|
auto* result = MUST(Array::create(realm, 0));
|
||||||
|
|
||||||
// 7. Let n be 0.
|
// 7. Let n be 0.
|
||||||
// 8. For each element part in formatted, in List order, do
|
// 8. For each element part in formatted, in List order, do
|
||||||
|
@ -87,7 +89,7 @@ JS_DEFINE_NATIVE_FUNCTION(DurationFormatPrototype::format_to_parts)
|
||||||
auto const& part = formatted[n];
|
auto const& part = formatted[n];
|
||||||
|
|
||||||
// a. Let obj be ! OrdinaryObjectCreate(%ObjectPrototype%).
|
// a. Let obj be ! OrdinaryObjectCreate(%ObjectPrototype%).
|
||||||
auto* object = Object::create(global_object, global_object.object_prototype());
|
auto* object = Object::create(realm, global_object.object_prototype());
|
||||||
|
|
||||||
// b. Perform ! CreateDataPropertyOrThrow(obj, "type", part.[[Type]]).
|
// b. Perform ! CreateDataPropertyOrThrow(obj, "type", part.[[Type]]).
|
||||||
MUST(object->create_data_property_or_throw(vm.names.type, js_string(vm, part.type)));
|
MUST(object->create_data_property_or_throw(vm.names.type, js_string(vm, part.type)));
|
||||||
|
@ -108,12 +110,14 @@ JS_DEFINE_NATIVE_FUNCTION(DurationFormatPrototype::format_to_parts)
|
||||||
// 1.4.5 Intl.DurationFormat.prototype.resolvedOptions ( ), https://tc39.es/proposal-intl-duration-format/#sec-Intl.DurationFormat.prototype.resolvedOptions
|
// 1.4.5 Intl.DurationFormat.prototype.resolvedOptions ( ), https://tc39.es/proposal-intl-duration-format/#sec-Intl.DurationFormat.prototype.resolvedOptions
|
||||||
JS_DEFINE_NATIVE_FUNCTION(DurationFormatPrototype::resolved_options)
|
JS_DEFINE_NATIVE_FUNCTION(DurationFormatPrototype::resolved_options)
|
||||||
{
|
{
|
||||||
|
auto& realm = *global_object.associated_realm();
|
||||||
|
|
||||||
// 1. Let df be the this value.
|
// 1. Let df be the this value.
|
||||||
// 2. Perform ? RequireInternalSlot(df, [[InitializedDurationFormat]]).
|
// 2. Perform ? RequireInternalSlot(df, [[InitializedDurationFormat]]).
|
||||||
auto* duration_format = TRY(typed_this_object(global_object));
|
auto* duration_format = TRY(typed_this_object(global_object));
|
||||||
|
|
||||||
// 3. Let options be ! OrdinaryObjectCreate(%Object.prototype%).
|
// 3. Let options be ! OrdinaryObjectCreate(%Object.prototype%).
|
||||||
auto* options = Object::create(global_object, global_object.object_prototype());
|
auto* options = Object::create(realm, global_object.object_prototype());
|
||||||
|
|
||||||
// 4. For each row of Table 2, except the header row, in table order, do
|
// 4. For each row of Table 2, except the header row, in table order, do
|
||||||
// a. Let p be the Property value of the current row.
|
// a. Let p be the Property value of the current row.
|
||||||
|
|
|
@ -61,6 +61,8 @@ void Intl::initialize(Realm& realm)
|
||||||
// 8.3.1 Intl.getCanonicalLocales ( locales ), https://tc39.es/ecma402/#sec-intl.getcanonicallocales
|
// 8.3.1 Intl.getCanonicalLocales ( locales ), https://tc39.es/ecma402/#sec-intl.getcanonicallocales
|
||||||
JS_DEFINE_NATIVE_FUNCTION(Intl::get_canonical_locales)
|
JS_DEFINE_NATIVE_FUNCTION(Intl::get_canonical_locales)
|
||||||
{
|
{
|
||||||
|
auto& realm = *global_object.associated_realm();
|
||||||
|
|
||||||
auto locales = vm.argument(0);
|
auto locales = vm.argument(0);
|
||||||
|
|
||||||
// 1. Let ll be ? CanonicalizeLocaleList(locales).
|
// 1. Let ll be ? CanonicalizeLocaleList(locales).
|
||||||
|
@ -72,7 +74,7 @@ JS_DEFINE_NATIVE_FUNCTION(Intl::get_canonical_locales)
|
||||||
marked_locale_list.append(js_string(vm, move(locale)));
|
marked_locale_list.append(js_string(vm, move(locale)));
|
||||||
|
|
||||||
// 2. Return CreateArrayFromList(ll).
|
// 2. Return CreateArrayFromList(ll).
|
||||||
return Array::create_from(global_object, marked_locale_list);
|
return Array::create_from(realm, marked_locale_list);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 1.4.4 AvailableTimeZones (), https://tc39.es/proposal-intl-enumeration/#sec-availablecurrencies
|
// 1.4.4 AvailableTimeZones (), https://tc39.es/proposal-intl-enumeration/#sec-availablecurrencies
|
||||||
|
@ -107,6 +109,8 @@ static Vector<StringView> available_time_zones()
|
||||||
// 2.2.2 Intl.supportedValuesOf ( key ), https://tc39.es/proposal-intl-enumeration/#sec-intl.supportedvaluesof
|
// 2.2.2 Intl.supportedValuesOf ( key ), https://tc39.es/proposal-intl-enumeration/#sec-intl.supportedvaluesof
|
||||||
JS_DEFINE_NATIVE_FUNCTION(Intl::supported_values_of)
|
JS_DEFINE_NATIVE_FUNCTION(Intl::supported_values_of)
|
||||||
{
|
{
|
||||||
|
auto& realm = *global_object.associated_realm();
|
||||||
|
|
||||||
// 1. Let key be ? ToString(key).
|
// 1. Let key be ? ToString(key).
|
||||||
auto key = TRY(vm.argument(0).to_string(global_object));
|
auto key = TRY(vm.argument(0).to_string(global_object));
|
||||||
|
|
||||||
|
@ -151,7 +155,7 @@ JS_DEFINE_NATIVE_FUNCTION(Intl::supported_values_of)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 9. Return CreateArrayFromList( list ).
|
// 9. Return CreateArrayFromList( list ).
|
||||||
return Array::create_from<StringView>(global_object, list, [&](auto value) { return js_string(vm, value); });
|
return Array::create_from<StringView>(realm, list, [&](auto value) { return js_string(vm, value); });
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -204,12 +204,13 @@ String format_list(ListFormat const& list_format, Vector<String> const& list)
|
||||||
Array* format_list_to_parts(GlobalObject& global_object, ListFormat const& list_format, Vector<String> const& list)
|
Array* format_list_to_parts(GlobalObject& global_object, ListFormat const& list_format, Vector<String> const& list)
|
||||||
{
|
{
|
||||||
auto& vm = global_object.vm();
|
auto& vm = global_object.vm();
|
||||||
|
auto& realm = *global_object.associated_realm();
|
||||||
|
|
||||||
// 1. Let parts be ! CreatePartsFromList(listFormat, list).
|
// 1. Let parts be ! CreatePartsFromList(listFormat, list).
|
||||||
auto parts = create_parts_from_list(list_format, list);
|
auto parts = create_parts_from_list(list_format, list);
|
||||||
|
|
||||||
// 2. Let result be ! ArrayCreate(0).
|
// 2. Let result be ! ArrayCreate(0).
|
||||||
auto* result = MUST(Array::create(global_object, 0));
|
auto* result = MUST(Array::create(realm, 0));
|
||||||
|
|
||||||
// 3. Let n be 0.
|
// 3. Let n be 0.
|
||||||
size_t n = 0;
|
size_t n = 0;
|
||||||
|
@ -217,7 +218,7 @@ Array* format_list_to_parts(GlobalObject& global_object, ListFormat const& list_
|
||||||
// 4. For each Record { [[Type]], [[Value]] } part in parts, do
|
// 4. For each Record { [[Type]], [[Value]] } part in parts, do
|
||||||
for (auto& part : parts) {
|
for (auto& part : parts) {
|
||||||
// a. Let O be OrdinaryObjectCreate(%Object.prototype%).
|
// a. Let O be OrdinaryObjectCreate(%Object.prototype%).
|
||||||
auto* object = Object::create(global_object, global_object.object_prototype());
|
auto* object = Object::create(realm, global_object.object_prototype());
|
||||||
|
|
||||||
// b. Perform ! CreateDataPropertyOrThrow(O, "type", part.[[Type]]).
|
// b. Perform ! CreateDataPropertyOrThrow(O, "type", part.[[Type]]).
|
||||||
MUST(object->create_data_property_or_throw(vm.names.type, js_string(vm, part.type)));
|
MUST(object->create_data_property_or_throw(vm.names.type, js_string(vm, part.type)));
|
||||||
|
|
|
@ -69,12 +69,14 @@ JS_DEFINE_NATIVE_FUNCTION(ListFormatPrototype::format_to_parts)
|
||||||
// 13.3.5 Intl.ListFormat.prototype.resolvedOptions ( ), https://tc39.es/ecma402/#sec-Intl.ListFormat.prototype.resolvedoptions
|
// 13.3.5 Intl.ListFormat.prototype.resolvedOptions ( ), https://tc39.es/ecma402/#sec-Intl.ListFormat.prototype.resolvedoptions
|
||||||
JS_DEFINE_NATIVE_FUNCTION(ListFormatPrototype::resolved_options)
|
JS_DEFINE_NATIVE_FUNCTION(ListFormatPrototype::resolved_options)
|
||||||
{
|
{
|
||||||
|
auto& realm = *global_object.associated_realm();
|
||||||
|
|
||||||
// 1. Let lf be the this value.
|
// 1. Let lf be the this value.
|
||||||
// 2. Perform ? RequireInternalSlot(lf, [[InitializedListFormat]]).
|
// 2. Perform ? RequireInternalSlot(lf, [[InitializedListFormat]]).
|
||||||
auto* list_format = TRY(typed_this_object(global_object));
|
auto* list_format = TRY(typed_this_object(global_object));
|
||||||
|
|
||||||
// 3. Let options be OrdinaryObjectCreate(%Object.prototype%).
|
// 3. Let options be OrdinaryObjectCreate(%Object.prototype%).
|
||||||
auto* options = Object::create(global_object, global_object.object_prototype());
|
auto* options = Object::create(realm, global_object.object_prototype());
|
||||||
|
|
||||||
// 4. For each row of Table 10, except the header row, in table order, do
|
// 4. For each row of Table 10, except the header row, in table order, do
|
||||||
// a. Let p be the Property value of the current row.
|
// a. Let p be the Property value of the current row.
|
||||||
|
|
|
@ -14,9 +14,9 @@
|
||||||
|
|
||||||
namespace JS::Intl {
|
namespace JS::Intl {
|
||||||
|
|
||||||
Locale* Locale::create(GlobalObject& global_object, Unicode::LocaleID const& locale_id)
|
Locale* Locale::create(Realm& realm, Unicode::LocaleID const& locale_id)
|
||||||
{
|
{
|
||||||
return global_object.heap().allocate<Locale>(global_object, locale_id, *global_object.intl_locale_prototype());
|
return realm.heap().allocate<Locale>(realm.global_object(), locale_id, *realm.global_object().intl_locale_prototype());
|
||||||
}
|
}
|
||||||
|
|
||||||
// 14 Locale Objects, https://tc39.es/ecma402/#locale-objects
|
// 14 Locale Objects, https://tc39.es/ecma402/#locale-objects
|
||||||
|
@ -58,6 +58,7 @@ Locale::Locale(Unicode::LocaleID const& locale_id, Object& prototype)
|
||||||
static Array* create_array_from_list_or_restricted(GlobalObject& global_object, Vector<StringView> list, Optional<String> restricted)
|
static Array* create_array_from_list_or_restricted(GlobalObject& global_object, Vector<StringView> list, Optional<String> restricted)
|
||||||
{
|
{
|
||||||
auto& vm = global_object.vm();
|
auto& vm = global_object.vm();
|
||||||
|
auto& realm = *global_object.associated_realm();
|
||||||
|
|
||||||
// 1. If restricted is not undefined, then
|
// 1. If restricted is not undefined, then
|
||||||
if (restricted.has_value()) {
|
if (restricted.has_value()) {
|
||||||
|
@ -66,7 +67,7 @@ static Array* create_array_from_list_or_restricted(GlobalObject& global_object,
|
||||||
}
|
}
|
||||||
|
|
||||||
// 2. Return ! CreateArrayFromList( list ).
|
// 2. Return ! CreateArrayFromList( list ).
|
||||||
return Array::create_from<StringView>(global_object, list, [&vm](auto value) {
|
return Array::create_from<StringView>(realm, list, [&vm](auto value) {
|
||||||
return js_string(vm, value);
|
return js_string(vm, value);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -152,6 +153,7 @@ Array* numbering_systems_of_locale(GlobalObject& global_object, Locale const& lo
|
||||||
Array* time_zones_of_locale(GlobalObject& global_object, StringView region)
|
Array* time_zones_of_locale(GlobalObject& global_object, StringView region)
|
||||||
{
|
{
|
||||||
auto& vm = global_object.vm();
|
auto& vm = global_object.vm();
|
||||||
|
auto& realm = *global_object.associated_realm();
|
||||||
|
|
||||||
// 1. Let locale be loc.[[Locale]].
|
// 1. Let locale be loc.[[Locale]].
|
||||||
// 2. Assert: locale matches the unicode_locale_id production.
|
// 2. Assert: locale matches the unicode_locale_id production.
|
||||||
|
@ -162,7 +164,7 @@ Array* time_zones_of_locale(GlobalObject& global_object, StringView region)
|
||||||
quick_sort(list);
|
quick_sort(list);
|
||||||
|
|
||||||
// 5. Return ! CreateArrayFromList( list ).
|
// 5. Return ! CreateArrayFromList( list ).
|
||||||
return Array::create_from<StringView>(global_object, list, [&vm](auto value) {
|
return Array::create_from<StringView>(realm, list, [&vm](auto value) {
|
||||||
return js_string(vm, value);
|
return js_string(vm, value);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,7 +21,7 @@ class Locale final : public Object {
|
||||||
JS_OBJECT(Locale, Object);
|
JS_OBJECT(Locale, Object);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static Locale* create(GlobalObject&, Unicode::LocaleID const&);
|
static Locale* create(Realm&, Unicode::LocaleID const&);
|
||||||
|
|
||||||
static constexpr auto relevant_extension_keys()
|
static constexpr auto relevant_extension_keys()
|
||||||
{
|
{
|
||||||
|
|
|
@ -55,6 +55,8 @@ void LocalePrototype::initialize(Realm& realm)
|
||||||
// 14.3.3 Intl.Locale.prototype.maximize ( ), https://tc39.es/ecma402/#sec-Intl.Locale.prototype.maximize
|
// 14.3.3 Intl.Locale.prototype.maximize ( ), https://tc39.es/ecma402/#sec-Intl.Locale.prototype.maximize
|
||||||
JS_DEFINE_NATIVE_FUNCTION(LocalePrototype::maximize)
|
JS_DEFINE_NATIVE_FUNCTION(LocalePrototype::maximize)
|
||||||
{
|
{
|
||||||
|
auto& realm = *global_object.associated_realm();
|
||||||
|
|
||||||
// 1. Let loc be the this value.
|
// 1. Let loc be the this value.
|
||||||
// 2. Perform ? RequireInternalSlot(loc, [[InitializedLocale]]).
|
// 2. Perform ? RequireInternalSlot(loc, [[InitializedLocale]]).
|
||||||
auto* locale_object = TRY(typed_this_object(global_object));
|
auto* locale_object = TRY(typed_this_object(global_object));
|
||||||
|
@ -67,12 +69,14 @@ JS_DEFINE_NATIVE_FUNCTION(LocalePrototype::maximize)
|
||||||
locale->language_id = maximal.release_value();
|
locale->language_id = maximal.release_value();
|
||||||
|
|
||||||
// 4. Return ! Construct(%Locale%, maximal).
|
// 4. Return ! Construct(%Locale%, maximal).
|
||||||
return Locale::create(global_object, *locale);
|
return Locale::create(realm, *locale);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 14.3.4 Intl.Locale.prototype.minimize ( ), https://tc39.es/ecma402/#sec-Intl.Locale.prototype.minimize
|
// 14.3.4 Intl.Locale.prototype.minimize ( ), https://tc39.es/ecma402/#sec-Intl.Locale.prototype.minimize
|
||||||
JS_DEFINE_NATIVE_FUNCTION(LocalePrototype::minimize)
|
JS_DEFINE_NATIVE_FUNCTION(LocalePrototype::minimize)
|
||||||
{
|
{
|
||||||
|
auto& realm = *global_object.associated_realm();
|
||||||
|
|
||||||
// 1. Let loc be the this value.
|
// 1. Let loc be the this value.
|
||||||
// 2. Perform ? RequireInternalSlot(loc, [[InitializedLocale]]).
|
// 2. Perform ? RequireInternalSlot(loc, [[InitializedLocale]]).
|
||||||
auto* locale_object = TRY(typed_this_object(global_object));
|
auto* locale_object = TRY(typed_this_object(global_object));
|
||||||
|
@ -85,7 +89,7 @@ JS_DEFINE_NATIVE_FUNCTION(LocalePrototype::minimize)
|
||||||
locale->language_id = minimal.release_value();
|
locale->language_id = minimal.release_value();
|
||||||
|
|
||||||
// 4. Return ! Construct(%Locale%, minimal).
|
// 4. Return ! Construct(%Locale%, minimal).
|
||||||
return Locale::create(global_object, *locale);
|
return Locale::create(realm, *locale);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 14.3.5 Intl.Locale.prototype.toString ( ), https://tc39.es/ecma402/#sec-Intl.Locale.prototype.toString
|
// 14.3.5 Intl.Locale.prototype.toString ( ), https://tc39.es/ecma402/#sec-Intl.Locale.prototype.toString
|
||||||
|
@ -247,12 +251,14 @@ JS_DEFINE_NATIVE_FUNCTION(LocalePrototype::time_zones)
|
||||||
// 1.4.21 get Intl.Locale.prototype.textInfo, https://tc39.es/proposal-intl-locale-info/#sec-Intl.Locale.prototype.textInfo
|
// 1.4.21 get Intl.Locale.prototype.textInfo, https://tc39.es/proposal-intl-locale-info/#sec-Intl.Locale.prototype.textInfo
|
||||||
JS_DEFINE_NATIVE_FUNCTION(LocalePrototype::text_info)
|
JS_DEFINE_NATIVE_FUNCTION(LocalePrototype::text_info)
|
||||||
{
|
{
|
||||||
|
auto& realm = *global_object.associated_realm();
|
||||||
|
|
||||||
// 1. Let loc be the this value.
|
// 1. Let loc be the this value.
|
||||||
// 2. Perform ? RequireInternalSlot(loc, [[InitializedLocale]]).
|
// 2. Perform ? RequireInternalSlot(loc, [[InitializedLocale]]).
|
||||||
auto* locale_object = TRY(typed_this_object(global_object));
|
auto* locale_object = TRY(typed_this_object(global_object));
|
||||||
|
|
||||||
// 3. Let info be ! ObjectCreate(%Object.prototype%).
|
// 3. Let info be ! ObjectCreate(%Object.prototype%).
|
||||||
auto* info = Object::create(global_object, global_object.object_prototype());
|
auto* info = Object::create(realm, global_object.object_prototype());
|
||||||
|
|
||||||
// 4. Let dir be ! CharacterDirectionOfLocale(loc).
|
// 4. Let dir be ! CharacterDirectionOfLocale(loc).
|
||||||
auto direction = character_direction_of_locale(*locale_object);
|
auto direction = character_direction_of_locale(*locale_object);
|
||||||
|
@ -267,18 +273,20 @@ JS_DEFINE_NATIVE_FUNCTION(LocalePrototype::text_info)
|
||||||
// 1.4.22 get Intl.Locale.prototype.weekInfo, https://tc39.es/proposal-intl-locale-info/#sec-Intl.Locale.prototype.weekInfo
|
// 1.4.22 get Intl.Locale.prototype.weekInfo, https://tc39.es/proposal-intl-locale-info/#sec-Intl.Locale.prototype.weekInfo
|
||||||
JS_DEFINE_NATIVE_FUNCTION(LocalePrototype::week_info)
|
JS_DEFINE_NATIVE_FUNCTION(LocalePrototype::week_info)
|
||||||
{
|
{
|
||||||
|
auto& realm = *global_object.associated_realm();
|
||||||
|
|
||||||
// 1. Let loc be the this value.
|
// 1. Let loc be the this value.
|
||||||
// 2. Perform ? RequireInternalSlot(loc, [[InitializedLocale]]).
|
// 2. Perform ? RequireInternalSlot(loc, [[InitializedLocale]]).
|
||||||
[[maybe_unused]] auto* locale_object = TRY(typed_this_object(global_object));
|
[[maybe_unused]] auto* locale_object = TRY(typed_this_object(global_object));
|
||||||
|
|
||||||
// 3. Let info be ! ObjectCreate(%Object.prototype%).
|
// 3. Let info be ! ObjectCreate(%Object.prototype%).
|
||||||
auto* info = Object::create(global_object, global_object.object_prototype());
|
auto* info = Object::create(realm, global_object.object_prototype());
|
||||||
|
|
||||||
// 4. Let wi be ! WeekInfoOfLocale(loc).
|
// 4. Let wi be ! WeekInfoOfLocale(loc).
|
||||||
auto week_info = week_info_of_locale(*locale_object);
|
auto week_info = week_info_of_locale(*locale_object);
|
||||||
|
|
||||||
// 5. Let we be ! CreateArrayFromList( wi.[[Weekend]] ).
|
// 5. Let we be ! CreateArrayFromList( wi.[[Weekend]] ).
|
||||||
auto weekend = Array::create_from<u8>(global_object, week_info.weekend, [](auto day) { return Value(day); });
|
auto weekend = Array::create_from<u8>(realm, week_info.weekend, [](auto day) { return Value(day); });
|
||||||
|
|
||||||
// 6. Perform ! CreateDataPropertyOrThrow(info, "firstDay", wi.[[FirstDay]]).
|
// 6. Perform ! CreateDataPropertyOrThrow(info, "firstDay", wi.[[FirstDay]]).
|
||||||
MUST(info->create_data_property_or_throw(vm.names.firstDay, Value(week_info.first_day)));
|
MUST(info->create_data_property_or_throw(vm.names.firstDay, Value(week_info.first_day)));
|
||||||
|
|
|
@ -910,13 +910,14 @@ String format_numeric(GlobalObject& global_object, NumberFormat& number_format,
|
||||||
Array* format_numeric_to_parts(GlobalObject& global_object, NumberFormat& number_format, MathematicalValue number)
|
Array* format_numeric_to_parts(GlobalObject& global_object, NumberFormat& number_format, MathematicalValue number)
|
||||||
{
|
{
|
||||||
auto& vm = global_object.vm();
|
auto& vm = global_object.vm();
|
||||||
|
auto& realm = *global_object.associated_realm();
|
||||||
|
|
||||||
// 1. Let parts be ? PartitionNumberPattern(numberFormat, x).
|
// 1. Let parts be ? PartitionNumberPattern(numberFormat, x).
|
||||||
// Note: Our implementation of PartitionNumberPattern does not throw.
|
// Note: Our implementation of PartitionNumberPattern does not throw.
|
||||||
auto parts = partition_number_pattern(global_object, number_format, move(number));
|
auto parts = partition_number_pattern(global_object, number_format, move(number));
|
||||||
|
|
||||||
// 2. Let result be ! ArrayCreate(0).
|
// 2. Let result be ! ArrayCreate(0).
|
||||||
auto* result = MUST(Array::create(global_object, 0));
|
auto* result = MUST(Array::create(realm, 0));
|
||||||
|
|
||||||
// 3. Let n be 0.
|
// 3. Let n be 0.
|
||||||
size_t n = 0;
|
size_t n = 0;
|
||||||
|
@ -924,7 +925,7 @@ Array* format_numeric_to_parts(GlobalObject& global_object, NumberFormat& number
|
||||||
// 4. For each Record { [[Type]], [[Value]] } part in parts, do
|
// 4. For each Record { [[Type]], [[Value]] } part in parts, do
|
||||||
for (auto& part : parts) {
|
for (auto& part : parts) {
|
||||||
// a. Let O be OrdinaryObjectCreate(%Object.prototype%).
|
// a. Let O be OrdinaryObjectCreate(%Object.prototype%).
|
||||||
auto* object = Object::create(global_object, global_object.object_prototype());
|
auto* object = Object::create(realm, global_object.object_prototype());
|
||||||
|
|
||||||
// b. Perform ! CreateDataPropertyOrThrow(O, "type", part.[[Type]]).
|
// b. Perform ! CreateDataPropertyOrThrow(O, "type", part.[[Type]]).
|
||||||
MUST(object->create_data_property_or_throw(vm.names.type, js_string(vm, part.type)));
|
MUST(object->create_data_property_or_throw(vm.names.type, js_string(vm, part.type)));
|
||||||
|
@ -1827,12 +1828,13 @@ ThrowCompletionOr<String> format_numeric_range(GlobalObject& global_object, Numb
|
||||||
ThrowCompletionOr<Array*> format_numeric_range_to_parts(GlobalObject& global_object, NumberFormat& number_format, MathematicalValue start, MathematicalValue end)
|
ThrowCompletionOr<Array*> format_numeric_range_to_parts(GlobalObject& global_object, NumberFormat& number_format, MathematicalValue start, MathematicalValue end)
|
||||||
{
|
{
|
||||||
auto& vm = global_object.vm();
|
auto& vm = global_object.vm();
|
||||||
|
auto& realm = *global_object.associated_realm();
|
||||||
|
|
||||||
// 1. Let parts be ? PartitionNumberRangePattern(numberFormat, x, y).
|
// 1. Let parts be ? PartitionNumberRangePattern(numberFormat, x, y).
|
||||||
auto parts = TRY(partition_number_range_pattern(global_object, number_format, move(start), move(end)));
|
auto parts = TRY(partition_number_range_pattern(global_object, number_format, move(start), move(end)));
|
||||||
|
|
||||||
// 2. Let result be ! ArrayCreate(0).
|
// 2. Let result be ! ArrayCreate(0).
|
||||||
auto* result = MUST(Array::create(global_object, 0));
|
auto* result = MUST(Array::create(realm, 0));
|
||||||
|
|
||||||
// 3. Let n be 0.
|
// 3. Let n be 0.
|
||||||
size_t n = 0;
|
size_t n = 0;
|
||||||
|
@ -1840,7 +1842,7 @@ ThrowCompletionOr<Array*> format_numeric_range_to_parts(GlobalObject& global_obj
|
||||||
// 4. For each Record { [[Type]], [[Value]] } part in parts, do
|
// 4. For each Record { [[Type]], [[Value]] } part in parts, do
|
||||||
for (auto& part : parts) {
|
for (auto& part : parts) {
|
||||||
// a. Let O be OrdinaryObjectCreate(%Object.prototype%).
|
// a. Let O be OrdinaryObjectCreate(%Object.prototype%).
|
||||||
auto* object = Object::create(global_object, global_object.object_prototype());
|
auto* object = Object::create(realm, global_object.object_prototype());
|
||||||
|
|
||||||
// b. Perform ! CreateDataPropertyOrThrow(O, "type", part.[[Type]]).
|
// b. Perform ! CreateDataPropertyOrThrow(O, "type", part.[[Type]]).
|
||||||
MUST(object->create_data_property_or_throw(vm.names.type, js_string(vm, part.type)));
|
MUST(object->create_data_property_or_throw(vm.names.type, js_string(vm, part.type)));
|
||||||
|
|
|
@ -12,9 +12,9 @@ namespace JS::Intl {
|
||||||
|
|
||||||
// 15.5.2 Number Format Functions, https://tc39.es/ecma402/#sec-number-format-functions
|
// 15.5.2 Number Format Functions, https://tc39.es/ecma402/#sec-number-format-functions
|
||||||
// 1.1.4 Number Format Functions, https://tc39.es/proposal-intl-numberformat-v3/out/numberformat/proposed.html#sec-number-format-functions
|
// 1.1.4 Number Format Functions, https://tc39.es/proposal-intl-numberformat-v3/out/numberformat/proposed.html#sec-number-format-functions
|
||||||
NumberFormatFunction* NumberFormatFunction::create(GlobalObject& global_object, NumberFormat& number_format)
|
NumberFormatFunction* NumberFormatFunction::create(Realm& realm, NumberFormat& number_format)
|
||||||
{
|
{
|
||||||
return global_object.heap().allocate<NumberFormatFunction>(global_object, number_format, *global_object.function_prototype());
|
return realm.heap().allocate<NumberFormatFunction>(realm.global_object(), number_format, *realm.global_object().function_prototype());
|
||||||
}
|
}
|
||||||
|
|
||||||
NumberFormatFunction::NumberFormatFunction(NumberFormat& number_format, Object& prototype)
|
NumberFormatFunction::NumberFormatFunction(NumberFormat& number_format, Object& prototype)
|
||||||
|
|
|
@ -16,7 +16,7 @@ class NumberFormatFunction final : public NativeFunction {
|
||||||
JS_OBJECT(NumberFormatFunction, NativeFunction);
|
JS_OBJECT(NumberFormatFunction, NativeFunction);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static NumberFormatFunction* create(GlobalObject&, NumberFormat&);
|
static NumberFormatFunction* create(Realm&, NumberFormat&);
|
||||||
|
|
||||||
explicit NumberFormatFunction(NumberFormat&, Object& prototype);
|
explicit NumberFormatFunction(NumberFormat&, Object& prototype);
|
||||||
virtual ~NumberFormatFunction() override = default;
|
virtual ~NumberFormatFunction() override = default;
|
||||||
|
|
|
@ -40,6 +40,8 @@ void NumberFormatPrototype::initialize(Realm& realm)
|
||||||
// 15.3.3 get Intl.NumberFormat.prototype.format, https://tc39.es/ecma402/#sec-intl.numberformat.prototype.format
|
// 15.3.3 get Intl.NumberFormat.prototype.format, https://tc39.es/ecma402/#sec-intl.numberformat.prototype.format
|
||||||
JS_DEFINE_NATIVE_FUNCTION(NumberFormatPrototype::format)
|
JS_DEFINE_NATIVE_FUNCTION(NumberFormatPrototype::format)
|
||||||
{
|
{
|
||||||
|
auto& realm = *global_object.associated_realm();
|
||||||
|
|
||||||
// 1. Let nf be the this value.
|
// 1. Let nf be the this value.
|
||||||
// 2. If the implementation supports the normative optional constructor mode of 4.3 Note 1, then
|
// 2. If the implementation supports the normative optional constructor mode of 4.3 Note 1, then
|
||||||
// a. Set nf to ? UnwrapNumberFormat(nf).
|
// a. Set nf to ? UnwrapNumberFormat(nf).
|
||||||
|
@ -50,7 +52,7 @@ JS_DEFINE_NATIVE_FUNCTION(NumberFormatPrototype::format)
|
||||||
if (!number_format->bound_format()) {
|
if (!number_format->bound_format()) {
|
||||||
// a. Let F be a new built-in function object as defined in Number Format Functions (15.1.4).
|
// a. Let F be a new built-in function object as defined in Number Format Functions (15.1.4).
|
||||||
// b. Set F.[[NumberFormat]] to nf.
|
// b. Set F.[[NumberFormat]] to nf.
|
||||||
auto* bound_format = NumberFormatFunction::create(global_object, *number_format);
|
auto* bound_format = NumberFormatFunction::create(realm, *number_format);
|
||||||
|
|
||||||
// c. Set nf.[[BoundFormat]] to F.
|
// c. Set nf.[[BoundFormat]] to F.
|
||||||
number_format->set_bound_format(bound_format);
|
number_format->set_bound_format(bound_format);
|
||||||
|
@ -134,6 +136,8 @@ JS_DEFINE_NATIVE_FUNCTION(NumberFormatPrototype::format_range_to_parts)
|
||||||
// 15.3.5 Intl.NumberFormat.prototype.resolvedOptions ( ), https://tc39.es/ecma402/#sec-intl.numberformat.prototype.resolvedoptions
|
// 15.3.5 Intl.NumberFormat.prototype.resolvedOptions ( ), https://tc39.es/ecma402/#sec-intl.numberformat.prototype.resolvedoptions
|
||||||
JS_DEFINE_NATIVE_FUNCTION(NumberFormatPrototype::resolved_options)
|
JS_DEFINE_NATIVE_FUNCTION(NumberFormatPrototype::resolved_options)
|
||||||
{
|
{
|
||||||
|
auto& realm = *global_object.associated_realm();
|
||||||
|
|
||||||
// 1. Let nf be the this value.
|
// 1. Let nf be the this value.
|
||||||
// 2. If the implementation supports the normative optional constructor mode of 4.3 Note 1, then
|
// 2. If the implementation supports the normative optional constructor mode of 4.3 Note 1, then
|
||||||
// a. Set nf to ? UnwrapNumberFormat(nf).
|
// a. Set nf to ? UnwrapNumberFormat(nf).
|
||||||
|
@ -141,7 +145,7 @@ JS_DEFINE_NATIVE_FUNCTION(NumberFormatPrototype::resolved_options)
|
||||||
auto* number_format = TRY(typed_this_object(global_object));
|
auto* number_format = TRY(typed_this_object(global_object));
|
||||||
|
|
||||||
// 4. Let options be OrdinaryObjectCreate(%Object.prototype%).
|
// 4. Let options be OrdinaryObjectCreate(%Object.prototype%).
|
||||||
auto* options = Object::create(global_object, global_object.object_prototype());
|
auto* options = Object::create(realm, global_object.object_prototype());
|
||||||
|
|
||||||
// 5. For each row of Table 11, except the header row, in table order, do
|
// 5. For each row of Table 11, except the header row, in table order, do
|
||||||
// a. Let p be the Property value of the current row.
|
// a. Let p be the Property value of the current row.
|
||||||
|
|
|
@ -79,12 +79,14 @@ JS_DEFINE_NATIVE_FUNCTION(PluralRulesPrototype::select_range)
|
||||||
// 1.4.5 Intl.PluralRules.prototype.resolvedOptions ( ), https://tc39.es/proposal-intl-numberformat-v3/out/pluralrules/proposed.html#sec-intl.pluralrules.prototype.resolvedoptions
|
// 1.4.5 Intl.PluralRules.prototype.resolvedOptions ( ), https://tc39.es/proposal-intl-numberformat-v3/out/pluralrules/proposed.html#sec-intl.pluralrules.prototype.resolvedoptions
|
||||||
JS_DEFINE_NATIVE_FUNCTION(PluralRulesPrototype::resolved_options)
|
JS_DEFINE_NATIVE_FUNCTION(PluralRulesPrototype::resolved_options)
|
||||||
{
|
{
|
||||||
|
auto& realm = *global_object.associated_realm();
|
||||||
|
|
||||||
// 1. Let pr be the this value.
|
// 1. Let pr be the this value.
|
||||||
// 2. Perform ? RequireInternalSlot(pr, [[InitializedPluralRules]]).
|
// 2. Perform ? RequireInternalSlot(pr, [[InitializedPluralRules]]).
|
||||||
auto* plural_rules = TRY(typed_this_object(global_object));
|
auto* plural_rules = TRY(typed_this_object(global_object));
|
||||||
|
|
||||||
// 3. Let options be OrdinaryObjectCreate(%Object.prototype%).
|
// 3. Let options be OrdinaryObjectCreate(%Object.prototype%).
|
||||||
auto* options = Object::create(global_object, global_object.object_prototype());
|
auto* options = Object::create(realm, global_object.object_prototype());
|
||||||
|
|
||||||
// 4. For each row of Table 13, except the header row, in table order, do
|
// 4. For each row of Table 13, except the header row, in table order, do
|
||||||
// a. Let p be the Property value of the current row.
|
// a. Let p be the Property value of the current row.
|
||||||
|
@ -106,7 +108,7 @@ JS_DEFINE_NATIVE_FUNCTION(PluralRulesPrototype::resolved_options)
|
||||||
// 5. Let pluralCategories be a List of Strings containing all possible results of PluralRuleSelect for the selected locale pr.[[Locale]].
|
// 5. Let pluralCategories be a List of Strings containing all possible results of PluralRuleSelect for the selected locale pr.[[Locale]].
|
||||||
auto available_categories = Unicode::available_plural_categories(plural_rules->locale(), plural_rules->type());
|
auto available_categories = Unicode::available_plural_categories(plural_rules->locale(), plural_rules->type());
|
||||||
|
|
||||||
auto* plural_categories = Array::create_from<Unicode::PluralCategory>(global_object, available_categories, [&](auto category) {
|
auto* plural_categories = Array::create_from<Unicode::PluralCategory>(realm, available_categories, [&](auto category) {
|
||||||
return js_string(vm, Unicode::plural_category_to_string(category));
|
return js_string(vm, Unicode::plural_category_to_string(category));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -248,12 +248,13 @@ ThrowCompletionOr<String> format_relative_time(GlobalObject& global_object, Rela
|
||||||
ThrowCompletionOr<Array*> format_relative_time_to_parts(GlobalObject& global_object, RelativeTimeFormat& relative_time_format, double value, StringView unit)
|
ThrowCompletionOr<Array*> format_relative_time_to_parts(GlobalObject& global_object, RelativeTimeFormat& relative_time_format, double value, StringView unit)
|
||||||
{
|
{
|
||||||
auto& vm = global_object.vm();
|
auto& vm = global_object.vm();
|
||||||
|
auto& realm = *global_object.associated_realm();
|
||||||
|
|
||||||
// 1. Let parts be ? PartitionRelativeTimePattern(relativeTimeFormat, value, unit).
|
// 1. Let parts be ? PartitionRelativeTimePattern(relativeTimeFormat, value, unit).
|
||||||
auto parts = TRY(partition_relative_time_pattern(global_object, relative_time_format, value, unit));
|
auto parts = TRY(partition_relative_time_pattern(global_object, relative_time_format, value, unit));
|
||||||
|
|
||||||
// 2. Let result be ! ArrayCreate(0).
|
// 2. Let result be ! ArrayCreate(0).
|
||||||
auto* result = MUST(Array::create(global_object, 0));
|
auto* result = MUST(Array::create(realm, 0));
|
||||||
|
|
||||||
// 3. Let n be 0.
|
// 3. Let n be 0.
|
||||||
size_t n = 0;
|
size_t n = 0;
|
||||||
|
@ -261,7 +262,7 @@ ThrowCompletionOr<Array*> format_relative_time_to_parts(GlobalObject& global_obj
|
||||||
// 4. For each Record { [[Type]], [[Value]], [[Unit]] } part in parts, do
|
// 4. For each Record { [[Type]], [[Value]], [[Unit]] } part in parts, do
|
||||||
for (auto& part : parts) {
|
for (auto& part : parts) {
|
||||||
// a. Let O be OrdinaryObjectCreate(%Object.prototype%).
|
// a. Let O be OrdinaryObjectCreate(%Object.prototype%).
|
||||||
auto* object = Object::create(global_object, global_object.object_prototype());
|
auto* object = Object::create(realm, global_object.object_prototype());
|
||||||
|
|
||||||
// b. Perform ! CreateDataPropertyOrThrow(O, "type", part.[[Type]]).
|
// b. Perform ! CreateDataPropertyOrThrow(O, "type", part.[[Type]]).
|
||||||
MUST(object->create_data_property_or_throw(vm.names.type, js_string(vm, part.type)));
|
MUST(object->create_data_property_or_throw(vm.names.type, js_string(vm, part.type)));
|
||||||
|
|
|
@ -69,12 +69,14 @@ JS_DEFINE_NATIVE_FUNCTION(RelativeTimeFormatPrototype::format_to_parts)
|
||||||
// 17.3.5 Intl.RelativeTimeFormat.prototype.resolvedOptions ( ), https://tc39.es/ecma402/#sec-intl.relativetimeformat.prototype.resolvedoptions
|
// 17.3.5 Intl.RelativeTimeFormat.prototype.resolvedOptions ( ), https://tc39.es/ecma402/#sec-intl.relativetimeformat.prototype.resolvedoptions
|
||||||
JS_DEFINE_NATIVE_FUNCTION(RelativeTimeFormatPrototype::resolved_options)
|
JS_DEFINE_NATIVE_FUNCTION(RelativeTimeFormatPrototype::resolved_options)
|
||||||
{
|
{
|
||||||
|
auto& realm = *global_object.associated_realm();
|
||||||
|
|
||||||
// 1. Let relativeTimeFormat be the this value.
|
// 1. Let relativeTimeFormat be the this value.
|
||||||
// 2. Perform ? RequireInternalSlot(relativeTimeFormat, [[InitializedRelativeTimeFormat]]).
|
// 2. Perform ? RequireInternalSlot(relativeTimeFormat, [[InitializedRelativeTimeFormat]]).
|
||||||
auto* relative_time_format = TRY(typed_this_object(global_object));
|
auto* relative_time_format = TRY(typed_this_object(global_object));
|
||||||
|
|
||||||
// 3. Let options be OrdinaryObjectCreate(%Object.prototype%).
|
// 3. Let options be OrdinaryObjectCreate(%Object.prototype%).
|
||||||
auto* options = Object::create(global_object, global_object.object_prototype());
|
auto* options = Object::create(realm, global_object.object_prototype());
|
||||||
|
|
||||||
// 4. For each row of Table 15, except the header row, in table order, do
|
// 4. For each row of Table 15, except the header row, in table order, do
|
||||||
// a. Let p be the Property value of the current row.
|
// a. Let p be the Property value of the current row.
|
||||||
|
|
|
@ -11,16 +11,15 @@
|
||||||
namespace JS::Intl {
|
namespace JS::Intl {
|
||||||
|
|
||||||
// 18.6.1 CreateSegmentIterator ( segmenter, string ), https://tc39.es/ecma402/#sec-createsegmentsobject
|
// 18.6.1 CreateSegmentIterator ( segmenter, string ), https://tc39.es/ecma402/#sec-createsegmentsobject
|
||||||
SegmentIterator* SegmentIterator::create(GlobalObject& global_object, Segmenter& segmenter, Utf16View const& string, Segments const& segments)
|
SegmentIterator* SegmentIterator::create(Realm& realm, Segmenter& segmenter, Utf16View const& string, Segments const& segments)
|
||||||
{
|
{
|
||||||
auto& realm = *global_object.associated_realm();
|
|
||||||
// 1. Let internalSlotsList be « [[IteratingSegmenter]], [[IteratedString]], [[IteratedStringNextSegmentCodeUnitIndex]] ».
|
// 1. Let internalSlotsList be « [[IteratingSegmenter]], [[IteratedString]], [[IteratedStringNextSegmentCodeUnitIndex]] ».
|
||||||
// 2. Let iterator be OrdinaryObjectCreate(%SegmentIteratorPrototype%, internalSlotsList).
|
// 2. Let iterator be OrdinaryObjectCreate(%SegmentIteratorPrototype%, internalSlotsList).
|
||||||
// 3. Set iterator.[[IteratingSegmenter]] to segmenter.
|
// 3. Set iterator.[[IteratingSegmenter]] to segmenter.
|
||||||
// 4. Set iterator.[[IteratedString]] to string.
|
// 4. Set iterator.[[IteratedString]] to string.
|
||||||
// 5. Set iterator.[[IteratedStringNextSegmentCodeUnitIndex]] to 0.
|
// 5. Set iterator.[[IteratedStringNextSegmentCodeUnitIndex]] to 0.
|
||||||
// 6. Return iterator.
|
// 6. Return iterator.
|
||||||
return global_object.heap().allocate<SegmentIterator>(global_object, realm, segmenter, move(string), segments);
|
return realm.heap().allocate<SegmentIterator>(realm.global_object(), realm, segmenter, move(string), segments);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 18.6 Segment Iterator Objects, https://tc39.es/ecma402/#sec-segment-iterator-objects
|
// 18.6 Segment Iterator Objects, https://tc39.es/ecma402/#sec-segment-iterator-objects
|
||||||
|
|
|
@ -16,7 +16,7 @@ class SegmentIterator final : public Object {
|
||||||
JS_OBJECT(SegmentIterator, Object);
|
JS_OBJECT(SegmentIterator, Object);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static SegmentIterator* create(GlobalObject&, Segmenter&, Utf16View const&, Segments const&);
|
static SegmentIterator* create(Realm&, Segmenter&, Utf16View const&, Segments const&);
|
||||||
|
|
||||||
SegmentIterator(Realm&, Segmenter&, Utf16View const&, Segments const&);
|
SegmentIterator(Realm&, Segmenter&, Utf16View const&, Segments const&);
|
||||||
virtual ~SegmentIterator() override = default;
|
virtual ~SegmentIterator() override = default;
|
||||||
|
|
|
@ -48,6 +48,7 @@ StringView Segmenter::segmenter_granularity_string() const
|
||||||
Object* create_segment_data_object(GlobalObject& global_object, Segmenter const& segmenter, Utf16View const& string, double start_index, double end_index)
|
Object* create_segment_data_object(GlobalObject& global_object, Segmenter const& segmenter, Utf16View const& string, double start_index, double end_index)
|
||||||
{
|
{
|
||||||
auto& vm = global_object.vm();
|
auto& vm = global_object.vm();
|
||||||
|
auto& realm = *global_object.associated_realm();
|
||||||
|
|
||||||
// 1. Let len be the length of string.
|
// 1. Let len be the length of string.
|
||||||
auto length = string.length_in_code_units();
|
auto length = string.length_in_code_units();
|
||||||
|
@ -62,7 +63,7 @@ Object* create_segment_data_object(GlobalObject& global_object, Segmenter const&
|
||||||
VERIFY(start_index < end_index);
|
VERIFY(start_index < end_index);
|
||||||
|
|
||||||
// 5. Let result be OrdinaryObjectCreate(%Object.prototype%).
|
// 5. Let result be OrdinaryObjectCreate(%Object.prototype%).
|
||||||
auto* result = Object::create(global_object, global_object.object_prototype());
|
auto* result = Object::create(realm, global_object.object_prototype());
|
||||||
|
|
||||||
// 6. Let segment be the substring of string from startIndex to endIndex.
|
// 6. Let segment be the substring of string from startIndex to endIndex.
|
||||||
auto segment = string.substring_view(start_index, end_index - start_index);
|
auto segment = string.substring_view(start_index, end_index - start_index);
|
||||||
|
|
|
@ -34,12 +34,14 @@ void SegmenterPrototype::initialize(Realm& realm)
|
||||||
// 18.3.4 Intl.Segmenter.prototype.resolvedOptions ( ), https://tc39.es/ecma402/#sec-intl.segmenter.prototype.resolvedoptions
|
// 18.3.4 Intl.Segmenter.prototype.resolvedOptions ( ), https://tc39.es/ecma402/#sec-intl.segmenter.prototype.resolvedoptions
|
||||||
JS_DEFINE_NATIVE_FUNCTION(SegmenterPrototype::resolved_options)
|
JS_DEFINE_NATIVE_FUNCTION(SegmenterPrototype::resolved_options)
|
||||||
{
|
{
|
||||||
|
auto& realm = *global_object.associated_realm();
|
||||||
|
|
||||||
// 1. Let segmenter be the this value.
|
// 1. Let segmenter be the this value.
|
||||||
// 2. Perform ? RequireInternalSlot(segmenter, [[InitializedSegmenter]]).
|
// 2. Perform ? RequireInternalSlot(segmenter, [[InitializedSegmenter]]).
|
||||||
auto* segmenter = TRY(typed_this_object(global_object));
|
auto* segmenter = TRY(typed_this_object(global_object));
|
||||||
|
|
||||||
// 3. Let options be OrdinaryObjectCreate(%Object.prototype%).
|
// 3. Let options be OrdinaryObjectCreate(%Object.prototype%).
|
||||||
auto* options = Object::create(global_object, global_object.object_prototype());
|
auto* options = Object::create(realm, global_object.object_prototype());
|
||||||
|
|
||||||
// 4. For each row of Table 16, except the header row, in table order, do
|
// 4. For each row of Table 16, except the header row, in table order, do
|
||||||
// a. Let p be the Property value of the current row.
|
// a. Let p be the Property value of the current row.
|
||||||
|
@ -56,6 +58,8 @@ JS_DEFINE_NATIVE_FUNCTION(SegmenterPrototype::resolved_options)
|
||||||
// 18.3.3 Intl.Segmenter.prototype.segment ( string ), https://tc39.es/ecma402/#sec-intl.segmenter.prototype.segment
|
// 18.3.3 Intl.Segmenter.prototype.segment ( string ), https://tc39.es/ecma402/#sec-intl.segmenter.prototype.segment
|
||||||
JS_DEFINE_NATIVE_FUNCTION(SegmenterPrototype::segment)
|
JS_DEFINE_NATIVE_FUNCTION(SegmenterPrototype::segment)
|
||||||
{
|
{
|
||||||
|
auto& realm = *global_object.associated_realm();
|
||||||
|
|
||||||
// 1. Let segmenter be the this value.
|
// 1. Let segmenter be the this value.
|
||||||
// 2. Perform ? RequireInternalSlot(segmenter, [[InitializedSegmenter]]).
|
// 2. Perform ? RequireInternalSlot(segmenter, [[InitializedSegmenter]]).
|
||||||
auto* segmenter = TRY(typed_this_object(global_object));
|
auto* segmenter = TRY(typed_this_object(global_object));
|
||||||
|
@ -64,7 +68,7 @@ JS_DEFINE_NATIVE_FUNCTION(SegmenterPrototype::segment)
|
||||||
auto string = TRY(vm.argument(0).to_utf16_string(global_object));
|
auto string = TRY(vm.argument(0).to_utf16_string(global_object));
|
||||||
|
|
||||||
// 4. Return ! CreateSegmentsObject(segmenter, string).
|
// 4. Return ! CreateSegmentsObject(segmenter, string).
|
||||||
return Segments::create(global_object, *segmenter, move(string));
|
return Segments::create(realm, *segmenter, move(string));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,15 +11,14 @@
|
||||||
namespace JS::Intl {
|
namespace JS::Intl {
|
||||||
|
|
||||||
// 18.5.1 CreateSegmentsObject ( segmenter, string ), https://tc39.es/ecma402/#sec-createsegmentsobject
|
// 18.5.1 CreateSegmentsObject ( segmenter, string ), https://tc39.es/ecma402/#sec-createsegmentsobject
|
||||||
Segments* Segments::create(GlobalObject& global_object, Segmenter& segmenter, Utf16String string)
|
Segments* Segments::create(Realm& realm, Segmenter& segmenter, Utf16String string)
|
||||||
{
|
{
|
||||||
auto& realm = *global_object.associated_realm();
|
|
||||||
// 1. Let internalSlotsList be « [[SegmentsSegmenter]], [[SegmentsString]] ».
|
// 1. Let internalSlotsList be « [[SegmentsSegmenter]], [[SegmentsString]] ».
|
||||||
// 2. Let segments be OrdinaryObjectCreate(%SegmentsPrototype%, internalSlotsList).
|
// 2. Let segments be OrdinaryObjectCreate(%SegmentsPrototype%, internalSlotsList).
|
||||||
// 3. Set segments.[[SegmentsSegmenter]] to segmenter.
|
// 3. Set segments.[[SegmentsSegmenter]] to segmenter.
|
||||||
// 4. Set segments.[[SegmentsString]] to string.
|
// 4. Set segments.[[SegmentsString]] to string.
|
||||||
// 5. Return segments.
|
// 5. Return segments.
|
||||||
return global_object.heap().allocate<Segments>(global_object, realm, segmenter, move(string));
|
return realm.heap().allocate<Segments>(realm.global_object(), realm, segmenter, move(string));
|
||||||
}
|
}
|
||||||
|
|
||||||
// 18.5 Segments Objects, https://tc39.es/ecma402/#sec-segments-objects
|
// 18.5 Segments Objects, https://tc39.es/ecma402/#sec-segments-objects
|
||||||
|
|
|
@ -16,7 +16,7 @@ class Segments final : public Object {
|
||||||
JS_OBJECT(Segments, Object);
|
JS_OBJECT(Segments, Object);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static Segments* create(GlobalObject&, Segmenter&, Utf16String);
|
static Segments* create(Realm&, Segmenter&, Utf16String);
|
||||||
|
|
||||||
Segments(Realm&, Segmenter&, Utf16String);
|
Segments(Realm&, Segmenter&, Utf16String);
|
||||||
virtual ~Segments() override = default;
|
virtual ~Segments() override = default;
|
||||||
|
|
|
@ -64,6 +64,8 @@ JS_DEFINE_NATIVE_FUNCTION(SegmentsPrototype::containing)
|
||||||
// 18.5.2.2 %SegmentsPrototype% [ @@iterator ] ( ), https://tc39.es/ecma402/#sec-%segmentsprototype%-@@iterator
|
// 18.5.2.2 %SegmentsPrototype% [ @@iterator ] ( ), https://tc39.es/ecma402/#sec-%segmentsprototype%-@@iterator
|
||||||
JS_DEFINE_NATIVE_FUNCTION(SegmentsPrototype::symbol_iterator)
|
JS_DEFINE_NATIVE_FUNCTION(SegmentsPrototype::symbol_iterator)
|
||||||
{
|
{
|
||||||
|
auto& realm = *global_object.associated_realm();
|
||||||
|
|
||||||
// 1. Let segments be the this value.
|
// 1. Let segments be the this value.
|
||||||
// 2. Perform ? RequireInternalSlot(segments, [[SegmentsSegmenter]]).
|
// 2. Perform ? RequireInternalSlot(segments, [[SegmentsSegmenter]]).
|
||||||
auto* segments = TRY(typed_this_object(global_object));
|
auto* segments = TRY(typed_this_object(global_object));
|
||||||
|
@ -75,7 +77,7 @@ JS_DEFINE_NATIVE_FUNCTION(SegmentsPrototype::symbol_iterator)
|
||||||
auto string = segments->segments_string();
|
auto string = segments->segments_string();
|
||||||
|
|
||||||
// 5. Return ! CreateSegmentIterator(segmenter, string).
|
// 5. Return ! CreateSegmentIterator(segmenter, string).
|
||||||
return SegmentIterator::create(global_object, segmenter, string, *segments);
|
return SegmentIterator::create(realm, segmenter, string, *segments);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -197,9 +197,10 @@ Completion async_iterator_close(GlobalObject& global_object, Iterator const& ite
|
||||||
Object* create_iterator_result_object(GlobalObject& global_object, Value value, bool done)
|
Object* create_iterator_result_object(GlobalObject& global_object, Value value, bool done)
|
||||||
{
|
{
|
||||||
auto& vm = global_object.vm();
|
auto& vm = global_object.vm();
|
||||||
|
auto& realm = *global_object.associated_realm();
|
||||||
|
|
||||||
// 1. Let obj be OrdinaryObjectCreate(%Object.prototype%).
|
// 1. Let obj be OrdinaryObjectCreate(%Object.prototype%).
|
||||||
auto* object = Object::create(global_object, global_object.object_prototype());
|
auto* object = Object::create(realm, global_object.object_prototype());
|
||||||
|
|
||||||
// 2. Perform ! CreateDataPropertyOrThrow(obj, "value", value).
|
// 2. Perform ! CreateDataPropertyOrThrow(obj, "value", value).
|
||||||
MUST(object->create_data_property_or_throw(vm.names.value, value));
|
MUST(object->create_data_property_or_throw(vm.names.value, value));
|
||||||
|
|
|
@ -45,6 +45,8 @@ void JSONObject::initialize(Realm& realm)
|
||||||
// 25.5.2 JSON.stringify ( value [ , replacer [ , space ] ] ), https://tc39.es/ecma262/#sec-json.stringify
|
// 25.5.2 JSON.stringify ( value [ , replacer [ , space ] ] ), https://tc39.es/ecma262/#sec-json.stringify
|
||||||
ThrowCompletionOr<String> JSONObject::stringify_impl(GlobalObject& global_object, Value value, Value replacer, Value space)
|
ThrowCompletionOr<String> JSONObject::stringify_impl(GlobalObject& global_object, Value value, Value replacer, Value space)
|
||||||
{
|
{
|
||||||
|
auto& realm = *global_object.associated_realm();
|
||||||
|
|
||||||
StringifyState state;
|
StringifyState state;
|
||||||
|
|
||||||
if (replacer.is_object()) {
|
if (replacer.is_object()) {
|
||||||
|
@ -99,7 +101,7 @@ ThrowCompletionOr<String> JSONObject::stringify_impl(GlobalObject& global_object
|
||||||
state.gap = String::empty();
|
state.gap = String::empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
auto* wrapper = Object::create(global_object, global_object.object_prototype());
|
auto* wrapper = Object::create(realm, global_object.object_prototype());
|
||||||
MUST(wrapper->create_data_property_or_throw(String::empty(), value));
|
MUST(wrapper->create_data_property_or_throw(String::empty(), value));
|
||||||
return serialize_json_property(global_object, state, String::empty(), wrapper);
|
return serialize_json_property(global_object, state, String::empty(), wrapper);
|
||||||
}
|
}
|
||||||
|
@ -392,6 +394,8 @@ String JSONObject::quote_json_string(String string)
|
||||||
// 25.5.1 JSON.parse ( text [ , reviver ] ), https://tc39.es/ecma262/#sec-json.parse
|
// 25.5.1 JSON.parse ( text [ , reviver ] ), https://tc39.es/ecma262/#sec-json.parse
|
||||||
JS_DEFINE_NATIVE_FUNCTION(JSONObject::parse)
|
JS_DEFINE_NATIVE_FUNCTION(JSONObject::parse)
|
||||||
{
|
{
|
||||||
|
auto& realm = *global_object.associated_realm();
|
||||||
|
|
||||||
auto string = TRY(vm.argument(0).to_string(global_object));
|
auto string = TRY(vm.argument(0).to_string(global_object));
|
||||||
auto reviver = vm.argument(1);
|
auto reviver = vm.argument(1);
|
||||||
|
|
||||||
|
@ -400,7 +404,7 @@ JS_DEFINE_NATIVE_FUNCTION(JSONObject::parse)
|
||||||
return vm.throw_completion<SyntaxError>(global_object, ErrorType::JsonMalformed);
|
return vm.throw_completion<SyntaxError>(global_object, 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(global_object, global_object.object_prototype());
|
auto* root = Object::create(realm, global_object.object_prototype());
|
||||||
auto root_name = String::empty();
|
auto root_name = String::empty();
|
||||||
MUST(root->create_data_property_or_throw(root_name, unfiltered));
|
MUST(root->create_data_property_or_throw(root_name, unfiltered));
|
||||||
return internalize_json_property(global_object, root, root_name, reviver.as_function());
|
return internalize_json_property(global_object, root, root_name, reviver.as_function());
|
||||||
|
@ -429,7 +433,8 @@ Value JSONObject::parse_json_value(GlobalObject& global_object, JsonValue const&
|
||||||
|
|
||||||
Object* JSONObject::parse_json_object(GlobalObject& global_object, JsonObject const& json_object)
|
Object* JSONObject::parse_json_object(GlobalObject& global_object, JsonObject const& json_object)
|
||||||
{
|
{
|
||||||
auto* object = Object::create(global_object, global_object.object_prototype());
|
auto& realm = *global_object.associated_realm();
|
||||||
|
auto* object = Object::create(realm, global_object.object_prototype());
|
||||||
json_object.for_each_member([&](auto& key, auto& value) {
|
json_object.for_each_member([&](auto& key, auto& value) {
|
||||||
object->define_direct_property(key, parse_json_value(global_object, value), default_attributes);
|
object->define_direct_property(key, parse_json_value(global_object, value), default_attributes);
|
||||||
});
|
});
|
||||||
|
@ -438,7 +443,8 @@ Object* JSONObject::parse_json_object(GlobalObject& global_object, JsonObject co
|
||||||
|
|
||||||
Array* JSONObject::parse_json_array(GlobalObject& global_object, JsonArray const& json_array)
|
Array* JSONObject::parse_json_array(GlobalObject& global_object, JsonArray const& json_array)
|
||||||
{
|
{
|
||||||
auto* array = MUST(Array::create(global_object, 0));
|
auto& realm = *global_object.associated_realm();
|
||||||
|
auto* array = MUST(Array::create(realm, 0));
|
||||||
size_t index = 0;
|
size_t index = 0;
|
||||||
json_array.for_each([&](auto& value) {
|
json_array.for_each([&](auto& value) {
|
||||||
array->define_direct_property(index++, parse_json_value(global_object, value), default_attributes);
|
array->define_direct_property(index++, parse_json_value(global_object, value), default_attributes);
|
||||||
|
|
|
@ -8,9 +8,9 @@
|
||||||
|
|
||||||
namespace JS {
|
namespace JS {
|
||||||
|
|
||||||
Map* Map::create(GlobalObject& global_object)
|
Map* Map::create(Realm& realm)
|
||||||
{
|
{
|
||||||
return global_object.heap().allocate<Map>(global_object, *global_object.map_prototype());
|
return realm.heap().allocate<Map>(realm.global_object(), *realm.global_object().map_prototype());
|
||||||
}
|
}
|
||||||
|
|
||||||
Map::Map(Object& prototype)
|
Map::Map(Object& prototype)
|
||||||
|
|
|
@ -20,7 +20,7 @@ class Map : public Object {
|
||||||
JS_OBJECT(Map, Object);
|
JS_OBJECT(Map, Object);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static Map* create(GlobalObject&);
|
static Map* create(Realm&);
|
||||||
|
|
||||||
explicit Map(Object& prototype);
|
explicit Map(Object& prototype);
|
||||||
virtual ~Map() override = default;
|
virtual ~Map() override = default;
|
||||||
|
|
|
@ -9,9 +9,9 @@
|
||||||
|
|
||||||
namespace JS {
|
namespace JS {
|
||||||
|
|
||||||
MapIterator* MapIterator::create(GlobalObject& global_object, Map& map, Object::PropertyKind iteration_kind)
|
MapIterator* MapIterator::create(Realm& realm, Map& map, Object::PropertyKind iteration_kind)
|
||||||
{
|
{
|
||||||
return global_object.heap().allocate<MapIterator>(global_object, map, iteration_kind, *global_object.map_iterator_prototype());
|
return realm.heap().allocate<MapIterator>(realm.global_object(), map, iteration_kind, *realm.global_object().map_iterator_prototype());
|
||||||
}
|
}
|
||||||
|
|
||||||
MapIterator::MapIterator(Map& map, Object::PropertyKind iteration_kind, Object& prototype)
|
MapIterator::MapIterator(Map& map, Object::PropertyKind iteration_kind, Object& prototype)
|
||||||
|
|
|
@ -16,7 +16,7 @@ class MapIterator final : public Object {
|
||||||
JS_OBJECT(MapIterator, Object);
|
JS_OBJECT(MapIterator, Object);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static MapIterator* create(GlobalObject&, Map& map, Object::PropertyKind iteration_kind);
|
static MapIterator* create(Realm&, Map& map, Object::PropertyKind iteration_kind);
|
||||||
|
|
||||||
explicit MapIterator(Map& map, Object::PropertyKind iteration_kind, Object& prototype);
|
explicit MapIterator(Map& map, Object::PropertyKind iteration_kind, Object& prototype);
|
||||||
virtual ~MapIterator() override = default;
|
virtual ~MapIterator() override = default;
|
||||||
|
|
|
@ -30,6 +30,8 @@ void MapIteratorPrototype::initialize(Realm& realm)
|
||||||
// 24.1.5.2.1 %MapIteratorPrototype%.next ( ), https://tc39.es/ecma262/#sec-%mapiteratorprototype%.next
|
// 24.1.5.2.1 %MapIteratorPrototype%.next ( ), https://tc39.es/ecma262/#sec-%mapiteratorprototype%.next
|
||||||
JS_DEFINE_NATIVE_FUNCTION(MapIteratorPrototype::next)
|
JS_DEFINE_NATIVE_FUNCTION(MapIteratorPrototype::next)
|
||||||
{
|
{
|
||||||
|
auto& realm = *global_object.associated_realm();
|
||||||
|
|
||||||
auto* map_iterator = TRY(typed_this_value(global_object));
|
auto* map_iterator = TRY(typed_this_value(global_object));
|
||||||
if (map_iterator->done())
|
if (map_iterator->done())
|
||||||
return create_iterator_result_object(global_object, js_undefined(), true);
|
return create_iterator_result_object(global_object, js_undefined(), true);
|
||||||
|
@ -48,7 +50,7 @@ JS_DEFINE_NATIVE_FUNCTION(MapIteratorPrototype::next)
|
||||||
if (iteration_kind == Object::PropertyKind::Value)
|
if (iteration_kind == Object::PropertyKind::Value)
|
||||||
return create_iterator_result_object(global_object, entry.value, false);
|
return create_iterator_result_object(global_object, entry.value, false);
|
||||||
|
|
||||||
return create_iterator_result_object(global_object, Array::create_from(global_object, { entry.key, entry.value }), false);
|
return create_iterator_result_object(global_object, Array::create_from(realm, { entry.key, entry.value }), false);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -57,9 +57,11 @@ JS_DEFINE_NATIVE_FUNCTION(MapPrototype::delete_)
|
||||||
// 24.1.3.4 Map.prototype.entries ( ), https://tc39.es/ecma262/#sec-map.prototype.entries
|
// 24.1.3.4 Map.prototype.entries ( ), https://tc39.es/ecma262/#sec-map.prototype.entries
|
||||||
JS_DEFINE_NATIVE_FUNCTION(MapPrototype::entries)
|
JS_DEFINE_NATIVE_FUNCTION(MapPrototype::entries)
|
||||||
{
|
{
|
||||||
|
auto& realm = *global_object.associated_realm();
|
||||||
|
|
||||||
auto* map = TRY(typed_this_object(global_object));
|
auto* map = TRY(typed_this_object(global_object));
|
||||||
|
|
||||||
return MapIterator::create(global_object, *map, Object::PropertyKind::KeyAndValue);
|
return MapIterator::create(realm, *map, Object::PropertyKind::KeyAndValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 24.1.3.5 Map.prototype.forEach ( callbackfn [ , thisArg ] ), https://tc39.es/ecma262/#sec-map.prototype.foreach
|
// 24.1.3.5 Map.prototype.forEach ( callbackfn [ , thisArg ] ), https://tc39.es/ecma262/#sec-map.prototype.foreach
|
||||||
|
@ -94,9 +96,11 @@ JS_DEFINE_NATIVE_FUNCTION(MapPrototype::has)
|
||||||
// 24.1.3.8 Map.prototype.keys ( ), https://tc39.es/ecma262/#sec-map.prototype.keys
|
// 24.1.3.8 Map.prototype.keys ( ), https://tc39.es/ecma262/#sec-map.prototype.keys
|
||||||
JS_DEFINE_NATIVE_FUNCTION(MapPrototype::keys)
|
JS_DEFINE_NATIVE_FUNCTION(MapPrototype::keys)
|
||||||
{
|
{
|
||||||
|
auto& realm = *global_object.associated_realm();
|
||||||
|
|
||||||
auto* map = TRY(typed_this_object(global_object));
|
auto* map = TRY(typed_this_object(global_object));
|
||||||
|
|
||||||
return MapIterator::create(global_object, *map, Object::PropertyKind::Key);
|
return MapIterator::create(realm, *map, Object::PropertyKind::Key);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 24.1.3.9 Map.prototype.set ( key, value ), https://tc39.es/ecma262/#sec-map.prototype.set
|
// 24.1.3.9 Map.prototype.set ( key, value ), https://tc39.es/ecma262/#sec-map.prototype.set
|
||||||
|
@ -113,9 +117,11 @@ JS_DEFINE_NATIVE_FUNCTION(MapPrototype::set)
|
||||||
// 24.1.3.11 Map.prototype.values ( ), https://tc39.es/ecma262/#sec-map.prototype.values
|
// 24.1.3.11 Map.prototype.values ( ), https://tc39.es/ecma262/#sec-map.prototype.values
|
||||||
JS_DEFINE_NATIVE_FUNCTION(MapPrototype::values)
|
JS_DEFINE_NATIVE_FUNCTION(MapPrototype::values)
|
||||||
{
|
{
|
||||||
|
auto& realm = *global_object.associated_realm();
|
||||||
|
|
||||||
auto* map = TRY(typed_this_object(global_object));
|
auto* map = TRY(typed_this_object(global_object));
|
||||||
|
|
||||||
return MapIterator::create(global_object, *map, Object::PropertyKind::Value);
|
return MapIterator::create(realm, *map, Object::PropertyKind::Value);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 24.1.3.10 get Map.prototype.size, https://tc39.es/ecma262/#sec-get-map.prototype.size
|
// 24.1.3.10 get Map.prototype.size, https://tc39.es/ecma262/#sec-get-map.prototype.size
|
||||||
|
|
|
@ -16,9 +16,9 @@ namespace JS {
|
||||||
|
|
||||||
// 10.3.3 CreateBuiltinFunction ( behaviour, length, name, additionalInternalSlotsList [ , realm [ , prototype [ , prefix ] ] ] ), https://tc39.es/ecma262/#sec-createbuiltinfunction
|
// 10.3.3 CreateBuiltinFunction ( behaviour, length, name, additionalInternalSlotsList [ , realm [ , prototype [ , prefix ] ] ] ), https://tc39.es/ecma262/#sec-createbuiltinfunction
|
||||||
// NOTE: This doesn't consider additionalInternalSlotsList, which is rarely used, and can either be implemented using only the `function` lambda, or needs a NativeFunction subclass.
|
// NOTE: This doesn't consider additionalInternalSlotsList, which is rarely used, and can either be implemented using only the `function` lambda, or needs a NativeFunction subclass.
|
||||||
NativeFunction* NativeFunction::create(GlobalObject& global_object, Function<ThrowCompletionOr<Value>(VM&, GlobalObject&)> behaviour, i32 length, PropertyKey const& name, Optional<Realm*> realm, Optional<Object*> prototype, Optional<StringView> const& prefix)
|
NativeFunction* NativeFunction::create(Realm& allocating_realm, Function<ThrowCompletionOr<Value>(VM&, GlobalObject&)> behaviour, i32 length, PropertyKey const& name, Optional<Realm*> realm, Optional<Object*> prototype, Optional<StringView> const& prefix)
|
||||||
{
|
{
|
||||||
auto& vm = global_object.vm();
|
auto& vm = allocating_realm.vm();
|
||||||
|
|
||||||
// 1. If realm is not present, set realm to the current Realm Record.
|
// 1. If realm is not present, set realm to the current Realm Record.
|
||||||
if (!realm.has_value())
|
if (!realm.has_value())
|
||||||
|
@ -36,7 +36,7 @@ NativeFunction* NativeFunction::create(GlobalObject& global_object, Function<Thr
|
||||||
// 7. Set func.[[Extensible]] to true.
|
// 7. Set func.[[Extensible]] to true.
|
||||||
// 8. Set func.[[Realm]] to realm.
|
// 8. Set func.[[Realm]] to realm.
|
||||||
// 9. Set func.[[InitialName]] to null.
|
// 9. Set func.[[InitialName]] to null.
|
||||||
auto* function = global_object.heap().allocate<NativeFunction>(global_object, move(behaviour), prototype.value(), *realm.value());
|
auto* function = allocating_realm.heap().allocate<NativeFunction>(allocating_realm.global_object(), move(behaviour), prototype.value(), *realm.value());
|
||||||
|
|
||||||
// 10. Perform SetFunctionLength(func, length).
|
// 10. Perform SetFunctionLength(func, length).
|
||||||
function->set_function_length(length);
|
function->set_function_length(length);
|
||||||
|
@ -51,10 +51,9 @@ NativeFunction* NativeFunction::create(GlobalObject& global_object, Function<Thr
|
||||||
return function;
|
return function;
|
||||||
}
|
}
|
||||||
|
|
||||||
NativeFunction* NativeFunction::create(GlobalObject& global_object, FlyString const& name, Function<ThrowCompletionOr<Value>(VM&, GlobalObject&)> function)
|
NativeFunction* NativeFunction::create(Realm& realm, FlyString const& name, Function<ThrowCompletionOr<Value>(VM&, GlobalObject&)> function)
|
||||||
{
|
{
|
||||||
auto& realm = *global_object.associated_realm();
|
return realm.heap().allocate<NativeFunction>(realm.global_object(), name, move(function), *realm.global_object().function_prototype());
|
||||||
return global_object.heap().allocate<NativeFunction>(global_object, name, move(function), *realm.global_object().function_prototype());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
NativeFunction::NativeFunction(Function<ThrowCompletionOr<Value>(VM&, GlobalObject&)> native_function, Object* prototype, Realm& realm)
|
NativeFunction::NativeFunction(Function<ThrowCompletionOr<Value>(VM&, GlobalObject&)> native_function, Object* prototype, Realm& realm)
|
||||||
|
|
|
@ -20,8 +20,8 @@ class NativeFunction : public FunctionObject {
|
||||||
JS_OBJECT(NativeFunction, FunctionObject);
|
JS_OBJECT(NativeFunction, FunctionObject);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static NativeFunction* create(GlobalObject&, Function<ThrowCompletionOr<Value>(VM&, GlobalObject&)> behaviour, i32 length, PropertyKey const& name, Optional<Realm*> = {}, Optional<Object*> prototype = {}, Optional<StringView> const& prefix = {});
|
static NativeFunction* create(Realm&, Function<ThrowCompletionOr<Value>(VM&, GlobalObject&)> behaviour, i32 length, PropertyKey const& name, Optional<Realm*> = {}, Optional<Object*> prototype = {}, Optional<StringView> const& prefix = {});
|
||||||
static NativeFunction* create(GlobalObject&, FlyString const& name, Function<ThrowCompletionOr<Value>(VM&, GlobalObject&)>);
|
static NativeFunction* create(Realm&, FlyString const& name, Function<ThrowCompletionOr<Value>(VM&, GlobalObject&)>);
|
||||||
|
|
||||||
NativeFunction(Function<ThrowCompletionOr<Value>(VM&, GlobalObject&)>, Object* prototype, Realm& realm);
|
NativeFunction(Function<ThrowCompletionOr<Value>(VM&, GlobalObject&)>, Object* prototype, Realm& realm);
|
||||||
NativeFunction(FlyString name, Function<ThrowCompletionOr<Value>(VM&, GlobalObject&)>, Object& prototype);
|
NativeFunction(FlyString name, Function<ThrowCompletionOr<Value>(VM&, GlobalObject&)>, Object& prototype);
|
||||||
|
|
|
@ -9,9 +9,9 @@
|
||||||
|
|
||||||
namespace JS {
|
namespace JS {
|
||||||
|
|
||||||
NumberObject* NumberObject::create(GlobalObject& global_object, double value)
|
NumberObject* NumberObject::create(Realm& realm, double value)
|
||||||
{
|
{
|
||||||
return global_object.heap().allocate<NumberObject>(global_object, value, *global_object.number_prototype());
|
return realm.heap().allocate<NumberObject>(realm.global_object(), value, *realm.global_object().number_prototype());
|
||||||
}
|
}
|
||||||
|
|
||||||
NumberObject::NumberObject(double value, Object& prototype)
|
NumberObject::NumberObject(double value, Object& prototype)
|
||||||
|
|
|
@ -14,7 +14,7 @@ class NumberObject : public Object {
|
||||||
JS_OBJECT(NumberObject, Object);
|
JS_OBJECT(NumberObject, Object);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static NumberObject* create(GlobalObject&, double);
|
static NumberObject* create(Realm&, double);
|
||||||
|
|
||||||
NumberObject(double, Object& prototype);
|
NumberObject(double, Object& prototype);
|
||||||
virtual ~NumberObject() override = default;
|
virtual ~NumberObject() override = default;
|
||||||
|
|
|
@ -24,14 +24,14 @@
|
||||||
namespace JS {
|
namespace JS {
|
||||||
|
|
||||||
// 10.1.12 OrdinaryObjectCreate ( proto [ , additionalInternalSlotsList ] ), https://tc39.es/ecma262/#sec-ordinaryobjectcreate
|
// 10.1.12 OrdinaryObjectCreate ( proto [ , additionalInternalSlotsList ] ), https://tc39.es/ecma262/#sec-ordinaryobjectcreate
|
||||||
Object* Object::create(GlobalObject& global_object, Object* prototype)
|
Object* Object::create(Realm& realm, Object* prototype)
|
||||||
{
|
{
|
||||||
if (!prototype)
|
if (!prototype)
|
||||||
return global_object.heap().allocate<Object>(global_object, *global_object.empty_object_shape());
|
return realm.heap().allocate<Object>(realm.global_object(), *realm.global_object().empty_object_shape());
|
||||||
else if (prototype == global_object.object_prototype())
|
else if (prototype == realm.global_object().object_prototype())
|
||||||
return global_object.heap().allocate<Object>(global_object, *global_object.new_object_shape());
|
return realm.heap().allocate<Object>(realm.global_object(), *realm.global_object().new_object_shape());
|
||||||
else
|
else
|
||||||
return global_object.heap().allocate<Object>(global_object, *prototype);
|
return realm.heap().allocate<Object>(realm.global_object(), *prototype);
|
||||||
}
|
}
|
||||||
|
|
||||||
GlobalObject& Object::global_object() const
|
GlobalObject& Object::global_object() const
|
||||||
|
@ -368,6 +368,7 @@ ThrowCompletionOr<MarkedVector<Value>> Object::enumerable_own_property_names(Pro
|
||||||
// spec text have been replaced with `continue`s in the loop below.
|
// spec text have been replaced with `continue`s in the loop below.
|
||||||
|
|
||||||
auto& global_object = this->global_object();
|
auto& global_object = this->global_object();
|
||||||
|
auto& realm = *global_object.associated_realm();
|
||||||
|
|
||||||
// 1. Let ownKeys be ? O.[[OwnPropertyKeys]]().
|
// 1. Let ownKeys be ? O.[[OwnPropertyKeys]]().
|
||||||
auto own_keys = TRY(internal_own_property_keys());
|
auto own_keys = TRY(internal_own_property_keys());
|
||||||
|
@ -408,7 +409,7 @@ ThrowCompletionOr<MarkedVector<Value>> Object::enumerable_own_property_names(Pro
|
||||||
VERIFY(kind == PropertyKind::KeyAndValue);
|
VERIFY(kind == PropertyKind::KeyAndValue);
|
||||||
|
|
||||||
// ii. Let entry be CreateArrayFromList(« key, value »).
|
// ii. Let entry be CreateArrayFromList(« key, value »).
|
||||||
auto entry = Array::create_from(global_object, { key, value });
|
auto entry = Array::create_from(realm, { key, value });
|
||||||
|
|
||||||
// iii. Append entry to properties.
|
// iii. Append entry to properties.
|
||||||
properties.append(entry);
|
properties.append(entry);
|
||||||
|
@ -1057,12 +1058,13 @@ void Object::set_prototype(Object* new_prototype)
|
||||||
|
|
||||||
void Object::define_native_accessor(PropertyKey const& property_key, Function<ThrowCompletionOr<Value>(VM&, GlobalObject&)> getter, Function<ThrowCompletionOr<Value>(VM&, GlobalObject&)> setter, PropertyAttributes attribute)
|
void Object::define_native_accessor(PropertyKey const& property_key, Function<ThrowCompletionOr<Value>(VM&, GlobalObject&)> getter, Function<ThrowCompletionOr<Value>(VM&, GlobalObject&)> setter, PropertyAttributes attribute)
|
||||||
{
|
{
|
||||||
|
auto& realm = *global_object().associated_realm();
|
||||||
FunctionObject* getter_function = nullptr;
|
FunctionObject* getter_function = nullptr;
|
||||||
if (getter)
|
if (getter)
|
||||||
getter_function = NativeFunction::create(global_object(), move(getter), 0, property_key, {}, {}, "get"sv);
|
getter_function = NativeFunction::create(realm, move(getter), 0, property_key, &realm, {}, "get"sv);
|
||||||
FunctionObject* setter_function = nullptr;
|
FunctionObject* setter_function = nullptr;
|
||||||
if (setter)
|
if (setter)
|
||||||
setter_function = NativeFunction::create(global_object(), move(setter), 1, property_key, {}, {}, "set"sv);
|
setter_function = NativeFunction::create(realm, move(setter), 1, property_key, &realm, {}, "set"sv);
|
||||||
return define_direct_accessor(property_key, getter_function, setter_function, attribute);
|
return define_direct_accessor(property_key, getter_function, setter_function, attribute);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1106,7 +1108,8 @@ Value Object::get_without_side_effects(PropertyKey const& property_key) const
|
||||||
|
|
||||||
void Object::define_native_function(PropertyKey const& property_key, Function<ThrowCompletionOr<Value>(VM&, GlobalObject&)> native_function, i32 length, PropertyAttributes attribute)
|
void Object::define_native_function(PropertyKey const& property_key, Function<ThrowCompletionOr<Value>(VM&, GlobalObject&)> native_function, i32 length, PropertyAttributes attribute)
|
||||||
{
|
{
|
||||||
auto* function = NativeFunction::create(global_object(), move(native_function), length, property_key);
|
auto& realm = *global_object().associated_realm();
|
||||||
|
auto* function = NativeFunction::create(realm, move(native_function), length, property_key, &realm);
|
||||||
define_direct_property(property_key, function, attribute);
|
define_direct_property(property_key, function, attribute);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -47,7 +47,7 @@ struct PrivateElement {
|
||||||
|
|
||||||
class Object : public Cell {
|
class Object : public Cell {
|
||||||
public:
|
public:
|
||||||
static Object* create(GlobalObject&, Object* prototype);
|
static Object* create(Realm&, Object* prototype);
|
||||||
|
|
||||||
Object(Realm&, Object* prototype);
|
Object(Realm&, Object* prototype);
|
||||||
explicit Object(Object& prototype);
|
explicit Object(Object& prototype);
|
||||||
|
|
|
@ -68,12 +68,13 @@ ThrowCompletionOr<Object*> ObjectConstructor::construct(FunctionObject& new_targ
|
||||||
{
|
{
|
||||||
auto& vm = this->vm();
|
auto& vm = this->vm();
|
||||||
auto& global_object = this->global_object();
|
auto& global_object = this->global_object();
|
||||||
|
auto& realm = *global_object.associated_realm();
|
||||||
|
|
||||||
if (&new_target != this)
|
if (&new_target != this)
|
||||||
return TRY(ordinary_create_from_constructor<Object>(global_object, new_target, &GlobalObject::object_prototype));
|
return TRY(ordinary_create_from_constructor<Object>(global_object, new_target, &GlobalObject::object_prototype));
|
||||||
auto value = vm.argument(0);
|
auto value = vm.argument(0);
|
||||||
if (value.is_nullish())
|
if (value.is_nullish())
|
||||||
return Object::create(global_object, global_object.object_prototype());
|
return Object::create(realm, global_object.object_prototype());
|
||||||
return value.to_object(global_object);
|
return value.to_object(global_object);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -112,15 +113,19 @@ static ThrowCompletionOr<MarkedVector<Value>> get_own_property_keys(GlobalObject
|
||||||
// 20.1.2.10 Object.getOwnPropertyNames ( O ), https://tc39.es/ecma262/#sec-object.getownpropertynames
|
// 20.1.2.10 Object.getOwnPropertyNames ( O ), https://tc39.es/ecma262/#sec-object.getownpropertynames
|
||||||
JS_DEFINE_NATIVE_FUNCTION(ObjectConstructor::get_own_property_names)
|
JS_DEFINE_NATIVE_FUNCTION(ObjectConstructor::get_own_property_names)
|
||||||
{
|
{
|
||||||
|
auto& realm = *global_object.associated_realm();
|
||||||
|
|
||||||
// 1. Return CreateArrayFromList(? GetOwnPropertyKeys(O, string)).
|
// 1. Return CreateArrayFromList(? GetOwnPropertyKeys(O, string)).
|
||||||
return Array::create_from(global_object, TRY(get_own_property_keys(global_object, vm.argument(0), GetOwnPropertyKeysType::String)));
|
return Array::create_from(realm, TRY(get_own_property_keys(global_object, vm.argument(0), GetOwnPropertyKeysType::String)));
|
||||||
}
|
}
|
||||||
|
|
||||||
// 20.1.2.11 Object.getOwnPropertySymbols ( O ), https://tc39.es/ecma262/#sec-object.getownpropertysymbols
|
// 20.1.2.11 Object.getOwnPropertySymbols ( O ), https://tc39.es/ecma262/#sec-object.getownpropertysymbols
|
||||||
JS_DEFINE_NATIVE_FUNCTION(ObjectConstructor::get_own_property_symbols)
|
JS_DEFINE_NATIVE_FUNCTION(ObjectConstructor::get_own_property_symbols)
|
||||||
{
|
{
|
||||||
|
auto& realm = *global_object.associated_realm();
|
||||||
|
|
||||||
// 1. Return CreateArrayFromList(? GetOwnPropertyKeys(O, symbol)).
|
// 1. Return CreateArrayFromList(? GetOwnPropertyKeys(O, symbol)).
|
||||||
return Array::create_from(global_object, TRY(get_own_property_keys(global_object, vm.argument(0), GetOwnPropertyKeysType::Symbol)));
|
return Array::create_from(realm, TRY(get_own_property_keys(global_object, vm.argument(0), GetOwnPropertyKeysType::Symbol)));
|
||||||
}
|
}
|
||||||
|
|
||||||
// 20.1.2.12 Object.getPrototypeOf ( O ), https://tc39.es/ecma262/#sec-object.getprototypeof
|
// 20.1.2.12 Object.getPrototypeOf ( O ), https://tc39.es/ecma262/#sec-object.getprototypeof
|
||||||
|
@ -218,9 +223,10 @@ JS_DEFINE_NATIVE_FUNCTION(ObjectConstructor::freeze)
|
||||||
// 20.1.2.7 Object.fromEntries ( iterable ), https://tc39.es/ecma262/#sec-object.fromentries
|
// 20.1.2.7 Object.fromEntries ( iterable ), https://tc39.es/ecma262/#sec-object.fromentries
|
||||||
JS_DEFINE_NATIVE_FUNCTION(ObjectConstructor::from_entries)
|
JS_DEFINE_NATIVE_FUNCTION(ObjectConstructor::from_entries)
|
||||||
{
|
{
|
||||||
|
auto& realm = *global_object.associated_realm();
|
||||||
auto iterable = TRY(require_object_coercible(global_object, vm.argument(0)));
|
auto iterable = TRY(require_object_coercible(global_object, vm.argument(0)));
|
||||||
|
|
||||||
auto* object = Object::create(global_object, global_object.object_prototype());
|
auto* object = Object::create(realm, global_object.object_prototype());
|
||||||
|
|
||||||
(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())
|
||||||
|
@ -262,6 +268,8 @@ JS_DEFINE_NATIVE_FUNCTION(ObjectConstructor::get_own_property_descriptor)
|
||||||
// 20.1.2.9 Object.getOwnPropertyDescriptors ( O ), https://tc39.es/ecma262/#sec-object.getownpropertydescriptors
|
// 20.1.2.9 Object.getOwnPropertyDescriptors ( O ), https://tc39.es/ecma262/#sec-object.getownpropertydescriptors
|
||||||
JS_DEFINE_NATIVE_FUNCTION(ObjectConstructor::get_own_property_descriptors)
|
JS_DEFINE_NATIVE_FUNCTION(ObjectConstructor::get_own_property_descriptors)
|
||||||
{
|
{
|
||||||
|
auto& realm = *global_object.associated_realm();
|
||||||
|
|
||||||
// 1. Let obj be ? ToObject(O).
|
// 1. Let obj be ? ToObject(O).
|
||||||
auto* object = TRY(vm.argument(0).to_object(global_object));
|
auto* object = TRY(vm.argument(0).to_object(global_object));
|
||||||
|
|
||||||
|
@ -269,7 +277,7 @@ JS_DEFINE_NATIVE_FUNCTION(ObjectConstructor::get_own_property_descriptors)
|
||||||
auto own_keys = TRY(object->internal_own_property_keys());
|
auto own_keys = TRY(object->internal_own_property_keys());
|
||||||
|
|
||||||
// 3. Let descriptors be OrdinaryObjectCreate(%Object.prototype%).
|
// 3. Let descriptors be OrdinaryObjectCreate(%Object.prototype%).
|
||||||
auto* descriptors = Object::create(global_object, global_object.object_prototype());
|
auto* descriptors = Object::create(realm, global_object.object_prototype());
|
||||||
|
|
||||||
// 4. For each element key of ownKeys, do
|
// 4. For each element key of ownKeys, do
|
||||||
for (auto& key : own_keys) {
|
for (auto& key : own_keys) {
|
||||||
|
@ -324,30 +332,38 @@ JS_DEFINE_NATIVE_FUNCTION(ObjectConstructor::is)
|
||||||
// 20.1.2.18 Object.keys ( O ), https://tc39.es/ecma262/#sec-object.keys
|
// 20.1.2.18 Object.keys ( O ), https://tc39.es/ecma262/#sec-object.keys
|
||||||
JS_DEFINE_NATIVE_FUNCTION(ObjectConstructor::keys)
|
JS_DEFINE_NATIVE_FUNCTION(ObjectConstructor::keys)
|
||||||
{
|
{
|
||||||
|
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));
|
||||||
auto name_list = TRY(object->enumerable_own_property_names(PropertyKind::Key));
|
auto name_list = TRY(object->enumerable_own_property_names(PropertyKind::Key));
|
||||||
return Array::create_from(global_object, name_list);
|
return Array::create_from(realm, name_list);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 20.1.2.23 Object.values ( O ), https://tc39.es/ecma262/#sec-object.values
|
// 20.1.2.23 Object.values ( O ), https://tc39.es/ecma262/#sec-object.values
|
||||||
JS_DEFINE_NATIVE_FUNCTION(ObjectConstructor::values)
|
JS_DEFINE_NATIVE_FUNCTION(ObjectConstructor::values)
|
||||||
{
|
{
|
||||||
|
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));
|
||||||
auto name_list = TRY(object->enumerable_own_property_names(PropertyKind::Value));
|
auto name_list = TRY(object->enumerable_own_property_names(PropertyKind::Value));
|
||||||
return Array::create_from(global_object, name_list);
|
return Array::create_from(realm, name_list);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 20.1.2.5 Object.entries ( O ), https://tc39.es/ecma262/#sec-object.entries
|
// 20.1.2.5 Object.entries ( O ), https://tc39.es/ecma262/#sec-object.entries
|
||||||
JS_DEFINE_NATIVE_FUNCTION(ObjectConstructor::entries)
|
JS_DEFINE_NATIVE_FUNCTION(ObjectConstructor::entries)
|
||||||
{
|
{
|
||||||
|
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));
|
||||||
auto name_list = TRY(object->enumerable_own_property_names(PropertyKind::KeyAndValue));
|
auto name_list = TRY(object->enumerable_own_property_names(PropertyKind::KeyAndValue));
|
||||||
return Array::create_from(global_object, name_list);
|
return Array::create_from(realm, name_list);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 20.1.2.2 Object.create ( O, Properties ), https://tc39.es/ecma262/#sec-object.create
|
// 20.1.2.2 Object.create ( O, Properties ), https://tc39.es/ecma262/#sec-object.create
|
||||||
JS_DEFINE_NATIVE_FUNCTION(ObjectConstructor::create)
|
JS_DEFINE_NATIVE_FUNCTION(ObjectConstructor::create)
|
||||||
{
|
{
|
||||||
|
auto& realm = *global_object.associated_realm();
|
||||||
|
|
||||||
auto proto = vm.argument(0);
|
auto proto = vm.argument(0);
|
||||||
auto properties = vm.argument(1);
|
auto properties = vm.argument(1);
|
||||||
|
|
||||||
|
@ -356,7 +372,7 @@ JS_DEFINE_NATIVE_FUNCTION(ObjectConstructor::create)
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::ObjectPrototypeWrongType);
|
return vm.throw_completion<TypeError>(global_object, ErrorType::ObjectPrototypeWrongType);
|
||||||
|
|
||||||
// 2. Let obj be OrdinaryObjectCreate(O).
|
// 2. Let obj be OrdinaryObjectCreate(O).
|
||||||
auto* object = Object::create(global_object, proto.is_null() ? nullptr : &proto.as_object());
|
auto* object = Object::create(realm, proto.is_null() ? nullptr : &proto.as_object());
|
||||||
|
|
||||||
// 3. If Properties is not undefined, then
|
// 3. If Properties is not undefined, then
|
||||||
if (!properties.is_undefined()) {
|
if (!properties.is_undefined()) {
|
||||||
|
|
|
@ -43,9 +43,9 @@ ThrowCompletionOr<Object*> promise_resolve(GlobalObject& global_object, Object&
|
||||||
return promise_capability.promise;
|
return promise_capability.promise;
|
||||||
}
|
}
|
||||||
|
|
||||||
Promise* Promise::create(GlobalObject& global_object)
|
Promise* Promise::create(Realm& realm)
|
||||||
{
|
{
|
||||||
return global_object.heap().allocate<Promise>(global_object, *global_object.promise_prototype());
|
return realm.heap().allocate<Promise>(realm.global_object(), *realm.global_object().promise_prototype());
|
||||||
}
|
}
|
||||||
|
|
||||||
// 27.2 Promise Objects, https://tc39.es/ecma262/#sec-promise-objects
|
// 27.2 Promise Objects, https://tc39.es/ecma262/#sec-promise-objects
|
||||||
|
@ -58,7 +58,10 @@ Promise::Promise(Object& prototype)
|
||||||
Promise::ResolvingFunctions Promise::create_resolving_functions()
|
Promise::ResolvingFunctions Promise::create_resolving_functions()
|
||||||
{
|
{
|
||||||
dbgln_if(PROMISE_DEBUG, "[Promise @ {} / create_resolving_functions()]", this);
|
dbgln_if(PROMISE_DEBUG, "[Promise @ {} / create_resolving_functions()]", this);
|
||||||
|
|
||||||
auto& vm = this->vm();
|
auto& vm = this->vm();
|
||||||
|
auto& global_object = this->global_object();
|
||||||
|
auto& realm = *global_object.associated_realm();
|
||||||
|
|
||||||
// 1. Let alreadyResolved be the Record { [[Value]]: false }.
|
// 1. Let alreadyResolved be the Record { [[Value]]: false }.
|
||||||
auto* already_resolved = vm.heap().allocate_without_global_object<AlreadyResolved>();
|
auto* already_resolved = vm.heap().allocate_without_global_object<AlreadyResolved>();
|
||||||
|
@ -70,9 +73,11 @@ Promise::ResolvingFunctions Promise::create_resolving_functions()
|
||||||
// 6. Set resolve.[[AlreadyResolved]] to alreadyResolved.
|
// 6. Set resolve.[[AlreadyResolved]] to alreadyResolved.
|
||||||
|
|
||||||
// 27.2.1.3.2 Promise Resolve Functions, https://tc39.es/ecma262/#sec-promise-resolve-functions
|
// 27.2.1.3.2 Promise Resolve Functions, https://tc39.es/ecma262/#sec-promise-resolve-functions
|
||||||
auto* resolve_function = PromiseResolvingFunction::create(global_object(), *this, *already_resolved, [](auto& vm, auto& global_object, auto& promise, auto& already_resolved) {
|
auto* resolve_function = PromiseResolvingFunction::create(realm, *this, *already_resolved, [](auto& vm, auto& global_object, auto& promise, auto& already_resolved) {
|
||||||
dbgln_if(PROMISE_DEBUG, "[Promise @ {} / PromiseResolvingFunction]: Resolve function was called", &promise);
|
dbgln_if(PROMISE_DEBUG, "[Promise @ {} / PromiseResolvingFunction]: Resolve function was called", &promise);
|
||||||
|
|
||||||
|
auto& realm = *global_object.associated_realm();
|
||||||
|
|
||||||
auto resolution = vm.argument(0);
|
auto resolution = vm.argument(0);
|
||||||
|
|
||||||
// 1. Let F be the active function object.
|
// 1. Let F be the active function object.
|
||||||
|
@ -94,7 +99,7 @@ Promise::ResolvingFunctions Promise::create_resolving_functions()
|
||||||
dbgln_if(PROMISE_DEBUG, "[Promise @ {} / PromiseResolvingFunction]: Promise can't be resolved with itself, rejecting with error", &promise);
|
dbgln_if(PROMISE_DEBUG, "[Promise @ {} / PromiseResolvingFunction]: Promise can't be resolved with itself, rejecting with error", &promise);
|
||||||
|
|
||||||
// a. Let selfResolutionError be a newly created TypeError object.
|
// a. Let selfResolutionError be a newly created TypeError object.
|
||||||
auto* self_resolution_error = TypeError::create(global_object, "Cannot resolve promise with itself");
|
auto* self_resolution_error = TypeError::create(realm, "Cannot resolve promise with itself");
|
||||||
|
|
||||||
// b. Perform RejectPromise(promise, selfResolutionError).
|
// b. Perform RejectPromise(promise, selfResolutionError).
|
||||||
promise.reject(self_resolution_error);
|
promise.reject(self_resolution_error);
|
||||||
|
@ -145,11 +150,11 @@ Promise::ResolvingFunctions Promise::create_resolving_functions()
|
||||||
|
|
||||||
// 14. Let job be NewPromiseResolveThenableJob(promise, resolution, thenJobCallback).
|
// 14. Let job be NewPromiseResolveThenableJob(promise, resolution, thenJobCallback).
|
||||||
dbgln_if(PROMISE_DEBUG, "[Promise @ {} / PromiseResolvingFunction]: Creating PromiseResolveThenableJob for thenable {}", &promise, resolution);
|
dbgln_if(PROMISE_DEBUG, "[Promise @ {} / PromiseResolvingFunction]: Creating PromiseResolveThenableJob for thenable {}", &promise, resolution);
|
||||||
auto [job, realm] = create_promise_resolve_thenable_job(global_object, promise, resolution, move(then_job_callback));
|
auto job = create_promise_resolve_thenable_job(global_object, promise, resolution, move(then_job_callback));
|
||||||
|
|
||||||
// 15. Perform HostEnqueuePromiseJob(job.[[Job]], job.[[Realm]]).
|
// 15. Perform HostEnqueuePromiseJob(job.[[Job]], job.[[Realm]]).
|
||||||
dbgln_if(PROMISE_DEBUG, "[Promise @ {} / PromiseResolvingFunction]: Enqueuing job @ {} in realm {}", &promise, &job, realm);
|
dbgln_if(PROMISE_DEBUG, "[Promise @ {} / PromiseResolvingFunction]: Enqueuing job @ {} in realm {}", &promise, &job.job, job.realm);
|
||||||
vm.host_enqueue_promise_job(move(job), realm);
|
vm.host_enqueue_promise_job(move(job.job), job.realm);
|
||||||
|
|
||||||
// 16. Return undefined.
|
// 16. Return undefined.
|
||||||
return js_undefined();
|
return js_undefined();
|
||||||
|
@ -163,7 +168,7 @@ Promise::ResolvingFunctions Promise::create_resolving_functions()
|
||||||
// 11. Set reject.[[AlreadyResolved]] to alreadyResolved.
|
// 11. Set reject.[[AlreadyResolved]] to alreadyResolved.
|
||||||
|
|
||||||
// 27.2.1.3.1 Promise Reject Functions, https://tc39.es/ecma262/#sec-promise-reject-functions
|
// 27.2.1.3.1 Promise Reject Functions, https://tc39.es/ecma262/#sec-promise-reject-functions
|
||||||
auto* reject_function = PromiseResolvingFunction::create(global_object(), *this, *already_resolved, [](auto& vm, auto&, auto& promise, auto& already_resolved) {
|
auto* reject_function = PromiseResolvingFunction::create(realm, *this, *already_resolved, [](auto& vm, auto&, auto& promise, auto& already_resolved) {
|
||||||
dbgln_if(PROMISE_DEBUG, "[Promise @ {} / PromiseResolvingFunction]: Reject function was called", &promise);
|
dbgln_if(PROMISE_DEBUG, "[Promise @ {} / PromiseResolvingFunction]: Reject function was called", &promise);
|
||||||
|
|
||||||
auto reason = vm.argument(0);
|
auto reason = vm.argument(0);
|
||||||
|
|
|
@ -27,7 +27,7 @@ public:
|
||||||
Handle,
|
Handle,
|
||||||
};
|
};
|
||||||
|
|
||||||
static Promise* create(GlobalObject&);
|
static Promise* create(Realm&);
|
||||||
|
|
||||||
explicit Promise(Object& prototype);
|
explicit Promise(Object& prototype);
|
||||||
virtual ~Promise() = default;
|
virtual ~Promise() = default;
|
||||||
|
|
|
@ -119,12 +119,13 @@ static ThrowCompletionOr<Value> perform_promise_common(GlobalObject& global_obje
|
||||||
static ThrowCompletionOr<Value> perform_promise_all(GlobalObject& global_object, Iterator& iterator_record, Value constructor, PromiseCapability result_capability, Value promise_resolve)
|
static ThrowCompletionOr<Value> perform_promise_all(GlobalObject& global_object, Iterator& iterator_record, Value constructor, PromiseCapability result_capability, Value promise_resolve)
|
||||||
{
|
{
|
||||||
auto& vm = global_object.vm();
|
auto& vm = global_object.vm();
|
||||||
|
auto& realm = *global_object.associated_realm();
|
||||||
|
|
||||||
return perform_promise_common(
|
return perform_promise_common(
|
||||||
global_object, iterator_record, constructor, result_capability, promise_resolve,
|
global_object, iterator_record, constructor, result_capability, promise_resolve,
|
||||||
[&](PromiseValueList& values) -> ThrowCompletionOr<Value> {
|
[&](PromiseValueList& values) -> ThrowCompletionOr<Value> {
|
||||||
// 1. Let valuesArray be CreateArrayFromList(values).
|
// 1. Let valuesArray be CreateArrayFromList(values).
|
||||||
auto* values_array = Array::create_from(global_object, values.values());
|
auto* values_array = Array::create_from(realm, values.values());
|
||||||
|
|
||||||
// 2. Perform ? Call(resultCapability.[[Resolve]], undefined, « valuesArray »).
|
// 2. Perform ? Call(resultCapability.[[Resolve]], undefined, « valuesArray »).
|
||||||
TRY(call(global_object, *result_capability.resolve, js_undefined(), values_array));
|
TRY(call(global_object, *result_capability.resolve, js_undefined(), values_array));
|
||||||
|
@ -141,7 +142,7 @@ static ThrowCompletionOr<Value> perform_promise_all(GlobalObject& global_object,
|
||||||
// o. Set onFulfilled.[[Values]] to values.
|
// o. Set onFulfilled.[[Values]] to values.
|
||||||
// p. Set onFulfilled.[[Capability]] to resultCapability.
|
// p. Set onFulfilled.[[Capability]] to resultCapability.
|
||||||
// q. Set onFulfilled.[[RemainingElements]] to remainingElementsCount.
|
// q. Set onFulfilled.[[RemainingElements]] to remainingElementsCount.
|
||||||
auto* on_fulfilled = PromiseAllResolveElementFunction::create(global_object, index, values, result_capability, remaining_elements_count);
|
auto* on_fulfilled = PromiseAllResolveElementFunction::create(realm, index, values, result_capability, remaining_elements_count);
|
||||||
on_fulfilled->define_direct_property(vm.names.name, js_string(vm, String::empty()), Attribute::Configurable);
|
on_fulfilled->define_direct_property(vm.names.name, js_string(vm, String::empty()), Attribute::Configurable);
|
||||||
|
|
||||||
// s. Perform ? Invoke(nextPromise, "then", « onFulfilled, resultCapability.[[Reject]] »).
|
// s. Perform ? Invoke(nextPromise, "then", « onFulfilled, resultCapability.[[Reject]] »).
|
||||||
|
@ -153,11 +154,12 @@ static ThrowCompletionOr<Value> perform_promise_all(GlobalObject& global_object,
|
||||||
static ThrowCompletionOr<Value> perform_promise_all_settled(GlobalObject& global_object, Iterator& iterator_record, Value constructor, PromiseCapability result_capability, Value promise_resolve)
|
static ThrowCompletionOr<Value> perform_promise_all_settled(GlobalObject& global_object, Iterator& iterator_record, Value constructor, PromiseCapability result_capability, Value promise_resolve)
|
||||||
{
|
{
|
||||||
auto& vm = global_object.vm();
|
auto& vm = global_object.vm();
|
||||||
|
auto& realm = *global_object.associated_realm();
|
||||||
|
|
||||||
return perform_promise_common(
|
return perform_promise_common(
|
||||||
global_object, iterator_record, constructor, result_capability, promise_resolve,
|
global_object, iterator_record, constructor, result_capability, promise_resolve,
|
||||||
[&](PromiseValueList& values) -> ThrowCompletionOr<Value> {
|
[&](PromiseValueList& values) -> ThrowCompletionOr<Value> {
|
||||||
auto* values_array = Array::create_from(global_object, values.values());
|
auto* values_array = Array::create_from(realm, values.values());
|
||||||
|
|
||||||
TRY(call(global_object, *result_capability.resolve, js_undefined(), values_array));
|
TRY(call(global_object, *result_capability.resolve, js_undefined(), values_array));
|
||||||
|
|
||||||
|
@ -173,7 +175,7 @@ static ThrowCompletionOr<Value> perform_promise_all_settled(GlobalObject& global
|
||||||
// p. Set onFulfilled.[[Values]] to values.
|
// p. Set onFulfilled.[[Values]] to values.
|
||||||
// q. Set onFulfilled.[[Capability]] to resultCapability.
|
// q. Set onFulfilled.[[Capability]] to resultCapability.
|
||||||
// r. Set onFulfilled.[[RemainingElements]] to remainingElementsCount.
|
// r. Set onFulfilled.[[RemainingElements]] to remainingElementsCount.
|
||||||
auto* on_fulfilled = PromiseAllSettledResolveElementFunction::create(global_object, index, values, result_capability, remaining_elements_count);
|
auto* on_fulfilled = PromiseAllSettledResolveElementFunction::create(realm, index, values, result_capability, remaining_elements_count);
|
||||||
on_fulfilled->define_direct_property(vm.names.name, js_string(vm, String::empty()), Attribute::Configurable);
|
on_fulfilled->define_direct_property(vm.names.name, js_string(vm, String::empty()), Attribute::Configurable);
|
||||||
|
|
||||||
// s. Let stepsRejected be the algorithm steps defined in Promise.allSettled Reject Element Functions.
|
// s. Let stepsRejected be the algorithm steps defined in Promise.allSettled Reject Element Functions.
|
||||||
|
@ -184,7 +186,7 @@ static ThrowCompletionOr<Value> perform_promise_all_settled(GlobalObject& global
|
||||||
// x. Set onRejected.[[Values]] to values.
|
// x. Set onRejected.[[Values]] to values.
|
||||||
// y. Set onRejected.[[Capability]] to resultCapability.
|
// y. Set onRejected.[[Capability]] to resultCapability.
|
||||||
// z. Set onRejected.[[RemainingElements]] to remainingElementsCount.
|
// z. Set onRejected.[[RemainingElements]] to remainingElementsCount.
|
||||||
auto* on_rejected = PromiseAllSettledRejectElementFunction::create(global_object, index, values, result_capability, remaining_elements_count);
|
auto* on_rejected = PromiseAllSettledRejectElementFunction::create(realm, index, values, result_capability, remaining_elements_count);
|
||||||
on_rejected->define_direct_property(vm.names.name, js_string(vm, String::empty()), Attribute::Configurable);
|
on_rejected->define_direct_property(vm.names.name, js_string(vm, String::empty()), Attribute::Configurable);
|
||||||
|
|
||||||
// ab. Perform ? Invoke(nextPromise, "then", « onFulfilled, onRejected »).
|
// ab. Perform ? Invoke(nextPromise, "then", « onFulfilled, onRejected »).
|
||||||
|
@ -196,15 +198,16 @@ static ThrowCompletionOr<Value> perform_promise_all_settled(GlobalObject& global
|
||||||
static ThrowCompletionOr<Value> perform_promise_any(GlobalObject& global_object, Iterator& iterator_record, Value constructor, PromiseCapability result_capability, Value promise_resolve)
|
static ThrowCompletionOr<Value> perform_promise_any(GlobalObject& global_object, Iterator& iterator_record, Value constructor, PromiseCapability result_capability, Value promise_resolve)
|
||||||
{
|
{
|
||||||
auto& vm = global_object.vm();
|
auto& vm = global_object.vm();
|
||||||
|
auto& realm = *global_object.associated_realm();
|
||||||
|
|
||||||
return perform_promise_common(
|
return perform_promise_common(
|
||||||
global_object, iterator_record, constructor, result_capability, promise_resolve,
|
global_object, iterator_record, constructor, result_capability, promise_resolve,
|
||||||
[&](PromiseValueList& errors) -> ThrowCompletionOr<Value> {
|
[&](PromiseValueList& errors) -> ThrowCompletionOr<Value> {
|
||||||
// 1. Let error be a newly created AggregateError object.
|
// 1. Let error be a newly created AggregateError object.
|
||||||
auto* error = AggregateError::create(global_object);
|
auto* error = AggregateError::create(realm);
|
||||||
|
|
||||||
// 2. Perform ! DefinePropertyOrThrow(error, "errors", PropertyDescriptor { [[Configurable]]: true, [[Enumerable]]: false, [[Writable]]: true, [[Value]]: CreateArrayFromList(errors) }).
|
// 2. Perform ! DefinePropertyOrThrow(error, "errors", PropertyDescriptor { [[Configurable]]: true, [[Enumerable]]: false, [[Writable]]: true, [[Value]]: CreateArrayFromList(errors) }).
|
||||||
auto* errors_array = Array::create_from(global_object, errors.values());
|
auto* errors_array = Array::create_from(realm, errors.values());
|
||||||
MUST(error->define_property_or_throw(vm.names.errors, { .value = errors_array, .writable = true, .enumerable = false, .configurable = true }));
|
MUST(error->define_property_or_throw(vm.names.errors, { .value = errors_array, .writable = true, .enumerable = false, .configurable = true }));
|
||||||
|
|
||||||
// 3. Return ThrowCompletion(error).
|
// 3. Return ThrowCompletion(error).
|
||||||
|
@ -219,7 +222,7 @@ static ThrowCompletionOr<Value> perform_promise_any(GlobalObject& global_object,
|
||||||
// o. Set onRejected.[[Errors]] to errors.
|
// o. Set onRejected.[[Errors]] to errors.
|
||||||
// p. Set onRejected.[[Capability]] to resultCapability.
|
// p. Set onRejected.[[Capability]] to resultCapability.
|
||||||
// q. Set onRejected.[[RemainingElements]] to remainingElementsCount.
|
// q. Set onRejected.[[RemainingElements]] to remainingElementsCount.
|
||||||
auto* on_rejected = PromiseAnyRejectElementFunction::create(global_object, index, errors, result_capability, remaining_elements_count);
|
auto* on_rejected = PromiseAnyRejectElementFunction::create(realm, index, errors, result_capability, remaining_elements_count);
|
||||||
on_rejected->define_direct_property(vm.names.name, js_string(vm, String::empty()), Attribute::Configurable);
|
on_rejected->define_direct_property(vm.names.name, js_string(vm, String::empty()), Attribute::Configurable);
|
||||||
|
|
||||||
// s. Perform ? Invoke(nextPromise, "then", « resultCapability.[[Resolve]], onRejected »).
|
// s. Perform ? Invoke(nextPromise, "then", « resultCapability.[[Resolve]], onRejected »).
|
||||||
|
|
|
@ -70,6 +70,8 @@ JS_DEFINE_NATIVE_FUNCTION(PromisePrototype::catch_)
|
||||||
// 27.2.5.3 Promise.prototype.finally ( onFinally ), https://tc39.es/ecma262/#sec-promise.prototype.finally
|
// 27.2.5.3 Promise.prototype.finally ( onFinally ), https://tc39.es/ecma262/#sec-promise.prototype.finally
|
||||||
JS_DEFINE_NATIVE_FUNCTION(PromisePrototype::finally)
|
JS_DEFINE_NATIVE_FUNCTION(PromisePrototype::finally)
|
||||||
{
|
{
|
||||||
|
auto& realm = *global_object.associated_realm();
|
||||||
|
|
||||||
auto on_finally = vm.argument(0);
|
auto on_finally = vm.argument(0);
|
||||||
|
|
||||||
// 1. Let promise be the this value.
|
// 1. Let promise be the this value.
|
||||||
|
@ -100,6 +102,7 @@ JS_DEFINE_NATIVE_FUNCTION(PromisePrototype::finally)
|
||||||
else {
|
else {
|
||||||
// a. Let thenFinallyClosure be a new Abstract Closure with parameters (value) that captures onFinally and C and performs the following steps when called:
|
// a. Let thenFinallyClosure be a new Abstract Closure with parameters (value) that captures onFinally and C and performs the following steps when called:
|
||||||
auto then_finally_closure = [constructor_handle = make_handle(constructor), on_finally_handle = make_handle(&on_finally.as_function())](auto& vm, auto& global_object) -> ThrowCompletionOr<Value> {
|
auto then_finally_closure = [constructor_handle = make_handle(constructor), on_finally_handle = make_handle(&on_finally.as_function())](auto& vm, auto& global_object) -> ThrowCompletionOr<Value> {
|
||||||
|
auto& realm = *global_object.associated_realm();
|
||||||
auto& constructor = const_cast<FunctionObject&>(*constructor_handle.cell());
|
auto& constructor = const_cast<FunctionObject&>(*constructor_handle.cell());
|
||||||
auto& on_finally = const_cast<FunctionObject&>(*on_finally_handle.cell());
|
auto& on_finally = const_cast<FunctionObject&>(*on_finally_handle.cell());
|
||||||
auto value = vm.argument(0);
|
auto value = vm.argument(0);
|
||||||
|
@ -117,17 +120,18 @@ JS_DEFINE_NATIVE_FUNCTION(PromisePrototype::finally)
|
||||||
};
|
};
|
||||||
|
|
||||||
// iv. Let valueThunk be CreateBuiltinFunction(returnValue, 0, "", « »).
|
// iv. Let valueThunk be CreateBuiltinFunction(returnValue, 0, "", « »).
|
||||||
auto* value_thunk = NativeFunction::create(global_object, move(return_value), 0, "");
|
auto* value_thunk = NativeFunction::create(realm, move(return_value), 0, "");
|
||||||
|
|
||||||
// v. Return ? Invoke(promise, "then", « valueThunk »).
|
// v. Return ? Invoke(promise, "then", « valueThunk »).
|
||||||
return TRY(Value(promise).invoke(global_object, vm.names.then, value_thunk));
|
return TRY(Value(promise).invoke(global_object, vm.names.then, value_thunk));
|
||||||
};
|
};
|
||||||
|
|
||||||
// b. Let thenFinally be CreateBuiltinFunction(thenFinallyClosure, 1, "", « »).
|
// b. Let thenFinally be CreateBuiltinFunction(thenFinallyClosure, 1, "", « »).
|
||||||
then_finally = NativeFunction::create(global_object, move(then_finally_closure), 1, "");
|
then_finally = NativeFunction::create(realm, move(then_finally_closure), 1, "");
|
||||||
|
|
||||||
// c. Let catchFinallyClosure be a new Abstract Closure with parameters (reason) that captures onFinally and C and performs the following steps when called:
|
// c. Let catchFinallyClosure be a new Abstract Closure with parameters (reason) that captures onFinally and C and performs the following steps when called:
|
||||||
auto catch_finally_closure = [constructor_handle = make_handle(constructor), on_finally_handle = make_handle(&on_finally.as_function())](auto& vm, auto& global_object) -> ThrowCompletionOr<Value> {
|
auto catch_finally_closure = [constructor_handle = make_handle(constructor), on_finally_handle = make_handle(&on_finally.as_function())](auto& vm, auto& global_object) -> ThrowCompletionOr<Value> {
|
||||||
|
auto& realm = *global_object.associated_realm();
|
||||||
auto& constructor = const_cast<FunctionObject&>(*constructor_handle.cell());
|
auto& constructor = const_cast<FunctionObject&>(*constructor_handle.cell());
|
||||||
auto& on_finally = const_cast<FunctionObject&>(*on_finally_handle.cell());
|
auto& on_finally = const_cast<FunctionObject&>(*on_finally_handle.cell());
|
||||||
auto reason = vm.argument(0);
|
auto reason = vm.argument(0);
|
||||||
|
@ -145,14 +149,14 @@ JS_DEFINE_NATIVE_FUNCTION(PromisePrototype::finally)
|
||||||
};
|
};
|
||||||
|
|
||||||
// iv. Let thrower be CreateBuiltinFunction(throwReason, 0, "", « »).
|
// iv. Let thrower be CreateBuiltinFunction(throwReason, 0, "", « »).
|
||||||
auto* thrower = NativeFunction::create(global_object, move(throw_reason), 0, "");
|
auto* thrower = NativeFunction::create(realm, move(throw_reason), 0, "");
|
||||||
|
|
||||||
// v. Return ? Invoke(promise, "then", « thrower »).
|
// v. Return ? Invoke(promise, "then", « thrower »).
|
||||||
return TRY(Value(promise).invoke(global_object, vm.names.then, thrower));
|
return TRY(Value(promise).invoke(global_object, vm.names.then, thrower));
|
||||||
};
|
};
|
||||||
|
|
||||||
// d. Let catchFinally be CreateBuiltinFunction(catchFinallyClosure, 1, "", « »).
|
// d. Let catchFinally be CreateBuiltinFunction(catchFinallyClosure, 1, "", « »).
|
||||||
catch_finally = NativeFunction::create(global_object, move(catch_finally_closure), 1, "");
|
catch_finally = NativeFunction::create(realm, move(catch_finally_closure), 1, "");
|
||||||
}
|
}
|
||||||
|
|
||||||
// 7. Return ? Invoke(promise, "then", « thenFinally, catchFinally »).
|
// 7. Return ? Invoke(promise, "then", « thenFinally, catchFinally »).
|
||||||
|
|
|
@ -15,6 +15,7 @@ namespace JS {
|
||||||
ThrowCompletionOr<PromiseCapability> new_promise_capability(GlobalObject& global_object, Value constructor)
|
ThrowCompletionOr<PromiseCapability> new_promise_capability(GlobalObject& global_object, Value constructor)
|
||||||
{
|
{
|
||||||
auto& vm = global_object.vm();
|
auto& vm = global_object.vm();
|
||||||
|
auto& realm = *global_object.associated_realm();
|
||||||
|
|
||||||
// 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())
|
||||||
|
@ -55,7 +56,7 @@ ThrowCompletionOr<PromiseCapability> new_promise_capability(GlobalObject& global
|
||||||
};
|
};
|
||||||
|
|
||||||
// 5. Let executor be CreateBuiltinFunction(executorClosure, 2, "", « »).
|
// 5. Let executor be CreateBuiltinFunction(executorClosure, 2, "", « »).
|
||||||
auto* executor = NativeFunction::create(global_object, move(executor_closure), 2, "");
|
auto* executor = NativeFunction::create(realm, move(executor_closure), 2, "");
|
||||||
|
|
||||||
// 6. Let promise be ? Construct(C, « executor »).
|
// 6. Let promise be ? Construct(C, « executor »).
|
||||||
auto* promise = TRY(construct(global_object, constructor.as_function(), executor));
|
auto* promise = TRY(construct(global_object, constructor.as_function(), executor));
|
||||||
|
|
|
@ -55,9 +55,9 @@ void PromiseResolvingElementFunction::visit_edges(Cell::Visitor& visitor)
|
||||||
visitor.visit(&m_remaining_elements);
|
visitor.visit(&m_remaining_elements);
|
||||||
}
|
}
|
||||||
|
|
||||||
PromiseAllResolveElementFunction* PromiseAllResolveElementFunction::create(GlobalObject& global_object, size_t index, PromiseValueList& values, PromiseCapability capability, RemainingElements& remaining_elements)
|
PromiseAllResolveElementFunction* PromiseAllResolveElementFunction::create(Realm& realm, size_t index, PromiseValueList& values, PromiseCapability capability, RemainingElements& remaining_elements)
|
||||||
{
|
{
|
||||||
return global_object.heap().allocate<PromiseAllResolveElementFunction>(global_object, index, values, capability, remaining_elements, *global_object.function_prototype());
|
return realm.heap().allocate<PromiseAllResolveElementFunction>(realm.global_object(), index, values, capability, remaining_elements, *realm.global_object().function_prototype());
|
||||||
}
|
}
|
||||||
|
|
||||||
PromiseAllResolveElementFunction::PromiseAllResolveElementFunction(size_t index, PromiseValueList& values, PromiseCapability capability, RemainingElements& remaining_elements, Object& prototype)
|
PromiseAllResolveElementFunction::PromiseAllResolveElementFunction(size_t index, PromiseValueList& values, PromiseCapability capability, RemainingElements& remaining_elements, Object& prototype)
|
||||||
|
@ -69,6 +69,7 @@ ThrowCompletionOr<Value> PromiseAllResolveElementFunction::resolve_element()
|
||||||
{
|
{
|
||||||
auto& vm = this->vm();
|
auto& vm = this->vm();
|
||||||
auto& global_object = this->global_object();
|
auto& global_object = this->global_object();
|
||||||
|
auto& realm = *global_object.associated_realm();
|
||||||
|
|
||||||
// 8. Set values[index] to x.
|
// 8. Set values[index] to x.
|
||||||
m_values.values()[m_index] = vm.argument(0);
|
m_values.values()[m_index] = vm.argument(0);
|
||||||
|
@ -77,7 +78,7 @@ ThrowCompletionOr<Value> PromiseAllResolveElementFunction::resolve_element()
|
||||||
// 10. If remainingElementsCount.[[Value]] is 0, then
|
// 10. If remainingElementsCount.[[Value]] is 0, then
|
||||||
if (--m_remaining_elements.value == 0) {
|
if (--m_remaining_elements.value == 0) {
|
||||||
// a. Let valuesArray be CreateArrayFromList(values).
|
// a. Let valuesArray be CreateArrayFromList(values).
|
||||||
auto* values_array = Array::create_from(global_object, m_values.values());
|
auto* values_array = Array::create_from(realm, m_values.values());
|
||||||
|
|
||||||
// b. Return ? Call(promiseCapability.[[Resolve]], undefined, « valuesArray »).
|
// b. Return ? Call(promiseCapability.[[Resolve]], undefined, « valuesArray »).
|
||||||
return JS::call(global_object, *m_capability.resolve, js_undefined(), values_array);
|
return JS::call(global_object, *m_capability.resolve, js_undefined(), values_array);
|
||||||
|
@ -87,9 +88,9 @@ ThrowCompletionOr<Value> PromiseAllResolveElementFunction::resolve_element()
|
||||||
return js_undefined();
|
return js_undefined();
|
||||||
}
|
}
|
||||||
|
|
||||||
PromiseAllSettledResolveElementFunction* PromiseAllSettledResolveElementFunction::create(GlobalObject& global_object, size_t index, PromiseValueList& values, PromiseCapability capability, RemainingElements& remaining_elements)
|
PromiseAllSettledResolveElementFunction* PromiseAllSettledResolveElementFunction::create(Realm& realm, size_t index, PromiseValueList& values, PromiseCapability capability, RemainingElements& remaining_elements)
|
||||||
{
|
{
|
||||||
return global_object.heap().allocate<PromiseAllSettledResolveElementFunction>(global_object, index, values, capability, remaining_elements, *global_object.function_prototype());
|
return realm.heap().allocate<PromiseAllSettledResolveElementFunction>(realm.global_object(), index, values, capability, remaining_elements, *realm.global_object().function_prototype());
|
||||||
}
|
}
|
||||||
|
|
||||||
PromiseAllSettledResolveElementFunction::PromiseAllSettledResolveElementFunction(size_t index, PromiseValueList& values, PromiseCapability capability, RemainingElements& remaining_elements, Object& prototype)
|
PromiseAllSettledResolveElementFunction::PromiseAllSettledResolveElementFunction(size_t index, PromiseValueList& values, PromiseCapability capability, RemainingElements& remaining_elements, Object& prototype)
|
||||||
|
@ -101,9 +102,10 @@ ThrowCompletionOr<Value> PromiseAllSettledResolveElementFunction::resolve_elemen
|
||||||
{
|
{
|
||||||
auto& vm = this->vm();
|
auto& vm = this->vm();
|
||||||
auto& global_object = this->global_object();
|
auto& global_object = this->global_object();
|
||||||
|
auto& realm = *global_object.associated_realm();
|
||||||
|
|
||||||
// 9. Let obj be OrdinaryObjectCreate(%Object.prototype%).
|
// 9. Let obj be OrdinaryObjectCreate(%Object.prototype%).
|
||||||
auto* object = Object::create(global_object, global_object.object_prototype());
|
auto* object = Object::create(realm, global_object.object_prototype());
|
||||||
|
|
||||||
// 10. Perform ! CreateDataPropertyOrThrow(obj, "status", "fulfilled").
|
// 10. Perform ! CreateDataPropertyOrThrow(obj, "status", "fulfilled").
|
||||||
MUST(object->create_data_property_or_throw(vm.names.status, js_string(vm, "fulfilled"sv)));
|
MUST(object->create_data_property_or_throw(vm.names.status, js_string(vm, "fulfilled"sv)));
|
||||||
|
@ -118,7 +120,7 @@ ThrowCompletionOr<Value> PromiseAllSettledResolveElementFunction::resolve_elemen
|
||||||
// 14. If remainingElementsCount.[[Value]] is 0, then
|
// 14. If remainingElementsCount.[[Value]] is 0, then
|
||||||
if (--m_remaining_elements.value == 0) {
|
if (--m_remaining_elements.value == 0) {
|
||||||
// a. Let valuesArray be CreateArrayFromList(values).
|
// a. Let valuesArray be CreateArrayFromList(values).
|
||||||
auto* values_array = Array::create_from(global_object, m_values.values());
|
auto* values_array = Array::create_from(realm, m_values.values());
|
||||||
|
|
||||||
// b. Return ? Call(promiseCapability.[[Resolve]], undefined, « valuesArray »).
|
// b. Return ? Call(promiseCapability.[[Resolve]], undefined, « valuesArray »).
|
||||||
return JS::call(global_object, *m_capability.resolve, js_undefined(), values_array);
|
return JS::call(global_object, *m_capability.resolve, js_undefined(), values_array);
|
||||||
|
@ -128,9 +130,9 @@ ThrowCompletionOr<Value> PromiseAllSettledResolveElementFunction::resolve_elemen
|
||||||
return js_undefined();
|
return js_undefined();
|
||||||
}
|
}
|
||||||
|
|
||||||
PromiseAllSettledRejectElementFunction* PromiseAllSettledRejectElementFunction::create(GlobalObject& global_object, size_t index, PromiseValueList& values, PromiseCapability capability, RemainingElements& remaining_elements)
|
PromiseAllSettledRejectElementFunction* PromiseAllSettledRejectElementFunction::create(Realm& realm, size_t index, PromiseValueList& values, PromiseCapability capability, RemainingElements& remaining_elements)
|
||||||
{
|
{
|
||||||
return global_object.heap().allocate<PromiseAllSettledRejectElementFunction>(global_object, index, values, capability, remaining_elements, *global_object.function_prototype());
|
return realm.heap().allocate<PromiseAllSettledRejectElementFunction>(realm.global_object(), index, values, capability, remaining_elements, *realm.global_object().function_prototype());
|
||||||
}
|
}
|
||||||
|
|
||||||
PromiseAllSettledRejectElementFunction::PromiseAllSettledRejectElementFunction(size_t index, PromiseValueList& values, PromiseCapability capability, RemainingElements& remaining_elements, Object& prototype)
|
PromiseAllSettledRejectElementFunction::PromiseAllSettledRejectElementFunction(size_t index, PromiseValueList& values, PromiseCapability capability, RemainingElements& remaining_elements, Object& prototype)
|
||||||
|
@ -142,9 +144,10 @@ ThrowCompletionOr<Value> PromiseAllSettledRejectElementFunction::resolve_element
|
||||||
{
|
{
|
||||||
auto& vm = this->vm();
|
auto& vm = this->vm();
|
||||||
auto& global_object = this->global_object();
|
auto& global_object = this->global_object();
|
||||||
|
auto& realm = *global_object.associated_realm();
|
||||||
|
|
||||||
// 9. Let obj be OrdinaryObjectCreate(%Object.prototype%).
|
// 9. Let obj be OrdinaryObjectCreate(%Object.prototype%).
|
||||||
auto* object = Object::create(global_object, global_object.object_prototype());
|
auto* object = Object::create(realm, global_object.object_prototype());
|
||||||
|
|
||||||
// 10. Perform ! CreateDataPropertyOrThrow(obj, "status", "rejected").
|
// 10. Perform ! CreateDataPropertyOrThrow(obj, "status", "rejected").
|
||||||
MUST(object->create_data_property_or_throw(vm.names.status, js_string(vm, "rejected"sv)));
|
MUST(object->create_data_property_or_throw(vm.names.status, js_string(vm, "rejected"sv)));
|
||||||
|
@ -159,7 +162,7 @@ ThrowCompletionOr<Value> PromiseAllSettledRejectElementFunction::resolve_element
|
||||||
// 14. If remainingElementsCount.[[Value]] is 0, then
|
// 14. If remainingElementsCount.[[Value]] is 0, then
|
||||||
if (--m_remaining_elements.value == 0) {
|
if (--m_remaining_elements.value == 0) {
|
||||||
// a. Let valuesArray be CreateArrayFromList(values).
|
// a. Let valuesArray be CreateArrayFromList(values).
|
||||||
auto* values_array = Array::create_from(global_object, m_values.values());
|
auto* values_array = Array::create_from(realm, m_values.values());
|
||||||
|
|
||||||
// b. Return ? Call(promiseCapability.[[Resolve]], undefined, « valuesArray »).
|
// b. Return ? Call(promiseCapability.[[Resolve]], undefined, « valuesArray »).
|
||||||
return JS::call(global_object, *m_capability.resolve, js_undefined(), values_array);
|
return JS::call(global_object, *m_capability.resolve, js_undefined(), values_array);
|
||||||
|
@ -169,9 +172,9 @@ ThrowCompletionOr<Value> PromiseAllSettledRejectElementFunction::resolve_element
|
||||||
return js_undefined();
|
return js_undefined();
|
||||||
}
|
}
|
||||||
|
|
||||||
PromiseAnyRejectElementFunction* PromiseAnyRejectElementFunction::create(GlobalObject& global_object, size_t index, PromiseValueList& errors, PromiseCapability capability, RemainingElements& remaining_elements)
|
PromiseAnyRejectElementFunction* PromiseAnyRejectElementFunction::create(Realm& realm, size_t index, PromiseValueList& errors, PromiseCapability capability, RemainingElements& remaining_elements)
|
||||||
{
|
{
|
||||||
return global_object.heap().allocate<PromiseAnyRejectElementFunction>(global_object, index, errors, capability, remaining_elements, *global_object.function_prototype());
|
return realm.heap().allocate<PromiseAnyRejectElementFunction>(realm.global_object(), index, errors, capability, remaining_elements, *realm.global_object().function_prototype());
|
||||||
}
|
}
|
||||||
|
|
||||||
PromiseAnyRejectElementFunction::PromiseAnyRejectElementFunction(size_t index, PromiseValueList& errors, PromiseCapability capability, RemainingElements& remaining_elements, Object& prototype)
|
PromiseAnyRejectElementFunction::PromiseAnyRejectElementFunction(size_t index, PromiseValueList& errors, PromiseCapability capability, RemainingElements& remaining_elements, Object& prototype)
|
||||||
|
@ -183,6 +186,7 @@ ThrowCompletionOr<Value> PromiseAnyRejectElementFunction::resolve_element()
|
||||||
{
|
{
|
||||||
auto& vm = this->vm();
|
auto& vm = this->vm();
|
||||||
auto& global_object = this->global_object();
|
auto& global_object = this->global_object();
|
||||||
|
auto& realm = *global_object.associated_realm();
|
||||||
|
|
||||||
// 8. Set errors[index] to x.
|
// 8. Set errors[index] to x.
|
||||||
m_values.values()[m_index] = vm.argument(0);
|
m_values.values()[m_index] = vm.argument(0);
|
||||||
|
@ -191,10 +195,10 @@ ThrowCompletionOr<Value> PromiseAnyRejectElementFunction::resolve_element()
|
||||||
// 10. If remainingElementsCount.[[Value]] is 0, then
|
// 10. If remainingElementsCount.[[Value]] is 0, then
|
||||||
if (--m_remaining_elements.value == 0) {
|
if (--m_remaining_elements.value == 0) {
|
||||||
// a. Let error be a newly created AggregateError object.
|
// a. Let error be a newly created AggregateError object.
|
||||||
auto* error = AggregateError::create(global_object);
|
auto* error = AggregateError::create(realm);
|
||||||
|
|
||||||
// b. Perform ! DefinePropertyOrThrow(error, "errors", PropertyDescriptor { [[Configurable]]: true, [[Enumerable]]: false, [[Writable]]: true, [[Value]]: CreateArrayFromList(errors) }).
|
// b. Perform ! DefinePropertyOrThrow(error, "errors", PropertyDescriptor { [[Configurable]]: true, [[Enumerable]]: false, [[Writable]]: true, [[Value]]: CreateArrayFromList(errors) }).
|
||||||
auto* errors_array = Array::create_from(global_object, m_values.values());
|
auto* errors_array = Array::create_from(realm, m_values.values());
|
||||||
MUST(error->define_property_or_throw(vm.names.errors, { .value = errors_array, .writable = true, .enumerable = false, .configurable = true }));
|
MUST(error->define_property_or_throw(vm.names.errors, { .value = errors_array, .writable = true, .enumerable = false, .configurable = true }));
|
||||||
|
|
||||||
// c. Return ? Call(promiseCapability.[[Reject]], undefined, « error »).
|
// c. Return ? Call(promiseCapability.[[Reject]], undefined, « error »).
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue