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:
Linus Groh 2022-08-16 00:20:49 +01:00
parent 5dd5896588
commit b99cc7d050
Notes: sideshowbarker 2024-07-19 01:59:31 +09:00
178 changed files with 883 additions and 609 deletions

View file

@ -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)

View file

@ -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)

View file

@ -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);

View file

@ -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));

View file

@ -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; }

View file

@ -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);

View file

@ -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));

View file

@ -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();

View file

@ -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 }).

View file

@ -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

View file

@ -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)

View file

@ -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;

View file

@ -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;
} }

View file

@ -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)

View file

@ -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

View file

@ -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);

View file

@ -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)

View file

@ -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);

View file

@ -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));

View file

@ -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)

View file

@ -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;

View file

@ -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);
} }
} }

View file

@ -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,

View file

@ -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)

View file

@ -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;

View file

@ -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));

View file

@ -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;
} }

View file

@ -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;

View file

@ -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)

View file

@ -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;

View file

@ -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)

View file

@ -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;

View file

@ -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;

View file

@ -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;

View file

@ -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);

View file

@ -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)

View file

@ -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;

View file

@ -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)

View file

@ -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);

View file

@ -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 {

View file

@ -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;

View file

@ -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; \

View file

@ -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; \

View file

@ -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);
} }

View file

@ -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;

View file

@ -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) {

View file

@ -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;

View file

@ -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());

View file

@ -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).

View file

@ -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)

View file

@ -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;

View file

@ -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.

View file

@ -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)));

View file

@ -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)

View file

@ -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;

View file

@ -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.

View file

@ -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.

View file

@ -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);

View file

@ -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.

View file

@ -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); });
} }
} }

View file

@ -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)));

View file

@ -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.

View file

@ -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);
}); });
} }

View file

@ -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()
{ {

View file

@ -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)));

View file

@ -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)));

View file

@ -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)

View file

@ -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;

View file

@ -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.

View file

@ -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));
}); });

View file

@ -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)));

View file

@ -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.

View file

@ -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

View file

@ -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;

View file

@ -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);

View file

@ -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));
} }
} }

View file

@ -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

View file

@ -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;

View file

@ -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);
} }
} }

View file

@ -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));

View file

@ -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);

View file

@ -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)

View file

@ -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;

View file

@ -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)

View file

@ -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;

View file

@ -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);
} }
} }

View file

@ -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

View file

@ -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)

View file

@ -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);

View file

@ -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)

View file

@ -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;

View file

@ -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);
} }

View file

@ -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);

View file

@ -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()) {

View file

@ -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);

View file

@ -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;

View file

@ -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 »).

View file

@ -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 »).

View file

@ -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));

View file

@ -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