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
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.
scoped_generator.append(R"~~~(
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@);
@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);
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) {
@ -1572,7 +1572,7 @@ static void generate_wrap_statement(SourceGenerator& generator, String const& va
auto dictionary_generator = scoped_generator.fork();
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;
@ -1664,6 +1664,7 @@ static void generate_function(SourceGenerator& generator, IDL::Function const& f
function_generator.append(R"~~~(
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) {
@ -1748,6 +1749,7 @@ static void generate_overload_arbiter(SourceGenerator& generator, auto const& ov
function_generator.append(R"~~~(
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);
@ -1835,7 +1837,7 @@ namespace Web::Bindings {
class @wrapper_class@ : public @wrapper_base_class@ {
JS_OBJECT(@name@, @wrapper_base_class@);
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@&);
virtual void initialize(JS::Realm&) override;
@ -2002,10 +2004,9 @@ using namespace Web::WebGL;
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 global_object.heap().allocate<@wrapper_class@>(global_object, realm, impl);
return realm.heap().allocate<@wrapper_class@>(realm.global_object(), realm, impl);
}
)~~~");
@ -2164,6 +2165,7 @@ JS::ThrowCompletionOr<Optional<JS::PropertyDescriptor>> @class_name@::legacy_pla
get_own_property_generator.append(R"~~~(
[[maybe_unused]] auto& global_object = this->global_object();
[[maybe_unused]] auto& realm = *global_object.associated_realm();
)~~~");
// 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)
{
[[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.
@ -2491,6 +2494,7 @@ JS::ThrowCompletionOr<bool> @class_name@::internal_define_own_property(JS::Prope
{
[[maybe_unused]] auto& vm = this->vm();
[[maybe_unused]] auto& global_object = this->global_object();
[[maybe_unused]] auto& realm = *global_object.associated_realm();
)~~~");
// 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)
{
[[maybe_unused]] auto& global_object = this->global_object();
[[maybe_unused]] auto& realm = *global_object.associated_realm();
)~~~");
// 1. If O supports indexed properties...
@ -2961,6 +2966,7 @@ JS::ThrowCompletionOr<JS::Object*> @constructor_class@::construct(FunctionObject
generator.append(R"~~~(
[[maybe_unused]] auto& vm = this->vm();
[[maybe_unused]] auto& global_object = this->global_object();
[[maybe_unused]] auto& realm = *global_object.associated_realm();
auto& window = static_cast<WindowObject&>(global_object);
)~~~");
@ -3247,7 +3253,7 @@ void @prototype_class@::initialize(JS::Realm& realm)
if (interface.has_unscopable_member) {
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"~~~(
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));
)~~~");
@ -3442,6 +3449,7 @@ JS_DEFINE_NATIVE_FUNCTION(@prototype_class@::@attribute.getter_callback@)
attribute_generator.append(R"~~~(
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 value = vm.argument(0);
@ -3493,6 +3501,7 @@ JS_DEFINE_NATIVE_FUNCTION(@prototype_class@::@attribute.setter_callback@)
stringifier_generator.append(R"~~~(
JS_DEFINE_NATIVE_FUNCTION(@class_name@::to_string)
{
[[maybe_unused]] auto& realm = *global_object.associated_realm();
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)
{
[[maybe_unused]] auto& realm = *global_object.associated_realm();
auto* impl = TRY(impl_from(vm, global_object));
auto callback = vm.argument(0);
@ -3586,7 +3596,7 @@ namespace Web::Bindings {
class @wrapper_class@ : public Wrapper {
JS_OBJECT(@name@, Wrapper);
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@&);
virtual void initialize(JS::Realm&) override;
@ -3658,10 +3668,9 @@ using namespace Web::WebGL;
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 global_object.heap().allocate<@wrapper_class@>(global_object, realm, impl);
return realm.heap().allocate<@wrapper_class@>(realm.global_object(), realm, 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)
{
auto& realm = *global_object.associated_realm();
auto filename = TRY(vm.argument(0).to_string(global_object));
auto file = Core::Stream::File::open(filename, Core::Stream::OpenMode::Read);
if (file.is_error())
@ -23,7 +24,7 @@ TESTJS_GLOBAL_FUNCTION(read_binary_wasm_file, readBinaryWasmFile)
if (file_size.is_error())
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());
if (read.is_error())
@ -46,20 +47,20 @@ public:
Wasm::Module& module() { return *m_module; }
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* instance = global_object.heap().allocate<WebAssemblyModule>(global_object, *global_object.object_prototype());
auto& vm = realm.vm();
auto* instance = realm.heap().allocate<WebAssemblyModule>(realm.global_object(), *realm.global_object().object_prototype());
instance->m_module = move(module);
Wasm::Linker linker(*instance->m_module);
linker.link(imports);
linker.link(spec_test_namespace());
auto link_result = linker.finish();
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());
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();
return instance;
}
@ -99,6 +100,7 @@ HashMap<Wasm::Linker::Name, Wasm::ExternValue> WebAssemblyModule::s_spec_test_na
TESTJS_GLOBAL_FUNCTION(parse_webassembly_module, parseWebAssemblyModule)
{
auto& realm = *global_object.associated_realm();
auto* object = TRY(vm.argument(0).to_object(global_object));
if (!is<JS::Uint8Array>(object))
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)

View file

@ -240,6 +240,8 @@ JS_DEFINE_NATIVE_FUNCTION(SheetGlobalObject::set_real_cell_contents)
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));
if (!is<SheetGlobalObject>(this_object))
@ -256,7 +258,7 @@ JS_DEFINE_NATIVE_FUNCTION(SheetGlobalObject::parse_cell_name)
if (!position.has_value())
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("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)
{
auto& realm = *global_object.associated_realm();
if (vm.argument_count() != 0)
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 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("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()) {
old_environment = vm.running_execution_context().lexical_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;
} else {
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
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())
given_name = "";
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 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: 7. Perform MakeConstructor(closure).
@ -1639,6 +1641,8 @@ private:
// 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
{
auto& realm = *global_object.associated_realm();
auto property_key_or_private_name = TRY(class_key_to_property_name(interpreter, global_object, *m_key));
Handle<ECMAScriptFunctionObject> 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.
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);
}
@ -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
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.
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] .
// 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.
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).
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
{
auto& vm = interpreter.vm();
auto& realm = *global_object.associated_realm();
auto* environment = vm.lexical_environment();
VERIFY(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);
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
{
InterpreterNodeScope node_scope { interpreter, *this };
auto& realm = *global_object.associated_realm();
// 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.
for (auto& property : m_properties) {
@ -3205,6 +3214,7 @@ void MetaProperty::dump(int indent) const
Completion MetaProperty::execute(Interpreter& interpreter, GlobalObject& global_object) const
{
InterpreterNodeScope node_scope { interpreter, *this };
auto& realm = *global_object.associated_realm();
// NewTarget : new . target
if (m_type == MetaProperty::Type::NewTarget) {
@ -3229,7 +3239,7 @@ Completion MetaProperty::execute(Interpreter& interpreter, GlobalObject& global_
// 4. If importMeta is empty, then
if (import_meta == nullptr) {
// 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).
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
{
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
// 1. Let referencingScriptOrModule be GetActiveScriptOrModule().
@ -3313,7 +3324,7 @@ Completion ImportCall::execute(Interpreter& interpreter, GlobalObject& global_ob
if (!options_value.is_undefined()) {
// a. If Type(options) is not 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 »).
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()) {
// i. If Type(assertionsObj) is not 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 »).
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
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 »).
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
{
InterpreterNodeScope node_scope { interpreter, *this };
auto& realm = *global_object.associated_realm();
// 1. Let pattern be CodePointsToString(BodyText of RegularExpressionLiteral).
auto pattern = this->pattern();
@ -3458,7 +3470,7 @@ Completion RegExpLiteral::execute(Interpreter& interpreter, GlobalObject& global
// 3. Return ! RegExpCreate(pattern, 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
@ -3478,9 +3490,10 @@ void ArrayExpression::dump(int indent) const
Completion ArrayExpression::execute(Interpreter& interpreter, GlobalObject& global_object) const
{
InterpreterNodeScope node_scope { interpreter, *this };
auto& realm = *global_object.associated_realm();
// 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.
@ -3593,7 +3606,7 @@ Completion TaggedTemplateLiteral::execute(Interpreter& interpreter, GlobalObject
ThrowCompletionOr<Value> TaggedTemplateLiteral::get_template_object(Interpreter& interpreter, GlobalObject& global_object) const
{
// 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]].
// 3. For each element e of templateRegistry, do
@ -3601,7 +3614,7 @@ ThrowCompletionOr<Value> TaggedTemplateLiteral::get_template_object(Interpreter&
// i. Return e.[[Array]].
// 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.
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() };
// 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).
// NOTE: We don't set count since we push the values using append which
// 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).
auto* raw_obj = MUST(Array::create(global_object, 0));
auto* raw_obj = MUST(Array::create(realm, 0));
// 10. Let index be 0.
// 11. Repeat, while index < count,
@ -3661,7 +3674,7 @@ ThrowCompletionOr<Value> TaggedTemplateLiteral::get_template_object(Interpreter&
MUST(template_->set_integrity_level(Object::IntegrityLevel::Frozen));
// 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.
return template_;
@ -4047,7 +4060,7 @@ Completion SwitchStatement::execute_impl(Interpreter& interpreter, GlobalObject&
auto* block_environment = new_declarative_environment(*old_environment);
// 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.
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
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
auto& realm = *global_object.associated_realm();
VERIFY(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.
@ -4474,7 +4489,7 @@ void ScopeNode::block_declaration_instantiation(GlobalObject& global_object, Env
if (is<FunctionDeclaration>(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));
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
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.
// 2. Let varNames be the VarDeclaredNames of script.
// 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) {
// a. Let fn be the sole element of the BoundNames of f.
// 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).
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_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;
@ -495,7 +495,7 @@ public:
bool has_top_level_await() const { return m_has_top_level_await; }
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:
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
{
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++) {
auto& value = interpreter.reg(Register(m_elements[0].index() + i));
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)
{
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.next, iterator.next_method, 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_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;
while (true) {
@ -234,7 +235,7 @@ ThrowCompletionOr<void> NewString::execute_impl(Bytecode::Interpreter& interpret
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 {};
}
@ -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* 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;
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
{
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 {};
}
@ -610,7 +611,7 @@ ThrowCompletionOr<void> PushDeclarativeEnvironment::execute_impl(Bytecode::Inter
ThrowCompletionOr<void> Yield::execute_impl(Bytecode::Interpreter& interpreter) const
{
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);
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);
@ -693,14 +694,15 @@ ThrowCompletionOr<void> GetObjectPropertyIterator::execute_impl(Bytecode::Interp
Iterator iterator {
.iterator = object,
.next_method = NativeFunction::create(
interpreter.global_object(),
interpreter.realm(),
[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);
if (!iterated_object_value.is_object())
return vm.throw_completion<InternalError>(global_object, "Invalid state for GetObjectPropertyIterator.next");
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) {
if (items.is_empty()) {
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
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());
// 1. Assert: module.[[Status]] is evaluating or evaluating-async.
VERIFY(m_status == ModuleStatus::Evaluating || m_status == ModuleStatus::EvaluatingAsync);
// 2. Assert: module.[[HasTLA]] is true.
VERIFY(m_has_top_level_await);
auto& global_object = realm().global_object();
// 3. Let capability be ! NewPromiseCapability(%Promise%).
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, "", « »).
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:
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, "", « »).
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));

View file

@ -349,8 +349,8 @@ void Heap::uproot_cell(Cell* cell)
m_uprooted_cells.append(cell);
}
// Temporary helper function as we can't pass a realm directly until Heap::allocate<T>() receives one.
// Heap.h only has a forward declaration of the GlobalObject, so no inlined member access possible.
// Temporary helper function as we can't pass a realm directly until Heap::allocate<T>() and VM::throw_completion<T>() receive one.
// Heap.h and VM.h only have a forward declaration of the GlobalObject, so no inlined member access possible.
Realm& realm_from_global_object(GlobalObject& global_object)
{
return *global_object.associated_realm();

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
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;
// 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) {
// a. Let fn be the sole element of the BoundNames of f.
// 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
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)
{
auto& vm = global_object.vm();
auto& realm = *global_object.associated_realm();
// 1. Let len be the number of elements in argumentsList.
auto length = arguments.size();
// 2. Let obj be OrdinaryObjectCreate(%Object.prototype%, « [[ParameterMap]] »).
// 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();
// 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>
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));
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

View file

@ -10,9 +10,9 @@
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)

View file

@ -15,7 +15,7 @@ class AggregateError : public Error {
JS_OBJECT(AggregateError, Error);
public:
static AggregateError* create(GlobalObject&);
static AggregateError* create(Realm&);
explicit AggregateError(Object& prototype);
virtual ~AggregateError() override = default;

View file

@ -41,6 +41,7 @@ ThrowCompletionOr<Object*> AggregateErrorConstructor::construct(FunctionObject&
{
auto& vm = this->vm();
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));
@ -53,7 +54,7 @@ ThrowCompletionOr<Object*> AggregateErrorConstructor::construct(FunctionObject&
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;
}

View file

@ -20,7 +20,7 @@ void ArgumentsObject::initialize(Realm& realm)
{
Base::initialize(realm);
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)

View file

@ -17,22 +17,22 @@
namespace JS {
// 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.
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%.
if (!prototype)
prototype = global_object.array_prototype();
prototype = realm.global_object().array_prototype();
// 3. Let A be MakeBasicObject(« [[Prototype]], [[Extensible]] »).
// 4. Set A.[[Prototype]] to proto.
// 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 }).
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
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).
auto* array = MUST(Array::create(global_object, 0));
auto* array = MUST(Array::create(realm, 0));
// 2. Let n be 0.
// 3. For each element e of elements, do

View file

@ -21,18 +21,18 @@ class Array : public Object {
JS_OBJECT(Array, Object);
public:
static ThrowCompletionOr<Array*> create(GlobalObject&, u64 length, Object* prototype = nullptr);
static Array* create_from(GlobalObject&, Vector<Value> const&);
static ThrowCompletionOr<Array*> create(Realm&, u64 length, Object* prototype = nullptr);
static Array* create_from(Realm&, Vector<Value> const&);
// Non-standard but equivalent to CreateArrayFromList.
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());
for (auto const& element : elements)
values.append(map_fn(element));
return Array::create_from(global_object, values);
return Array::create_from(realm, values);
}
explicit Array(Object& prototype);

View file

@ -11,23 +11,23 @@
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);
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)

View file

@ -25,9 +25,9 @@ class ArrayBuffer : public Object {
JS_OBJECT(ArrayBuffer, Object);
public:
static ThrowCompletionOr<ArrayBuffer*> create(GlobalObject&, size_t);
static ArrayBuffer* create(GlobalObject&, ByteBuffer);
static ArrayBuffer* create(GlobalObject&, ByteBuffer*);
static ThrowCompletionOr<ArrayBuffer*> create(Realm&, size_t);
static ArrayBuffer* create(Realm&, ByteBuffer);
static ArrayBuffer* create(Realm&, ByteBuffer*);
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)
{
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)
return MUST(Array::create(global_object(), 0, proto));
return MUST(Array::create(realm, 0, proto));
if (vm.argument_count() == 1) {
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;
if (!length.is_number()) {
MUST(array->create_data_property_or_throw(0, length));
int_length = 1;
} else {
int_length = MUST(length.to_u32(global_object()));
int_length = MUST(length.to_u32(global_object));
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));
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)
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
JS_DEFINE_NATIVE_FUNCTION(ArrayConstructor::from)
{
auto& realm = *global_object.associated_realm();
auto constructor = vm.this_value(global_object);
FunctionObject* map_fn = nullptr;
@ -102,7 +105,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayConstructor::from)
if (constructor.is_constructor())
array = TRY(JS::construct(global_object, constructor.as_function(), {}));
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));
@ -147,7 +150,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayConstructor::from)
if (constructor.is_constructor())
array = TRY(JS::construct(global_object, constructor.as_function(), Value(length)));
else
array = TRY(Array::create(global_object, length));
array = TRY(Array::create(realm, length));
for (size_t k = 0; k < length; ++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
JS_DEFINE_NATIVE_FUNCTION(ArrayConstructor::of)
{
auto& realm = *global_object.associated_realm();
auto this_value = vm.this_value(global_object);
Object* array;
if (this_value.is_constructor())
array = TRY(JS::construct(global_object, this_value.as_function(), Value(vm.argument_count())));
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)
TRY(array->create_data_property_or_throw(k, vm.argument(k)));
TRY(array->set(vm.names.length, Value(vm.argument_count()), Object::ShouldThrowExceptions::Yes));

View file

@ -9,9 +9,9 @@
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)

View file

@ -14,7 +14,7 @@ class ArrayIterator final : public Object {
JS_OBJECT(ArrayIterator, Object);
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);
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.
JS_DEFINE_NATIVE_FUNCTION(ArrayIteratorPrototype::next)
{
auto& realm = *global_object.associated_realm();
auto* iterator = TRY(typed_this_value(global_object));
auto target_array = iterator->array();
if (target_array.is_undefined())
@ -71,7 +73,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayIteratorPrototype::next)
if (iteration_kind == Object::PropertyKind::Value)
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
// 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
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.copyWithin, 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)
{
auto& vm = global_object.vm();
auto& realm = *global_object.associated_realm();
auto is_array = TRY(Value(&original_array).is_array(global_object));
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));
if (constructor.is_constructor()) {
@ -140,7 +141,7 @@ static ThrowCompletionOr<Object*> array_species_create(GlobalObject& global_obje
}
if (constructor.is_undefined())
return TRY(Array::create(global_object, length));
return TRY(Array::create(realm, length));
if (!constructor.is_constructor())
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
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));
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
@ -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
JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::group)
{
auto& realm = *global_object.associated_realm();
auto callback_function = vm.argument(0);
auto this_arg = vm.argument(1);
@ -788,12 +793,12 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::group)
}
// 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
for (auto& group : groups) {
// 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).
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
JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::group_to_map)
{
auto& realm = *global_object.associated_realm();
auto callback_function = vm.argument(0);
auto this_arg = vm.argument(1);
@ -858,12 +865,12 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::group_to_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
for (auto& group : groups) {
// 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 }.
// 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
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));
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
@ -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
JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::to_reversed)
{
auto& realm = *global_object.associated_realm();
// 1. Let O be ? ToObject(this value).
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));
// 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.
// 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
JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::to_sorted)
{
auto& realm = *global_object.associated_realm();
auto comparefn = vm.argument(0);
// 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));
// 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:
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
JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::to_spliced)
{
auto& realm = *global_object.associated_realm();
auto start = vm.argument(0);
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);
// 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.
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
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));
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
JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::with)
{
auto& realm = *global_object.associated_realm();
auto index = vm.argument(0);
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);
// 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.
// 9. Repeat, while k < len,

View file

@ -11,10 +11,9 @@
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 global_object.heap().allocate<AsyncFromSyncIterator>(global_object, realm, sync_iterator_record);
return realm.heap().allocate<AsyncFromSyncIterator>(realm.global_object(), realm, 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);
public:
static AsyncFromSyncIterator* create(GlobalObject&, Iterator sync_iterator_record);
static AsyncFromSyncIterator* create(Realm&, Iterator sync_iterator_record);
explicit AsyncFromSyncIterator(Realm&, Iterator sync_iterator_record);
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
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.
// 2. Let done be Completion(IteratorComplete(result)).
// 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, "", « »).
// 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).
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
JS_DEFINE_NATIVE_FUNCTION(AsyncFromSyncIteratorPrototype::return_)
{
auto& realm = *global_object.associated_realm();
// 1. Let O be the this value.
// 2. Assert: O is an Object that has a [[SyncIteratorRecord]] internal slot.
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
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 »).
MUST(call(global_object, *promise_capability.reject, js_undefined(), error));
// 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
JS_DEFINE_NATIVE_FUNCTION(AsyncFromSyncIteratorPrototype::throw_)
{
auto& realm = *global_object.associated_realm();
// 1. Let O be the this value.
// 2. Assert: O is an Object that has a [[SyncIteratorRecord]] internal slot.
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
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 »).
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)
{
auto& vm = global_object.vm();
auto& realm = *global_object.associated_realm();
// 1. Let asyncIterator be OrdinaryObjectCreate(%AsyncFromSyncIteratorPrototype%, « [[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").
auto next_method = MUST(async_iterator->get(vm.names.next));

View file

@ -12,20 +12,19 @@
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 = global_object.heap().allocate<AsyncFunctionDriverWrapper>(global_object, realm, generator_object);
return wrapper->react_to_async_task_completion(global_object.vm(), global_object, js_undefined(), true);
auto wrapper = realm.heap().allocate<AsyncFunctionDriverWrapper>(realm.global_object(), realm, generator_object);
return wrapper->react_to_async_task_completion(realm.vm(), realm.global_object(), js_undefined(), true);
}
AsyncFunctionDriverWrapper::AsyncFunctionDriverWrapper(Realm& realm, GeneratorObject* generator_object)
: Promise(*realm.global_object().promise_prototype())
, 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);
}))
, 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);
}))
{
@ -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)
{
auto& realm = *global_object.associated_realm();
auto generator_result = is_successful
? m_generator_object->next_impl(vm, global_object, value, {})
: m_generator_object->next_impl(vm, global_object, {}, value);
if (generator_result.is_throw_completion()) {
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());
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));
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);
return promise;
}

View file

@ -18,7 +18,7 @@ class AsyncFunctionDriverWrapper final : public Promise {
JS_OBJECT(AsyncFunctionDriverWrapper, Promise);
public:
static ThrowCompletionOr<Value> create(GlobalObject&, GeneratorObject*);
static ThrowCompletionOr<Value> create(Realm&, GeneratorObject*);
explicit AsyncFunctionDriverWrapper(Realm&, GeneratorObject*);
virtual ~AsyncFunctionDriverWrapper() override = default;

View file

@ -9,9 +9,9 @@
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)

View file

@ -15,7 +15,7 @@ class BigIntObject final : public Object {
JS_OBJECT(BigIntObject, Object);
public:
static BigIntObject* create(GlobalObject&, BigInt&);
static BigIntObject* create(Realm&, BigInt&);
BigIntObject(BigInt&, Object& prototype);
virtual ~BigIntObject() override = default;

View file

@ -9,9 +9,9 @@
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)

View file

@ -14,7 +14,7 @@ class BooleanObject : public Object {
JS_OBJECT(BooleanObject, Object);
public:
static BooleanObject* create(GlobalObject&, bool);
static BooleanObject* create(Realm&, bool);
BooleanObject(bool, Object& prototype);
virtual ~BooleanObject() override = default;

View file

@ -12,10 +12,8 @@
namespace JS {
// 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]]().
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.
// 8. Set obj.[[BoundThis]] to boundThis.
// 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.
return object;

View file

@ -15,7 +15,7 @@ class BoundFunction final : public FunctionObject {
JS_OBJECT(BoundFunction, FunctionObject);
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);
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)
{
auto& vm = global_object.vm();
auto& realm = *global_object.associated_realm();
// 1. Let asyncContext be the running execution context.
// 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, "", « »).
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:
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, "", « »).
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).
auto* promise = verify_cast<Promise>(promise_object);

View file

@ -8,9 +8,9 @@
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)

View file

@ -16,7 +16,7 @@ class DataView : public Object {
JS_OBJECT(DataView, Object);
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);
virtual ~DataView() override = default;

View file

@ -16,9 +16,9 @@
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)

View file

@ -15,7 +15,7 @@ class Date final : public Object {
JS_OBJECT(Date, Object);
public:
static Date* create(GlobalObject&, double date_value);
static Date* create(Realm&, double date_value);
static Date* now(GlobalObject&);
Date(double date_value, Object& prototype);

View file

@ -28,29 +28,29 @@
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;
switch (kind) {
case FunctionKind::Normal:
prototype = global_object.function_prototype();
prototype = realm.global_object().function_prototype();
break;
case FunctionKind::Generator:
prototype = global_object.generator_function_prototype();
prototype = realm.global_object().generator_function_prototype();
break;
case FunctionKind::Async:
prototype = global_object.async_function_prototype();
prototype = realm.global_object().async_function_prototype();
break;
case FunctionKind::AsyncGenerator:
prototype = global_object.async_generator_function_prototype();
prototype = realm.global_object().async_generator_function_prototype();
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)
@ -119,12 +119,12 @@ void ECMAScriptFunctionObject::initialize(Realm& realm)
break;
case FunctionKind::Generator:
// 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;
case FunctionKind::Async:
break;
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;
}
// 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)
{
auto& vm = this->vm();
auto& global_object = this->global_object();
auto& realm = *global_object.associated_realm();
auto& callee_context = vm.running_execution_context();
@ -399,24 +401,24 @@ ThrowCompletionOr<void> ECMAScriptFunctionObject::function_declaration_instantia
if (MUST(environment->has_binding(parameter_name)))
continue;
MUST(environment->create_mutable_binding(global_object(), parameter_name, false));
MUST(environment->create_mutable_binding(global_object, parameter_name, false));
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) {
Object* arguments_object;
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
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())
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
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());
}
@ -435,7 +437,7 @@ ThrowCompletionOr<void> ECMAScriptFunctionObject::function_declaration_instantia
[&](auto const& param) -> ThrowCompletionOr<void> {
Value argument_value;
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)
array->indexed_properties().append(execution_context_arguments[rest_index]);
argument_value = array;
@ -449,7 +451,7 @@ ThrowCompletionOr<void> ECMAScriptFunctionObject::function_declaration_instantia
// Resulting value is in the accumulator.
argument_value = value_and_frame.frame->registers.at(0);
} 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 {
argument_value = js_undefined();
@ -461,12 +463,12 @@ ThrowCompletionOr<void> ECMAScriptFunctionObject::function_declaration_instantia
Reference reference = TRY(vm.resolve_binding(param, used_environment));
// Here the difference from hasDuplicates is important
if (has_duplicates)
return reference.put_value(global_object(), argument_value);
return reference.put_value(global_object, argument_value);
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)>) {
// 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) {
scope_body->for_each_var_declared_name([&](auto const& name) {
if (!parameter_names.contains(name) && instantiated_var_names.set(name) == AK::HashSetResult::InsertedNewEntry) {
MUST(environment->create_mutable_binding(global_object(), name, false));
MUST(environment->initialize_binding(global_object(), name, js_undefined()));
MUST(environment->create_mutable_binding(global_object, name, false));
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) {
if (instantiated_var_names.set(name) != AK::HashSetResult::InsertedNewEntry)
return;
MUST(var_environment->create_mutable_binding(global_object(), name, false));
MUST(var_environment->create_mutable_binding(global_object, name, false));
Value initial_value;
if (!parameter_names.contains(name) || function_names.contains(name))
initial_value = js_undefined();
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;
// 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()) {
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->create_mutable_binding(global_object, function_name, false));
MUST(var_environment->initialize_binding(global_object, function_name, js_undefined()));
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) {
declaration.for_each_bound_name([&](auto const& name) {
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
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;
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());
MUST(var_environment->set_mutable_binding(global_object(), declaration.name(), function, false));
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));
}
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
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.
// 2. Let runningContext be the 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:
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.
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()
{
auto& vm = this->vm();
auto& global_object = this->global_object();
auto& realm = *global_object.associated_realm();
auto* bytecode_interpreter = Bytecode::Interpreter::current();
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 (!m_bytecode_executable) {
@ -828,23 +834,23 @@ Completion ECMAScriptFunctionObject::ordinary_call_evaluate_body()
if (m_kind == FunctionKind::Normal)
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
// See AwaitExpression::generate_bytecode() for the transformation.
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);
return { Completion::Type::Return, generator_object, {} };
} else {
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;
Interpreter* ast_interpreter = vm.interpreter_if_exists();
if (!ast_interpreter) {
local_interpreter = Interpreter::create_with_existing_realm(*realm());
local_interpreter = Interpreter::create_with_existing_realm(realm);
ast_interpreter = local_interpreter.ptr();
}
@ -856,12 +862,12 @@ Completion ECMAScriptFunctionObject::ordinary_call_evaluate_body()
TRY(function_declaration_instantiation(ast_interpreter));
// 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
else if (m_kind == FunctionKind::Async) {
// 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)).
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
if (declaration_result.is_throw_completion()) {
// 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,
else {

View file

@ -32,8 +32,8 @@ public:
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(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, 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);
virtual void initialize(Realm&) override;

View file

@ -14,15 +14,15 @@
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* error = Error::create(global_object);
auto& vm = realm.vm();
auto* error = Error::create(realm);
u8 attr = Attribute::Writable | Attribute::Configurable;
error->define_direct_property(vm.names.message, js_string(vm, message), attr);
return error;
@ -97,15 +97,16 @@ String Error::stack_string() const
}
#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* error = ClassName::create(global_object); \
auto& vm = realm.vm(); \
auto* error = ClassName::create(realm); \
u8 attr = Attribute::Writable | Attribute::Configurable; \
error->define_direct_property(vm.names.message, js_string(vm, message), attr); \
return error; \

View file

@ -23,8 +23,8 @@ class Error : public Object {
JS_OBJECT(Error, Object);
public:
static Error* create(GlobalObject&);
static Error* create(GlobalObject&, String const& message);
static Error* create(Realm&);
static Error* create(Realm&, String const& message);
explicit Error(Object& prototype);
virtual ~Error() override = default;
@ -48,8 +48,8 @@ private:
JS_OBJECT(ClassName, Error); \
\
public: \
static ClassName* create(GlobalObject&); \
static ClassName* create(GlobalObject&, String const& message); \
static ClassName* create(Realm&); \
static ClassName* create(Realm&, String const& message); \
\
explicit ClassName(Object& prototype); \
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));
// 25. Let realmF be the current Realm Record.
auto* realm = vm.current_realm();
auto& realm = *vm.current_realm();
// 26. Let env be realmF.[[GlobalEnv]].
auto* environment = &realm->global_environment();
auto& environment = realm.global_environment();
// 27. Let privateEnv be null.
PrivateEnvironment* private_environment = nullptr;
// 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.
// 29. Perform SetFunctionName(F, "anonymous").
@ -234,7 +234,7 @@ ThrowCompletionOr<ECMAScriptFunctionObject*> FunctionConstructor::create_dynamic
// 30. If kind is generator, then
if (kind == FunctionKind::Generator) {
// 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 }).
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
else if (kind == FunctionKind::AsyncGenerator) {
// 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 }).
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).
else if (kind == FunctionKind::Normal) {
// 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);
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
JS_DEFINE_NATIVE_FUNCTION(FunctionPrototype::bind)
{
auto& realm = *global_object.associated_realm();
auto this_argument = vm.argument(0);
// 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).
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.
auto arg_count = vm.argument_count() > 0 ? vm.argument_count() - 1 : 0;

View file

@ -13,22 +13,21 @@
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)
Value generating_function_prototype;
if (generating_function->kind() == FunctionKind::Async) {
// 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
// changed thus we hardcode the prototype.
generating_function_prototype = global_object.generator_prototype();
generating_function_prototype = realm.global_object().generator_prototype();
} 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 object = global_object.heap().allocate<GeneratorObject>(global_object, realm, *generating_function_prototype_object, move(execution_context));
auto* generating_function_prototype_object = TRY(generating_function_prototype.to_object(realm.global_object()));
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_frame = move(frame);
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)
{
auto& realm = *global_object.associated_realm();
auto bytecode_interpreter = Bytecode::Interpreter::current();
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 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);
if (m_done) {

View file

@ -16,7 +16,7 @@ class GeneratorObject final : public Object {
JS_OBJECT(GeneratorObject, Object);
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);
virtual void initialize(Realm&) override;
virtual ~GeneratorObject() override = default;

View file

@ -225,9 +225,11 @@ void GlobalObject::initialize_global_object()
define_native_function(vm.names.eval, eval, 1, attr);
// 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) {
return vm.throw_completion<TypeError>(global_object, ErrorType::RestrictedFunctionPropertiesAccess);
});
m_throw_type_error_function = NativeFunction::create(
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.name, js_string(vm, ""), 0);
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)
{
auto& vm = global_object.vm();
auto& realm = *global_object.associated_realm();
// 1. If locales is undefined, then
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
if (locales.is_string() || (locales.is_object() && is<Locale>(locales.as_object()))) {
// a. Let O be CreateArrayFromList(« locales »).
object = Array::create_from(global_object, { locales });
object = Array::create_from(realm, { locales });
}
// 4. 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)
{
auto& vm = global_object.vm();
auto& realm = *global_object.associated_realm();
// 1. Set options to ? CoerceOptionsToObject(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).
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
ThrowCompletionOr<Object*> coerce_options_to_object(GlobalObject& global_object, Value options)
{
auto& realm = *global_object.associated_realm();
// 1. If options is undefined, then
if (options.is_undefined()) {
// a. Return OrdinaryObjectCreate(null).
return Object::create(global_object, nullptr);
return Object::create(realm, nullptr);
}
// 2. Return ? ToObject(options).

View file

@ -11,10 +11,9 @@
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 global_object.heap().allocate<CollatorCompareFunction>(global_object, realm, collator);
return realm.heap().allocate<CollatorCompareFunction>(realm.global_object(), realm, collator);
}
CollatorCompareFunction::CollatorCompareFunction(Realm& realm, Collator& collator)

View file

@ -14,7 +14,7 @@ class CollatorCompareFunction : public NativeFunction {
JS_OBJECT(CollatorCompareFunction, NativeFunction);
public:
static CollatorCompareFunction* create(GlobalObject&, Collator&);
static CollatorCompareFunction* create(Realm&, Collator&);
CollatorCompareFunction(Realm&, Collator&);
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
JS_DEFINE_NATIVE_FUNCTION(CollatorPrototype::compare_getter)
{
auto& realm = *global_object.associated_realm();
// 1. Let collator be the this value.
// 2. Perform ? RequireInternalSlot(collator, [[InitializedCollator]]).
auto* collator = TRY(typed_this_object(global_object));
@ -42,7 +44,7 @@ JS_DEFINE_NATIVE_FUNCTION(CollatorPrototype::compare_getter)
if (!collator->bound_compare()) {
// a. Let F be a new built-in function object as defined in 10.3.3.1.
// 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.
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
JS_DEFINE_NATIVE_FUNCTION(CollatorPrototype::resolved_options)
{
auto& realm = *global_object.associated_realm();
// 1. Let collator be the this value.
// 2. Perform ? RequireInternalSlot(collator, [[InitializedCollator]]).
auto* collator = TRY(typed_this_object(global_object));
// 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
// 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)
{
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).
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));
// 2. Let options be OrdinaryObjectCreate(options).
options = Object::create(global_object, options);
options = Object::create(realm, options);
// 3. Let needDefaults be 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)
{
auto& vm = global_object.vm();
auto& realm = *global_object.associated_realm();
// 1. Let x be TimeClip(x).
time = time_clip(time);
@ -550,7 +552,7 @@ ThrowCompletionOr<Vector<PatternPartition>> format_date_time_pattern(GlobalObjec
};
// 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).
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));
// 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).
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();
// 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).
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)
{
auto& vm = global_object.vm();
auto& realm = *global_object.associated_realm();
// 1. Let parts be ? PartitionDateTimePattern(dateTimeFormat, x).
auto parts = TRY(partition_date_time_pattern(global_object, date_time_format, time));
// 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.
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
for (auto& part : parts) {
// 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]]).
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)
{
auto& vm = global_object.vm();
auto& realm = *global_object.associated_realm();
// 1. Let parts be ? PartitionDateTimeRangePattern(dateTimeFormat, x, y).
auto parts = TRY(partition_date_time_range_pattern(global_object, date_time_format, start, end));
// 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.
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
for (auto& part : parts) {
// 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]]).
MUST(object->create_data_property_or_throw(vm.names.type, js_string(vm, part.type)));

View file

@ -14,9 +14,9 @@
namespace JS::Intl {
// 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)

View file

@ -16,7 +16,7 @@ class DateTimeFormatFunction final : public NativeFunction {
JS_OBJECT(DateTimeFormatFunction, NativeFunction);
public:
static DateTimeFormatFunction* create(GlobalObject&, DateTimeFormat&);
static DateTimeFormatFunction* create(Realm&, DateTimeFormat&);
explicit DateTimeFormatFunction(DateTimeFormat&, Object& prototype);
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
JS_DEFINE_NATIVE_FUNCTION(DateTimeFormatPrototype::format)
{
auto& realm = *global_object.associated_realm();
// 1. Let dtf be the this value.
// 2. If the implementation supports the normative optional constructor mode of 4.3 Note 1, then
// a. Set dtf to ? UnwrapDateTimeFormat(dtf).
@ -50,7 +52,7 @@ JS_DEFINE_NATIVE_FUNCTION(DateTimeFormatPrototype::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).
// 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.
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
JS_DEFINE_NATIVE_FUNCTION(DateTimeFormatPrototype::resolved_options)
{
auto& realm = *global_object.associated_realm();
// 1. Let dtf be the this value.
// 2. If the implementation supports the normative optional constructor mode of 4.3 Note 1, then
// 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));
// 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
// 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
JS_DEFINE_NATIVE_FUNCTION(DisplayNamesPrototype::resolved_options)
{
auto& realm = *global_object.associated_realm();
// 1. Let displayNames be this value.
// 2. Perform ? RequireInternalSlot(displayNames, [[InitializedDisplayNames]]).
auto* display_names = TRY(typed_this_object(global_object));
// 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
// 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)
{
auto& vm = global_object.vm();
auto& realm = *global_object.associated_realm();
// 1. Let result be a new empty List.
Vector<PatternPartition> result;
@ -349,7 +350,7 @@ ThrowCompletionOr<Vector<PatternPartition>> partition_duration_format_pattern(Gl
}
// 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.
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
JS_DEFINE_NATIVE_FUNCTION(DurationFormatPrototype::format_to_parts)
{
auto& realm = *global_object.associated_realm();
// 1. Let df be this value.
// 2. Perform ? RequireInternalSlot(df, [[InitializedDurationFormat]]).
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));
// 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.
// 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];
// 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]]).
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
JS_DEFINE_NATIVE_FUNCTION(DurationFormatPrototype::resolved_options)
{
auto& realm = *global_object.associated_realm();
// 1. Let df be the this value.
// 2. Perform ? RequireInternalSlot(df, [[InitializedDurationFormat]]).
auto* duration_format = TRY(typed_this_object(global_object));
// 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
// 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
JS_DEFINE_NATIVE_FUNCTION(Intl::get_canonical_locales)
{
auto& realm = *global_object.associated_realm();
auto locales = vm.argument(0);
// 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)));
// 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
@ -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
JS_DEFINE_NATIVE_FUNCTION(Intl::supported_values_of)
{
auto& realm = *global_object.associated_realm();
// 1. Let key be ? ToString(key).
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 ).
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)
{
auto& vm = global_object.vm();
auto& realm = *global_object.associated_realm();
// 1. Let parts be ! CreatePartsFromList(listFormat, list).
auto parts = create_parts_from_list(list_format, list);
// 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.
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
for (auto& part : parts) {
// 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]]).
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
JS_DEFINE_NATIVE_FUNCTION(ListFormatPrototype::resolved_options)
{
auto& realm = *global_object.associated_realm();
// 1. Let lf be the this value.
// 2. Perform ? RequireInternalSlot(lf, [[InitializedListFormat]]).
auto* list_format = TRY(typed_this_object(global_object));
// 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
// a. Let p be the Property value of the current row.

View file

@ -14,9 +14,9 @@
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
@ -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)
{
auto& vm = global_object.vm();
auto& realm = *global_object.associated_realm();
// 1. If restricted is not undefined, then
if (restricted.has_value()) {
@ -66,7 +67,7 @@ static Array* create_array_from_list_or_restricted(GlobalObject& global_object,
}
// 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);
});
}
@ -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)
{
auto& vm = global_object.vm();
auto& realm = *global_object.associated_realm();
// 1. Let locale be loc.[[Locale]].
// 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);
// 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);
});
}

View file

@ -21,7 +21,7 @@ class Locale final : public Object {
JS_OBJECT(Locale, Object);
public:
static Locale* create(GlobalObject&, Unicode::LocaleID const&);
static Locale* create(Realm&, Unicode::LocaleID const&);
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
JS_DEFINE_NATIVE_FUNCTION(LocalePrototype::maximize)
{
auto& realm = *global_object.associated_realm();
// 1. Let loc be the this value.
// 2. Perform ? RequireInternalSlot(loc, [[InitializedLocale]]).
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();
// 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
JS_DEFINE_NATIVE_FUNCTION(LocalePrototype::minimize)
{
auto& realm = *global_object.associated_realm();
// 1. Let loc be the this value.
// 2. Perform ? RequireInternalSlot(loc, [[InitializedLocale]]).
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();
// 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
@ -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
JS_DEFINE_NATIVE_FUNCTION(LocalePrototype::text_info)
{
auto& realm = *global_object.associated_realm();
// 1. Let loc be the this value.
// 2. Perform ? RequireInternalSlot(loc, [[InitializedLocale]]).
auto* locale_object = TRY(typed_this_object(global_object));
// 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).
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
JS_DEFINE_NATIVE_FUNCTION(LocalePrototype::week_info)
{
auto& realm = *global_object.associated_realm();
// 1. Let loc be the this value.
// 2. Perform ? RequireInternalSlot(loc, [[InitializedLocale]]).
[[maybe_unused]] auto* locale_object = TRY(typed_this_object(global_object));
// 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).
auto week_info = week_info_of_locale(*locale_object);
// 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]]).
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)
{
auto& vm = global_object.vm();
auto& realm = *global_object.associated_realm();
// 1. Let parts be ? PartitionNumberPattern(numberFormat, x).
// Note: Our implementation of PartitionNumberPattern does not throw.
auto parts = partition_number_pattern(global_object, number_format, move(number));
// 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.
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
for (auto& part : parts) {
// 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]]).
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)
{
auto& vm = global_object.vm();
auto& realm = *global_object.associated_realm();
// 1. Let parts be ? PartitionNumberRangePattern(numberFormat, x, y).
auto parts = TRY(partition_number_range_pattern(global_object, number_format, move(start), move(end)));
// 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.
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
for (auto& part : parts) {
// 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]]).
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
// 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)

View file

@ -16,7 +16,7 @@ class NumberFormatFunction final : public NativeFunction {
JS_OBJECT(NumberFormatFunction, NativeFunction);
public:
static NumberFormatFunction* create(GlobalObject&, NumberFormat&);
static NumberFormatFunction* create(Realm&, NumberFormat&);
explicit NumberFormatFunction(NumberFormat&, Object& prototype);
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
JS_DEFINE_NATIVE_FUNCTION(NumberFormatPrototype::format)
{
auto& realm = *global_object.associated_realm();
// 1. Let nf be the this value.
// 2. If the implementation supports the normative optional constructor mode of 4.3 Note 1, then
// a. Set nf to ? UnwrapNumberFormat(nf).
@ -50,7 +52,7 @@ JS_DEFINE_NATIVE_FUNCTION(NumberFormatPrototype::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).
// 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.
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
JS_DEFINE_NATIVE_FUNCTION(NumberFormatPrototype::resolved_options)
{
auto& realm = *global_object.associated_realm();
// 1. Let nf be the this value.
// 2. If the implementation supports the normative optional constructor mode of 4.3 Note 1, then
// 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));
// 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
// 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
JS_DEFINE_NATIVE_FUNCTION(PluralRulesPrototype::resolved_options)
{
auto& realm = *global_object.associated_realm();
// 1. Let pr be the this value.
// 2. Perform ? RequireInternalSlot(pr, [[InitializedPluralRules]]).
auto* plural_rules = TRY(typed_this_object(global_object));
// 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
// 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]].
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));
});

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)
{
auto& vm = global_object.vm();
auto& realm = *global_object.associated_realm();
// 1. Let parts be ? PartitionRelativeTimePattern(relativeTimeFormat, value, unit).
auto parts = TRY(partition_relative_time_pattern(global_object, relative_time_format, value, unit));
// 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.
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
for (auto& part : parts) {
// 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]]).
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
JS_DEFINE_NATIVE_FUNCTION(RelativeTimeFormatPrototype::resolved_options)
{
auto& realm = *global_object.associated_realm();
// 1. Let relativeTimeFormat be the this value.
// 2. Perform ? RequireInternalSlot(relativeTimeFormat, [[InitializedRelativeTimeFormat]]).
auto* relative_time_format = TRY(typed_this_object(global_object));
// 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
// a. Let p be the Property value of the current row.

View file

@ -11,16 +11,15 @@
namespace JS::Intl {
// 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]] ».
// 2. Let iterator be OrdinaryObjectCreate(%SegmentIteratorPrototype%, internalSlotsList).
// 3. Set iterator.[[IteratingSegmenter]] to segmenter.
// 4. Set iterator.[[IteratedString]] to string.
// 5. Set iterator.[[IteratedStringNextSegmentCodeUnitIndex]] to 0.
// 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

View file

@ -16,7 +16,7 @@ class SegmentIterator final : public Object {
JS_OBJECT(SegmentIterator, Object);
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&);
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)
{
auto& vm = global_object.vm();
auto& realm = *global_object.associated_realm();
// 1. Let len be the length of string.
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);
// 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.
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
JS_DEFINE_NATIVE_FUNCTION(SegmenterPrototype::resolved_options)
{
auto& realm = *global_object.associated_realm();
// 1. Let segmenter be the this value.
// 2. Perform ? RequireInternalSlot(segmenter, [[InitializedSegmenter]]).
auto* segmenter = TRY(typed_this_object(global_object));
// 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
// 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
JS_DEFINE_NATIVE_FUNCTION(SegmenterPrototype::segment)
{
auto& realm = *global_object.associated_realm();
// 1. Let segmenter be the this value.
// 2. Perform ? RequireInternalSlot(segmenter, [[InitializedSegmenter]]).
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));
// 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 {
// 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]] ».
// 2. Let segments be OrdinaryObjectCreate(%SegmentsPrototype%, internalSlotsList).
// 3. Set segments.[[SegmentsSegmenter]] to segmenter.
// 4. Set segments.[[SegmentsString]] to string.
// 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

View file

@ -16,7 +16,7 @@ class Segments final : public Object {
JS_OBJECT(Segments, Object);
public:
static Segments* create(GlobalObject&, Segmenter&, Utf16String);
static Segments* create(Realm&, Segmenter&, Utf16String);
Segments(Realm&, Segmenter&, Utf16String);
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
JS_DEFINE_NATIVE_FUNCTION(SegmentsPrototype::symbol_iterator)
{
auto& realm = *global_object.associated_realm();
// 1. Let segments be the this value.
// 2. Perform ? RequireInternalSlot(segments, [[SegmentsSegmenter]]).
auto* segments = TRY(typed_this_object(global_object));
@ -75,7 +77,7 @@ JS_DEFINE_NATIVE_FUNCTION(SegmentsPrototype::symbol_iterator)
auto string = segments->segments_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)
{
auto& vm = global_object.vm();
auto& realm = *global_object.associated_realm();
// 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).
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
ThrowCompletionOr<String> JSONObject::stringify_impl(GlobalObject& global_object, Value value, Value replacer, Value space)
{
auto& realm = *global_object.associated_realm();
StringifyState state;
if (replacer.is_object()) {
@ -99,7 +101,7 @@ ThrowCompletionOr<String> JSONObject::stringify_impl(GlobalObject& global_object
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));
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
JS_DEFINE_NATIVE_FUNCTION(JSONObject::parse)
{
auto& realm = *global_object.associated_realm();
auto string = TRY(vm.argument(0).to_string(global_object));
auto reviver = vm.argument(1);
@ -400,7 +404,7 @@ JS_DEFINE_NATIVE_FUNCTION(JSONObject::parse)
return vm.throw_completion<SyntaxError>(global_object, ErrorType::JsonMalformed);
Value unfiltered = parse_json_value(global_object, json.value());
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();
MUST(root->create_data_property_or_throw(root_name, unfiltered));
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)
{
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) {
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)
{
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;
json_array.for_each([&](auto& value) {
array->define_direct_property(index++, parse_json_value(global_object, value), default_attributes);

View file

@ -8,9 +8,9 @@
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)

View file

@ -20,7 +20,7 @@ class Map : public Object {
JS_OBJECT(Map, Object);
public:
static Map* create(GlobalObject&);
static Map* create(Realm&);
explicit Map(Object& prototype);
virtual ~Map() override = default;

View file

@ -9,9 +9,9 @@
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)

View file

@ -16,7 +16,7 @@ class MapIterator final : public Object {
JS_OBJECT(MapIterator, Object);
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);
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
JS_DEFINE_NATIVE_FUNCTION(MapIteratorPrototype::next)
{
auto& realm = *global_object.associated_realm();
auto* map_iterator = TRY(typed_this_value(global_object));
if (map_iterator->done())
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)
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
JS_DEFINE_NATIVE_FUNCTION(MapPrototype::entries)
{
auto& realm = *global_object.associated_realm();
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
@ -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
JS_DEFINE_NATIVE_FUNCTION(MapPrototype::keys)
{
auto& realm = *global_object.associated_realm();
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
@ -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
JS_DEFINE_NATIVE_FUNCTION(MapPrototype::values)
{
auto& realm = *global_object.associated_realm();
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

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
// 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.
if (!realm.has_value())
@ -36,7 +36,7 @@ NativeFunction* NativeFunction::create(GlobalObject& global_object, Function<Thr
// 7. Set func.[[Extensible]] to true.
// 8. Set func.[[Realm]] to realm.
// 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).
function->set_function_length(length);
@ -51,10 +51,9 @@ NativeFunction* NativeFunction::create(GlobalObject& global_object, Function<Thr
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 global_object.heap().allocate<NativeFunction>(global_object, name, move(function), *realm.global_object().function_prototype());
return realm.heap().allocate<NativeFunction>(realm.global_object(), name, move(function), *realm.global_object().function_prototype());
}
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);
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(GlobalObject&, FlyString const& name, Function<ThrowCompletionOr<Value>(VM&, GlobalObject&)>);
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(Realm&, FlyString const& name, Function<ThrowCompletionOr<Value>(VM&, GlobalObject&)>);
NativeFunction(Function<ThrowCompletionOr<Value>(VM&, GlobalObject&)>, Object* prototype, Realm& realm);
NativeFunction(FlyString name, Function<ThrowCompletionOr<Value>(VM&, GlobalObject&)>, Object& prototype);

View file

@ -9,9 +9,9 @@
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)

View file

@ -14,7 +14,7 @@ class NumberObject : public Object {
JS_OBJECT(NumberObject, Object);
public:
static NumberObject* create(GlobalObject&, double);
static NumberObject* create(Realm&, double);
NumberObject(double, Object& prototype);
virtual ~NumberObject() override = default;

View file

@ -24,14 +24,14 @@
namespace JS {
// 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)
return global_object.heap().allocate<Object>(global_object, *global_object.empty_object_shape());
else if (prototype == 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().empty_object_shape());
else if (prototype == realm.global_object().object_prototype())
return realm.heap().allocate<Object>(realm.global_object(), *realm.global_object().new_object_shape());
else
return global_object.heap().allocate<Object>(global_object, *prototype);
return realm.heap().allocate<Object>(realm.global_object(), *prototype);
}
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.
auto& global_object = this->global_object();
auto& realm = *global_object.associated_realm();
// 1. Let ownKeys be ? O.[[OwnPropertyKeys]]().
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);
// 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.
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)
{
auto& realm = *global_object().associated_realm();
FunctionObject* getter_function = nullptr;
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;
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);
}
@ -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)
{
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);
}

View file

@ -47,7 +47,7 @@ struct PrivateElement {
class Object : public Cell {
public:
static Object* create(GlobalObject&, Object* prototype);
static Object* create(Realm&, Object* prototype);
Object(Realm&, Object* prototype);
explicit Object(Object& prototype);

View file

@ -68,12 +68,13 @@ ThrowCompletionOr<Object*> ObjectConstructor::construct(FunctionObject& new_targ
{
auto& vm = this->vm();
auto& global_object = this->global_object();
auto& realm = *global_object.associated_realm();
if (&new_target != this)
return TRY(ordinary_create_from_constructor<Object>(global_object, new_target, &GlobalObject::object_prototype));
auto value = vm.argument(0);
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);
}
@ -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
JS_DEFINE_NATIVE_FUNCTION(ObjectConstructor::get_own_property_names)
{
auto& realm = *global_object.associated_realm();
// 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
JS_DEFINE_NATIVE_FUNCTION(ObjectConstructor::get_own_property_symbols)
{
auto& realm = *global_object.associated_realm();
// 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
@ -218,9 +223,10 @@ JS_DEFINE_NATIVE_FUNCTION(ObjectConstructor::freeze)
// 20.1.2.7 Object.fromEntries ( iterable ), https://tc39.es/ecma262/#sec-object.fromentries
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* 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> {
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
JS_DEFINE_NATIVE_FUNCTION(ObjectConstructor::get_own_property_descriptors)
{
auto& realm = *global_object.associated_realm();
// 1. Let obj be ? ToObject(O).
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());
// 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
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
JS_DEFINE_NATIVE_FUNCTION(ObjectConstructor::keys)
{
auto& realm = *global_object.associated_realm();
auto* object = TRY(vm.argument(0).to_object(global_object));
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
JS_DEFINE_NATIVE_FUNCTION(ObjectConstructor::values)
{
auto& realm = *global_object.associated_realm();
auto* object = TRY(vm.argument(0).to_object(global_object));
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
JS_DEFINE_NATIVE_FUNCTION(ObjectConstructor::entries)
{
auto& realm = *global_object.associated_realm();
auto* object = TRY(vm.argument(0).to_object(global_object));
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
JS_DEFINE_NATIVE_FUNCTION(ObjectConstructor::create)
{
auto& realm = *global_object.associated_realm();
auto proto = vm.argument(0);
auto properties = vm.argument(1);
@ -356,7 +372,7 @@ JS_DEFINE_NATIVE_FUNCTION(ObjectConstructor::create)
return vm.throw_completion<TypeError>(global_object, ErrorType::ObjectPrototypeWrongType);
// 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
if (!properties.is_undefined()) {

View file

@ -43,9 +43,9 @@ ThrowCompletionOr<Object*> promise_resolve(GlobalObject& global_object, Object&
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
@ -58,7 +58,10 @@ Promise::Promise(Object& prototype)
Promise::ResolvingFunctions Promise::create_resolving_functions()
{
dbgln_if(PROMISE_DEBUG, "[Promise @ {} / create_resolving_functions()]", this);
auto& vm = this->vm();
auto& global_object = this->global_object();
auto& realm = *global_object.associated_realm();
// 1. Let alreadyResolved be the Record { [[Value]]: false }.
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.
// 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);
auto& realm = *global_object.associated_realm();
auto resolution = vm.argument(0);
// 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);
// 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).
promise.reject(self_resolution_error);
@ -145,11 +150,11 @@ Promise::ResolvingFunctions Promise::create_resolving_functions()
// 14. Let job be NewPromiseResolveThenableJob(promise, resolution, thenJobCallback).
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]]).
dbgln_if(PROMISE_DEBUG, "[Promise @ {} / PromiseResolvingFunction]: Enqueuing job @ {} in realm {}", &promise, &job, realm);
vm.host_enqueue_promise_job(move(job), realm);
dbgln_if(PROMISE_DEBUG, "[Promise @ {} / PromiseResolvingFunction]: Enqueuing job @ {} in realm {}", &promise, &job.job, job.realm);
vm.host_enqueue_promise_job(move(job.job), job.realm);
// 16. Return undefined.
return js_undefined();
@ -163,7 +168,7 @@ Promise::ResolvingFunctions Promise::create_resolving_functions()
// 11. Set reject.[[AlreadyResolved]] to alreadyResolved.
// 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);
auto reason = vm.argument(0);

View file

@ -27,7 +27,7 @@ public:
Handle,
};
static Promise* create(GlobalObject&);
static Promise* create(Realm&);
explicit Promise(Object& prototype);
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)
{
auto& vm = global_object.vm();
auto& realm = *global_object.associated_realm();
return perform_promise_common(
global_object, iterator_record, constructor, result_capability, promise_resolve,
[&](PromiseValueList& values) -> ThrowCompletionOr<Value> {
// 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 »).
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.
// p. Set onFulfilled.[[Capability]] to resultCapability.
// 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);
// 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)
{
auto& vm = global_object.vm();
auto& realm = *global_object.associated_realm();
return perform_promise_common(
global_object, iterator_record, constructor, result_capability, promise_resolve,
[&](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));
@ -173,7 +175,7 @@ static ThrowCompletionOr<Value> perform_promise_all_settled(GlobalObject& global
// p. Set onFulfilled.[[Values]] to values.
// q. Set onFulfilled.[[Capability]] to resultCapability.
// 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);
// 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.
// y. Set onRejected.[[Capability]] to resultCapability.
// 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);
// 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)
{
auto& vm = global_object.vm();
auto& realm = *global_object.associated_realm();
return perform_promise_common(
global_object, iterator_record, constructor, result_capability, promise_resolve,
[&](PromiseValueList& errors) -> ThrowCompletionOr<Value> {
// 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) }).
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 }));
// 3. Return ThrowCompletion(error).
@ -219,7 +222,7 @@ static ThrowCompletionOr<Value> perform_promise_any(GlobalObject& global_object,
// o. Set onRejected.[[Errors]] to errors.
// p. Set onRejected.[[Capability]] to resultCapability.
// 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);
// 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
JS_DEFINE_NATIVE_FUNCTION(PromisePrototype::finally)
{
auto& realm = *global_object.associated_realm();
auto on_finally = vm.argument(0);
// 1. Let promise be the this value.
@ -100,6 +102,7 @@ JS_DEFINE_NATIVE_FUNCTION(PromisePrototype::finally)
else {
// 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& realm = *global_object.associated_realm();
auto& constructor = const_cast<FunctionObject&>(*constructor_handle.cell());
auto& on_finally = const_cast<FunctionObject&>(*on_finally_handle.cell());
auto value = vm.argument(0);
@ -117,17 +120,18 @@ JS_DEFINE_NATIVE_FUNCTION(PromisePrototype::finally)
};
// 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 »).
return TRY(Value(promise).invoke(global_object, vm.names.then, value_thunk));
};
// 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:
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& on_finally = const_cast<FunctionObject&>(*on_finally_handle.cell());
auto reason = vm.argument(0);
@ -145,14 +149,14 @@ JS_DEFINE_NATIVE_FUNCTION(PromisePrototype::finally)
};
// 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 »).
return TRY(Value(promise).invoke(global_object, vm.names.then, thrower));
};
// 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 »).

View file

@ -15,6 +15,7 @@ namespace JS {
ThrowCompletionOr<PromiseCapability> new_promise_capability(GlobalObject& global_object, Value constructor)
{
auto& vm = global_object.vm();
auto& realm = *global_object.associated_realm();
// 1. If IsConstructor(C) is false, throw a TypeError exception.
if (!constructor.is_constructor())
@ -55,7 +56,7 @@ ThrowCompletionOr<PromiseCapability> new_promise_capability(GlobalObject& global
};
// 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 »).
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);
}
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)
@ -69,6 +69,7 @@ ThrowCompletionOr<Value> PromiseAllResolveElementFunction::resolve_element()
{
auto& vm = this->vm();
auto& global_object = this->global_object();
auto& realm = *global_object.associated_realm();
// 8. Set values[index] to x.
m_values.values()[m_index] = vm.argument(0);
@ -77,7 +78,7 @@ ThrowCompletionOr<Value> PromiseAllResolveElementFunction::resolve_element()
// 10. If remainingElementsCount.[[Value]] is 0, then
if (--m_remaining_elements.value == 0) {
// 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 »).
return JS::call(global_object, *m_capability.resolve, js_undefined(), values_array);
@ -87,9 +88,9 @@ ThrowCompletionOr<Value> PromiseAllResolveElementFunction::resolve_element()
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)
@ -101,9 +102,10 @@ ThrowCompletionOr<Value> PromiseAllSettledResolveElementFunction::resolve_elemen
{
auto& vm = this->vm();
auto& global_object = this->global_object();
auto& realm = *global_object.associated_realm();
// 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").
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
if (--m_remaining_elements.value == 0) {
// 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 »).
return JS::call(global_object, *m_capability.resolve, js_undefined(), values_array);
@ -128,9 +130,9 @@ ThrowCompletionOr<Value> PromiseAllSettledResolveElementFunction::resolve_elemen
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)
@ -142,9 +144,10 @@ ThrowCompletionOr<Value> PromiseAllSettledRejectElementFunction::resolve_element
{
auto& vm = this->vm();
auto& global_object = this->global_object();
auto& realm = *global_object.associated_realm();
// 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").
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
if (--m_remaining_elements.value == 0) {
// 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 »).
return JS::call(global_object, *m_capability.resolve, js_undefined(), values_array);
@ -169,9 +172,9 @@ ThrowCompletionOr<Value> PromiseAllSettledRejectElementFunction::resolve_element
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)
@ -183,6 +186,7 @@ ThrowCompletionOr<Value> PromiseAnyRejectElementFunction::resolve_element()
{
auto& vm = this->vm();
auto& global_object = this->global_object();
auto& realm = *global_object.associated_realm();
// 8. Set errors[index] to x.
m_values.values()[m_index] = vm.argument(0);
@ -191,10 +195,10 @@ ThrowCompletionOr<Value> PromiseAnyRejectElementFunction::resolve_element()
// 10. If remainingElementsCount.[[Value]] is 0, then
if (--m_remaining_elements.value == 0) {
// 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) }).
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 }));
// c. Return ? Call(promiseCapability.[[Reject]], undefined, « error »).

Some files were not shown because too many files have changed in this diff Show more