LibJS: Replace GlobalObject with VM in common AOs [Part 18/19]

This commit is contained in:
Linus Groh 2022-08-21 19:24:32 +01:00
parent 7856886ed5
commit 25849f8a6d
Notes: sideshowbarker 2024-07-17 07:53:28 +09:00
95 changed files with 536 additions and 677 deletions

View file

@ -3548,7 +3548,7 @@ JS_DEFINE_NATIVE_FUNCTION(@prototype_class@::for_each)
generate_variable_statement(iterator_generator, "wrapped_key", interface.pair_iterator_types->get<0>(), "key", interface);
generate_variable_statement(iterator_generator, "wrapped_value", interface.pair_iterator_types->get<1>(), "value", interface);
iterator_generator.append(R"~~~(
TRY(call(global_object, callback.as_function(), vm.argument(1), wrapped_value, wrapped_key, this_value));
TRY(call(vm, callback.as_function(), vm.argument(1), wrapped_value, wrapped_key, this_value));
return {};
}));

View file

@ -425,8 +425,8 @@ RefPtr<Sheet> Sheet::from_json(JsonObject const& object, Workbook& workbook)
cell = make<Cell>(obj.get("value"sv).to_string(), position, *sheet);
break;
case Cell::Formula: {
auto& interpreter = sheet->interpreter();
auto value_or_error = JS::call(interpreter.global_object(), parse_function, json, JS::js_string(interpreter.heap(), obj.get("value"sv).as_string()));
auto& vm = sheet->interpreter().vm();
auto value_or_error = JS::call(vm, parse_function, json, JS::js_string(vm, obj.get("value"sv).as_string()));
if (value_or_error.is_error()) {
warnln("Failed to load previous value for cell {}, leaving as undefined", position.to_cell_identifier(sheet));
value_or_error = JS::js_undefined();
@ -557,9 +557,10 @@ JsonObject Sheet::to_json() const
JsonObject data;
data.set("kind", it.value->kind() == Cell::Kind::Formula ? "Formula" : "LiteralString");
if (it.value->kind() == Cell::Formula) {
auto& vm = interpreter().vm();
data.set("source", it.value->data());
auto json = interpreter().global_object().get_without_side_effects("JSON");
auto stringified_or_error = JS::call(interpreter().global_object(), json.as_object().get_without_side_effects("stringify").as_function(), json, it.value->evaluated_data());
auto stringified_or_error = JS::call(vm, json.as_object().get_without_side_effects("stringify").as_function(), json, it.value->evaluated_data());
VERIFY(!stringified_or_error.is_error());
data.set("value", stringified_or_error.release_value().to_string_without_side_effects());
} else {

View file

@ -385,7 +385,6 @@ static ThrowCompletionOr<void> argument_list_evaluation(Interpreter& interpreter
Completion NewExpression::execute(Interpreter& interpreter) const
{
InterpreterNodeScope node_scope { interpreter, *this };
auto& global_object = interpreter.global_object();
auto& vm = interpreter.vm();
// 1. Let ref be the result of evaluating constructExpr.
@ -403,7 +402,7 @@ Completion NewExpression::execute(Interpreter& interpreter) const
return throw_type_error_for_callee(interpreter, constructor, "constructor"sv);
// 6. Return ? Construct(constructor, argList).
return Value { TRY(construct(global_object, constructor.as_function(), move(arg_list))) };
return Value { TRY(construct(vm, constructor.as_function(), move(arg_list))) };
}
Completion CallExpression::throw_type_error_for_callee(Interpreter& interpreter, Value callee_value, StringView call_type) const
@ -450,10 +449,10 @@ Completion CallExpression::execute(Interpreter& interpreter) const
&& callee_reference.name().as_string() == vm.names.eval.as_string()) {
auto script_value = arg_list.size() == 0 ? js_undefined() : arg_list[0];
return perform_eval(global_object, script_value, vm.in_strict_mode() ? CallerMode::Strict : CallerMode::NonStrict, EvalMode::Direct);
return perform_eval(vm, script_value, vm.in_strict_mode() ? CallerMode::Strict : CallerMode::NonStrict, EvalMode::Direct);
}
return call(global_object, function, this_value, move(arg_list));
return call(vm, function, this_value, move(arg_list));
}
// 13.3.7.1 Runtime Semantics: Evaluation, https://tc39.es/ecma262/#sec-super-keyword-runtime-semantics-evaluation
@ -461,7 +460,6 @@ Completion CallExpression::execute(Interpreter& interpreter) const
Completion SuperCall::execute(Interpreter& interpreter) const
{
InterpreterNodeScope node_scope { interpreter, *this };
auto& global_object = interpreter.global_object();
auto& vm = interpreter.vm();
// 1. Let newTarget be GetNewTarget().
@ -485,7 +483,7 @@ Completion SuperCall::execute(Interpreter& interpreter) const
VERIFY(value.is_object() && is<Array>(value.as_object()));
auto& array_value = static_cast<Array const&>(value.as_object());
auto length = MUST(length_of_array_like(global_object, array_value));
auto length = MUST(length_of_array_like(vm, array_value));
for (size_t i = 0; i < length; ++i)
arg_list.append(array_value.get_without_side_effects(PropertyKey { i }));
} else {
@ -497,7 +495,7 @@ Completion SuperCall::execute(Interpreter& interpreter) const
return vm.throw_completion<TypeError>(ErrorType::NotAConstructor, "Super constructor");
// 6. Let result be ? Construct(func, argList, newTarget).
auto* result = TRY(construct(global_object, static_cast<FunctionObject&>(*func), move(arg_list), &new_target.as_function()));
auto* result = TRY(construct(vm, static_cast<FunctionObject&>(*func), move(arg_list), &new_target.as_function()));
// 7. Let thisER be GetThisEnvironment().
auto& this_er = verify_cast<FunctionEnvironment>(get_this_environment(vm));
@ -1196,7 +1194,7 @@ Completion ForAwaitOfStatement::loop_evaluation(Interpreter& interpreter, Vector
// 6. Repeat,
while (true) {
// a. Let nextResult be ? Call(iteratorRecord.[[NextMethod]], iteratorRecord.[[Iterator]]).
auto next_result = TRY(call(global_object, iterator.next_method, iterator.iterator));
auto next_result = TRY(call(vm, iterator.next_method, iterator.iterator));
// b. If iteratorKind is async, set nextResult to ? Await(nextResult).
next_result = TRY(await(global_object, next_result));
@ -1397,7 +1395,6 @@ ThrowCompletionOr<Reference> Identifier::to_reference(Interpreter& interpreter)
ThrowCompletionOr<Reference> MemberExpression::to_reference(Interpreter& interpreter) const
{
auto& global_object = interpreter.global_object();
auto& vm = interpreter.vm();
// 13.3.7.1 Runtime Semantics: Evaluation
@ -1434,7 +1431,7 @@ ThrowCompletionOr<Reference> MemberExpression::to_reference(Interpreter& interpr
bool strict = interpreter.vm().in_strict_mode();
// 7. Return ? MakeSuperPropertyReference(actualThis, propertyKey, strict).
return TRY(make_super_property_reference(global_object, actual_this, property_key, strict));
return TRY(make_super_property_reference(vm, actual_this, property_key, strict));
}
auto base_reference = TRY(m_object->to_reference(interpreter));
@ -1456,7 +1453,7 @@ ThrowCompletionOr<Reference> MemberExpression::to_reference(Interpreter& interpr
auto value = TRY(m_property->execute(interpreter)).release_value();
VERIFY(!value.is_empty());
TRY(require_object_coercible(global_object, base_value));
TRY(require_object_coercible(vm, base_value));
property_key = TRY(PropertyKey::from_value(vm, value));
} else if (is<PrivateIdentifier>(*m_property)) {
@ -1464,7 +1461,7 @@ ThrowCompletionOr<Reference> MemberExpression::to_reference(Interpreter& interpr
return make_private_reference(interpreter.vm(), base_value, private_identifier.string());
} else {
property_key = verify_cast<Identifier>(*m_property).string();
TRY(require_object_coercible(global_object, base_value));
TRY(require_object_coercible(vm, base_value));
}
if (!property_key.is_valid())
return Reference {};
@ -1760,7 +1757,7 @@ Completion ClassExpression::execute(Interpreter& interpreter) const
// 15.7.15 Runtime Semantics: BindingClassDeclarationEvaluation, https://tc39.es/ecma262/#sec-runtime-semantics-bindingclassdeclarationevaluation
static ThrowCompletionOr<Value> binding_class_declaration_evaluation(Interpreter& interpreter, ClassExpression const& class_expression)
{
auto& global_object = interpreter.global_object();
auto& vm = interpreter.vm();
// ClassDeclaration : class ClassTail
if (!class_expression.has_name()) {
@ -1790,7 +1787,7 @@ static ThrowCompletionOr<Value> binding_class_declaration_evaluation(Interpreter
auto* env = interpreter.lexical_environment();
// 5. Perform ? InitializeBoundName(className, value, env).
TRY(initialize_bound_name(global_object, class_name, value, env));
TRY(initialize_bound_name(vm, class_name, value, env));
// 6. Return value.
return value;
@ -1970,7 +1967,7 @@ ThrowCompletionOr<ECMAScriptFunctionObject*> ClassExpression::class_definition_e
[&](Handle<ECMAScriptFunctionObject> static_block_function) -> ThrowCompletionOr<void> {
VERIFY(!static_block_function.is_null());
// We discard any value returned here.
TRY(call(global_object, *static_block_function.cell(), class_constructor_value));
TRY(call(vm, *static_block_function.cell(), class_constructor_value));
return {};
}));
}
@ -3374,7 +3371,7 @@ Completion ImportCall::execute(Interpreter& interpreter) const
if (!options_value.is_object()) {
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));
MUST(call(vm, *promise_capability.reject, js_undefined(), error));
// ii. Return promiseCapability.[[Promise]].
return Value { promise_capability.promise };
@ -3390,7 +3387,7 @@ Completion ImportCall::execute(Interpreter& interpreter) const
if (!assertion_object.is_object()) {
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));
MUST(call(vm, *promise_capability.reject, js_undefined(), error));
// 2. Return promiseCapability.[[Promise]].
return Value { promise_capability.promise };
@ -3415,7 +3412,7 @@ Completion ImportCall::execute(Interpreter& interpreter) const
if (!value.is_string()) {
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));
MUST(call(vm, *promise_capability.reject, js_undefined(), error));
// b. Return promiseCapability.[[Promise]].
return Value { promise_capability.promise };
@ -3619,7 +3616,7 @@ void TaggedTemplateLiteral::dump(int indent) const
Completion TaggedTemplateLiteral::execute(Interpreter& interpreter) const
{
InterpreterNodeScope node_scope { interpreter, *this };
auto& global_object = interpreter.global_object();
auto& vm = interpreter.vm();
// NOTE: This is both
// MemberExpression : MemberExpression TemplateLiteral
@ -3652,7 +3649,7 @@ Completion TaggedTemplateLiteral::execute(Interpreter& interpreter) const
arguments.append(TRY(expressions[i].execute(interpreter)).release_value());
// 5. Return ? EvaluateCall(tagFunc, tagRef, TemplateLiteral, tailCall).
return call(global_object, tag, js_undefined(), move(arguments));
return call(vm, tag, js_undefined(), move(arguments));
}
// 13.2.8.3 GetTemplateObject ( templateLiteral ), https://tc39.es/ecma262/#sec-gettemplateobject
@ -4364,7 +4361,7 @@ FlyString ExportStatement::local_name_for_default = "*default*";
Completion ExportStatement::execute(Interpreter& interpreter) const
{
InterpreterNodeScope node_scope { interpreter, *this };
auto& global_object = interpreter.global_object();
auto& vm = interpreter.vm();
if (!is_default_export()) {
if (m_statement) {
@ -4418,7 +4415,7 @@ Completion ExportStatement::execute(Interpreter& interpreter) const
auto* env = interpreter.lexical_environment();
// b. Perform ? InitializeBoundName("*default*", value, env).
TRY(initialize_bound_name(global_object, ExportStatement::local_name_for_default, value, env));
TRY(initialize_bound_name(vm, ExportStatement::local_name_for_default, value, env));
}
// 4. Return empty.
@ -4432,13 +4429,13 @@ Completion ExportStatement::execute(Interpreter& interpreter) const
// 2. Else,
// a. Let rhs be the result of evaluating AssignmentExpression.
// b. Let value be ? GetValue(rhs).
auto value = TRY(interpreter.vm().named_evaluation_if_anonymous_function(*m_statement, "default"));
auto value = TRY(vm.named_evaluation_if_anonymous_function(*m_statement, "default"));
// 3. Let env be the running execution context's LexicalEnvironment.
auto* env = interpreter.lexical_environment();
// 4. Perform ? InitializeBoundName("*default*", value, env).
TRY(initialize_bound_name(global_object, ExportStatement::local_name_for_default, value, env));
TRY(initialize_bound_name(vm, ExportStatement::local_name_for_default, value, env));
// 5. Return empty.
return Optional<Value> {};

View file

@ -492,27 +492,29 @@ ThrowCompletionOr<void> JumpUndefined::execute_impl(Bytecode::Interpreter& inter
ThrowCompletionOr<void> Call::execute_impl(Bytecode::Interpreter& interpreter) const
{
auto& vm = interpreter.vm();
auto callee = interpreter.reg(m_callee);
if (m_type == CallType::Call && !callee.is_function())
return interpreter.vm().throw_completion<TypeError>(ErrorType::IsNotA, callee.to_string_without_side_effects(), "function"sv);
return vm.throw_completion<TypeError>(ErrorType::IsNotA, callee.to_string_without_side_effects(), "function"sv);
if (m_type == CallType::Construct && !callee.is_constructor())
return interpreter.vm().throw_completion<TypeError>(ErrorType::IsNotA, callee.to_string_without_side_effects(), "constructor"sv);
return vm.throw_completion<TypeError>(ErrorType::IsNotA, callee.to_string_without_side_effects(), "constructor"sv);
auto& function = callee.as_function();
auto this_value = interpreter.reg(m_this_value);
MarkedVector<Value> argument_values { interpreter.vm().heap() };
MarkedVector<Value> argument_values { vm.heap() };
for (size_t i = 0; i < m_argument_count; ++i)
argument_values.append(interpreter.reg(m_arguments[i]));
Value return_value;
if (m_type == CallType::Call)
return_value = TRY(call(interpreter.global_object(), function, this_value, move(argument_values)));
return_value = TRY(call(vm, function, this_value, move(argument_values)));
else
return_value = TRY(construct(interpreter.global_object(), function, move(argument_values)));
return_value = TRY(construct(vm, function, move(argument_values)));
interpreter.accumulator() = return_value;
return {};

View file

@ -234,7 +234,7 @@ ThrowCompletionOr<Promise*> CyclicModule::evaluate(VM& vm)
VERIFY(m_evaluation_error.is_error() && same_value(*m_evaluation_error.throw_completion().value(), *result.throw_completion().value()));
// d. Perform ! Call(capability.[[Reject]], undefined, « result.[[Value]] »).
MUST(call(global_object, m_top_level_capability->reject, js_undefined(), *result.throw_completion().value()));
MUST(call(vm, m_top_level_capability->reject, js_undefined(), *result.throw_completion().value()));
}
// 10. Else,
else {
@ -248,7 +248,7 @@ ThrowCompletionOr<Promise*> CyclicModule::evaluate(VM& vm)
// i. Assert: module.[[Status]] is evaluated.
VERIFY(m_status == ModuleStatus::Evaluated);
// ii. Perform ! Call(capability.[[Resolve]], undefined, « undefined »).
MUST(call(global_object, m_top_level_capability->resolve, js_undefined(), js_undefined()));
MUST(call(vm, m_top_level_capability->resolve, js_undefined(), js_undefined()));
}
// d. Assert: stack is empty.
@ -551,9 +551,8 @@ void CyclicModule::async_module_execution_fulfilled(VM& vm)
// a. Assert: module.[[CycleRoot]] is module.
VERIFY(m_cycle_root == this);
VERIFY(vm.current_realm());
// b. Perform ! Call(module.[[TopLevelCapability]].[[Resolve]], undefined, « undefined »).
MUST(call(vm.current_realm()->global_object(), m_top_level_capability->resolve, js_undefined(), js_undefined()));
MUST(call(vm, m_top_level_capability->resolve, js_undefined(), js_undefined()));
}
// 8. Let execList be a new empty List.
@ -600,9 +599,8 @@ void CyclicModule::async_module_execution_fulfilled(VM& vm)
// a. Assert: m.[[CycleRoot]] is m.
VERIFY(module->m_cycle_root == module);
VERIFY(vm.current_realm());
// b. Perform ! Call(m.[[TopLevelCapability]].[[Resolve]], undefined, « undefined »).
MUST(call(vm.current_realm()->global_object(), module->m_top_level_capability->resolve, js_undefined(), js_undefined()));
MUST(call(vm, module->m_top_level_capability->resolve, js_undefined(), js_undefined()));
}
}
}
@ -650,9 +648,8 @@ void CyclicModule::async_module_execution_rejected(VM& vm, Value error)
// a. Assert: module.[[CycleRoot]] is module.
VERIFY(m_cycle_root == this);
VERIFY(vm.current_realm());
// b. Perform ! Call(module.[[TopLevelCapability]].[[Reject]], undefined, « error »).
MUST(call(vm.current_realm()->global_object(), m_top_level_capability->reject, js_undefined(), error));
MUST(call(vm, m_top_level_capability->reject, js_undefined(), error));
}
// 9. Return unused.

View file

@ -34,22 +34,19 @@
namespace JS {
// 7.2.1 RequireObjectCoercible ( argument ), https://tc39.es/ecma262/#sec-requireobjectcoercible
ThrowCompletionOr<Value> require_object_coercible(GlobalObject& global_object, Value value)
ThrowCompletionOr<Value> require_object_coercible(VM& vm, Value value)
{
auto& vm = global_object.vm();
if (value.is_nullish())
return vm.throw_completion<TypeError>(ErrorType::NotObjectCoercible, value.to_string_without_side_effects());
return value;
}
// 7.3.14 Call ( F, V [ , argumentsList ] ), https://tc39.es/ecma262/#sec-call
ThrowCompletionOr<Value> call_impl(GlobalObject& global_object, Value function, Value this_value, Optional<MarkedVector<Value>> arguments_list)
ThrowCompletionOr<Value> call_impl(VM& vm, Value function, Value this_value, Optional<MarkedVector<Value>> arguments_list)
{
auto& vm = global_object.vm();
// 1. If argumentsList is not present, set argumentsList to a new empty List.
if (!arguments_list.has_value())
arguments_list = MarkedVector<Value> { global_object.heap() };
arguments_list = MarkedVector<Value> { vm.heap() };
// 2. If IsCallable(F) is false, throw a TypeError exception.
if (!function.is_function())
@ -59,11 +56,11 @@ ThrowCompletionOr<Value> call_impl(GlobalObject& global_object, Value function,
return function.as_function().internal_call(this_value, move(*arguments_list));
}
ThrowCompletionOr<Value> call_impl(GlobalObject& global_object, FunctionObject& function, Value this_value, Optional<MarkedVector<Value>> arguments_list)
ThrowCompletionOr<Value> call_impl(VM& vm, FunctionObject& function, Value this_value, Optional<MarkedVector<Value>> arguments_list)
{
// 1. If argumentsList is not present, set argumentsList to a new empty List.
if (!arguments_list.has_value())
arguments_list = MarkedVector<Value> { global_object.heap() };
arguments_list = MarkedVector<Value> { vm.heap() };
// 2. If IsCallable(F) is false, throw a TypeError exception.
// Note: Called with a FunctionObject ref
@ -73,7 +70,7 @@ ThrowCompletionOr<Value> call_impl(GlobalObject& global_object, FunctionObject&
}
// 7.3.15 Construct ( F [ , argumentsList [ , newTarget ] ] ), https://tc39.es/ecma262/#sec-construct
ThrowCompletionOr<Object*> construct_impl(GlobalObject& global_object, FunctionObject& function, Optional<MarkedVector<Value>> arguments_list, FunctionObject* new_target)
ThrowCompletionOr<Object*> construct_impl(VM& vm, FunctionObject& function, Optional<MarkedVector<Value>> arguments_list, FunctionObject* new_target)
{
// 1. If newTarget is not present, set newTarget to F.
if (!new_target)
@ -81,26 +78,22 @@ ThrowCompletionOr<Object*> construct_impl(GlobalObject& global_object, FunctionO
// 2. If argumentsList is not present, set argumentsList to a new empty List.
if (!arguments_list.has_value())
arguments_list = MarkedVector<Value> { global_object.heap() };
arguments_list = MarkedVector<Value> { vm.heap() };
// 3. Return ? F.[[Construct]](argumentsList, newTarget).
return function.internal_construct(move(*arguments_list), *new_target);
}
// 7.3.19 LengthOfArrayLike ( obj ), https://tc39.es/ecma262/#sec-lengthofarraylike
ThrowCompletionOr<size_t> length_of_array_like(GlobalObject& global_object, Object const& object)
ThrowCompletionOr<size_t> length_of_array_like(VM& vm, Object const& object)
{
auto& vm = global_object.vm();
auto result = TRY(object.get(vm.names.length));
return result.to_length(vm);
}
// 7.3.20 CreateListFromArrayLike ( obj [ , elementTypes ] ), https://tc39.es/ecma262/#sec-createlistfromarraylike
ThrowCompletionOr<MarkedVector<Value>> create_list_from_array_like(GlobalObject& global_object, Value value, Function<ThrowCompletionOr<void>(Value)> check_value)
ThrowCompletionOr<MarkedVector<Value>> create_list_from_array_like(VM& vm, Value value, Function<ThrowCompletionOr<void>(Value)> check_value)
{
auto& vm = global_object.vm();
auto& heap = global_object.heap();
// 1. If elementTypes is not present, set elementTypes to « Undefined, Null, Boolean, String, Symbol, Number, BigInt, Object ».
// 2. If Type(obj) is not Object, throw a TypeError exception.
@ -110,10 +103,10 @@ ThrowCompletionOr<MarkedVector<Value>> create_list_from_array_like(GlobalObject&
auto& array_like = value.as_object();
// 3. Let len be ? LengthOfArrayLike(obj).
auto length = TRY(length_of_array_like(global_object, array_like));
auto length = TRY(length_of_array_like(vm, array_like));
// 4. Let list be a new empty List.
auto list = MarkedVector<Value> { heap };
auto list = MarkedVector<Value> { vm.heap() };
list.ensure_capacity(length);
// 5. Let index be 0.
@ -138,10 +131,8 @@ ThrowCompletionOr<MarkedVector<Value>> create_list_from_array_like(GlobalObject&
}
// 7.3.23 SpeciesConstructor ( O, defaultConstructor ), https://tc39.es/ecma262/#sec-speciesconstructor
ThrowCompletionOr<FunctionObject*> species_constructor(GlobalObject& global_object, Object const& object, FunctionObject& default_constructor)
ThrowCompletionOr<FunctionObject*> species_constructor(VM& vm, Object const& object, FunctionObject& default_constructor)
{
auto& vm = global_object.vm();
// 1. Let C be ? Get(O, "constructor").
auto constructor = TRY(object.get(vm.names.constructor));
@ -169,10 +160,8 @@ ThrowCompletionOr<FunctionObject*> species_constructor(GlobalObject& global_obje
}
// 7.3.25 GetFunctionRealm ( obj ), https://tc39.es/ecma262/#sec-getfunctionrealm
ThrowCompletionOr<Realm*> get_function_realm(GlobalObject& global_object, FunctionObject const& function)
ThrowCompletionOr<Realm*> get_function_realm(VM& vm, FunctionObject const& function)
{
auto& vm = global_object.vm();
// 1. If obj has a [[Realm]] internal slot, then
if (function.realm()) {
// a. Return obj.[[Realm]].
@ -187,7 +176,7 @@ ThrowCompletionOr<Realm*> get_function_realm(GlobalObject& global_object, Functi
auto& target = bound_function.bound_target_function();
// b. Return ? GetFunctionRealm(target).
return get_function_realm(global_object, target);
return get_function_realm(vm, target);
}
// 3. If obj is a Proxy exotic object, then
@ -203,7 +192,7 @@ ThrowCompletionOr<Realm*> get_function_realm(GlobalObject& global_object, Functi
// c. Return ? GetFunctionRealm(proxyTarget).
VERIFY(proxy_target.is_function());
return get_function_realm(global_object, static_cast<FunctionObject const&>(proxy_target));
return get_function_realm(vm, static_cast<FunctionObject const&>(proxy_target));
}
// 4. Return the current Realm Record.
@ -211,10 +200,8 @@ ThrowCompletionOr<Realm*> get_function_realm(GlobalObject& global_object, Functi
}
// 8.5.2.1 InitializeBoundName ( name, value, environment ), https://tc39.es/ecma262/#sec-initializeboundname
ThrowCompletionOr<void> initialize_bound_name(GlobalObject& global_object, FlyString const& name, Value value, Environment* environment)
ThrowCompletionOr<void> initialize_bound_name(VM& vm, FlyString const& name, Value value, Environment* environment)
{
auto& vm = global_object.vm();
// 1. If environment is not undefined, then
if (environment) {
// a. Perform ! environment.InitializeBinding(name, value).
@ -375,10 +362,8 @@ bool validate_and_apply_property_descriptor(Object* object, PropertyKey const& p
}
// 10.1.14 GetPrototypeFromConstructor ( constructor, intrinsicDefaultProto ), https://tc39.es/ecma262/#sec-getprototypefromconstructor
ThrowCompletionOr<Object*> get_prototype_from_constructor(GlobalObject& global_object, FunctionObject const& constructor, Object* (GlobalObject::*intrinsic_default_prototype)())
ThrowCompletionOr<Object*> get_prototype_from_constructor(VM& vm, FunctionObject const& constructor, Object* (GlobalObject::*intrinsic_default_prototype)())
{
auto& vm = global_object.vm();
// 1. Assert: intrinsicDefaultProto is this specification's name of an intrinsic object. The corresponding object must be an intrinsic that is intended to be used as the [[Prototype]] value of an object.
// 2. Let proto be ? Get(constructor, "prototype").
@ -387,7 +372,7 @@ ThrowCompletionOr<Object*> get_prototype_from_constructor(GlobalObject& global_o
// 3. If Type(proto) is not Object, then
if (!prototype.is_object()) {
// a. Let realm be ? GetFunctionRealm(constructor).
auto* realm = TRY(get_function_realm(global_object, constructor));
auto* realm = TRY(get_function_realm(vm, constructor));
// b. Set proto to realm's intrinsic object named intrinsicDefaultProto.
prototype = (realm->global_object().*intrinsic_default_prototype)();
@ -494,23 +479,26 @@ Object* get_super_constructor(VM& vm)
}
// 13.3.7.3 MakeSuperPropertyReference ( actualThis, propertyKey, strict ), https://tc39.es/ecma262/#sec-makesuperpropertyreference
ThrowCompletionOr<Reference> make_super_property_reference(GlobalObject& global_object, Value actual_this, PropertyKey const& property_key, bool strict)
ThrowCompletionOr<Reference> make_super_property_reference(VM& vm, Value actual_this, PropertyKey const& property_key, bool strict)
{
auto& vm = global_object.vm();
// 1. Let env be GetThisEnvironment().
auto& env = verify_cast<FunctionEnvironment>(get_this_environment(vm));
// 2. Assert: env.HasSuperBinding() is true.
VERIFY(env.has_super_binding());
// 3. Let baseValue be ? env.GetSuperBase().
auto base_value = TRY(env.get_super_base());
// 4. Let bv be ? RequireObjectCoercible(baseValue).
auto bv = TRY(require_object_coercible(global_object, base_value));
auto bv = TRY(require_object_coercible(vm, base_value));
// 5. Return the Reference Record { [[Base]]: bv, [[ReferencedName]]: propertyKey, [[Strict]]: strict, [[ThisValue]]: actualThis }.
return Reference { bv, property_key, actual_this, strict };
}
// 19.2.1.1 PerformEval ( x, strictCaller, direct ), https://tc39.es/ecma262/#sec-performeval
ThrowCompletionOr<Value> perform_eval(GlobalObject& global_object, Value x, CallerMode strict_caller, EvalMode direct)
ThrowCompletionOr<Value> perform_eval(VM& vm, Value x, CallerMode strict_caller, EvalMode direct)
{
// 1. Assert: If direct is false, then strictCaller is also false.
VERIFY(direct == EvalMode::Direct || strict_caller == CallerMode::NonStrict);
@ -519,8 +507,6 @@ ThrowCompletionOr<Value> perform_eval(GlobalObject& global_object, Value x, Call
if (!x.is_string())
return x;
auto& vm = global_object.vm();
// 3. Let evalRealm be the current Realm Record.
auto& eval_realm = *vm.running_execution_context().realm;
@ -688,7 +674,7 @@ ThrowCompletionOr<Value> perform_eval(GlobalObject& global_object, Value x, Call
};
// 28. Let result be Completion(EvalDeclarationInstantiation(body, varEnv, lexEnv, privateEnv, strictEval)).
TRY(eval_declaration_instantiation(vm, eval_realm.global_object(), program, variable_environment, lexical_environment, private_environment, strict_eval));
TRY(eval_declaration_instantiation(vm, program, variable_environment, lexical_environment, private_environment, strict_eval));
Optional<Value> eval_result;
@ -724,9 +710,9 @@ 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)
ThrowCompletionOr<void> eval_declaration_instantiation(VM& vm, Program const& program, Environment* variable_environment, Environment* lexical_environment, PrivateEnvironment* private_environment, bool strict)
{
auto& realm = *global_object.associated_realm();
auto& realm = *vm.current_realm();
GlobalEnvironment* global_var_environment = variable_environment->is_global_environment() ? static_cast<GlobalEnvironment*>(variable_environment) : nullptr;
// 1. Let varNames be the VarDeclaredNames of body.
@ -1034,17 +1020,16 @@ ThrowCompletionOr<void> eval_declaration_instantiation(VM& vm, GlobalObject& glo
}
// 10.4.4.6 CreateUnmappedArgumentsObject ( argumentsList ), https://tc39.es/ecma262/#sec-createunmappedargumentsobject
Object* create_unmapped_arguments_object(GlobalObject& global_object, Span<Value> arguments)
Object* create_unmapped_arguments_object(VM& vm, Span<Value> arguments)
{
auto& vm = global_object.vm();
auto& realm = *global_object.associated_realm();
auto& realm = *vm.current_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(realm, global_object.object_prototype());
auto* object = Object::create(realm, realm.global_object().object_prototype());
object->set_has_parameter_map();
// 4. Perform ! DefinePropertyOrThrow(obj, "length", PropertyDescriptor { [[Value]]: 𝔽(len), [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: true }).
@ -1063,11 +1048,11 @@ Object* create_unmapped_arguments_object(GlobalObject& global_object, Span<Value
}
// 7. Perform ! DefinePropertyOrThrow(obj, @@iterator, PropertyDescriptor { [[Value]]: %Array.prototype.values%, [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: true }).
auto* array_prototype_values = global_object.array_prototype_values_function();
auto* array_prototype_values = realm.global_object().array_prototype_values_function();
MUST(object->define_property_or_throw(*vm.well_known_symbol_iterator(), { .value = array_prototype_values, .writable = true, .enumerable = false, .configurable = true }));
// 8. Perform ! DefinePropertyOrThrow(obj, "callee", PropertyDescriptor { [[Get]]: %ThrowTypeError%, [[Set]]: %ThrowTypeError%, [[Enumerable]]: false, [[Configurable]]: false }).
auto* throw_type_error = global_object.throw_type_error_function();
auto* throw_type_error = realm.global_object().throw_type_error_function();
MUST(object->define_property_or_throw(vm.names.callee, { .get = throw_type_error, .set = throw_type_error, .enumerable = false, .configurable = false }));
// 9. Return obj.
@ -1075,10 +1060,9 @@ Object* create_unmapped_arguments_object(GlobalObject& global_object, Span<Value
}
// 10.4.4.7 CreateMappedArgumentsObject ( func, formals, argumentsList, env ), https://tc39.es/ecma262/#sec-createmappedargumentsobject
Object* create_mapped_arguments_object(GlobalObject& global_object, FunctionObject& function, Vector<FunctionNode::Parameter> const& formals, Span<Value> arguments, Environment& environment)
Object* create_mapped_arguments_object(VM& vm, FunctionObject& function, Vector<FunctionNode::Parameter> const& formals, Span<Value> arguments, Environment& environment)
{
auto& vm = global_object.vm();
auto& realm = *global_object.associated_realm();
auto& realm = *vm.current_realm();
// 1. Assert: formals does not contain a rest parameter, any binding patterns, or any initializers. It may contain duplicate identifiers.
@ -1146,7 +1130,7 @@ Object* create_mapped_arguments_object(GlobalObject& global_object, FunctionObje
}
// 20. Perform ! DefinePropertyOrThrow(obj, @@iterator, PropertyDescriptor { [[Value]]: %Array.prototype.values%, [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: true }).
auto* array_prototype_values = global_object.array_prototype_values_function();
auto* array_prototype_values = realm.global_object().array_prototype_values_function();
MUST(object->define_property_or_throw(*vm.well_known_symbol_iterator(), { .value = array_prototype_values, .writable = true, .enumerable = false, .configurable = true }));
// 21. Perform ! DefinePropertyOrThrow(obj, "callee", PropertyDescriptor { [[Value]]: func, [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: true }).
@ -1218,9 +1202,8 @@ CanonicalIndex canonical_numeric_index_string(PropertyKey const& property_key, C
}
// 22.1.3.17.1 GetSubstitution ( matched, str, position, captures, namedCaptures, replacement ), https://tc39.es/ecma262/#sec-getsubstitution
ThrowCompletionOr<String> get_substitution(GlobalObject& global_object, Utf16View const& matched, Utf16View const& str, size_t position, Span<Value> captures, Value named_captures, Value replacement)
ThrowCompletionOr<String> get_substitution(VM& vm, Utf16View const& matched, Utf16View const& str, size_t position, Span<Value> captures, Value named_captures, Value replacement)
{
auto& vm = global_object.vm();
auto replace_string = TRY(replacement.to_utf16_string(vm));
auto replace_view = replace_string.view();

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2020-2021, Linus Groh <linusg@serenityos.org>
* Copyright (c) 2020-2022, Linus Groh <linusg@serenityos.org>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
@ -26,28 +26,28 @@ PrivateEnvironment* new_private_environment(VM& vm, PrivateEnvironment* outer);
Environment& get_this_environment(VM&);
bool can_be_held_weakly(Value);
Object* get_super_constructor(VM&);
ThrowCompletionOr<Reference> make_super_property_reference(GlobalObject&, Value actual_this, PropertyKey const&, bool strict);
ThrowCompletionOr<Value> require_object_coercible(GlobalObject&, Value);
ThrowCompletionOr<Value> call_impl(GlobalObject&, Value function, Value this_value, Optional<MarkedVector<Value>> = {});
ThrowCompletionOr<Value> call_impl(GlobalObject&, FunctionObject& function, Value this_value, Optional<MarkedVector<Value>> = {});
ThrowCompletionOr<Object*> construct_impl(GlobalObject&, FunctionObject&, Optional<MarkedVector<Value>> = {}, FunctionObject* new_target = nullptr);
ThrowCompletionOr<size_t> length_of_array_like(GlobalObject&, Object const&);
ThrowCompletionOr<MarkedVector<Value>> create_list_from_array_like(GlobalObject&, Value, Function<ThrowCompletionOr<void>(Value)> = {});
ThrowCompletionOr<FunctionObject*> species_constructor(GlobalObject&, Object const&, FunctionObject& default_constructor);
ThrowCompletionOr<Realm*> get_function_realm(GlobalObject&, FunctionObject const&);
ThrowCompletionOr<void> initialize_bound_name(GlobalObject&, FlyString const&, Value, Environment*);
ThrowCompletionOr<Reference> make_super_property_reference(VM&, Value actual_this, PropertyKey const&, bool strict);
ThrowCompletionOr<Value> require_object_coercible(VM&, Value);
ThrowCompletionOr<Value> call_impl(VM&, Value function, Value this_value, Optional<MarkedVector<Value>> = {});
ThrowCompletionOr<Value> call_impl(VM&, FunctionObject& function, Value this_value, Optional<MarkedVector<Value>> = {});
ThrowCompletionOr<Object*> construct_impl(VM&, FunctionObject&, Optional<MarkedVector<Value>> = {}, FunctionObject* new_target = nullptr);
ThrowCompletionOr<size_t> length_of_array_like(VM&, Object const&);
ThrowCompletionOr<MarkedVector<Value>> create_list_from_array_like(VM&, Value, Function<ThrowCompletionOr<void>(Value)> = {});
ThrowCompletionOr<FunctionObject*> species_constructor(VM&, Object const&, FunctionObject& default_constructor);
ThrowCompletionOr<Realm*> get_function_realm(VM&, FunctionObject const&);
ThrowCompletionOr<void> initialize_bound_name(VM&, FlyString const&, Value, Environment*);
bool is_compatible_property_descriptor(bool extensible, PropertyDescriptor const&, Optional<PropertyDescriptor> const& current);
bool validate_and_apply_property_descriptor(Object*, PropertyKey const&, bool extensible, PropertyDescriptor const&, Optional<PropertyDescriptor> const& current);
ThrowCompletionOr<Object*> get_prototype_from_constructor(GlobalObject&, FunctionObject const& constructor, Object* (GlobalObject::*intrinsic_default_prototype)());
Object* create_unmapped_arguments_object(GlobalObject&, Span<Value> arguments);
Object* create_mapped_arguments_object(GlobalObject&, FunctionObject&, Vector<FunctionNode::Parameter> const&, Span<Value> arguments, Environment&);
ThrowCompletionOr<Object*> get_prototype_from_constructor(VM&, FunctionObject const& constructor, Object* (GlobalObject::*intrinsic_default_prototype)());
Object* create_unmapped_arguments_object(VM&, Span<Value> arguments);
Object* create_mapped_arguments_object(VM&, FunctionObject&, Vector<FunctionNode::Parameter> const&, Span<Value> arguments, Environment&);
enum class CanonicalIndexMode {
DetectNumericRoundtrip,
IgnoreNumericRoundtrip,
};
CanonicalIndex canonical_numeric_index_string(PropertyKey const&, CanonicalIndexMode needs_numeric);
ThrowCompletionOr<String> get_substitution(GlobalObject&, Utf16View const& matched, Utf16View const& str, size_t position, Span<Value> captures, Value named_captures, Value replacement);
ThrowCompletionOr<String> get_substitution(VM&, Utf16View const& matched, Utf16View const& str, size_t position, Span<Value> captures, Value named_captures, Value replacement);
enum class CallerMode {
Strict,
@ -57,84 +57,84 @@ enum class EvalMode {
Direct,
Indirect
};
ThrowCompletionOr<Value> perform_eval(GlobalObject&, Value, CallerMode, EvalMode);
ThrowCompletionOr<Value> perform_eval(VM&, Value, CallerMode, EvalMode);
ThrowCompletionOr<void> eval_declaration_instantiation(VM& vm, GlobalObject& global_object, Program const& program, Environment* variable_environment, Environment* lexical_environment, PrivateEnvironment* private_environment, bool strict);
ThrowCompletionOr<void> eval_declaration_instantiation(VM& vm, Program const& program, Environment* variable_environment, Environment* lexical_environment, PrivateEnvironment* private_environment, bool strict);
// 7.3.14 Call ( F, V [ , argumentsList ] ), https://tc39.es/ecma262/#sec-call
ALWAYS_INLINE ThrowCompletionOr<Value> call(GlobalObject& global_object, Value function, Value this_value, MarkedVector<Value> arguments_list)
ALWAYS_INLINE ThrowCompletionOr<Value> call(VM& vm, Value function, Value this_value, MarkedVector<Value> arguments_list)
{
return call_impl(global_object, function, this_value, move(arguments_list));
return call_impl(vm, function, this_value, move(arguments_list));
}
ALWAYS_INLINE ThrowCompletionOr<Value> call(GlobalObject& global_object, Value function, Value this_value, Optional<MarkedVector<Value>> arguments_list)
ALWAYS_INLINE ThrowCompletionOr<Value> call(VM& vm, Value function, Value this_value, Optional<MarkedVector<Value>> arguments_list)
{
return call_impl(global_object, function, this_value, move(arguments_list));
return call_impl(vm, function, this_value, move(arguments_list));
}
template<typename... Args>
ALWAYS_INLINE ThrowCompletionOr<Value> call(GlobalObject& global_object, Value function, Value this_value, Args&&... args)
ALWAYS_INLINE ThrowCompletionOr<Value> call(VM& vm, Value function, Value this_value, Args&&... args)
{
if constexpr (sizeof...(Args) > 0) {
MarkedVector<Value> arguments_list { global_object.heap() };
MarkedVector<Value> arguments_list { vm.heap() };
(..., arguments_list.append(forward<Args>(args)));
return call_impl(global_object, function, this_value, move(arguments_list));
return call_impl(vm, function, this_value, move(arguments_list));
}
return call_impl(global_object, function, this_value);
return call_impl(vm, function, this_value);
}
ALWAYS_INLINE ThrowCompletionOr<Value> call(GlobalObject& global_object, FunctionObject& function, Value this_value, MarkedVector<Value> arguments_list)
ALWAYS_INLINE ThrowCompletionOr<Value> call(VM& vm, FunctionObject& function, Value this_value, MarkedVector<Value> arguments_list)
{
return call_impl(global_object, function, this_value, move(arguments_list));
return call_impl(vm, function, this_value, move(arguments_list));
}
ALWAYS_INLINE ThrowCompletionOr<Value> call(GlobalObject& global_object, FunctionObject& function, Value this_value, Optional<MarkedVector<Value>> arguments_list)
ALWAYS_INLINE ThrowCompletionOr<Value> call(VM& vm, FunctionObject& function, Value this_value, Optional<MarkedVector<Value>> arguments_list)
{
return call_impl(global_object, function, this_value, move(arguments_list));
return call_impl(vm, function, this_value, move(arguments_list));
}
template<typename... Args>
ALWAYS_INLINE ThrowCompletionOr<Value> call(GlobalObject& global_object, FunctionObject& function, Value this_value, Args&&... args)
ALWAYS_INLINE ThrowCompletionOr<Value> call(VM& vm, FunctionObject& function, Value this_value, Args&&... args)
{
if constexpr (sizeof...(Args) > 0) {
MarkedVector<Value> arguments_list { global_object.heap() };
MarkedVector<Value> arguments_list { vm.heap() };
(..., arguments_list.append(forward<Args>(args)));
return call_impl(global_object, function, this_value, move(arguments_list));
return call_impl(vm, function, this_value, move(arguments_list));
}
return call_impl(global_object, function, this_value);
return call_impl(vm, function, this_value);
}
// 7.3.15 Construct ( F [ , argumentsList [ , newTarget ] ] ), https://tc39.es/ecma262/#sec-construct
template<typename... Args>
ALWAYS_INLINE ThrowCompletionOr<Object*> construct(GlobalObject& global_object, FunctionObject& function, Args&&... args)
ALWAYS_INLINE ThrowCompletionOr<Object*> construct(VM& vm, FunctionObject& function, Args&&... args)
{
if constexpr (sizeof...(Args) > 0) {
MarkedVector<Value> arguments_list { global_object.heap() };
MarkedVector<Value> arguments_list { vm.heap() };
(..., arguments_list.append(forward<Args>(args)));
return construct_impl(global_object, function, move(arguments_list));
return construct_impl(vm, function, move(arguments_list));
}
return construct_impl(global_object, function);
return construct_impl(vm, function);
}
ALWAYS_INLINE ThrowCompletionOr<Object*> construct(GlobalObject& global_object, FunctionObject& function, MarkedVector<Value> arguments_list, FunctionObject* new_target = nullptr)
ALWAYS_INLINE ThrowCompletionOr<Object*> construct(VM& vm, FunctionObject& function, MarkedVector<Value> arguments_list, FunctionObject* new_target = nullptr)
{
return construct_impl(global_object, function, move(arguments_list), new_target);
return construct_impl(vm, function, move(arguments_list), new_target);
}
ALWAYS_INLINE ThrowCompletionOr<Object*> construct(GlobalObject& global_object, FunctionObject& function, Optional<MarkedVector<Value>> arguments_list, FunctionObject* new_target = nullptr)
ALWAYS_INLINE ThrowCompletionOr<Object*> construct(VM& vm, FunctionObject& function, Optional<MarkedVector<Value>> arguments_list, FunctionObject* new_target = nullptr)
{
return construct_impl(global_object, function, move(arguments_list), new_target);
return construct_impl(vm, function, move(arguments_list), new_target);
}
// 10.1.13 OrdinaryCreateFromConstructor ( constructor, intrinsicDefaultProto [ , internalSlotsList ] ), https://tc39.es/ecma262/#sec-ordinarycreatefromconstructor
template<typename T, typename... Args>
ThrowCompletionOr<T*> ordinary_create_from_constructor(GlobalObject& global_object, FunctionObject const& constructor, Object* (GlobalObject::*intrinsic_default_prototype)(), Args&&... args)
ThrowCompletionOr<T*> ordinary_create_from_constructor(VM& vm, FunctionObject const& constructor, Object* (GlobalObject::*intrinsic_default_prototype)(), Args&&... args)
{
auto& realm = *global_object.associated_realm();
auto* prototype = TRY(get_prototype_from_constructor(global_object, constructor, intrinsic_default_prototype));
auto& realm = *vm.current_realm();
auto* prototype = TRY(get_prototype_from_constructor(vm, constructor, intrinsic_default_prototype));
return realm.heap().allocate<T>(realm, forward<Args>(args)..., *prototype);
}

View file

@ -43,7 +43,7 @@ ThrowCompletionOr<Object*> AggregateErrorConstructor::construct(FunctionObject&
auto& global_object = this->global_object();
auto& realm = *global_object.associated_realm();
auto* aggregate_error = TRY(ordinary_create_from_constructor<AggregateError>(global_object, new_target, &GlobalObject::aggregate_error_prototype));
auto* aggregate_error = TRY(ordinary_create_from_constructor<AggregateError>(vm, new_target, &GlobalObject::aggregate_error_prototype));
if (!vm.argument(1).is_undefined()) {
auto message = TRY(vm.argument(1).to_string(vm));

View file

@ -159,9 +159,6 @@ ThrowCompletionOr<bool> Array::set_length(PropertyDescriptor const& property_des
// 1.1.1.2 CompareArrayElements ( x, y, comparefn ), https://tc39.es/proposal-change-array-by-copy/#sec-comparearrayelements
ThrowCompletionOr<double> compare_array_elements(VM& vm, Value x, Value y, FunctionObject* comparefn)
{
auto& realm = *vm.current_realm();
auto& global_object = realm.global_object();
// 1. If x and y are both undefined, return +0𝔽.
if (x.is_undefined() && y.is_undefined())
return 0;
@ -177,7 +174,7 @@ ThrowCompletionOr<double> compare_array_elements(VM& vm, Value x, Value y, Funct
// 4. If comparefn is not undefined, then
if (comparefn != nullptr) {
// a. Let v be ? ToNumber(? Call(comparefn, undefined, « x, y »)).
auto value = TRY(call(global_object, comparefn, js_undefined(), x, y));
auto value = TRY(call(vm, comparefn, js_undefined(), x, y));
auto value_number = TRY(value.to_number(vm));
// b. If v is NaN, return +0𝔽.

View file

@ -53,11 +53,8 @@ void ArrayBuffer::visit_edges(Cell::Visitor& visitor)
// 25.1.2.1 AllocateArrayBuffer ( constructor, byteLength ), https://tc39.es/ecma262/#sec-allocatearraybuffer
ThrowCompletionOr<ArrayBuffer*> allocate_array_buffer(VM& vm, FunctionObject& constructor, size_t byte_length)
{
auto& realm = *vm.current_realm();
auto& global_object = realm.global_object();
// 1. Let obj be ? OrdinaryCreateFromConstructor(constructor, "%ArrayBuffer.prototype%", « [[ArrayBufferData]], [[ArrayBufferByteLength]], [[ArrayBufferDetachKey]] »).
auto* obj = TRY(ordinary_create_from_constructor<ArrayBuffer>(global_object, constructor, &GlobalObject::array_buffer_prototype, nullptr));
auto* obj = TRY(ordinary_create_from_constructor<ArrayBuffer>(vm, constructor, &GlobalObject::array_buffer_prototype, nullptr));
// 2. Let block be ? CreateByteDataBlock(byteLength).
auto block = ByteBuffer::create_zeroed(byte_length);

View file

@ -80,10 +80,10 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayBufferPrototype::slice)
auto new_length = max(final - first, 0.0);
// 15. Let ctor be ? SpeciesConstructor(O, %ArrayBuffer%).
auto* constructor = TRY(species_constructor(global_object, *array_buffer_object, *global_object.array_buffer_constructor()));
auto* constructor = TRY(species_constructor(vm, *array_buffer_object, *global_object.array_buffer_constructor()));
// 16. Let new be ? Construct(ctor, « 𝔽(newLen) »).
auto* new_array_buffer = TRY(construct(global_object, *constructor, Value(new_length)));
auto* new_array_buffer = TRY(construct(vm, *constructor, Value(new_length)));
// 17. Perform ? RequireInternalSlot(new, [[ArrayBufferData]]).
if (!is<ArrayBuffer>(new_array_buffer))

View file

@ -53,7 +53,7 @@ ThrowCompletionOr<Object*> ArrayConstructor::construct(FunctionObject& new_targe
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(vm, new_target, &GlobalObject::array_prototype));
if (vm.argument_count() == 0)
return MUST(Array::create(realm, 0, proto));
@ -103,7 +103,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayConstructor::from)
if (using_iterator) {
Object* array;
if (constructor.is_constructor())
array = TRY(JS::construct(global_object, constructor.as_function(), {}));
array = TRY(JS::construct(vm, constructor.as_function(), {}));
else
array = MUST(Array::create(realm, 0));
@ -126,7 +126,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayConstructor::from)
Value mapped_value;
if (map_fn) {
auto mapped_value_or_error = JS::call(global_object, *map_fn, this_arg, next_value, Value(k));
auto mapped_value_or_error = JS::call(vm, *map_fn, this_arg, next_value, Value(k));
if (mapped_value_or_error.is_error())
return TRY(iterator_close(vm, iterator, mapped_value_or_error.release_error()));
mapped_value = mapped_value_or_error.release_value();
@ -144,11 +144,11 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayConstructor::from)
auto* array_like = MUST(items.to_object(vm));
auto length = TRY(length_of_array_like(global_object, *array_like));
auto length = TRY(length_of_array_like(vm, *array_like));
Object* array;
if (constructor.is_constructor())
array = TRY(JS::construct(global_object, constructor.as_function(), Value(length)));
array = TRY(JS::construct(vm, constructor.as_function(), Value(length)));
else
array = TRY(Array::create(realm, length));
@ -156,7 +156,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayConstructor::from)
auto k_value = TRY(array_like->get(k));
Value mapped_value;
if (map_fn)
mapped_value = TRY(JS::call(global_object, *map_fn, this_arg, k_value, Value(k)));
mapped_value = TRY(JS::call(vm, *map_fn, this_arg, k_value, Value(k)));
else
mapped_value = k_value;
TRY(array->create_data_property_or_throw(k, mapped_value));
@ -181,7 +181,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayConstructor::of)
auto this_value = vm.this_value();
Object* array;
if (this_value.is_constructor())
array = TRY(JS::construct(global_object, this_value.as_function(), Value(vm.argument_count())));
array = TRY(JS::construct(vm, this_value.as_function(), Value(vm.argument_count())));
else
array = TRY(Array::create(realm, vm.argument_count()));
for (size_t k = 0; k < vm.argument_count(); ++k)

View file

@ -56,7 +56,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayIteratorPrototype::next)
length = typed_array.array_length();
} else {
length = TRY(length_of_array_like(global_object, array));
length = TRY(length_of_array_like(vm, array));
}
if (index >= length) {

View file

@ -116,7 +116,6 @@ void ArrayPrototype::initialize(Realm& realm)
static ThrowCompletionOr<Object*> array_species_create(VM& vm, Object& original_array, size_t length)
{
auto& realm = *vm.current_realm();
auto& global_object = realm.global_object();
auto is_array = TRY(Value(&original_array).is_array(vm));
@ -127,7 +126,7 @@ static ThrowCompletionOr<Object*> array_species_create(VM& vm, Object& original_
if (constructor.is_constructor()) {
auto& constructor_function = constructor.as_function();
auto* this_realm = vm.current_realm();
auto* constructor_realm = TRY(get_function_realm(global_object, constructor_function));
auto* constructor_realm = TRY(get_function_realm(vm, constructor_function));
if (constructor_realm != this_realm) {
if (&constructor_function == constructor_realm->global_object().array_constructor())
constructor = js_undefined();
@ -146,14 +145,14 @@ static ThrowCompletionOr<Object*> array_species_create(VM& vm, Object& original_
if (!constructor.is_constructor())
return vm.throw_completion<TypeError>(ErrorType::NotAConstructor, constructor.to_string_without_side_effects());
return TRY(construct(global_object, constructor.as_function(), Value(length)));
return TRY(construct(vm, constructor.as_function(), Value(length)));
}
// 23.1.3.1 Array.prototype.at ( index ), https://tc39.es/ecma262/#sec-array.prototype.at
JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::at)
{
auto* this_object = TRY(vm.this_value().to_object(vm));
auto length = TRY(length_of_array_like(global_object, *this_object));
auto length = TRY(length_of_array_like(vm, *this_object));
auto relative_index = TRY(vm.argument(0).to_integer_or_infinity(vm));
if (Value(relative_index).is_infinity())
return js_undefined();
@ -196,7 +195,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::concat)
VERIFY(arg.is_object());
Object& obj = arg.as_object();
size_t k = 0;
auto length = TRY(length_of_array_like(global_object, obj));
auto length = TRY(length_of_array_like(vm, obj));
if (n + length > MAX_ARRAY_LIKE_INDEX)
return vm.throw_completion<TypeError>(ErrorType::ArrayMaxSize);
@ -231,7 +230,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::concat)
JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::copy_within)
{
auto* this_object = TRY(vm.this_value().to_object(vm));
auto length = TRY(length_of_array_like(global_object, *this_object));
auto length = TRY(length_of_array_like(vm, *this_object));
auto relative_target = TRY(vm.argument(0).to_integer_or_infinity(vm));
@ -313,7 +312,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::every)
auto* object = TRY(vm.this_value().to_object(vm));
// 2. Let len be ? LengthOfArrayLike(O).
auto length = TRY(length_of_array_like(global_object, *object));
auto length = TRY(length_of_array_like(vm, *object));
// 3. If IsCallable(callbackfn) is false, throw a TypeError exception.
if (!callback_function.is_function())
@ -334,7 +333,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::every)
auto k_value = TRY(object->get(property_key));
// ii. Let testResult be ToBoolean(? Call(callbackfn, thisArg, « kValue, 𝔽(k), O »)).
auto test_result = TRY(call(global_object, callback_function.as_function(), this_arg, k_value, Value(k), object)).to_boolean();
auto test_result = TRY(call(vm, callback_function.as_function(), this_arg, k_value, Value(k), object)).to_boolean();
// iii. If testResult is false, return false.
if (!test_result)
@ -353,7 +352,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::fill)
{
auto* this_object = TRY(vm.this_value().to_object(vm));
auto length = TRY(length_of_array_like(global_object, *this_object));
auto length = TRY(length_of_array_like(vm, *this_object));
double relative_start = 0;
double relative_end = length;
@ -399,7 +398,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::filter)
auto* object = TRY(vm.this_value().to_object(vm));
// 2. Let len be ? LengthOfArrayLike(O).
auto length = TRY(length_of_array_like(global_object, *object));
auto length = TRY(length_of_array_like(vm, *object));
// 3. If IsCallable(callbackfn) is false, throw a TypeError exception.
if (!callback_function.is_function())
@ -428,7 +427,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::filter)
auto k_value = TRY(object->get(k));
// ii. Let selected be ToBoolean(? Call(callbackfn, thisArg, « kValue, 𝔽(k), O »)).
auto selected = TRY(call(global_object, callback_function.as_function(), this_arg, k_value, Value(k), object)).to_boolean();
auto selected = TRY(call(vm, callback_function.as_function(), this_arg, k_value, Value(k), object)).to_boolean();
// iii. If selected is true, then
if (selected) {
@ -457,7 +456,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::find)
auto* object = TRY(vm.this_value().to_object(vm));
// 2. Let len be ? LengthOfArrayLike(O).
auto length = TRY(length_of_array_like(global_object, *object));
auto length = TRY(length_of_array_like(vm, *object));
// 3. If IsCallable(predicate) is false, throw a TypeError exception.
if (!predicate.is_function())
@ -473,7 +472,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::find)
auto k_value = TRY(object->get(property_key));
// c. Let testResult be ToBoolean(? Call(predicate, thisArg, « kValue, 𝔽(k), O »)).
auto test_result = TRY(call(global_object, predicate.as_function(), this_arg, k_value, Value(k), object)).to_boolean();
auto test_result = TRY(call(vm, predicate.as_function(), this_arg, k_value, Value(k), object)).to_boolean();
// d. If testResult is true, return kValue.
if (test_result)
@ -496,7 +495,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::find_index)
auto* object = TRY(vm.this_value().to_object(vm));
// 2. Let len be ? LengthOfArrayLike(O).
auto length = TRY(length_of_array_like(global_object, *object));
auto length = TRY(length_of_array_like(vm, *object));
// 3. If IsCallable(predicate) is false, throw a TypeError exception.
if (!predicate.is_function())
@ -512,7 +511,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::find_index)
auto k_value = TRY(object->get(property_key));
// c. Let testResult be ToBoolean(? Call(predicate, thisArg, « kValue, 𝔽(k), O »)).
auto test_result = TRY(call(global_object, predicate.as_function(), this_arg, k_value, Value(k), object)).to_boolean();
auto test_result = TRY(call(vm, predicate.as_function(), this_arg, k_value, Value(k), object)).to_boolean();
// d. If testResult is true, return 𝔽(k).
if (test_result)
@ -535,7 +534,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::find_last)
auto* object = TRY(vm.this_value().to_object(vm));
// 2. Let len be ? LengthOfArrayLike(O).
auto length = TRY(length_of_array_like(global_object, *object));
auto length = TRY(length_of_array_like(vm, *object));
// 3. If IsCallable(predicate) is false, throw a TypeError exception.
if (!predicate.is_function())
@ -551,7 +550,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::find_last)
auto k_value = TRY(object->get(property_key));
// c. Let testResult be ToBoolean(? Call(predicate, thisArg, « kValue, 𝔽(k), O »)).
auto test_result = TRY(call(global_object, predicate.as_function(), this_arg, k_value, Value((double)k), object)).to_boolean();
auto test_result = TRY(call(vm, predicate.as_function(), this_arg, k_value, Value((double)k), object)).to_boolean();
// d. If testResult is true, return kValue.
if (test_result)
@ -574,7 +573,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::find_last_index)
auto* object = TRY(vm.this_value().to_object(vm));
// 2. Let len be ? LengthOfArrayLike(O).
auto length = TRY(length_of_array_like(global_object, *object));
auto length = TRY(length_of_array_like(vm, *object));
// 3. If IsCallable(predicate) is false, throw a TypeError exception.
if (!predicate.is_function())
@ -590,7 +589,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::find_last_index)
auto k_value = TRY(object->get(property_key));
// c. Let testResult be ToBoolean(? Call(predicate, thisArg, « kValue, 𝔽(k), O »)).
auto test_result = TRY(call(global_object, predicate.as_function(), this_arg, k_value, Value((double)k), object)).to_boolean();
auto test_result = TRY(call(vm, predicate.as_function(), this_arg, k_value, Value((double)k), object)).to_boolean();
// d. If testResult is true, return 𝔽(k).
if (test_result)
@ -607,8 +606,6 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::find_last_index)
static ThrowCompletionOr<size_t> flatten_into_array(VM& vm, Object& new_array, Object& array, size_t array_length, size_t target_index, double depth, FunctionObject* mapper_func = {}, Value this_arg = {})
{
VERIFY(!mapper_func || (!this_arg.is_empty() && depth == 1));
auto& realm = *vm.current_realm();
auto& global_object = realm.global_object();
for (size_t j = 0; j < array_length; ++j) {
auto value_exists = TRY(array.has_property(j));
@ -618,13 +615,13 @@ static ThrowCompletionOr<size_t> flatten_into_array(VM& vm, Object& new_array, O
auto value = TRY(array.get(j));
if (mapper_func)
value = TRY(call(global_object, *mapper_func, this_arg, value, Value(j), &array));
value = TRY(call(vm, *mapper_func, this_arg, value, Value(j), &array));
if (depth > 0 && TRY(value.is_array(vm))) {
if (vm.did_reach_stack_space_limit())
return vm.throw_completion<InternalError>(ErrorType::CallStackSizeExceeded);
auto length = TRY(length_of_array_like(global_object, value.as_object()));
auto length = TRY(length_of_array_like(vm, value.as_object()));
target_index = TRY(flatten_into_array(vm, new_array, value.as_object(), length, target_index, depth - 1));
continue;
}
@ -644,7 +641,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::flat)
{
auto* this_object = TRY(vm.this_value().to_object(vm));
auto length = TRY(length_of_array_like(global_object, *this_object));
auto length = TRY(length_of_array_like(vm, *this_object));
double depth = 1;
if (!vm.argument(0).is_undefined()) {
@ -668,7 +665,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::flat_map)
auto* object = TRY(vm.this_value().to_object(vm));
// 2. Let sourceLen be ? LengthOfArrayLike(O).
auto source_length = TRY(length_of_array_like(global_object, *object));
auto source_length = TRY(length_of_array_like(vm, *object));
// 3. If IsCallable(mapperFunction) is false, throw a TypeError exception.
if (!mapper_function.is_function())
@ -694,7 +691,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::for_each)
auto* object = TRY(vm.this_value().to_object(vm));
// 2. Let len be ? LengthOfArrayLike(O).
auto length = TRY(length_of_array_like(global_object, *object));
auto length = TRY(length_of_array_like(vm, *object));
// 3. If IsCallable(callbackfn) is false, throw a TypeError exception.
if (!callback_function.is_function())
@ -715,7 +712,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::for_each)
auto k_value = TRY(object->get(property_key));
// ii. Perform ? Call(callbackfn, thisArg, « kValue, 𝔽(k), O »).
TRY(call(global_object, callback_function.as_function(), this_arg, k_value, Value(k), object));
TRY(call(vm, callback_function.as_function(), this_arg, k_value, Value(k), object));
}
// d. Set k to k + 1.
@ -765,7 +762,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::group)
auto* this_object = TRY(vm.this_value().to_object(vm));
// 2. Let len be ? LengthOfArrayLike(O).
auto length = TRY(length_of_array_like(global_object, *this_object));
auto length = TRY(length_of_array_like(vm, *this_object));
// 3. If IsCallable(callbackfn) is false, throw a TypeError exception.
if (!callback_function.is_function())
@ -784,7 +781,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::group)
auto k_value = TRY(this_object->get(index_property));
// c. Let propertyKey be ? ToPropertyKey(? Call(callbackfn, thisArg, « kValue, 𝔽(k), O »)).
auto property_key_value = TRY(call(global_object, callback_function.as_function(), this_arg, k_value, Value(index), this_object));
auto property_key_value = TRY(call(vm, callback_function.as_function(), this_arg, k_value, Value(index), this_object));
auto property_key = TRY(property_key_value.to_property_key(vm));
// d. Perform AddValueToKeyedGroup(groups, propertyKey, kValue).
@ -821,7 +818,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::group_to_map)
auto* this_object = TRY(vm.this_value().to_object(vm));
// 2. Let len be ? LengthOfArrayLike(O).
auto length = TRY(length_of_array_like(global_object, *this_object));
auto length = TRY(length_of_array_like(vm, *this_object));
// 3. If IsCallable(callbackfn) is false, throw a TypeError exception.
if (!callback_function.is_function())
@ -853,7 +850,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::group_to_map)
auto k_value = TRY(this_object->get(index_property));
// c. Let key be ? Call(callbackfn, thisArg, « kValue, 𝔽(k), O »).
auto key = TRY(call(global_object, callback_function.as_function(), this_arg, k_value, Value(index), this_object));
auto key = TRY(call(vm, callback_function.as_function(), this_arg, k_value, Value(index), this_object));
// d. If key is -0𝔽, set key to +0𝔽.
if (key.is_negative_zero())
@ -886,7 +883,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::group_to_map)
JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::includes)
{
auto* this_object = TRY(vm.this_value().to_object(vm));
auto length = TRY(length_of_array_like(global_object, *this_object));
auto length = TRY(length_of_array_like(vm, *this_object));
if (length == 0)
return Value(false);
u64 from_index = 0;
@ -923,7 +920,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::index_of)
auto* object = TRY(vm.this_value().to_object(vm));
// 2. Let len be ? LengthOfArrayLike(O).
auto length = TRY(length_of_array_like(global_object, *object));
auto length = TRY(length_of_array_like(vm, *object));
// 3. If len is 0, return -1𝔽.
if (length == 0)
@ -1000,7 +997,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::join)
s_array_join_seen_objects.remove(this_object);
};
auto length = TRY(length_of_array_like(global_object, *this_object));
auto length = TRY(length_of_array_like(vm, *this_object));
String separator = ",";
if (!vm.argument(0).is_undefined())
separator = TRY(vm.argument(0).to_string(vm));
@ -1038,7 +1035,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::last_index_of)
auto* object = TRY(vm.this_value().to_object(vm));
// 2. Let len be ? LengthOfArrayLike(O).
auto length = TRY(length_of_array_like(global_object, *object));
auto length = TRY(length_of_array_like(vm, *object));
// 3. If len is 0, return -1𝔽.
if (length == 0)
@ -1106,7 +1103,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::map)
auto* object = TRY(vm.this_value().to_object(vm));
// 2. Let len be ? LengthOfArrayLike(O).
auto length = TRY(length_of_array_like(global_object, *object));
auto length = TRY(length_of_array_like(vm, *object));
// 3. If IsCallable(callbackfn) is false, throw a TypeError exception.
if (!callback_function.is_function())
@ -1130,7 +1127,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::map)
auto k_value = TRY(object->get(property_key));
// ii. Let mappedValue be ? Call(callbackfn, thisArg, « kValue, 𝔽(k), O »).
auto mapped_value = TRY(call(global_object, callback_function.as_function(), this_arg, k_value, Value(k), object));
auto mapped_value = TRY(call(vm, callback_function.as_function(), this_arg, k_value, Value(k), object));
// iii. Perform ? CreateDataPropertyOrThrow(A, Pk, mappedValue).
TRY(array->create_data_property_or_throw(property_key, mapped_value));
@ -1147,7 +1144,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::map)
JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::pop)
{
auto* this_object = TRY(vm.this_value().to_object(vm));
auto length = TRY(length_of_array_like(global_object, *this_object));
auto length = TRY(length_of_array_like(vm, *this_object));
if (length == 0) {
TRY(this_object->set(vm.names.length, Value(0), Object::ShouldThrowExceptions::Yes));
return js_undefined();
@ -1163,7 +1160,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::pop)
JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::push)
{
auto* this_object = TRY(vm.this_value().to_object(vm));
auto length = TRY(length_of_array_like(global_object, *this_object));
auto length = TRY(length_of_array_like(vm, *this_object));
auto argument_count = vm.argument_count();
auto new_length = length + argument_count;
if (new_length > MAX_ARRAY_LIKE_INDEX)
@ -1185,7 +1182,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::reduce)
auto* object = TRY(vm.this_value().to_object(vm));
// 2. Let len be ? LengthOfArrayLike(O).
auto length = TRY(length_of_array_like(global_object, *object));
auto length = TRY(length_of_array_like(vm, *object));
// 3. If IsCallable(callbackfn) is false, throw a TypeError exception.
if (!callback_function.is_function())
@ -1247,7 +1244,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::reduce)
auto k_value = TRY(object->get(property_key));
// ii. Set accumulator to ? Call(callbackfn, undefined, « accumulator, kValue, 𝔽(k), O »).
accumulator = TRY(call(global_object, callback_function.as_function(), js_undefined(), accumulator, k_value, Value(k), object));
accumulator = TRY(call(vm, callback_function.as_function(), js_undefined(), accumulator, k_value, Value(k), object));
}
// d. Set k to k + 1.
@ -1267,7 +1264,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::reduce_right)
auto* object = TRY(vm.this_value().to_object(vm));
// 2. Let len be ? LengthOfArrayLike(O).
auto length = TRY(length_of_array_like(global_object, *object));
auto length = TRY(length_of_array_like(vm, *object));
// 3. If IsCallable(callbackfn) is false, throw a TypeError exception.
if (!callback_function.is_function())
@ -1329,7 +1326,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::reduce_right)
auto k_value = TRY(object->get(property_key));
// ii. Set accumulator to ? Call(callbackfn, undefined, « accumulator, kValue, 𝔽(k), O »).
accumulator = TRY(call(global_object, callback_function.as_function(), js_undefined(), accumulator, k_value, Value((size_t)k), object));
accumulator = TRY(call(vm, callback_function.as_function(), js_undefined(), accumulator, k_value, Value((size_t)k), object));
}
// d. Set k to k - 1.
@ -1343,7 +1340,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::reduce_right)
JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::reverse)
{
auto* this_object = TRY(vm.this_value().to_object(vm));
auto length = TRY(length_of_array_like(global_object, *this_object));
auto length = TRY(length_of_array_like(vm, *this_object));
auto middle = length / 2;
for (size_t lower = 0; lower < middle; ++lower) {
@ -1378,7 +1375,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::reverse)
JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::shift)
{
auto* this_object = TRY(vm.this_value().to_object(vm));
auto length = TRY(length_of_array_like(global_object, *this_object));
auto length = TRY(length_of_array_like(vm, *this_object));
if (length == 0) {
TRY(this_object->set(vm.names.length, Value(0), Object::ShouldThrowExceptions::Yes));
return js_undefined();
@ -1406,7 +1403,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::slice)
{
auto* this_object = TRY(vm.this_value().to_object(vm));
auto initial_length = TRY(length_of_array_like(global_object, *this_object));
auto initial_length = TRY(length_of_array_like(vm, *this_object));
auto relative_start = TRY(vm.argument(0).to_integer_or_infinity(vm));
@ -1467,7 +1464,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::some)
auto* object = TRY(vm.this_value().to_object(vm));
// 2. Let len be ? LengthOfArrayLike(O).
auto length = TRY(length_of_array_like(global_object, *object));
auto length = TRY(length_of_array_like(vm, *object));
// 3. If IsCallable(callbackfn) is false, throw a TypeError exception.
if (!callback_function.is_function())
@ -1488,7 +1485,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::some)
auto k_value = TRY(object->get(property_key));
// ii. Let testResult be ToBoolean(? Call(callbackfn, thisArg, « kValue, 𝔽(k), O »)).
auto test_result = TRY(call(global_object, callback_function.as_function(), this_arg, k_value, Value(k), object)).to_boolean();
auto test_result = TRY(call(vm, callback_function.as_function(), this_arg, k_value, Value(k), object)).to_boolean();
// iii. If testResult is true, return true.
if (test_result)
@ -1571,7 +1568,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::sort)
auto* object = TRY(vm.this_value().to_object(vm));
// 3. Let len be ? LengthOfArrayLike(obj).
auto length = TRY(length_of_array_like(global_object, *object));
auto length = TRY(length_of_array_like(vm, *object));
// 4. 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> {
@ -1612,7 +1609,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::splice)
{
auto* this_object = TRY(vm.this_value().to_object(vm));
auto initial_length = TRY(length_of_array_like(global_object, *this_object));
auto initial_length = TRY(length_of_array_like(vm, *this_object));
auto relative_start = TRY(vm.argument(0).to_integer_or_infinity(vm));
@ -1712,7 +1709,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::to_locale_string)
};
// 2. Let len be ? ToLength(? Get(array, "length")).
auto length = TRY(length_of_array_like(global_object, *this_object));
auto length = TRY(length_of_array_like(vm, *this_object));
// 3. Let separator be the implementation-defined list-separator String value appropriate for the host environment's current locale (such as ", ").
constexpr auto separator = ","sv;
@ -1758,7 +1755,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::to_reversed)
auto* object = TRY(vm.this_value().to_object(vm));
// 2. Let len be ? LengthOfArrayLike(O).
auto length = TRY(length_of_array_like(global_object, *object));
auto length = TRY(length_of_array_like(vm, *object));
// 3. Let A be ? ArrayCreate(𝔽(len)).
auto* array = TRY(Array::create(realm, length));
@ -1800,7 +1797,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::to_sorted)
auto* object = TRY(vm.this_value().to_object(vm));
// 3. Let len be ? LengthOfArrayLike(O).
auto length = TRY(length_of_array_like(global_object, *object));
auto length = TRY(length_of_array_like(vm, *object));
// 4. Let A be ? ArrayCreate(𝔽(len)).
auto* array = TRY(Array::create(realm, length));
@ -1839,7 +1836,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::to_spliced)
auto* object = TRY(vm.this_value().to_object(vm));
// 2. Let len be ? LengthOfArrayLike(O).
auto length = TRY(length_of_array_like(global_object, *object));
auto length = TRY(length_of_array_like(vm, *object));
// 3. Let relativeStart be ? ToIntegerOrInfinity(start).
auto relative_start = TRY(start.to_integer_or_infinity(vm));
@ -1972,14 +1969,14 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::to_string)
func = global_object.object_prototype_to_string_function();
// 4. Return ? Call(func, array).
return TRY(call(global_object, func.as_function(), array));
return TRY(call(vm, func.as_function(), array));
}
// 23.1.3.34 Array.prototype.unshift ( ...items ), https://tc39.es/ecma262/#sec-array.prototype.unshift
JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::unshift)
{
auto* this_object = TRY(vm.this_value().to_object(vm));
auto length = TRY(length_of_array_like(global_object, *this_object));
auto length = TRY(length_of_array_like(vm, *this_object));
auto arg_count = vm.argument_count();
size_t new_length = length + arg_count;
if (arg_count > 0) {
@ -2029,7 +2026,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::with)
auto* object = TRY(vm.this_value().to_object(vm));
// 2. Let len be ? LengthOfArrayLike(O).
auto length = TRY(length_of_array_like(global_object, *object));
auto length = TRY(length_of_array_like(vm, *object));
// 3. Let relativeIndex be ? ToIntegerOrInfinity(index).
auto relative_index = TRY(index.to_integer_or_infinity(vm));

View file

@ -117,7 +117,7 @@ JS_DEFINE_NATIVE_FUNCTION(AsyncFromSyncIteratorPrototype::return_)
auto* iter_result = create_iterator_result_object(vm, vm.argument(0), true);
// b. Perform ! Call(promiseCapability.[[Resolve]], undefined, « iterResult »).
MUST(call(global_object, *promise_capability.reject, js_undefined(), iter_result));
MUST(call(vm, *promise_capability.reject, js_undefined(), iter_result));
// c. Return promiseCapability.[[Promise]].
return promise_capability.promise;
@ -129,14 +129,14 @@ JS_DEFINE_NATIVE_FUNCTION(AsyncFromSyncIteratorPrototype::return_)
// a. Let result be Completion(Call(return, syncIterator)).
// 10. IfAbruptRejectPromise(result, promiseCapability).
auto result = TRY_OR_REJECT(vm, promise_capability,
(vm.argument_count() > 0 ? call(global_object, return_method, sync_iterator, vm.argument(0))
: call(global_object, return_method, sync_iterator)));
(vm.argument_count() > 0 ? call(vm, return_method, sync_iterator, vm.argument(0))
: call(vm, return_method, sync_iterator)));
// 11. If Type(result) is not Object, then
if (!result.is_object()) {
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));
MUST(call(vm, *promise_capability.reject, js_undefined(), error));
// b. Return promiseCapability.[[Promise]].
return promise_capability.promise;
}
@ -167,7 +167,7 @@ JS_DEFINE_NATIVE_FUNCTION(AsyncFromSyncIteratorPrototype::throw_)
// 7. If throw is undefined, then
if (throw_method == nullptr) {
// a. Perform ! Call(promiseCapability.[[Reject]], undefined, « value »).
MUST(call(global_object, *promise_capability.reject, js_undefined(), vm.argument(0)));
MUST(call(vm, *promise_capability.reject, js_undefined(), vm.argument(0)));
// b. Return promiseCapability.[[Promise]].
return promise_capability.promise;
}
@ -177,14 +177,14 @@ JS_DEFINE_NATIVE_FUNCTION(AsyncFromSyncIteratorPrototype::throw_)
// a. Let result be Completion(Call(throw, syncIterator)).
// 10. IfAbruptRejectPromise(result, promiseCapability).
auto result = TRY_OR_REJECT(vm, promise_capability,
(vm.argument_count() > 0 ? call(global_object, throw_method, sync_iterator, vm.argument(0))
: call(global_object, throw_method, sync_iterator)));
(vm.argument_count() > 0 ? call(vm, throw_method, sync_iterator, vm.argument(0))
: call(vm, throw_method, sync_iterator)));
// 11. If Type(result) is not Object, then
if (!result.is_object()) {
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));
MUST(call(vm, *promise_capability.reject, js_undefined(), error));
// b. Return promiseCapability.[[Promise]].
return promise_capability.promise;

View file

@ -70,7 +70,7 @@ JS_DEFINE_NATIVE_FUNCTION(BigIntPrototype::to_locale_string)
auto* bigint = TRY(this_bigint_value(global_object, vm.this_value()));
// 2. Let numberFormat be ? Construct(%NumberFormat%, « locales, options »).
auto* number_format = static_cast<Intl::NumberFormat*>(TRY(construct(global_object, *global_object.intl_number_format_constructor(), locales, options)));
auto* number_format = static_cast<Intl::NumberFormat*>(TRY(construct(vm, *global_object.intl_number_format_constructor(), locales, options)));
// 3. Return ? FormatNumeric(numberFormat, x).
auto formatted = Intl::format_numeric(vm, *number_format, Value(bigint));

View file

@ -40,10 +40,9 @@ ThrowCompletionOr<Value> BooleanConstructor::call()
ThrowCompletionOr<Object*> BooleanConstructor::construct(FunctionObject& new_target)
{
auto& vm = this->vm();
auto& global_object = this->global_object();
auto b = vm.argument(0).to_boolean();
return TRY(ordinary_create_from_constructor<BooleanObject>(global_object, new_target, &GlobalObject::boolean_prototype, b));
return TRY(ordinary_create_from_constructor<BooleanObject>(vm, new_target, &GlobalObject::boolean_prototype, b));
}
}

View file

@ -45,6 +45,8 @@ BoundFunction::BoundFunction(Realm& realm, FunctionObject& bound_target_function
// 10.4.1.1 [[Call]] ( thisArgument, argumentsList ), https://tc39.es/ecma262/#sec-bound-function-exotic-objects-call-thisargument-argumentslist
ThrowCompletionOr<Value> BoundFunction::internal_call([[maybe_unused]] Value this_argument, MarkedVector<Value> arguments_list)
{
auto& vm = this->vm();
// 1. Let target be F.[[BoundTargetFunction]].
auto& target = *m_bound_target_function;
@ -60,12 +62,14 @@ ThrowCompletionOr<Value> BoundFunction::internal_call([[maybe_unused]] Value thi
args.extend(move(arguments_list));
// 5. Return ? Call(target, boundThis, args).
return call(global_object(), &target, bound_this, move(args));
return call(vm, &target, bound_this, move(args));
}
// 10.4.1.2 [[Construct]] ( argumentsList, newTarget ), https://tc39.es/ecma262/#sec-bound-function-exotic-objects-construct-argumentslist-newtarget
ThrowCompletionOr<Object*> BoundFunction::internal_construct(MarkedVector<Value> arguments_list, FunctionObject& new_target)
{
auto& vm = this->vm();
// 1. Let target be F.[[BoundTargetFunction]].
auto& target = *m_bound_target_function;
@ -86,7 +90,7 @@ ThrowCompletionOr<Object*> BoundFunction::internal_construct(MarkedVector<Value>
final_new_target = &target;
// 6. Return ? Construct(target, args, newTarget).
return construct(global_object(), target, move(args), final_new_target);
return construct(vm, target, move(args), final_new_target);
}
void BoundFunction::visit_edges(Visitor& visitor)

View file

@ -40,7 +40,6 @@ ThrowCompletionOr<Value> DataViewConstructor::call()
ThrowCompletionOr<Object*> DataViewConstructor::construct(FunctionObject& new_target)
{
auto& vm = this->vm();
auto& global_object = this->global_object();
auto buffer = vm.argument(0);
if (!buffer.is_object() || !is<ArrayBuffer>(buffer.as_object()))
@ -67,7 +66,7 @@ ThrowCompletionOr<Object*> DataViewConstructor::construct(FunctionObject& new_ta
return vm.throw_completion<RangeError>(ErrorType::InvalidLength, vm.names.DataView);
}
auto* data_view = TRY(ordinary_create_from_constructor<DataView>(global_object, new_target, &GlobalObject::data_view_prototype, &array_buffer, view_byte_length, offset));
auto* data_view = TRY(ordinary_create_from_constructor<DataView>(vm, new_target, &GlobalObject::data_view_prototype, &array_buffer, view_byte_length, offset));
if (array_buffer.is_detached())
return vm.throw_completion<TypeError>(ErrorType::DetachedArrayBuffer);

View file

@ -287,7 +287,7 @@ ThrowCompletionOr<Object*> DateConstructor::construct(FunctionObject& new_target
// 6. Let O be ? OrdinaryCreateFromConstructor(NewTarget, "%Date.prototype%", « [[DateValue]] »).
// 7. Set O.[[DateValue]] to dv.
// 8. Return O.
return TRY(ordinary_create_from_constructor<Date>(global_object, new_target, &GlobalObject::date_prototype, date_value));
return TRY(ordinary_create_from_constructor<Date>(vm, new_target, &GlobalObject::date_prototype, date_value));
}
// 21.4.3.1 Date.now ( ), https://tc39.es/ecma262/#sec-date.now

View file

@ -987,7 +987,7 @@ static ThrowCompletionOr<Intl::DateTimeFormat*> construct_date_time_format(VM& v
{
auto& realm = *vm.current_realm();
auto& global_object = realm.global_object();
auto* date_time_format = TRY(construct(global_object, *global_object.intl_date_time_format_constructor(), locales, options));
auto* date_time_format = TRY(construct(vm, *global_object.intl_date_time_format_constructor(), locales, options));
return static_cast<Intl::DateTimeFormat*>(date_time_format);
}

View file

@ -196,7 +196,6 @@ ThrowCompletionOr<Value> ECMAScriptFunctionObject::internal_call(Value this_argu
ThrowCompletionOr<Object*> ECMAScriptFunctionObject::internal_construct(MarkedVector<Value> arguments_list, FunctionObject& new_target)
{
auto& vm = this->vm();
auto& global_object = this->global_object();
// 1. Let callerContext be the running execution context.
// NOTE: No-op, kept by the VM in its execution context stack.
@ -209,7 +208,7 @@ ThrowCompletionOr<Object*> ECMAScriptFunctionObject::internal_construct(MarkedVe
// 3. If kind is base, then
if (kind == ConstructorKind::Base) {
// a. Let thisArgument be ? OrdinaryCreateFromConstructor(newTarget, "%Object.prototype%").
this_argument = TRY(ordinary_create_from_constructor<Object>(global_object, new_target, &GlobalObject::object_prototype));
this_argument = TRY(ordinary_create_from_constructor<Object>(vm, new_target, &GlobalObject::object_prototype));
}
ExecutionContext callee_context(heap());
@ -409,9 +408,9 @@ ThrowCompletionOr<void> ECMAScriptFunctionObject::function_declaration_instantia
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(vm, 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(vm, *this, formal_parameters(), vm.running_execution_context().arguments, *environment);
if (is_strict_mode())
MUST(environment->create_immutable_binding(vm, vm.names.arguments.as_string(), false));
@ -728,7 +727,7 @@ void async_block_start(VM& vm, NonnullRefPtr<Statement> const& async_body, Promi
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(realm, "", [&async_body, &promise_capability](auto& vm, auto& global_object) -> ThrowCompletionOr<Value> {
auto* execution_steps = NativeFunction::create(realm, "", [&async_body, &promise_capability](auto& vm, auto&) -> ThrowCompletionOr<Value> {
// a. Let result be the result of evaluating asyncBody.
auto result = async_body->execute(vm.interpreter());
@ -740,12 +739,12 @@ void async_block_start(VM& vm, NonnullRefPtr<Statement> const& async_body, Promi
// d. If result.[[Type]] is normal, then
if (result.type() == Completion::Type::Normal) {
// i. Perform ! Call(promiseCapability.[[Resolve]], undefined, « undefined »).
MUST(call(global_object, promise_capability.resolve, js_undefined(), js_undefined()));
MUST(call(vm, promise_capability.resolve, js_undefined(), js_undefined()));
}
// e. Else if result.[[Type]] is return, then
else if (result.type() == Completion::Type::Return) {
// i. Perform ! Call(promiseCapability.[[Resolve]], undefined, « result.[[Value]] »).
MUST(call(global_object, promise_capability.resolve, js_undefined(), *result.value()));
MUST(call(vm, promise_capability.resolve, js_undefined(), *result.value()));
}
// f. Else,
else {
@ -753,7 +752,7 @@ void async_block_start(VM& vm, NonnullRefPtr<Statement> const& async_body, Promi
VERIFY(result.type() == Completion::Type::Throw);
// ii. Perform ! Call(promiseCapability.[[Reject]], undefined, « result.[[Value]] »).
MUST(call(global_object, promise_capability.reject, js_undefined(), *result.value()));
MUST(call(vm, promise_capability.reject, js_undefined(), *result.value()));
}
// g. Return unused.
// NOTE: We don't support returning an empty/optional/unused value here.
@ -766,7 +765,7 @@ void async_block_start(VM& vm, NonnullRefPtr<Statement> const& async_body, Promi
return;
// 5. Resume the suspended evaluation of asyncContext. Let result be the value returned by the resumed computation.
auto result = call(global_object, *execution_steps, async_context.this_value.is_empty() ? js_undefined() : async_context.this_value);
auto result = call(vm, *execution_steps, async_context.this_value.is_empty() ? js_undefined() : async_context.this_value);
// 6. Assert: When we return here, asyncContext has already been removed from the execution context stack and runningContext is the currently running execution context.
VERIFY(&vm.running_execution_context() == &running_context);
@ -875,7 +874,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(vm, promise_capability.reject, js_undefined(), *declaration_result.throw_completion().value()));
}
// 4. Else,
else {

View file

@ -38,13 +38,12 @@ ThrowCompletionOr<Value> ErrorConstructor::call()
ThrowCompletionOr<Object*> ErrorConstructor::construct(FunctionObject& new_target)
{
auto& vm = this->vm();
auto& global_object = this->global_object();
auto message = vm.argument(0);
auto options = vm.argument(1);
// 2. Let O be ? OrdinaryCreateFromConstructor(newTarget, "%Error.prototype%", « [[ErrorData]] »).
auto* error = TRY(ordinary_create_from_constructor<Error>(global_object, new_target, &GlobalObject::error_prototype));
auto* error = TRY(ordinary_create_from_constructor<Error>(vm, new_target, &GlobalObject::error_prototype));
// 3. If message is not undefined, then
if (!message.is_undefined()) {
@ -92,13 +91,12 @@ ThrowCompletionOr<Object*> ErrorConstructor::construct(FunctionObject& new_targe
ThrowCompletionOr<Object*> ConstructorName::construct(FunctionObject& new_target) \
{ \
auto& vm = this->vm(); \
auto& global_object = this->global_object(); \
\
auto message = vm.argument(0); \
auto options = vm.argument(1); \
\
/* 2. Let O be ? OrdinaryCreateFromConstructor(newTarget, "%NativeError.prototype%", « [[ErrorData]] »). */ \
auto* error = TRY(ordinary_create_from_constructor<ClassName>(global_object, new_target, &GlobalObject::snake_name##_prototype)); \
auto* error = TRY(ordinary_create_from_constructor<ClassName>(vm, new_target, &GlobalObject::snake_name##_prototype)); \
\
/* 3. If message is not undefined, then */ \
if (!message.is_undefined()) { \

View file

@ -40,7 +40,6 @@ ThrowCompletionOr<Value> FinalizationRegistryConstructor::call()
ThrowCompletionOr<Object*> FinalizationRegistryConstructor::construct(FunctionObject& new_target)
{
auto& vm = this->vm();
auto& global_object = this->global_object();
// NOTE: Step 1 is implemented in FinalizationRegistryConstructor::call()
@ -57,7 +56,7 @@ ThrowCompletionOr<Object*> FinalizationRegistryConstructor::construct(FunctionOb
// 7. Set finalizationRegistry.[[Cells]] to a new empty List.
// NOTE: This is done inside FinalizationRegistry instead of here.
// 8. Return finalizationRegistry.
return TRY(ordinary_create_from_constructor<FinalizationRegistry>(global_object, new_target, &GlobalObject::finalization_registry_prototype, *realm(), vm.host_make_job_callback(cleanup_callback.as_function())));
return TRY(ordinary_create_from_constructor<FinalizationRegistry>(vm, new_target, &GlobalObject::finalization_registry_prototype, *realm(), vm.host_make_job_callback(cleanup_callback.as_function())));
}
}

View file

@ -214,7 +214,7 @@ ThrowCompletionOr<ECMAScriptFunctionObject*> FunctionConstructor::create_dynamic
}
// 24. Let proto be ? GetPrototypeFromConstructor(newTarget, fallbackProto).
auto* prototype = TRY(get_prototype_from_constructor(global_object, *new_target, fallback_prototype));
auto* prototype = TRY(get_prototype_from_constructor(vm, *new_target, fallback_prototype));
// 25. Let realmF be the current Realm Record.
auto& realm = *vm.current_realm();

View file

@ -66,16 +66,16 @@ JS_DEFINE_NATIVE_FUNCTION(FunctionPrototype::apply)
// FIXME: a. Perform PrepareForTailCall().
// b. Return ? Call(func, thisArg).
return TRY(JS::call(global_object, function, this_arg));
return TRY(JS::call(vm, function, this_arg));
}
// 4. Let argList be ? CreateListFromArrayLike(argArray).
auto arguments = TRY(create_list_from_array_like(global_object, arg_array));
auto arguments = TRY(create_list_from_array_like(vm, arg_array));
// FIXME: 5. Perform PrepareForTailCall().
// 6. Return ? Call(func, thisArg, argList).
return TRY(JS::call(global_object, function, this_arg, move(arguments)));
return TRY(JS::call(vm, function, this_arg, move(arguments)));
}
// 20.2.3.2 Function.prototype.bind ( thisArg, ...args ), https://tc39.es/ecma262/#sec-function.prototype.bind
@ -136,7 +136,7 @@ JS_DEFINE_NATIVE_FUNCTION(FunctionPrototype::call)
}
// 4. Return ? Call(func, thisArg, args).
return TRY(JS::call(global_object, function, this_arg, move(arguments)));
return TRY(JS::call(vm, function, this_arg, move(arguments)));
}
// 20.2.3.5 Function.prototype.toString ( ), https://tc39.es/ecma262/#sec-function.prototype.tostring

View file

@ -494,7 +494,7 @@ JS_DEFINE_NATIVE_FUNCTION(GlobalObject::parse_int)
// 19.2.1 eval ( x ), https://tc39.es/ecma262/#sec-eval-x
JS_DEFINE_NATIVE_FUNCTION(GlobalObject::eval)
{
return perform_eval(global_object, vm.argument(0), CallerMode::NonStrict, EvalMode::Indirect);
return perform_eval(vm, vm.argument(0), CallerMode::NonStrict, EvalMode::Indirect);
}
// 19.2.6.1.1 Encode ( string, unescapedSet ), https://tc39.es/ecma262/#sec-encode

View file

@ -160,7 +160,6 @@ ThrowCompletionOr<Value> CollatorConstructor::call()
ThrowCompletionOr<Object*> CollatorConstructor::construct(FunctionObject& new_target)
{
auto& vm = this->vm();
auto& global_object = this->global_object();
auto locales = vm.argument(0);
auto options = vm.argument(1);
@ -172,7 +171,7 @@ ThrowCompletionOr<Object*> CollatorConstructor::construct(FunctionObject& new_ta
// a. Append [[CaseFirst]] as the last element of internalSlotsList.
// 5. Let collator be ? OrdinaryCreateFromConstructor(newTarget, "%Collator.prototype%", internalSlotsList).
auto* collator = TRY(ordinary_create_from_constructor<Collator>(global_object, new_target, &GlobalObject::intl_collator_prototype));
auto* collator = TRY(ordinary_create_from_constructor<Collator>(vm, new_target, &GlobalObject::intl_collator_prototype));
// 6. Return ? InitializeCollator(collator, locales, options).
return TRY(initialize_collator(vm, *collator, locales, options));

View file

@ -546,7 +546,7 @@ ThrowCompletionOr<Vector<PatternPartition>> format_date_time_pattern(VM& vm, Dat
auto const& data_locale = date_time_format.data_locale();
auto construct_number_format = [&](auto* options) -> ThrowCompletionOr<NumberFormat*> {
auto* number_format = TRY(construct(global_object, *global_object.intl_number_format_constructor(), js_string(vm, locale), options));
auto* number_format = TRY(construct(vm, *global_object.intl_number_format_constructor(), js_string(vm, locale), options));
return static_cast<NumberFormat*>(number_format);
};

View file

@ -48,13 +48,12 @@ ThrowCompletionOr<Value> DateTimeFormatConstructor::call()
ThrowCompletionOr<Object*> DateTimeFormatConstructor::construct(FunctionObject& new_target)
{
auto& vm = this->vm();
auto& global_object = this->global_object();
auto locales = vm.argument(0);
auto options = vm.argument(1);
// 2. Let dateTimeFormat be ? OrdinaryCreateFromConstructor(newTarget, "%DateTimeFormat.prototype%", « [[InitializedDateTimeFormat]], [[Locale]], [[Calendar]], [[NumberingSystem]], [[TimeZone]], [[Weekday]], [[Era]], [[Year]], [[Month]], [[Day]], [[DayPeriod]], [[Hour]], [[Minute]], [[Second]], [[FractionalSecondDigits]], [[TimeZoneName]], [[HourCycle]], [[Pattern]], [[BoundFormat]] »).
auto* date_time_format = TRY(ordinary_create_from_constructor<DateTimeFormat>(global_object, new_target, &GlobalObject::intl_date_time_format_prototype));
auto* date_time_format = TRY(ordinary_create_from_constructor<DateTimeFormat>(vm, new_target, &GlobalObject::intl_date_time_format_prototype));
// 3. Perform ? InitializeDateTimeFormat(dateTimeFormat, locales, options).
TRY(initialize_date_time_format(vm, *date_time_format, locales, options));

View file

@ -49,7 +49,7 @@ ThrowCompletionOr<Value> DateTimeFormatFunction::call()
// 3. If date is not provided or is undefined, then
if (date.is_undefined()) {
// a. Let x be ! Call(%Date.now%, undefined).
date_value = MUST(JS::call(global_object, global_object.date_constructor_now_function(), js_undefined())).as_double();
date_value = MUST(JS::call(vm, global_object.date_constructor_now_function(), js_undefined())).as_double();
}
// 4. Else,
else {

View file

@ -76,7 +76,7 @@ JS_DEFINE_NATIVE_FUNCTION(DateTimeFormatPrototype::format_to_parts)
// 3. If date is undefined, then
if (date.is_undefined()) {
// a. Let x be ! Call(%Date.now%, undefined).
date_value = MUST(call(global_object, global_object.date_constructor_now_function(), js_undefined())).as_double();
date_value = MUST(call(vm, global_object.date_constructor_now_function(), js_undefined())).as_double();
}
// 4. Else,
else {

View file

@ -47,13 +47,12 @@ ThrowCompletionOr<Value> DisplayNamesConstructor::call()
ThrowCompletionOr<Object*> DisplayNamesConstructor::construct(FunctionObject& new_target)
{
auto& vm = this->vm();
auto& global_object = this->global_object();
auto locale_value = vm.argument(0);
auto options_value = vm.argument(1);
// 2. Let displayNames be ? OrdinaryCreateFromConstructor(NewTarget, "%DisplayNames.prototype%", « [[InitializedDisplayNames]], [[Locale]], [[Style]], [[Type]], [[Fallback]], [[LanguageDisplay]], [[Fields]] »).
auto* display_names = TRY(ordinary_create_from_constructor<DisplayNames>(global_object, new_target, &GlobalObject::intl_display_names_prototype));
auto* display_names = TRY(ordinary_create_from_constructor<DisplayNames>(vm, new_target, &GlobalObject::intl_display_names_prototype));
// 3. Let requestedLocales be ? CanonicalizeLocaleList(locales).
auto requested_locales = TRY(canonicalize_locale_list(vm, locale_value));

View file

@ -403,7 +403,7 @@ ThrowCompletionOr<Vector<PatternPartition>> partition_duration_format_pattern(VM
}
// o. Let nf be ? Construct(%NumberFormat%, « durationFormat.[[Locale]], nfOpts »).
auto* number_format = static_cast<Intl::NumberFormat*>(TRY(construct(global_object, *global_object.intl_number_format_constructor(), js_string(vm, duration_format.locale()), number_format_options)));
auto* number_format = static_cast<Intl::NumberFormat*>(TRY(construct(vm, *global_object.intl_number_format_constructor(), js_string(vm, duration_format.locale()), number_format_options)));
// FIXME: durationFormat.[[NumberFormat]] is not a thing, the spec likely means 'nf' in this case
// p. Let num be ! FormatNumeric(durationFormat.[[NumberFormat]], value).
@ -432,7 +432,7 @@ ThrowCompletionOr<Vector<PatternPartition>> partition_duration_format_pattern(VM
// t. Else,
else {
// i. Let pr be ? Construct(%PluralRules%, « durationFormat.[[Locale]] »).
auto* plural_rules = TRY(construct(global_object, *global_object.intl_plural_rules_constructor(), js_string(vm, duration_format.locale())));
auto* plural_rules = TRY(construct(vm, *global_object.intl_plural_rules_constructor(), js_string(vm, duration_format.locale())));
// ii. Let prv be ! ResolvePlural(pr, value).
auto plurality = resolve_plural(static_cast<PluralRules&>(*plural_rules), value);
@ -480,7 +480,7 @@ ThrowCompletionOr<Vector<PatternPartition>> partition_duration_format_pattern(VM
}
// 3. Let lf be ? Construct(%ListFormat%, « durationFormat.[[Locale]] »).
auto* list_format = static_cast<Intl::ListFormat*>(TRY(construct(global_object, *global_object.intl_list_format_constructor(), js_string(vm, duration_format.locale()))));
auto* list_format = static_cast<Intl::ListFormat*>(TRY(construct(vm, *global_object.intl_list_format_constructor(), js_string(vm, duration_format.locale()))));
// FIXME: CreatePartsFromList expects a list of strings and creates a list of Pattern Partition records, but we already created a list of Pattern Partition records
// so we try to hack something together from it that looks mostly right

View file

@ -44,13 +44,12 @@ ThrowCompletionOr<Value> DurationFormatConstructor::call()
ThrowCompletionOr<Object*> DurationFormatConstructor::construct(FunctionObject& new_target)
{
auto& vm = this->vm();
auto& global_object = this->global_object();
auto locales = vm.argument(0);
auto options_value = vm.argument(1);
// 2. Let durationFormat be ? OrdinaryCreateFromConstructor(NewTarget, "%DurationFormatPrototype%", « [[InitializedDurationFormat]], [[Locale]], [[DataLocale]], [[NumberingSystem]], [[Style]], [[YearsStyle]], [[YearsDisplay]], [[MonthsStyle]], [[MonthsDisplay]] , [[WeeksStyle]], [[WeeksDisplay]] , [[DaysStyle]], [[DaysDisplay]] , [[HoursStyle]], [[HoursDisplay]] , [[MinutesStyle]], [[MinutesDisplay]] , [[SecondsStyle]], [[SecondsDisplay]] , [[MillisecondsStyle]], [[MillisecondsDisplay]] , [[MicrosecondsStyle]], [[MicrosecondsDisplay]] , [[NanosecondsStyle]], [[NanosecondsDisplay]], [[FractionalDigits]] »).
auto* duration_format = TRY(ordinary_create_from_constructor<DurationFormat>(global_object, new_target, &GlobalObject::intl_duration_format_prototype));
auto* duration_format = TRY(ordinary_create_from_constructor<DurationFormat>(vm, new_target, &GlobalObject::intl_duration_format_prototype));
// 3. Let requestedLocales be ? CanonicalizeLocaleList(locales).
auto requested_locales = TRY(canonicalize_locale_list(vm, locales));

View file

@ -46,13 +46,12 @@ ThrowCompletionOr<Value> ListFormatConstructor::call()
ThrowCompletionOr<Object*> ListFormatConstructor::construct(FunctionObject& new_target)
{
auto& vm = this->vm();
auto& global_object = this->global_object();
auto locale_value = vm.argument(0);
auto options_value = vm.argument(1);
// 2. Let listFormat be ? OrdinaryCreateFromConstructor(NewTarget, "%ListFormat.prototype%", « [[InitializedListFormat]], [[Locale]], [[Type]], [[Style]], [[Templates]] »).
auto* list_format = TRY(ordinary_create_from_constructor<ListFormat>(global_object, new_target, &GlobalObject::intl_list_format_prototype));
auto* list_format = TRY(ordinary_create_from_constructor<ListFormat>(vm, new_target, &GlobalObject::intl_list_format_prototype));
// 3. Let requestedLocales be ? CanonicalizeLocaleList(locales).
auto requested_locales = TRY(canonicalize_locale_list(vm, locale_value));

View file

@ -243,7 +243,6 @@ ThrowCompletionOr<Value> LocaleConstructor::call()
ThrowCompletionOr<Object*> LocaleConstructor::construct(FunctionObject& new_target)
{
auto& vm = this->vm();
auto& global_object = this->global_object();
auto tag_value = vm.argument(0);
auto options_value = vm.argument(1);
@ -258,7 +257,7 @@ ThrowCompletionOr<Object*> LocaleConstructor::construct(FunctionObject& new_targ
// a. Append [[Numeric]] as the last element of internalSlotsList.
// 6. Let locale be ? OrdinaryCreateFromConstructor(NewTarget, "%Locale.prototype%", internalSlotsList).
auto* locale = TRY(ordinary_create_from_constructor<Locale>(global_object, new_target, &GlobalObject::intl_locale_prototype));
auto* locale = TRY(ordinary_create_from_constructor<Locale>(vm, new_target, &GlobalObject::intl_locale_prototype));
String tag;

View file

@ -45,13 +45,12 @@ ThrowCompletionOr<Value> NumberFormatConstructor::call()
ThrowCompletionOr<Object*> NumberFormatConstructor::construct(FunctionObject& new_target)
{
auto& vm = this->vm();
auto& global_object = this->global_object();
auto locales = vm.argument(0);
auto options = vm.argument(1);
// 2. Let numberFormat be ? OrdinaryCreateFromConstructor(newTarget, "%NumberFormat.prototype%", « [[InitializedNumberFormat]], [[Locale]], [[DataLocale]], [[NumberingSystem]], [[Style]], [[Unit]], [[UnitDisplay]], [[Currency]], [[CurrencyDisplay]], [[CurrencySign]], [[MinimumIntegerDigits]], [[MinimumFractionDigits]], [[MaximumFractionDigits]], [[MinimumSignificantDigits]], [[MaximumSignificantDigits]], [[RoundingType]], [[Notation]], [[CompactDisplay]], [[UseGrouping]], [[SignDisplay]], [[BoundFormat]] »).
auto* number_format = TRY(ordinary_create_from_constructor<NumberFormat>(global_object, new_target, &GlobalObject::intl_number_format_prototype));
auto* number_format = TRY(ordinary_create_from_constructor<NumberFormat>(vm, new_target, &GlobalObject::intl_number_format_prototype));
// 3. Perform ? InitializeNumberFormat(numberFormat, locales, options).
TRY(initialize_number_format(vm, *number_format, locales, options));

View file

@ -46,13 +46,12 @@ ThrowCompletionOr<Value> PluralRulesConstructor::call()
ThrowCompletionOr<Object*> PluralRulesConstructor::construct(FunctionObject& new_target)
{
auto& vm = this->vm();
auto& global_object = this->global_object();
auto locales = vm.argument(0);
auto options = vm.argument(1);
// 2. Let pluralRules be ? OrdinaryCreateFromConstructor(NewTarget, "%PluralRules.prototype%", « [[InitializedPluralRules]], [[Locale]], [[Type]], [[MinimumIntegerDigits]], [[MinimumFractionDigits]], [[MaximumFractionDigits]], [[MinimumSignificantDigits]], [[MaximumSignificantDigits]], [[RoundingType]] »).
auto* plural_rules = TRY(ordinary_create_from_constructor<PluralRules>(global_object, new_target, &GlobalObject::intl_plural_rules_prototype));
auto* plural_rules = TRY(ordinary_create_from_constructor<PluralRules>(vm, new_target, &GlobalObject::intl_plural_rules_prototype));
// 3. Return ? InitializePluralRules(pluralRules, locales, options).
return TRY(initialize_plural_rules(vm, *plural_rules, locales, options));

View file

@ -49,13 +49,12 @@ ThrowCompletionOr<Value> RelativeTimeFormatConstructor::call()
ThrowCompletionOr<Object*> RelativeTimeFormatConstructor::construct(FunctionObject& new_target)
{
auto& vm = this->vm();
auto& global_object = this->global_object();
auto locales = vm.argument(0);
auto options = vm.argument(1);
// 2. Let relativeTimeFormat be ? OrdinaryCreateFromConstructor(NewTarget, "%RelativeTimeFormat.prototype%", « [[InitializedRelativeTimeFormat]], [[Locale]], [[DataLocale]], [[Style]], [[Numeric]], [[NumberFormat]], [[NumberingSystem]], [[PluralRules]] »).
auto* relative_time_format = TRY(ordinary_create_from_constructor<RelativeTimeFormat>(global_object, new_target, &GlobalObject::intl_relative_time_format_prototype));
auto* relative_time_format = TRY(ordinary_create_from_constructor<RelativeTimeFormat>(vm, new_target, &GlobalObject::intl_relative_time_format_prototype));
// 3. Return ? InitializeRelativeTimeFormat(relativeTimeFormat, locales, options).
return TRY(initialize_relative_time_format(vm, *relative_time_format, locales, options));
@ -140,11 +139,11 @@ ThrowCompletionOr<RelativeTimeFormat*> initialize_relative_time_format(VM& vm, R
relative_time_format.set_numeric(numeric.as_string().string());
// 19. Let relativeTimeFormat.[[NumberFormat]] be ! Construct(%NumberFormat%, « locale »).
auto* number_format = MUST(construct(global_object, *global_object.intl_number_format_constructor(), js_string(vm, locale)));
auto* number_format = MUST(construct(vm, *global_object.intl_number_format_constructor(), js_string(vm, locale)));
relative_time_format.set_number_format(static_cast<NumberFormat*>(number_format));
// 20. Let relativeTimeFormat.[[PluralRules]] be ! Construct(%PluralRules%, « locale »).
auto* plural_rules = MUST(construct(global_object, *global_object.intl_plural_rules_constructor(), js_string(vm, locale)));
auto* plural_rules = MUST(construct(vm, *global_object.intl_plural_rules_constructor(), js_string(vm, locale)));
relative_time_format.set_plural_rules(static_cast<PluralRules*>(plural_rules));
// 21. Return relativeTimeFormat.

View file

@ -45,14 +45,13 @@ ThrowCompletionOr<Value> SegmenterConstructor::call()
ThrowCompletionOr<Object*> SegmenterConstructor::construct(FunctionObject& new_target)
{
auto& vm = this->vm();
auto& global_object = this->global_object();
auto locales = vm.argument(0);
auto options_value = vm.argument(1);
// 2. Let internalSlotsList be « [[InitializedSegmenter]], [[Locale]], [[SegmenterGranularity]] ».
// 3. Let segmenter be ? OrdinaryCreateFromConstructor(NewTarget, "%Segmenter.prototype%", internalSlotsList).
auto* segmenter = TRY(ordinary_create_from_constructor<Segmenter>(global_object, new_target, &GlobalObject::intl_segmenter_prototype));
auto* segmenter = TRY(ordinary_create_from_constructor<Segmenter>(vm, new_target, &GlobalObject::intl_segmenter_prototype));
// 4. Let requestedLocales be ? CanonicalizeLocaleList(locales).
auto requested_locales = TRY(canonicalize_locale_list(vm, locales));

View file

@ -17,9 +17,6 @@ namespace JS {
// 7.4.2 GetIterator ( obj [ , hint [ , method ] ] ), https://tc39.es/ecma262/#sec-getiterator
ThrowCompletionOr<Iterator> get_iterator(VM& vm, Value value, IteratorHint hint, Optional<Value> method)
{
auto& realm = *vm.current_realm();
auto& global_object = realm.global_object();
// 1. If hint is not present, set hint to sync.
// 2. If method is not present, then
@ -54,7 +51,7 @@ ThrowCompletionOr<Iterator> get_iterator(VM& vm, Value value, IteratorHint hint,
return vm.throw_completion<TypeError>(ErrorType::NotIterable, value.to_string_without_side_effects());
// 3. Let iterator be ? Call(method, obj).
auto iterator = TRY(call(global_object, *method, value));
auto iterator = TRY(call(vm, *method, value));
// 4. If Type(iterator) is not Object, throw a TypeError exception.
if (!iterator.is_object())
@ -73,18 +70,15 @@ ThrowCompletionOr<Iterator> get_iterator(VM& vm, Value value, IteratorHint hint,
// 7.4.3 IteratorNext ( iteratorRecord [ , value ] ), https://tc39.es/ecma262/#sec-iteratornext
ThrowCompletionOr<Object*> iterator_next(VM& vm, Iterator const& iterator_record, Optional<Value> value)
{
auto& realm = *vm.current_realm();
auto& global_object = realm.global_object();
Value result;
// 1. If value is not present, then
if (!value.has_value()) {
// a. Let result be ? Call(iteratorRecord.[[NextMethod]], iteratorRecord.[[Iterator]]).
result = TRY(call(global_object, iterator_record.next_method, iterator_record.iterator));
result = TRY(call(vm, iterator_record.next_method, iterator_record.iterator));
} else {
// a. Let result be ? Call(iteratorRecord.[[NextMethod]], iteratorRecord.[[Iterator]], « value »).
result = TRY(call(global_object, iterator_record.next_method, iterator_record.iterator, *value));
result = TRY(call(vm, iterator_record.next_method, iterator_record.iterator, *value));
}
// 3. If Type(result) is not Object, throw a TypeError exception.
@ -155,7 +149,7 @@ static Completion iterator_close_impl(VM& vm, Iterator const& iterator_record, C
return completion;
// c. Set innerResult to Completion(Call(return, iterator)).
inner_result = call(global_object, return_method, iterator);
inner_result = call(vm, return_method, iterator);
// Note: If this is AsyncIteratorClose perform one extra step.
if (iterator_hint == IteratorHint::Async && !inner_result.is_error()) {

View file

@ -57,7 +57,7 @@ ThrowCompletionOr<String> JSONObject::stringify_impl(VM& vm, Value value, Value
auto is_array = TRY(replacer.is_array(vm));
if (is_array) {
auto& replacer_object = replacer.as_object();
auto replacer_length = TRY(length_of_array_like(global_object, replacer_object));
auto replacer_length = TRY(length_of_array_like(vm, replacer_object));
Vector<String> list;
for (size_t i = 0; i < replacer_length; ++i) {
auto replacer_value = TRY(replacer_object.get(i));
@ -127,9 +127,6 @@ JS_DEFINE_NATIVE_FUNCTION(JSONObject::stringify)
// 25.5.2.1 SerializeJSONProperty ( state, key, holder ), https://tc39.es/ecma262/#sec-serializejsonproperty
ThrowCompletionOr<String> JSONObject::serialize_json_property(VM& vm, StringifyState& state, PropertyKey const& key, Object* holder)
{
auto& realm = *vm.current_realm();
auto& global_object = realm.global_object();
// 1. Let value be ? Get(holder, key).
auto value = TRY(holder->get(key));
@ -141,14 +138,14 @@ ThrowCompletionOr<String> JSONObject::serialize_json_property(VM& vm, StringifyS
// b. If IsCallable(toJSON) is true, then
if (to_json.is_function()) {
// i. Set value to ? Call(toJSON, value, « key »).
value = TRY(call(global_object, to_json.as_function(), value, js_string(vm, key.to_string())));
value = TRY(call(vm, to_json.as_function(), value, js_string(vm, key.to_string())));
}
}
// 3. If state.[[ReplacerFunction]] is not undefined, then
if (state.replacer_function) {
// a. Set value to ? Call(state.[[ReplacerFunction]], holder, « key, value »).
value = TRY(call(global_object, *state.replacer_function, holder, js_string(vm, key.to_string()), value));
value = TRY(call(vm, *state.replacer_function, holder, js_string(vm, key.to_string()), value));
}
// 4. If Type(value) is Object, then
@ -292,9 +289,6 @@ ThrowCompletionOr<String> JSONObject::serialize_json_object(VM& vm, StringifySta
// 25.5.2.5 SerializeJSONArray ( state, value ), https://tc39.es/ecma262/#sec-serializejsonarray
ThrowCompletionOr<String> JSONObject::serialize_json_array(VM& vm, StringifyState& state, Object& object)
{
auto& realm = *vm.current_realm();
auto& global_object = realm.global_object();
if (state.seen_objects.contains(&object))
return vm.throw_completion<TypeError>(ErrorType::JsonCircular);
@ -303,7 +297,7 @@ ThrowCompletionOr<String> JSONObject::serialize_json_array(VM& vm, StringifyStat
state.indent = String::formatted("{}{}", state.indent, state.gap);
Vector<String> property_strings;
auto length = TRY(length_of_array_like(global_object, object));
auto length = TRY(length_of_array_like(vm, object));
// Optimization
property_strings.ensure_capacity(length);
@ -458,9 +452,6 @@ Array* JSONObject::parse_json_array(VM& vm, JsonArray const& json_array)
// 25.5.1.1 InternalizeJSONProperty ( holder, name, reviver ), https://tc39.es/ecma262/#sec-internalizejsonproperty
ThrowCompletionOr<Value> JSONObject::internalize_json_property(VM& vm, Object* holder, PropertyKey const& name, FunctionObject& reviver)
{
auto& realm = *vm.current_realm();
auto& global_object = realm.global_object();
auto value = TRY(holder->get(name));
if (value.is_object()) {
auto is_array = TRY(value.is_array(vm));
@ -476,7 +467,7 @@ ThrowCompletionOr<Value> JSONObject::internalize_json_property(VM& vm, Object* h
};
if (is_array) {
auto length = TRY(length_of_array_like(global_object, value_object));
auto length = TRY(length_of_array_like(vm, value_object));
for (size_t i = 0; i < length; ++i)
TRY(process_property(i));
} else {
@ -486,7 +477,7 @@ ThrowCompletionOr<Value> JSONObject::internalize_json_property(VM& vm, Object* h
}
}
return TRY(call(global_object, reviver, holder, js_string(vm, name.to_string()), value));
return TRY(call(vm, reviver, holder, js_string(vm, name.to_string()), value));
}
}

View file

@ -32,14 +32,11 @@ inline JobCallback make_job_callback(FunctionObject& callback)
// 9.5.3 HostCallJobCallback ( jobCallback, V, argumentsList ), https://tc39.es/ecma262/#sec-hostcalljobcallback
inline ThrowCompletionOr<Value> call_job_callback(VM& vm, JobCallback& job_callback, Value this_value, MarkedVector<Value> arguments_list)
{
auto& realm = *vm.current_realm();
auto& global_object = realm.global_object();
// 1. Assert: IsCallable(jobCallback.[[Callback]]) is true.
VERIFY(!job_callback.callback.is_null());
// 2. Return ? Call(jobCallback.[[Callback]], V, argumentsList).
return call(global_object, job_callback.callback.cell(), this_value, move(arguments_list));
return call(vm, job_callback.callback.cell(), this_value, move(arguments_list));
}
}

View file

@ -42,9 +42,8 @@ ThrowCompletionOr<Value> MapConstructor::call()
ThrowCompletionOr<Object*> MapConstructor::construct(FunctionObject& new_target)
{
auto& vm = this->vm();
auto& global_object = this->global_object();
auto* map = TRY(ordinary_create_from_constructor<Map>(global_object, new_target, &GlobalObject::map_prototype));
auto* map = TRY(ordinary_create_from_constructor<Map>(vm, new_target, &GlobalObject::map_prototype));
if (vm.argument(0).is_nullish())
return map;
@ -59,7 +58,7 @@ ThrowCompletionOr<Object*> MapConstructor::construct(FunctionObject& new_target)
auto key = TRY(iterator_value.as_object().get(0));
auto value = TRY(iterator_value.as_object().get(1));
TRY(JS::call(global_object, adder.as_function(), map, key, value));
TRY(JS::call(vm, adder.as_function(), map, key, value));
return {};
}));

View file

@ -72,7 +72,7 @@ JS_DEFINE_NATIVE_FUNCTION(MapPrototype::for_each)
return vm.throw_completion<TypeError>(ErrorType::NotAFunction, vm.argument(0).to_string_without_side_effects());
auto this_value = vm.this_value();
for (auto& entry : *map)
TRY(call(global_object, vm.argument(0).as_function(), vm.argument(1), entry.value, entry.key, this_value));
TRY(call(vm, vm.argument(0).as_function(), vm.argument(1), entry.value, entry.key, this_value));
return js_undefined();
}

View file

@ -87,9 +87,10 @@ ThrowCompletionOr<Value> NumberConstructor::call()
ThrowCompletionOr<Object*> NumberConstructor::construct(FunctionObject& new_target)
{
auto& global_object = this->global_object();
auto& vm = this->vm();
auto number = TRY(get_value_from_constructor_argument(global_object));
return TRY(ordinary_create_from_constructor<NumberObject>(global_object, new_target, &GlobalObject::number_prototype, number.as_double()));
return TRY(ordinary_create_from_constructor<NumberObject>(vm, new_target, &GlobalObject::number_prototype, number.as_double()));
}
// 21.1.2.2 Number.isFinite ( number ), https://tc39.es/ecma262/#sec-number.isfinite

View file

@ -327,7 +327,7 @@ JS_DEFINE_NATIVE_FUNCTION(NumberPrototype::to_locale_string)
auto number_value = TRY(this_number_value(global_object, vm.this_value()));
// 2. Let numberFormat be ? Construct(%NumberFormat%, « locales, options »).
auto* number_format = static_cast<Intl::NumberFormat*>(TRY(construct(global_object, *global_object.intl_number_format_constructor(), locales, options)));
auto* number_format = static_cast<Intl::NumberFormat*>(TRY(construct(vm, *global_object.intl_number_format_constructor(), locales, options)));
// 3. Return ? FormatNumeric(numberFormat, x).
// Note: Our implementation of FormatNumeric does not throw.

View file

@ -518,9 +518,11 @@ ThrowCompletionOr<void> Object::private_method_or_accessor_add(PrivateElement el
// 7.3.30 PrivateGet ( O, P ), https://tc39.es/ecma262/#sec-privateget
ThrowCompletionOr<Value> Object::private_get(PrivateName const& name)
{
auto& vm = this->vm();
auto* entry = private_element_find(name);
if (!entry)
return vm().throw_completion<TypeError>(ErrorType::PrivateFieldDoesNotExistOnObject, name.description);
return vm.throw_completion<TypeError>(ErrorType::PrivateFieldDoesNotExistOnObject, name.description);
auto& value = entry->value;
@ -530,24 +532,26 @@ ThrowCompletionOr<Value> Object::private_get(PrivateName const& name)
VERIFY(value.is_accessor());
auto* getter = value.as_accessor().getter();
if (!getter)
return vm().throw_completion<TypeError>(ErrorType::PrivateFieldGetAccessorWithoutGetter, name.description);
return vm.throw_completion<TypeError>(ErrorType::PrivateFieldGetAccessorWithoutGetter, name.description);
// 8. Return ? Call(getter, Receiver).
return TRY(call(global_object(), *getter, this));
return TRY(call(vm, *getter, this));
}
// 7.3.31 PrivateSet ( O, P, value ), https://tc39.es/ecma262/#sec-privateset
ThrowCompletionOr<void> Object::private_set(PrivateName const& name, Value value)
{
auto& vm = this->vm();
auto* entry = private_element_find(name);
if (!entry)
return vm().throw_completion<TypeError>(ErrorType::PrivateFieldDoesNotExistOnObject, name.description);
return vm.throw_completion<TypeError>(ErrorType::PrivateFieldDoesNotExistOnObject, name.description);
if (entry->kind == PrivateElement::Kind::Field) {
entry->value = value;
return {};
} else if (entry->kind == PrivateElement::Kind::Method) {
return vm().throw_completion<TypeError>(ErrorType::PrivateFieldSetMethod, name.description);
return vm.throw_completion<TypeError>(ErrorType::PrivateFieldSetMethod, name.description);
}
VERIFY(entry->kind == PrivateElement::Kind::Accessor);
@ -556,15 +560,17 @@ ThrowCompletionOr<void> Object::private_set(PrivateName const& name, Value value
VERIFY(accessor.is_accessor());
auto* setter = accessor.as_accessor().setter();
if (!setter)
return vm().throw_completion<TypeError>(ErrorType::PrivateFieldSetAccessorWithoutSetter, name.description);
return vm.throw_completion<TypeError>(ErrorType::PrivateFieldSetAccessorWithoutSetter, name.description);
TRY(call(global_object(), *setter, this, value));
TRY(call(vm, *setter, this, value));
return {};
}
// 7.3.32 DefineField ( receiver, fieldRecord ), https://tc39.es/ecma262/#sec-definefield
ThrowCompletionOr<void> Object::define_field(ClassFieldDefinition const& field)
{
auto& vm = this->vm();
// 1. Let fieldName be fieldRecord.[[Name]].
auto const& field_name = field.name;
@ -576,7 +582,7 @@ ThrowCompletionOr<void> Object::define_field(ClassFieldDefinition const& field)
// 3. If initializer is not empty, then
if (!initializer.is_null()) {
// a. Let initValue be ? Call(initializer, receiver).
init_value = TRY(call(global_object(), initializer.cell(), this));
init_value = TRY(call(vm, initializer.cell(), this));
}
// 4. Else, let initValue be undefined.
@ -757,6 +763,8 @@ ThrowCompletionOr<Value> Object::internal_get(PropertyKey const& property_key, V
VERIFY(!receiver.is_empty());
VERIFY(property_key.is_valid());
auto& vm = this->vm();
// 1. Let desc be ? O.[[GetOwnProperty]](P).
auto descriptor = TRY(internal_get_own_property(property_key));
@ -788,7 +796,7 @@ ThrowCompletionOr<Value> Object::internal_get(PropertyKey const& property_key, V
return js_undefined();
// 7. Return ? Call(getter, Receiver).
return TRY(call(global_object(), *getter, receiver));
return TRY(call(vm, *getter, receiver));
}
// 10.1.9 [[Set]] ( P, V, Receiver ), https://tc39.es/ecma262/#sec-ordinary-object-internal-methods-and-internal-slots-set-p-v-receiver
@ -812,6 +820,8 @@ ThrowCompletionOr<bool> Object::ordinary_set_with_own_descriptor(PropertyKey con
VERIFY(!value.is_empty());
VERIFY(!receiver.is_empty());
auto& vm = this->vm();
// 1. If ownDesc is undefined, then
if (!own_descriptor.has_value()) {
// a. Let parent be ? O.[[GetPrototypeOf]]().
@ -884,7 +894,7 @@ ThrowCompletionOr<bool> Object::ordinary_set_with_own_descriptor(PropertyKey con
return false;
// 6. Perform ? Call(setter, Receiver, « V »).
(void)TRY(call(global_object(), *setter, receiver, value));
(void)TRY(call(vm, *setter, receiver, value));
// 7. Return true.
return true;
@ -1258,7 +1268,7 @@ ThrowCompletionOr<Value> Object::ordinary_to_primitive(Value::PreferredType pref
// b. If IsCallable(method) is true, then
if (method.is_function()) {
// i. Let result be ? Call(method, O).
auto result = TRY(call(global_object(), method.as_function(), const_cast<Object*>(this)));
auto result = TRY(call(vm, method.as_function(), const_cast<Object*>(this)));
// ii. If Type(result) is not Object, return result.
if (!result.is_object())

View file

@ -71,7 +71,7 @@ ThrowCompletionOr<Object*> ObjectConstructor::construct(FunctionObject& new_targ
auto& realm = *global_object.associated_realm();
if (&new_target != this)
return TRY(ordinary_create_from_constructor<Object>(global_object, new_target, &GlobalObject::object_prototype));
return TRY(ordinary_create_from_constructor<Object>(vm, new_target, &GlobalObject::object_prototype));
auto value = vm.argument(0);
if (value.is_nullish())
return Object::create(realm, global_object.object_prototype());
@ -144,7 +144,7 @@ JS_DEFINE_NATIVE_FUNCTION(ObjectConstructor::set_prototype_of)
auto proto = vm.argument(1);
// 1. Set O to ? RequireObjectCoercible(O).
auto object = TRY(require_object_coercible(global_object, vm.argument(0)));
auto object = TRY(require_object_coercible(vm, vm.argument(0)));
// 2. If Type(proto) is neither Object nor Null, throw a TypeError exception.
if (!proto.is_object() && !proto.is_null())
@ -224,7 +224,7 @@ JS_DEFINE_NATIVE_FUNCTION(ObjectConstructor::freeze)
JS_DEFINE_NATIVE_FUNCTION(ObjectConstructor::from_entries)
{
auto& realm = *global_object.associated_realm();
auto iterable = TRY(require_object_coercible(global_object, vm.argument(0)));
auto iterable = TRY(require_object_coercible(vm, vm.argument(0)));
auto* object = Object::create(realm, global_object.object_prototype());

View file

@ -264,7 +264,7 @@ JS_DEFINE_NATIVE_FUNCTION(ObjectPrototype::proto_getter)
// B.2.2.1.2 set Object.prototype.__proto__, https://tc39.es/ecma262/#sec-set-object.prototype.__proto__
JS_DEFINE_NATIVE_FUNCTION(ObjectPrototype::proto_setter)
{
auto object = TRY(require_object_coercible(global_object, vm.this_value()));
auto object = TRY(require_object_coercible(vm, vm.this_value()));
auto proto = vm.argument(0);
if (!proto.is_object() && !proto.is_null())

View file

@ -21,9 +21,6 @@ namespace JS {
// 27.2.4.7.1 PromiseResolve ( C, x ), https://tc39.es/ecma262/#sec-promise-resolve
ThrowCompletionOr<Object*> promise_resolve(VM& vm, Object& constructor, Value value)
{
auto& realm = *vm.current_realm();
auto& global_object = realm.global_object();
// 1. If IsPromise(x) is true, then
if (value.is_object() && is<Promise>(value.as_object())) {
// a. Let xConstructor be ? Get(x, "constructor").
@ -38,7 +35,7 @@ ThrowCompletionOr<Object*> promise_resolve(VM& vm, Object& constructor, Value va
auto promise_capability = TRY(new_promise_capability(vm, &constructor));
// 3. Perform ? Call(promiseCapability.[[Resolve]], undefined, « x »).
(void)TRY(call(global_object, *promise_capability.resolve, js_undefined(), value));
(void)TRY(call(vm, *promise_capability.resolve, js_undefined(), value));
// 4. Return promiseCapability.[[Promise]].
return promise_capability.promise;

View file

@ -41,9 +41,6 @@ using InvokeElementFunctionCallback = Function<ThrowCompletionOr<Value>(PromiseV
static ThrowCompletionOr<Value> perform_promise_common(VM& vm, Iterator& iterator_record, Value constructor, PromiseCapability result_capability, Value promise_resolve, EndOfElementsCallback end_of_list, InvokeElementFunctionCallback invoke_element_function)
{
auto& realm = *vm.current_realm();
auto& global_object = realm.global_object();
VERIFY(constructor.is_constructor());
VERIFY(promise_resolve.is_function());
@ -100,7 +97,7 @@ static ThrowCompletionOr<Value> perform_promise_common(VM& vm, Iterator& iterato
values->values().append(js_undefined());
// i. Let nextPromise be ? Call(promiseResolve, constructor, « nextValue »).
auto next_promise = TRY(call(global_object, promise_resolve.as_function(), constructor, next_value));
auto next_promise = TRY(call(vm, promise_resolve.as_function(), constructor, next_value));
// j-q. are handled in `invoke_element_function`
@ -119,7 +116,6 @@ static ThrowCompletionOr<Value> perform_promise_common(VM& vm, Iterator& iterato
static ThrowCompletionOr<Value> perform_promise_all(VM& vm, Iterator& iterator_record, Value constructor, PromiseCapability result_capability, Value promise_resolve)
{
auto& realm = *vm.current_realm();
auto& global_object = realm.global_object();
return perform_promise_common(
vm, iterator_record, constructor, result_capability, promise_resolve,
@ -128,7 +124,7 @@ static ThrowCompletionOr<Value> perform_promise_all(VM& vm, Iterator& iterator_r
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));
TRY(call(vm, *result_capability.resolve, js_undefined(), values_array));
// iv. Return resultCapability.[[Promise]].
return Value(result_capability.promise);
@ -154,14 +150,13 @@ static ThrowCompletionOr<Value> perform_promise_all(VM& vm, Iterator& iterator_r
static ThrowCompletionOr<Value> perform_promise_all_settled(VM& vm, Iterator& iterator_record, Value constructor, PromiseCapability result_capability, Value promise_resolve)
{
auto& realm = *vm.current_realm();
auto& global_object = realm.global_object();
return perform_promise_common(
vm, iterator_record, constructor, result_capability, promise_resolve,
[&](PromiseValueList& values) -> ThrowCompletionOr<Value> {
auto* values_array = Array::create_from(realm, values.values());
TRY(call(global_object, *result_capability.resolve, js_undefined(), values_array));
TRY(call(vm, *result_capability.resolve, js_undefined(), values_array));
return Value(result_capability.promise);
},
@ -283,7 +278,6 @@ ThrowCompletionOr<Value> PromiseConstructor::call()
ThrowCompletionOr<Object*> PromiseConstructor::construct(FunctionObject& new_target)
{
auto& vm = this->vm();
auto& global_object = this->global_object();
auto executor = vm.argument(0);
@ -296,18 +290,18 @@ ThrowCompletionOr<Object*> PromiseConstructor::construct(FunctionObject& new_tar
// 5. Set promise.[[PromiseFulfillReactions]] to a new empty List.
// 6. Set promise.[[PromiseRejectReactions]] to a new empty List.
// 7. Set promise.[[PromiseIsHandled]] to false.
auto* promise = TRY(ordinary_create_from_constructor<Promise>(global_object, new_target, &GlobalObject::promise_prototype));
auto* promise = TRY(ordinary_create_from_constructor<Promise>(vm, new_target, &GlobalObject::promise_prototype));
// 8. Let resolvingFunctions be CreateResolvingFunctions(promise).
auto [resolve_function, reject_function] = promise->create_resolving_functions();
// 9. Let completion be Completion(Call(executor, undefined, « resolvingFunctions.[[Resolve]], resolvingFunctions.[[Reject]] »)).
auto completion = JS::call(global_object, executor.as_function(), js_undefined(), &resolve_function, &reject_function);
auto completion = JS::call(vm, executor.as_function(), js_undefined(), &resolve_function, &reject_function);
// 10. If completion is an abrupt completion, then
if (completion.is_error()) {
// a. Perform ? Call(resolvingFunctions.[[Reject]], undefined, « completion.[[Value]] »).
TRY(JS::call(global_object, reject_function, js_undefined(), *completion.release_error().value()));
TRY(JS::call(vm, reject_function, js_undefined(), *completion.release_error().value()));
}
// 11. Return promise.
@ -462,7 +456,7 @@ JS_DEFINE_NATIVE_FUNCTION(PromiseConstructor::reject)
auto promise_capability = TRY(new_promise_capability(vm, constructor));
// 3. Perform ? Call(promiseCapability.[[Reject]], undefined, « r »).
[[maybe_unused]] auto result = TRY(JS::call(global_object, *promise_capability.reject, js_undefined(), reason));
[[maybe_unused]] auto result = TRY(JS::call(vm, *promise_capability.reject, js_undefined(), reason));
// 4. Return promiseCapability.[[Promise]].
return promise_capability.promise;

View file

@ -18,9 +18,6 @@ namespace JS {
// 27.2.2.1 NewPromiseReactionJob ( reaction, argument ), https://tc39.es/ecma262/#sec-newpromisereactionjob
static ThrowCompletionOr<Value> run_reaction_job(VM& vm, PromiseReaction& reaction, Value argument)
{
auto& realm = *vm.current_realm();
auto& global_object = realm.global_object();
// a. Let promiseCapability be reaction.[[Capability]].
auto& promise_capability = reaction.capability();
@ -78,23 +75,20 @@ static ThrowCompletionOr<Value> run_reaction_job(VM& vm, PromiseReaction& reacti
// i. Return ? Call(promiseCapability.[[Reject]], undefined, « handlerResult.[[Value]] »).
auto* reject_function = promise_capability.value().reject;
dbgln_if(PROMISE_DEBUG, "run_reaction_job: Calling PromiseCapability's reject function @ {}", reject_function);
return call(global_object, *reject_function, js_undefined(), *handler_result.value());
return call(vm, *reject_function, js_undefined(), *handler_result.value());
}
// i. Else,
else {
// i. Return ? Call(promiseCapability.[[Resolve]], undefined, « handlerResult.[[Value]] »).
auto* resolve_function = promise_capability.value().resolve;
dbgln_if(PROMISE_DEBUG, "[PromiseReactionJob]: Calling PromiseCapability's resolve function @ {}", resolve_function);
return call(global_object, *resolve_function, js_undefined(), *handler_result.value());
return call(vm, *resolve_function, js_undefined(), *handler_result.value());
}
}
// 27.2.2.1 NewPromiseReactionJob ( reaction, argument ), https://tc39.es/ecma262/#sec-newpromisereactionjob
PromiseJob create_promise_reaction_job(VM& vm, PromiseReaction& reaction, Value argument)
{
auto& realm = *vm.current_realm();
auto& global_object = realm.global_object();
// 1. Let job be a new Job Abstract Closure with no parameters that captures reaction and argument and performs the following steps when called:
// See run_reaction_job for "the following steps".
auto job = [&vm, reaction = make_handle(&reaction), argument = make_handle(argument)]() mutable {
@ -108,7 +102,7 @@ PromiseJob create_promise_reaction_job(VM& vm, PromiseReaction& reaction, Value
auto& handler = reaction.handler();
if (handler.has_value()) {
// a. Let getHandlerRealmResult be Completion(GetFunctionRealm(reaction.[[Handler]].[[Callback]])).
auto get_handler_realm_result = get_function_realm(global_object, *handler->callback.cell());
auto get_handler_realm_result = get_function_realm(vm, *handler->callback.cell());
// b. If getHandlerRealmResult is a normal completion, set handlerRealm to getHandlerRealmResult.[[Value]].
if (!get_handler_realm_result.is_throw_completion()) {
@ -128,9 +122,6 @@ PromiseJob create_promise_reaction_job(VM& vm, PromiseReaction& reaction, Value
// 27.2.2.2 NewPromiseResolveThenableJob ( promiseToResolve, thenable, then ), https://tc39.es/ecma262/#sec-newpromiseresolvethenablejob
static ThrowCompletionOr<Value> run_resolve_thenable_job(VM& vm, Promise& promise_to_resolve, Value thenable, JobCallback& then)
{
auto& realm = *vm.current_realm();
auto& global_object = realm.global_object();
// a. Let resolvingFunctions be CreateResolvingFunctions(promiseToResolve).
auto [resolve_function, reject_function] = promise_to_resolve.create_resolving_functions();
@ -145,7 +136,7 @@ static ThrowCompletionOr<Value> run_resolve_thenable_job(VM& vm, Promise& promis
if (then_call_result.is_error()) {
// i. Return ? Call(resolvingFunctions.[[Reject]], undefined, « thenCallResult.[[Value]] »).
dbgln_if(PROMISE_DEBUG, "run_resolve_thenable_job: then_call_result is an abrupt completion, calling reject function with value {}", *then_call_result.throw_completion().value());
return call(global_object, &reject_function, js_undefined(), *then_call_result.throw_completion().value());
return call(vm, &reject_function, js_undefined(), *then_call_result.throw_completion().value());
}
// d. Return ? thenCallResult.
@ -156,11 +147,8 @@ static ThrowCompletionOr<Value> run_resolve_thenable_job(VM& vm, Promise& promis
// 27.2.2.2 NewPromiseResolveThenableJob ( promiseToResolve, thenable, then ), https://tc39.es/ecma262/#sec-newpromiseresolvethenablejob
PromiseJob create_promise_resolve_thenable_job(VM& vm, Promise& promise_to_resolve, Value thenable, JobCallback then)
{
auto& realm = *vm.current_realm();
auto& global_object = realm.global_object();
// 2. Let getThenRealmResult be Completion(GetFunctionRealm(then.[[Callback]])).
auto get_then_realm_result = get_function_realm(global_object, *then.callback.cell());
auto get_then_realm_result = get_function_realm(vm, *then.callback.cell());
Realm* then_realm;

View file

@ -46,7 +46,7 @@ JS_DEFINE_NATIVE_FUNCTION(PromisePrototype::then)
auto* promise = TRY(typed_this_object(vm));
// 3. Let C be ? SpeciesConstructor(promise, %Promise%).
auto* constructor = TRY(species_constructor(global_object, *promise, *global_object.promise_constructor()));
auto* constructor = TRY(species_constructor(vm, *promise, *global_object.promise_constructor()));
// 4. Let resultCapability be ? NewPromiseCapability(C).
auto result_capability = TRY(new_promise_capability(vm, constructor));
@ -82,7 +82,7 @@ JS_DEFINE_NATIVE_FUNCTION(PromisePrototype::finally)
return vm.throw_completion<TypeError>(ErrorType::NotAnObject, promise.to_string_without_side_effects());
// 3. Let C be ? SpeciesConstructor(promise, %Promise%).
auto* constructor = TRY(species_constructor(global_object, promise.as_object(), *global_object.promise_constructor()));
auto* constructor = TRY(species_constructor(vm, promise.as_object(), *global_object.promise_constructor()));
// 4. Assert: IsConstructor(C) is true.
VERIFY(constructor);
@ -108,7 +108,7 @@ JS_DEFINE_NATIVE_FUNCTION(PromisePrototype::finally)
auto value = vm.argument(0);
// i. Let result be ? Call(onFinally, undefined).
auto result = TRY(call(global_object, on_finally, js_undefined()));
auto result = TRY(call(vm, on_finally, js_undefined()));
// ii. Let promise be ? PromiseResolve(C, result).
auto* promise = TRY(promise_resolve(vm, constructor, result));
@ -137,7 +137,7 @@ JS_DEFINE_NATIVE_FUNCTION(PromisePrototype::finally)
auto reason = vm.argument(0);
// i. Let result be ? Call(onFinally, undefined).
auto result = TRY(call(global_object, on_finally, js_undefined()));
auto result = TRY(call(vm, on_finally, js_undefined()));
// ii. Let promise be ? PromiseResolve(C, result).
auto* promise = TRY(promise_resolve(vm, constructor, result));

View file

@ -15,7 +15,6 @@ namespace JS {
ThrowCompletionOr<PromiseCapability> new_promise_capability(VM& vm, Value constructor)
{
auto& realm = *vm.current_realm();
auto& global_object = realm.global_object();
// 1. If IsConstructor(C) is false, throw a TypeError exception.
if (!constructor.is_constructor())
@ -59,7 +58,7 @@ ThrowCompletionOr<PromiseCapability> new_promise_capability(VM& vm, Value constr
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));
auto* promise = TRY(construct(vm, constructor.as_function(), executor));
// 7. If IsCallable(promiseCapability.[[Resolve]]) is false, throw a TypeError exception.
if (!promise_capability_functions.resolve.is_function())

View file

@ -23,13 +23,11 @@ struct PromiseCapability {
// 27.2.1.1.1 IfAbruptRejectPromise ( value, capability ), https://tc39.es/ecma262/#sec-ifabruptrejectpromise
#define __TRY_OR_REJECT(vm, capability, expression, CALL_CHECK) \
({ \
auto& _realm = *vm.current_realm(); \
auto& _global_object = _realm.global_object(); \
auto _temporary_try_or_reject_result = (expression); \
/* 1. If value is an abrupt completion, then */ \
if (_temporary_try_or_reject_result.is_error()) { \
/* a. Perform ? Call(capability.[[Reject]], undefined, « value.[[Value]] »). */ \
CALL_CHECK(JS::call(_global_object, *capability.reject, js_undefined(), *_temporary_try_or_reject_result.release_error().value())); \
CALL_CHECK(JS::call(vm, *capability.reject, js_undefined(), *_temporary_try_or_reject_result.release_error().value())); \
\
/* b. Return capability.[[Promise]]. */ \
return capability.promise; \
@ -48,13 +46,11 @@ struct PromiseCapability {
// 27.2.1.1.1 IfAbruptRejectPromise ( value, capability ), https://tc39.es/ecma262/#sec-ifabruptrejectpromise
#define TRY_OR_REJECT_WITH_VALUE(vm, capability, expression) \
({ \
auto& _realm = *vm.current_realm(); \
auto& _global_object = _realm.global_object(); \
auto _temporary_try_or_reject_result = (expression); \
/* 1. If value is an abrupt completion, then */ \
if (_temporary_try_or_reject_result.is_error()) { \
/* a. Perform ? Call(capability.[[Reject]], undefined, « value.[[Value]] »). */ \
TRY(JS::call(_global_object, *capability.reject, js_undefined(), *_temporary_try_or_reject_result.release_error().value())); \
TRY(JS::call(vm, *capability.reject, js_undefined(), *_temporary_try_or_reject_result.release_error().value())); \
\
/* b. Return capability.[[Promise]]. */ \
return Value { capability.promise }; \

View file

@ -81,7 +81,7 @@ ThrowCompletionOr<Value> PromiseAllResolveElementFunction::resolve_element()
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);
return JS::call(vm, *m_capability.resolve, js_undefined(), values_array);
}
// 11. Return undefined.
@ -123,7 +123,7 @@ ThrowCompletionOr<Value> PromiseAllSettledResolveElementFunction::resolve_elemen
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);
return JS::call(vm, *m_capability.resolve, js_undefined(), values_array);
}
// 15. Return undefined.
@ -165,7 +165,7 @@ ThrowCompletionOr<Value> PromiseAllSettledRejectElementFunction::resolve_element
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);
return JS::call(vm, *m_capability.resolve, js_undefined(), values_array);
}
// 15. Return undefined.
@ -202,7 +202,7 @@ ThrowCompletionOr<Value> PromiseAnyRejectElementFunction::resolve_element()
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 »).
return JS::call(global_object, *m_capability.reject, js_undefined(), error);
return JS::call(vm, *m_capability.reject, js_undefined(), error);
}
return js_undefined();

View file

@ -44,7 +44,6 @@ static Value property_key_to_value(VM& vm, PropertyKey const& property_key)
ThrowCompletionOr<Object*> ProxyObject::internal_get_prototype_of() const
{
auto& vm = this->vm();
auto& global_object = this->global_object();
// 1. Let handler be O.[[ProxyHandler]].
@ -65,7 +64,7 @@ ThrowCompletionOr<Object*> ProxyObject::internal_get_prototype_of() const
}
// 7. Let handlerProto be ? Call(trap, handler, « target »).
auto handler_proto = TRY(call(global_object, *trap, &m_handler, &m_target));
auto handler_proto = TRY(call(vm, *trap, &m_handler, &m_target));
// 8. If Type(handlerProto) is neither Object nor Null, throw a TypeError exception.
if (!handler_proto.is_object() && !handler_proto.is_null())
@ -93,7 +92,6 @@ ThrowCompletionOr<Object*> ProxyObject::internal_get_prototype_of() const
ThrowCompletionOr<bool> ProxyObject::internal_set_prototype_of(Object* prototype)
{
auto& vm = this->vm();
auto& global_object = this->global_object();
// 1. Let handler be O.[[ProxyHandler]].
@ -114,7 +112,7 @@ ThrowCompletionOr<bool> ProxyObject::internal_set_prototype_of(Object* prototype
}
// 7. Let booleanTrapResult be ToBoolean(? Call(trap, handler, « target, V »)).
auto trap_result = TRY(call(global_object, *trap, &m_handler, &m_target, prototype)).to_boolean();
auto trap_result = TRY(call(vm, *trap, &m_handler, &m_target, prototype)).to_boolean();
// 8. If booleanTrapResult is false, return false.
if (!trap_result)
@ -142,7 +140,6 @@ ThrowCompletionOr<bool> ProxyObject::internal_set_prototype_of(Object* prototype
ThrowCompletionOr<bool> ProxyObject::internal_is_extensible() const
{
auto& vm = this->vm();
auto& global_object = this->global_object();
// 1. Let handler be O.[[ProxyHandler]].
@ -163,7 +160,7 @@ ThrowCompletionOr<bool> ProxyObject::internal_is_extensible() const
}
// 7. Let booleanTrapResult be ToBoolean(? Call(trap, handler, « target »)).
auto trap_result = TRY(call(global_object, *trap, &m_handler, &m_target)).to_boolean();
auto trap_result = TRY(call(vm, *trap, &m_handler, &m_target)).to_boolean();
// 8. Let targetResult be ? IsExtensible(target).
auto target_result = TRY(m_target.is_extensible());
@ -180,7 +177,6 @@ ThrowCompletionOr<bool> ProxyObject::internal_is_extensible() const
ThrowCompletionOr<bool> ProxyObject::internal_prevent_extensions()
{
auto& vm = this->vm();
auto& global_object = this->global_object();
// 1. Let handler be O.[[ProxyHandler]].
@ -201,7 +197,7 @@ ThrowCompletionOr<bool> ProxyObject::internal_prevent_extensions()
}
// 7. Let booleanTrapResult be ToBoolean(? Call(trap, handler, « target »)).
auto trap_result = TRY(call(global_object, *trap, &m_handler, &m_target)).to_boolean();
auto trap_result = TRY(call(vm, *trap, &m_handler, &m_target)).to_boolean();
// 8. If booleanTrapResult is true, then
if (trap_result) {
@ -244,7 +240,7 @@ ThrowCompletionOr<Optional<PropertyDescriptor>> ProxyObject::internal_get_own_pr
}
// 7. Let trapResultObj be ? Call(trap, handler, « target, P »).
auto trap_result = TRY(call(global_object, *trap, &m_handler, &m_target, property_key_to_value(vm, property_key)));
auto trap_result = TRY(call(vm, *trap, &m_handler, &m_target, property_key_to_value(vm, property_key)));
// 8. If Type(trapResultObj) is neither Object nor Undefined, throw a TypeError exception.
if (!trap_result.is_object() && !trap_result.is_undefined())
@ -339,7 +335,7 @@ ThrowCompletionOr<bool> ProxyObject::internal_define_own_property(PropertyKey co
auto descriptor_object = from_property_descriptor(global_object, property_descriptor);
// 8. Let booleanTrapResult be ToBoolean(? Call(trap, handler, « target, P, descObj »)).
auto trap_result = TRY(call(global_object, *trap, &m_handler, &m_target, property_key_to_value(vm, property_key), descriptor_object)).to_boolean();
auto trap_result = TRY(call(vm, *trap, &m_handler, &m_target, property_key_to_value(vm, property_key), descriptor_object)).to_boolean();
// 9. If booleanTrapResult is false, return false.
if (!trap_result)
@ -396,7 +392,6 @@ ThrowCompletionOr<bool> ProxyObject::internal_define_own_property(PropertyKey co
ThrowCompletionOr<bool> ProxyObject::internal_has_property(PropertyKey const& property_key) const
{
auto& vm = this->vm();
auto& global_object = this->global_object();
VERIFY(property_key.is_valid());
@ -419,7 +414,7 @@ ThrowCompletionOr<bool> ProxyObject::internal_has_property(PropertyKey const& pr
}
// 7. Let booleanTrapResult be ToBoolean(? Call(trap, handler, « target, P »)).
auto trap_result = TRY(call(global_object, *trap, &m_handler, &m_target, property_key_to_value(vm, property_key))).to_boolean();
auto trap_result = TRY(call(vm, *trap, &m_handler, &m_target, property_key_to_value(vm, property_key))).to_boolean();
// 8. If booleanTrapResult is false, then
if (!trap_result) {
@ -451,7 +446,6 @@ ThrowCompletionOr<Value> ProxyObject::internal_get(PropertyKey const& property_k
VERIFY(!receiver.is_empty());
auto& vm = this->vm();
auto& global_object = this->global_object();
VERIFY(property_key.is_valid());
VERIFY(!receiver.is_empty());
@ -491,7 +485,7 @@ ThrowCompletionOr<Value> ProxyObject::internal_get(PropertyKey const& property_k
}
// 7. Let trapResult be ? Call(trap, handler, « target, P, Receiver »).
auto trap_result = TRY(call(global_object, *trap, &m_handler, &m_target, property_key_to_value(vm, property_key), receiver));
auto trap_result = TRY(call(vm, *trap, &m_handler, &m_target, property_key_to_value(vm, property_key), receiver));
// 8. Let targetDesc be ? target.[[GetOwnProperty]](P).
auto target_descriptor = TRY(m_target.internal_get_own_property(property_key));
@ -520,7 +514,6 @@ ThrowCompletionOr<Value> ProxyObject::internal_get(PropertyKey const& property_k
ThrowCompletionOr<bool> ProxyObject::internal_set(PropertyKey const& property_key, Value value, Value receiver)
{
auto& vm = this->vm();
auto& global_object = this->global_object();
VERIFY(property_key.is_valid());
VERIFY(!value.is_empty());
@ -545,7 +538,7 @@ ThrowCompletionOr<bool> ProxyObject::internal_set(PropertyKey const& property_ke
}
// 7. Let booleanTrapResult be ToBoolean(? Call(trap, handler, « target, P, V, Receiver »)).
auto trap_result = TRY(call(global_object, *trap, &m_handler, &m_target, property_key_to_value(vm, property_key), value, receiver)).to_boolean();
auto trap_result = TRY(call(vm, *trap, &m_handler, &m_target, property_key_to_value(vm, property_key), value, receiver)).to_boolean();
// 8. If booleanTrapResult is false, return false.
if (!trap_result)
@ -578,7 +571,6 @@ ThrowCompletionOr<bool> ProxyObject::internal_set(PropertyKey const& property_ke
ThrowCompletionOr<bool> ProxyObject::internal_delete(PropertyKey const& property_key)
{
auto& vm = this->vm();
auto& global_object = this->global_object();
VERIFY(property_key.is_valid());
@ -601,7 +593,7 @@ ThrowCompletionOr<bool> ProxyObject::internal_delete(PropertyKey const& property
}
// 7. Let booleanTrapResult be ToBoolean(? Call(trap, handler, « target, P »)).
auto trap_result = TRY(call(global_object, *trap, &m_handler, &m_target, property_key_to_value(vm, property_key))).to_boolean();
auto trap_result = TRY(call(vm, *trap, &m_handler, &m_target, property_key_to_value(vm, property_key))).to_boolean();
// 8. If booleanTrapResult is false, return false.
if (!trap_result)
@ -633,7 +625,6 @@ ThrowCompletionOr<bool> ProxyObject::internal_delete(PropertyKey const& property
ThrowCompletionOr<MarkedVector<Value>> ProxyObject::internal_own_property_keys() const
{
auto& vm = this->vm();
auto& global_object = this->global_object();
// 1. Let handler be O.[[ProxyHandler]].
@ -654,12 +645,11 @@ ThrowCompletionOr<MarkedVector<Value>> ProxyObject::internal_own_property_keys()
}
// 7. Let trapResultArray be ? Call(trap, handler, « target »).
auto trap_result_array = TRY(call(global_object, *trap, &m_handler, &m_target));
auto trap_result_array = TRY(call(vm, *trap, &m_handler, &m_target));
// 8. Let trapResult be ? CreateListFromArrayLike(trapResultArray, « String, Symbol »).
HashTable<PropertyKey> unique_keys;
auto trap_result = TRY(create_list_from_array_like(global_object, trap_result_array, [&](auto value) -> ThrowCompletionOr<void> {
auto& vm = global_object.vm();
auto trap_result = TRY(create_list_from_array_like(vm, trap_result_array, [&](auto value) -> ThrowCompletionOr<void> {
if (!value.is_string() && !value.is_symbol())
return vm.throw_completion<TypeError>(ErrorType::ProxyOwnPropertyKeysNotStringOrSymbol);
auto property_key = MUST(value.to_property_key(vm));
@ -780,14 +770,14 @@ ThrowCompletionOr<Value> ProxyObject::internal_call(Value this_argument, MarkedV
// 6. If trap is undefined, then
if (!trap) {
// a. Return ? Call(target, thisArgument, argumentsList).
return call(global_object, &m_target, this_argument, move(arguments_list));
return call(vm, &m_target, this_argument, move(arguments_list));
}
// 7. Let argArray be CreateArrayFromList(argumentsList).
auto* arguments_array = Array::create_from(realm, arguments_list);
// 8. Return ? Call(trap, handler, « target, thisArgument, argArray »).
return call(global_object, trap, &m_handler, &m_target, this_argument, arguments_array);
return call(vm, trap, &m_handler, &m_target, this_argument, arguments_array);
}
bool ProxyObject::has_constructor() const
@ -829,14 +819,14 @@ ThrowCompletionOr<Object*> ProxyObject::internal_construct(MarkedVector<Value> a
// 7. If trap is undefined, then
if (!trap) {
// a. Return ? Construct(target, argumentsList, newTarget).
return construct(global_object, static_cast<FunctionObject&>(m_target), move(arguments_list), &new_target);
return construct(vm, static_cast<FunctionObject&>(m_target), move(arguments_list), &new_target);
}
// 8. Let argArray be CreateArrayFromList(argumentsList).
auto* arguments_array = Array::create_from(realm, arguments_list);
// 9. Let newObj be ? Call(trap, handler, « target, argArray, newTarget »).
auto new_object = TRY(call(global_object, trap, &m_handler, &m_target, arguments_array, &new_target));
auto new_object = TRY(call(vm, trap, &m_handler, &m_target, arguments_array, &new_target));
// 10. If Type(newObj) is not Object, throw a TypeError exception.
if (!new_object.is_object())

View file

@ -55,11 +55,11 @@ JS_DEFINE_NATIVE_FUNCTION(ReflectObject::apply)
return vm.throw_completion<TypeError>(ErrorType::NotAFunction, target.to_string_without_side_effects());
// 2. Let args be ? CreateListFromArrayLike(argumentsList).
auto args = TRY(create_list_from_array_like(global_object, arguments_list));
auto args = TRY(create_list_from_array_like(vm, arguments_list));
// 3. Perform PrepareForTailCall().
// 4. Return ? Call(target, thisArgument, args).
return TRY(call(global_object, target.as_function(), this_argument, move(args)));
return TRY(call(vm, target.as_function(), this_argument, move(args)));
}
// 28.1.2 Reflect.construct ( target, argumentsList [ , newTarget ] ), https://tc39.es/ecma262/#sec-reflect.construct
@ -81,10 +81,10 @@ JS_DEFINE_NATIVE_FUNCTION(ReflectObject::construct)
return vm.throw_completion<TypeError>(ErrorType::NotAConstructor, new_target.to_string_without_side_effects());
// 4. Let args be ? CreateListFromArrayLike(argumentsList).
auto args = TRY(create_list_from_array_like(global_object, arguments_list));
auto args = TRY(create_list_from_array_like(vm, arguments_list));
// 5. Return ? Construct(target, args, newTarget).
return TRY(JS::construct(global_object, target.as_function(), move(args), &new_target.as_function()));
return TRY(JS::construct(vm, target.as_function(), move(args), &new_target.as_function()));
}
// 28.1.3 Reflect.defineProperty ( target, propertyKey, attributes ), https://tc39.es/ecma262/#sec-reflect.defineproperty

View file

@ -356,16 +356,13 @@ static ThrowCompletionOr<Value> regexp_builtin_exec(VM& vm, RegExpObject& regexp
// 22.2.5.2.1 RegExpExec ( R, S ), https://tc39.es/ecma262/#sec-regexpexec
ThrowCompletionOr<Value> regexp_exec(VM& vm, Object& regexp_object, Utf16String string)
{
auto& realm = *vm.current_realm();
auto& global_object = realm.global_object();
// 1. Let exec be ? Get(R, "exec").
auto exec = TRY(regexp_object.get(vm.names.exec));
// 2. If IsCallable(exec) is true, then
if (exec.is_function()) {
// a. Let result be ? Call(exec, R, « S »).
auto result = TRY(call(global_object, exec.as_function(), &regexp_object, js_string(vm, move(string))));
auto result = TRY(call(vm, exec.as_function(), &regexp_object, js_string(vm, move(string))));
// b. If Type(result) is neither Object nor Null, throw a TypeError exception.
if (!result.is_object() && !result.is_null())
@ -579,7 +576,7 @@ JS_DEFINE_NATIVE_FUNCTION(RegExpPrototype::symbol_match_all)
auto string = TRY(vm.argument(0).to_utf16_string(vm));
// 4. Let C be ? SpeciesConstructor(R, %RegExp%).
auto* constructor = TRY(species_constructor(global_object, *regexp_object, *global_object.regexp_constructor()));
auto* constructor = TRY(species_constructor(vm, *regexp_object, *global_object.regexp_constructor()));
// 5. Let flags be ? ToString(? Get(R, "flags")).
auto flags_value = TRY(regexp_object->get(vm.names.flags));
@ -596,7 +593,7 @@ JS_DEFINE_NATIVE_FUNCTION(RegExpPrototype::symbol_match_all)
bool full_unicode = flags.contains('u') || flags.contains('v');
// 6. Let matcher be ? Construct(C, « R, flags »).
auto* matcher = TRY(construct(global_object, *constructor, regexp_object, js_string(vm, move(flags))));
auto* matcher = TRY(construct(vm, *constructor, regexp_object, js_string(vm, move(flags))));
// 7. Let lastIndex be ? ToLength(? Get(R, "lastIndex")).
auto last_index_value = TRY(regexp_object->get(vm.names.lastIndex));
@ -694,7 +691,7 @@ JS_DEFINE_NATIVE_FUNCTION(RegExpPrototype::symbol_replace)
// 14. For each element result of results, do
for (auto& result : results) {
// a. Let resultLength be ? LengthOfArrayLike(result).
size_t result_length = TRY(length_of_array_like(global_object, *result));
size_t result_length = TRY(length_of_array_like(vm, *result));
// b. Let nCaptures be max(resultLength - 1, 0).
size_t n_captures = result_length == 0 ? 0 : result_length - 1;
@ -761,7 +758,7 @@ JS_DEFINE_NATIVE_FUNCTION(RegExpPrototype::symbol_replace)
}
// v. Let replValue be ? Call(replaceValue, undefined, replacerArgs).
auto replace_result = TRY(call(global_object, replace_value.as_function(), js_undefined(), move(replacer_args)));
auto replace_result = TRY(call(vm, replace_value.as_function(), js_undefined(), move(replacer_args)));
// vi. Let replacement be ? ToString(replValue).
replacement = TRY(replace_result.to_string(vm));
@ -775,7 +772,7 @@ JS_DEFINE_NATIVE_FUNCTION(RegExpPrototype::symbol_replace)
}
// ii. Let replacement be ? GetSubstitution(matched, S, position, captures, namedCaptures, replaceValue).
replacement = TRY(get_substitution(global_object, matched.view(), string.view(), position, captures, named_captures, replace_value));
replacement = TRY(get_substitution(vm, matched.view(), string.view(), position, captures, named_captures, replace_value));
}
// m. If position ≥ nextSourcePosition, then
@ -879,7 +876,7 @@ JS_DEFINE_NATIVE_FUNCTION(RegExpPrototype::symbol_split)
auto string = TRY(vm.argument(0).to_utf16_string(vm));
// 4. Let C be ? SpeciesConstructor(rx, %RegExp%).
auto* constructor = TRY(species_constructor(global_object, *regexp_object, *global_object.regexp_constructor()));
auto* constructor = TRY(species_constructor(vm, *regexp_object, *global_object.regexp_constructor()));
// 5. Let flags be ? ToString(? Get(rx, "flags")).
auto flags_value = TRY(regexp_object->get(vm.names.flags));
@ -894,7 +891,7 @@ JS_DEFINE_NATIVE_FUNCTION(RegExpPrototype::symbol_split)
auto new_flags = flags.find('y').has_value() ? move(flags) : String::formatted("{}y", flags);
// 10. Let splitter be ? Construct(C, « rx, newFlags »).
auto* splitter = TRY(construct(global_object, *constructor, regexp_object, js_string(vm, move(new_flags))));
auto* splitter = TRY(construct(vm, *constructor, regexp_object, js_string(vm, move(new_flags))));
// 11. Let A be ! ArrayCreate(0).
auto* array = MUST(Array::create(realm, 0));
@ -982,7 +979,7 @@ JS_DEFINE_NATIVE_FUNCTION(RegExpPrototype::symbol_split)
last_match_end = last_index;
// 6. Let numberOfCaptures be ? LengthOfArrayLike(z).
auto number_of_captures = TRY(length_of_array_like(global_object, result.as_object()));
auto number_of_captures = TRY(length_of_array_like(vm, result.as_object()));
// 7. Set numberOfCaptures to max(numberOfCaptures - 1, 0).
if (number_of_captures > 0)

View file

@ -42,9 +42,8 @@ ThrowCompletionOr<Value> SetConstructor::call()
ThrowCompletionOr<Object*> SetConstructor::construct(FunctionObject& new_target)
{
auto& vm = this->vm();
auto& global_object = this->global_object();
auto* set = TRY(ordinary_create_from_constructor<Set>(global_object, new_target, &GlobalObject::set_prototype));
auto* set = TRY(ordinary_create_from_constructor<Set>(vm, new_target, &GlobalObject::set_prototype));
if (vm.argument(0).is_nullish())
return set;
@ -54,7 +53,7 @@ ThrowCompletionOr<Object*> SetConstructor::construct(FunctionObject& new_target)
return vm.throw_completion<TypeError>(ErrorType::NotAFunction, "'add' property of Set");
(void)TRY(get_iterator_values(vm, vm.argument(0), [&](Value iterator_value) -> Optional<Completion> {
TRY(JS::call(global_object, adder.as_function(), set, iterator_value));
TRY(JS::call(vm, adder.as_function(), set, iterator_value));
return {};
}));

View file

@ -85,7 +85,7 @@ JS_DEFINE_NATIVE_FUNCTION(SetPrototype::for_each)
return vm.throw_completion<TypeError>(ErrorType::NotAFunction, vm.argument(0).to_string_without_side_effects());
auto this_value = vm.this_value();
for (auto& entry : *set)
TRY(call(global_object, vm.argument(0).as_function(), vm.argument(1), entry.key, entry.key, this_value));
TRY(call(vm, vm.argument(0).as_function(), vm.argument(1), entry.key, entry.key, this_value));
return js_undefined();
}

View file

@ -164,7 +164,7 @@ ThrowCompletionOr<Value> perform_shadow_realm_eval(VM& vm, StringView source_tex
TRY(vm.push_execution_context(eval_context, eval_realm.global_object()));
// 16. Let result be Completion(EvalDeclarationInstantiation(body, varEnv, lexEnv, null, strictEval)).
auto eval_result = eval_declaration_instantiation(vm, eval_realm.global_object(), program, variable_environment, lexical_environment, nullptr, strict_eval);
auto eval_result = eval_declaration_instantiation(vm, program, variable_environment, lexical_environment, nullptr, strict_eval);
Completion result;

View file

@ -40,7 +40,6 @@ ThrowCompletionOr<Value> ShadowRealmConstructor::call()
ThrowCompletionOr<Object*> ShadowRealmConstructor::construct(FunctionObject& new_target)
{
auto& vm = this->vm();
auto& global_object = this->global_object();
// 3. Let realmRec be CreateRealm().
auto* realm = Realm::create(vm);
@ -60,7 +59,7 @@ ThrowCompletionOr<Object*> ShadowRealmConstructor::construct(FunctionObject& new
// 2. Let O be ? OrdinaryCreateFromConstructor(NewTarget, "%ShadowRealm.prototype%", « [[ShadowRealm]], [[ExecutionContext]] »).
// 4. Set O.[[ShadowRealm]] to realmRec.
// 9. Set O.[[ExecutionContext]] to context.
auto* object = TRY(ordinary_create_from_constructor<ShadowRealm>(global_object, new_target, &GlobalObject::shadow_realm_prototype, *realm, move(context)));
auto* object = TRY(ordinary_create_from_constructor<ShadowRealm>(vm, new_target, &GlobalObject::shadow_realm_prototype, *realm, move(context)));
// 10. Perform ? SetRealmGlobalObject(realmRec, undefined, undefined).
auto* new_global_object = vm.heap().allocate_without_realm<GlobalObject>(*realm);

View file

@ -61,7 +61,7 @@ ThrowCompletionOr<Object*> StringConstructor::construct(FunctionObject& new_targ
primitive_string = js_string(vm, "");
else
primitive_string = TRY(vm.argument(0).to_primitive_string(vm));
auto* prototype = TRY(get_prototype_from_constructor(global_object, new_target, &GlobalObject::string_prototype));
auto* prototype = TRY(get_prototype_from_constructor(vm, new_target, &GlobalObject::string_prototype));
return StringObject::create(realm, *primitive_string, *prototype);
}
@ -71,7 +71,7 @@ JS_DEFINE_NATIVE_FUNCTION(StringConstructor::raw)
auto* cooked = TRY(vm.argument(0).to_object(vm));
auto raw_value = TRY(cooked->get(vm.names.raw));
auto* raw = TRY(raw_value.to_object(vm));
auto literal_segments = TRY(length_of_array_like(global_object, *raw));
auto literal_segments = TRY(length_of_array_like(vm, *raw));
if (literal_segments == 0)
return js_string(vm, "");

View file

@ -34,19 +34,13 @@ namespace JS {
static ThrowCompletionOr<String> ak_string_from(VM& vm)
{
auto& realm = *vm.current_realm();
auto& global_object = realm.global_object();
auto this_value = TRY(require_object_coercible(global_object, vm.this_value()));
auto this_value = TRY(require_object_coercible(vm, vm.this_value()));
return TRY(this_value.to_string(vm));
}
static ThrowCompletionOr<Utf16String> utf16_string_from(VM& vm)
{
auto& realm = *vm.current_realm();
auto& global_object = realm.global_object();
auto this_value = TRY(require_object_coercible(global_object, vm.this_value()));
auto this_value = TRY(require_object_coercible(vm, vm.this_value()));
return TRY(this_value.to_utf16_string(vm));
}
@ -491,11 +485,8 @@ JS_DEFINE_NATIVE_FUNCTION(StringPrototype::pad_end)
ThrowCompletionOr<String> trim_string(VM& vm, Value input_value, TrimMode where)
{
auto& realm = *vm.current_realm();
auto& global_object = realm.global_object();
// 1. Let str be ? RequireObjectCoercible(string).
auto input_string = TRY(require_object_coercible(global_object, input_value));
auto input_string = TRY(require_object_coercible(vm, input_value));
// 2. Let S be ? ToString(str).
auto string = TRY(input_string.to_string(vm));
@ -533,7 +524,7 @@ JS_DEFINE_NATIVE_FUNCTION(StringPrototype::trim_end)
JS_DEFINE_NATIVE_FUNCTION(StringPrototype::concat)
{
// 1. Let O be ? RequireObjectCoercible(this value).
auto object = TRY(require_object_coercible(global_object, vm.this_value()));
auto object = TRY(require_object_coercible(vm, vm.this_value()));
// 2. Let S be ? ToString(O).
auto* string = TRY(object.to_primitive_string(vm));
@ -659,7 +650,7 @@ JS_DEFINE_NATIVE_FUNCTION(StringPrototype::split)
{
auto& realm = *global_object.associated_realm();
auto object = TRY(require_object_coercible(global_object, vm.this_value()));
auto object = TRY(require_object_coercible(vm, vm.this_value()));
auto separator_argument = vm.argument(0);
auto limit_argument = vm.argument(1);
@ -667,7 +658,7 @@ JS_DEFINE_NATIVE_FUNCTION(StringPrototype::split)
if (!separator_argument.is_nullish()) {
auto splitter = TRY(separator_argument.get_method(vm, *vm.well_known_symbol_split()));
if (splitter)
return TRY(call(global_object, *splitter, separator_argument, object, limit_argument));
return TRY(call(vm, *splitter, separator_argument, object, limit_argument));
}
auto string = TRY(object.to_utf16_string(vm));
@ -782,7 +773,7 @@ JS_DEFINE_NATIVE_FUNCTION(StringPrototype::symbol_iterator)
{
auto& realm = *global_object.associated_realm();
auto this_object = TRY(require_object_coercible(global_object, vm.this_value()));
auto this_object = TRY(require_object_coercible(vm, vm.this_value()));
auto string = TRY(this_object.to_string(vm));
return StringIterator::create(realm, string);
}
@ -790,11 +781,11 @@ JS_DEFINE_NATIVE_FUNCTION(StringPrototype::symbol_iterator)
// 22.1.3.12 String.prototype.match ( regexp ), https://tc39.es/ecma262/#sec-string.prototype.match
JS_DEFINE_NATIVE_FUNCTION(StringPrototype::match)
{
auto this_object = TRY(require_object_coercible(global_object, vm.this_value()));
auto this_object = TRY(require_object_coercible(vm, vm.this_value()));
auto regexp = vm.argument(0);
if (!regexp.is_nullish()) {
if (auto* matcher = TRY(regexp.get_method(vm, *vm.well_known_symbol_match())))
return TRY(call(global_object, *matcher, regexp, this_object));
return TRY(call(vm, *matcher, regexp, this_object));
}
auto string = TRY(this_object.to_utf16_string(vm));
@ -806,19 +797,19 @@ JS_DEFINE_NATIVE_FUNCTION(StringPrototype::match)
// 22.1.3.13 String.prototype.matchAll ( regexp ), https://tc39.es/ecma262/#sec-string.prototype.matchall
JS_DEFINE_NATIVE_FUNCTION(StringPrototype::match_all)
{
auto this_object = TRY(require_object_coercible(global_object, vm.this_value()));
auto this_object = TRY(require_object_coercible(vm, vm.this_value()));
auto regexp = vm.argument(0);
if (!regexp.is_nullish()) {
auto is_regexp = TRY(regexp.is_regexp(vm));
if (is_regexp) {
auto flags = TRY(regexp.as_object().get("flags"));
auto flags_object = TRY(require_object_coercible(global_object, flags));
auto flags_object = TRY(require_object_coercible(vm, flags));
auto flags_string = TRY(flags_object.to_string(vm));
if (!flags_string.contains('g'))
return vm.throw_completion<TypeError>(ErrorType::StringNonGlobalRegExp);
}
if (auto* matcher = TRY(regexp.get_method(vm, *vm.well_known_symbol_match_all())))
return TRY(call(global_object, *matcher, regexp, this_object));
return TRY(call(vm, *matcher, regexp, this_object));
}
auto string = TRY(this_object.to_utf16_string(vm));
@ -855,13 +846,13 @@ JS_DEFINE_NATIVE_FUNCTION(StringPrototype::normalize)
// 22.1.3.18 String.prototype.replace ( searchValue, replaceValue ), https://tc39.es/ecma262/#sec-string.prototype.replace
JS_DEFINE_NATIVE_FUNCTION(StringPrototype::replace)
{
auto this_object = TRY(require_object_coercible(global_object, vm.this_value()));
auto this_object = TRY(require_object_coercible(vm, vm.this_value()));
auto search_value = vm.argument(0);
auto replace_value = vm.argument(1);
if (!search_value.is_nullish()) {
if (auto* replacer = TRY(search_value.get_method(vm, *vm.well_known_symbol_replace())))
return TRY(call(global_object, *replacer, search_value, this_object, replace_value));
return TRY(call(vm, *replacer, search_value, this_object, replace_value));
}
auto string = TRY(this_object.to_utf16_string(vm));
@ -880,10 +871,10 @@ JS_DEFINE_NATIVE_FUNCTION(StringPrototype::replace)
String replacement;
if (replace_value.is_function()) {
auto result = TRY(call(global_object, replace_value.as_function(), js_undefined(), js_string(vm, search_string), Value(position.value()), js_string(vm, string)));
auto result = TRY(call(vm, replace_value.as_function(), js_undefined(), js_string(vm, search_string), Value(position.value()), js_string(vm, string)));
replacement = TRY(result.to_string(vm));
} else {
replacement = TRY(get_substitution(global_object, search_string.view(), string.view(), *position, {}, js_undefined(), replace_value));
replacement = TRY(get_substitution(vm, search_string.view(), string.view(), *position, {}, js_undefined(), replace_value));
}
StringBuilder builder;
@ -897,7 +888,7 @@ JS_DEFINE_NATIVE_FUNCTION(StringPrototype::replace)
// 22.1.3.19 String.prototype.replaceAll ( searchValue, replaceValue ), https://tc39.es/ecma262/#sec-string.prototype.replaceall
JS_DEFINE_NATIVE_FUNCTION(StringPrototype::replace_all)
{
auto this_object = TRY(require_object_coercible(global_object, vm.this_value()));
auto this_object = TRY(require_object_coercible(vm, vm.this_value()));
auto search_value = vm.argument(0);
auto replace_value = vm.argument(1);
@ -906,7 +897,7 @@ JS_DEFINE_NATIVE_FUNCTION(StringPrototype::replace_all)
if (is_regexp) {
auto flags = TRY(search_value.as_object().get(vm.names.flags));
auto flags_object = TRY(require_object_coercible(global_object, flags));
auto flags_object = TRY(require_object_coercible(vm, flags));
auto flags_string = TRY(flags_object.to_string(vm));
if (!flags_string.contains('g'))
return vm.throw_completion<TypeError>(ErrorType::StringNonGlobalRegExp);
@ -914,7 +905,7 @@ JS_DEFINE_NATIVE_FUNCTION(StringPrototype::replace_all)
auto* replacer = TRY(search_value.get_method(vm, *vm.well_known_symbol_replace()));
if (replacer)
return TRY(call(global_object, *replacer, search_value, this_object, replace_value));
return TRY(call(vm, *replacer, search_value, this_object, replace_value));
}
auto string = TRY(this_object.to_utf16_string(vm));
@ -945,10 +936,10 @@ JS_DEFINE_NATIVE_FUNCTION(StringPrototype::replace_all)
String replacement;
if (replace_value.is_function()) {
auto result = TRY(call(global_object, replace_value.as_function(), js_undefined(), js_string(vm, search_string), Value(position), js_string(vm, string)));
auto result = TRY(call(vm, replace_value.as_function(), js_undefined(), js_string(vm, search_string), Value(position), js_string(vm, string)));
replacement = TRY(result.to_string(vm));
} else {
replacement = TRY(get_substitution(global_object, search_string.view(), string.view(), position, {}, js_undefined(), replace_value));
replacement = TRY(get_substitution(vm, search_string.view(), string.view(), position, {}, js_undefined(), replace_value));
}
result.append(preserved);
@ -966,11 +957,11 @@ JS_DEFINE_NATIVE_FUNCTION(StringPrototype::replace_all)
// 22.1.3.20 String.prototype.search ( regexp ), https://tc39.es/ecma262/#sec-string.prototype.search
JS_DEFINE_NATIVE_FUNCTION(StringPrototype::search)
{
auto this_object = TRY(require_object_coercible(global_object, vm.this_value()));
auto this_object = TRY(require_object_coercible(vm, vm.this_value()));
auto regexp = vm.argument(0);
if (!regexp.is_nullish()) {
if (auto* searcher = TRY(regexp.get_method(vm, *vm.well_known_symbol_search())))
return TRY(call(global_object, *searcher, regexp, this_object));
return TRY(call(vm, *searcher, regexp, this_object));
}
auto string = TRY(this_object.to_utf16_string(vm));
@ -982,10 +973,7 @@ JS_DEFINE_NATIVE_FUNCTION(StringPrototype::search)
// B.2.2.2.1 CreateHTML ( string, tag, attribute, value ), https://tc39.es/ecma262/#sec-createhtml
static ThrowCompletionOr<Value> create_html(VM& vm, Value string, String const& tag, String const& attribute, Value value)
{
auto& realm = *vm.current_realm();
auto& global_object = realm.global_object();
TRY(require_object_coercible(global_object, string));
TRY(require_object_coercible(vm, string));
auto str = TRY(string.to_string(vm));
StringBuilder builder;
builder.append('<');
@ -1089,7 +1077,7 @@ JS_DEFINE_NATIVE_FUNCTION(StringPrototype::sup)
JS_DEFINE_NATIVE_FUNCTION(StringPrototype::locale_compare)
{
// 1. Let O be ? RequireObjectCoercible(this value).
auto object = TRY(require_object_coercible(global_object, vm.this_value()));
auto object = TRY(require_object_coercible(vm, vm.this_value()));
// 2. Let S be ? ToString(O).
auto string = TRY(object.to_string(vm));
@ -1098,7 +1086,7 @@ JS_DEFINE_NATIVE_FUNCTION(StringPrototype::locale_compare)
auto that_value = TRY(vm.argument(0).to_string(vm));
// 4. Let collator be ? Construct(%Collator%, « locales, options »).
auto* collator = TRY(construct(global_object, *global_object.intl_collator_constructor(), vm.argument(1), vm.argument(2)));
auto* collator = TRY(construct(vm, *global_object.intl_collator_constructor(), vm.argument(1), vm.argument(2)));
// 5. Return CompareStrings(collator, S, thatValue).
return Intl::compare_strings(static_cast<Intl::Collator&>(*collator), Utf8View(string), Utf8View(that_value));

View file

@ -75,7 +75,7 @@ ThrowCompletionOr<Calendar*> create_temporal_calendar(VM& vm, String const& iden
// 3. Let object be ? OrdinaryCreateFromConstructor(newTarget, "%Temporal.Calendar.prototype%", « [[InitializedTemporalCalendar]], [[Identifier]] »).
// 4. Set object.[[Identifier]] to identifier.
auto* object = TRY(ordinary_create_from_constructor<Calendar>(global_object, *new_target, &GlobalObject::temporal_calendar_prototype, identifier));
auto* object = TRY(ordinary_create_from_constructor<Calendar>(vm, *new_target, &GlobalObject::temporal_calendar_prototype, identifier));
// 5. Return object.
return object;
@ -103,7 +103,6 @@ Calendar* get_iso8601_calendar(VM& vm)
ThrowCompletionOr<Vector<String>> calendar_fields(VM& vm, Object& calendar, Vector<StringView> const& field_names)
{
auto& realm = *vm.current_realm();
auto& global_object = realm.global_object();
// 1. Let fields be ? GetMethod(calendar, "fields").
auto fields = TRY(Value(&calendar).get_method(vm, vm.names.fields));
@ -117,7 +116,7 @@ ThrowCompletionOr<Vector<String>> calendar_fields(VM& vm, Object& calendar, Vect
// 3. If fields is not undefined, then
if (fields) {
// a. Set fieldsArray to ? Call(fields, calendar, « fieldsArray »).
fields_array = TRY(call(global_object, *fields, &calendar, fields_array));
fields_array = TRY(call(vm, *fields, &calendar, fields_array));
}
// 4. Return ? IterableToListOfType(fieldsArray, « String »).
@ -132,9 +131,6 @@ ThrowCompletionOr<Vector<String>> calendar_fields(VM& vm, Object& calendar, Vect
// 12.2.5 CalendarMergeFields ( calendar, fields, additionalFields ), https://tc39.es/proposal-temporal/#sec-temporal-calendarmergefields
ThrowCompletionOr<Object*> calendar_merge_fields(VM& vm, Object& calendar, Object& fields, Object& additional_fields)
{
auto& realm = *vm.current_realm();
auto& global_object = realm.global_object();
// 1. Let mergeFields be ? GetMethod(calendar, "mergeFields").
auto* merge_fields = TRY(Value(&calendar).get_method(vm, vm.names.mergeFields));
@ -145,7 +141,7 @@ ThrowCompletionOr<Object*> calendar_merge_fields(VM& vm, Object& calendar, Objec
}
// 3. Let result be ? Call(mergeFields, calendar, « fields, additionalFields »).
auto result = TRY(call(global_object, merge_fields, &calendar, &fields, &additional_fields));
auto result = TRY(call(vm, merge_fields, &calendar, &fields, &additional_fields));
// 4. If Type(result) is not Object, throw a TypeError exception.
if (!result.is_object())
@ -159,8 +155,6 @@ ThrowCompletionOr<Object*> calendar_merge_fields(VM& vm, Object& calendar, Objec
ThrowCompletionOr<PlainDate*> calendar_date_add(VM& vm, Object& calendar, Value date, Duration& duration, Object* options, FunctionObject* date_add)
{
// NOTE: `date` is a `Value` because we sometimes need to pass a PlainDate, sometimes a PlainDateTime, and sometimes undefined.
auto& realm = *vm.current_realm();
auto& global_object = realm.global_object();
// 1. Assert: Type(calendar) is Object.
// 2. If options is not present, set options to undefined.
@ -171,7 +165,7 @@ ThrowCompletionOr<PlainDate*> calendar_date_add(VM& vm, Object& calendar, Value
date_add = TRY(Value(&calendar).get_method(vm, vm.names.dateAdd));
// 5. Let addedDate be ? Call(dateAdd, calendar, « date, duration, options »).
auto added_date = TRY(call(global_object, date_add ?: js_undefined(), &calendar, date, &duration, options ?: js_undefined()));
auto added_date = TRY(call(vm, date_add ?: js_undefined(), &calendar, date, &duration, options ?: js_undefined()));
// 6. Perform ? RequireInternalSlot(addedDate, [[InitializedTemporalDate]]).
auto* added_date_object = TRY(added_date.to_object(vm));
@ -185,9 +179,6 @@ ThrowCompletionOr<PlainDate*> calendar_date_add(VM& vm, Object& calendar, Value
// 12.2.7 CalendarDateUntil ( calendar, one, two, options [ , dateUntil ] ), https://tc39.es/proposal-temporal/#sec-temporal-calendardateuntil
ThrowCompletionOr<Duration*> calendar_date_until(VM& vm, Object& calendar, Value one, Value two, Object& options, FunctionObject* date_until)
{
auto& realm = *vm.current_realm();
auto& global_object = realm.global_object();
// 1. Assert: Type(calendar) is Object.
// 2. If dateUntil is not present, set dateUntil to ? GetMethod(calendar, "dateUntil").
@ -195,7 +186,7 @@ ThrowCompletionOr<Duration*> calendar_date_until(VM& vm, Object& calendar, Value
date_until = TRY(Value(&calendar).get_method(vm, vm.names.dateUntil));
// 3. Let duration be ? Call(dateUntil, calendar, « one, two, options »).
auto duration = TRY(call(global_object, date_until ?: js_undefined(), &calendar, one, two, &options));
auto duration = TRY(call(vm, date_until ?: js_undefined(), &calendar, one, two, &options));
// 4. Perform ? RequireInternalSlot(duration, [[InitializedTemporalDuration]]).
auto* duration_object = TRY(duration.to_object(vm));

View file

@ -348,7 +348,7 @@ ThrowCompletionOr<Duration*> create_temporal_duration(VM& vm, double years, doub
// 11. Set object.[[Milliseconds]] to (𝔽(milliseconds)).
// 12. Set object.[[Microseconds]] to (𝔽(microseconds)).
// 13. Set object.[[Nanoseconds]] to (𝔽(nanoseconds)).
auto* object = TRY(ordinary_create_from_constructor<Duration>(global_object, *new_target, &GlobalObject::temporal_duration_prototype, years, months, weeks, days, hours, minutes, seconds, milliseconds, microseconds, nanoseconds));
auto* object = TRY(ordinary_create_from_constructor<Duration>(vm, *new_target, &GlobalObject::temporal_duration_prototype, years, months, weeks, days, hours, minutes, seconds, milliseconds, microseconds, nanoseconds));
// 14. Return object.
return object;

View file

@ -66,7 +66,7 @@ ThrowCompletionOr<Instant*> create_temporal_instant(VM& vm, BigInt const& epoch_
// 4. Let object be ? OrdinaryCreateFromConstructor(newTarget, "%Temporal.Instant.prototype%", « [[InitializedTemporalInstant]], [[Nanoseconds]] »).
// 5. Set object.[[Nanoseconds]] to epochNanoseconds.
auto* object = TRY(ordinary_create_from_constructor<Instant>(global_object, *new_target, &GlobalObject::temporal_instant_prototype, epoch_nanoseconds));
auto* object = TRY(ordinary_create_from_constructor<Instant>(vm, *new_target, &GlobalObject::temporal_instant_prototype, epoch_nanoseconds));
// 6. Return object.
return object;

View file

@ -75,7 +75,7 @@ ThrowCompletionOr<PlainDate*> create_temporal_date(VM& vm, i32 iso_year, u8 iso_
// 10. Set object.[[ISOMonth]] to isoMonth.
// 11. Set object.[[ISODay]] to isoDay.
// 12. Set object.[[Calendar]] to calendar.
auto* object = TRY(ordinary_create_from_constructor<PlainDate>(global_object, *new_target, &GlobalObject::temporal_plain_date_prototype, iso_year, iso_month, iso_day, calendar));
auto* object = TRY(ordinary_create_from_constructor<PlainDate>(vm, *new_target, &GlobalObject::temporal_plain_date_prototype, iso_year, iso_month, iso_day, calendar));
return object;
}

View file

@ -262,7 +262,7 @@ ThrowCompletionOr<PlainDateTime*> create_temporal_date_time(VM& vm, i32 iso_year
// 15. Set object.[[ISOMicrosecond]] to microsecond.
// 16. Set object.[[ISONanosecond]] to nanosecond.
// 17. Set object.[[Calendar]] to calendar.
auto* object = TRY(ordinary_create_from_constructor<PlainDateTime>(global_object, *new_target, &GlobalObject::temporal_plain_date_prototype, iso_year, iso_month, iso_day, hour, minute, second, millisecond, microsecond, nanosecond, calendar));
auto* object = TRY(ordinary_create_from_constructor<PlainDateTime>(vm, *new_target, &GlobalObject::temporal_plain_date_prototype, iso_year, iso_month, iso_day, hour, minute, second, millisecond, microsecond, nanosecond, calendar));
// 18. Return object.
return object;

View file

@ -167,7 +167,7 @@ ThrowCompletionOr<PlainMonthDay*> create_temporal_month_day(VM& vm, u8 iso_month
// 8. Set object.[[ISODay]] to isoDay.
// 9. Set object.[[Calendar]] to calendar.
// 10. Set object.[[ISOYear]] to referenceISOYear.
auto* object = TRY(ordinary_create_from_constructor<PlainMonthDay>(global_object, *new_target, &GlobalObject::temporal_plain_month_day_prototype, iso_month, iso_day, reference_iso_year, calendar));
auto* object = TRY(ordinary_create_from_constructor<PlainMonthDay>(vm, *new_target, &GlobalObject::temporal_plain_month_day_prototype, iso_month, iso_day, reference_iso_year, calendar));
// 11. Return object.
return object;

View file

@ -331,7 +331,7 @@ ThrowCompletionOr<PlainTime*> create_temporal_time(VM& vm, u8 hour, u8 minute, u
// 9. Set object.[[ISOMicrosecond]] to microsecond.
// 10. Set object.[[ISONanosecond]] to nanosecond.
// 11. Set object.[[Calendar]] to ! GetISO8601Calendar().
auto* object = TRY(ordinary_create_from_constructor<PlainTime>(global_object, *new_target, &GlobalObject::temporal_plain_time_prototype, hour, minute, second, millisecond, microsecond, nanosecond, *get_iso8601_calendar(vm)));
auto* object = TRY(ordinary_create_from_constructor<PlainTime>(vm, *new_target, &GlobalObject::temporal_plain_time_prototype, hour, minute, second, millisecond, microsecond, nanosecond, *get_iso8601_calendar(vm)));
// 12. Return object.
return object;

View file

@ -208,7 +208,7 @@ ThrowCompletionOr<PlainYearMonth*> create_temporal_year_month(VM& vm, i32 iso_ye
// 8. Set object.[[ISOMonth]] to isoMonth.
// 9. Set object.[[Calendar]] to calendar.
// 10. Set object.[[ISODay]] to referenceISODay.
auto* object = TRY(ordinary_create_from_constructor<PlainYearMonth>(global_object, *new_target, &GlobalObject::temporal_plain_year_month_prototype, iso_year, iso_month, reference_iso_day, calendar));
auto* object = TRY(ordinary_create_from_constructor<PlainYearMonth>(vm, *new_target, &GlobalObject::temporal_plain_year_month_prototype, iso_year, iso_month, reference_iso_day, calendar));
// 11. Return object.
return object;

View file

@ -73,7 +73,7 @@ ThrowCompletionOr<TimeZone*> create_temporal_time_zone(VM& vm, String const& ide
new_target = global_object.temporal_time_zone_constructor();
// 2. Let object be ? OrdinaryCreateFromConstructor(newTarget, "%Temporal.TimeZone.prototype%", « [[InitializedTemporalTimeZone]], [[Identifier]], [[OffsetNanoseconds]] »).
auto* object = TRY(ordinary_create_from_constructor<TimeZone>(global_object, *new_target, &GlobalObject::temporal_time_zone_prototype));
auto* object = TRY(ordinary_create_from_constructor<TimeZone>(vm, *new_target, &GlobalObject::temporal_time_zone_prototype));
// 3. Let offsetNanosecondsResult be Completion(ParseTimeZoneOffsetString(identifier)).
auto offset_nanoseconds_result = parse_time_zone_offset_string(vm, identifier);
@ -476,14 +476,11 @@ ThrowCompletionOr<Object*> to_temporal_time_zone(VM& vm, Value temporal_time_zon
// 11.6.11 GetOffsetNanosecondsFor ( timeZone, instant ), https://tc39.es/proposal-temporal/#sec-temporal-getoffsetnanosecondsfor
ThrowCompletionOr<double> get_offset_nanoseconds_for(VM& vm, Value time_zone, Instant& instant)
{
auto& realm = *vm.current_realm();
auto& global_object = realm.global_object();
// 1. Let getOffsetNanosecondsFor be ? GetMethod(timeZone, "getOffsetNanosecondsFor").
auto* get_offset_nanoseconds_for = TRY(time_zone.get_method(vm, vm.names.getOffsetNanosecondsFor));
// 2. Let offsetNanoseconds be ? Call(getOffsetNanosecondsFor, timeZone, « instant »).
auto offset_nanoseconds_value = TRY(call(global_object, get_offset_nanoseconds_for, time_zone, &instant));
auto offset_nanoseconds_value = TRY(call(vm, get_offset_nanoseconds_for, time_zone, &instant));
// 3. If Type(offsetNanoseconds) is not Number, throw a TypeError exception.
if (!offset_nanoseconds_value.is_number())

View file

@ -281,7 +281,7 @@ ThrowCompletionOr<ZonedDateTime*> create_temporal_zoned_date_time(VM& vm, BigInt
// 4. Set object.[[Nanoseconds]] to epochNanoseconds.
// 5. Set object.[[TimeZone]] to timeZone.
// 6. Set object.[[Calendar]] to calendar.
auto* object = TRY(ordinary_create_from_constructor<ZonedDateTime>(global_object, *new_target, &GlobalObject::temporal_time_zone_prototype, epoch_nanoseconds, time_zone, calendar));
auto* object = TRY(ordinary_create_from_constructor<ZonedDateTime>(vm, *new_target, &GlobalObject::temporal_time_zone_prototype, epoch_nanoseconds, time_zone, calendar));
// 7. Return object.
return object;

View file

@ -264,11 +264,8 @@ static ThrowCompletionOr<void> allocate_typed_array_buffer(VM& vm, TypedArray<T>
template<typename T>
static ThrowCompletionOr<void> initialize_typed_array_from_array_like(VM& vm, TypedArray<T>& typed_array, Object const& array_like)
{
auto& realm = *vm.current_realm();
auto& global_object = realm.global_object();
// 1. Let len be ? LengthOfArrayLike(arrayLike).
auto length = TRY(length_of_array_like(global_object, array_like));
auto length = TRY(length_of_array_like(vm, array_like));
// 2. Perform ? AllocateTypedArrayBuffer(O, len).
TRY(allocate_typed_array_buffer(vm, typed_array, length));
@ -321,14 +318,11 @@ static ThrowCompletionOr<void> initialize_typed_array_from_list(VM& vm, TypedArr
// 23.2.4.2 TypedArrayCreate ( constructor, argumentList ), https://tc39.es/ecma262/#typedarray-create
ThrowCompletionOr<TypedArrayBase*> typed_array_create(VM& vm, FunctionObject& constructor, MarkedVector<Value> arguments)
{
auto& realm = *vm.current_realm();
auto& global_object = realm.global_object();
Optional<Value> first_argument;
if (!arguments.is_empty())
first_argument = arguments[0];
// 1. Let newTypedArray be ? Construct(constructor, argumentList).
auto* new_typed_array = TRY(construct(global_object, constructor, move(arguments)));
auto* new_typed_array = TRY(construct(vm, constructor, move(arguments)));
// 2. Perform ? ValidateTypedArray(newTypedArray).
if (!new_typed_array->is_typed_array())
@ -369,16 +363,13 @@ ThrowCompletionOr<TypedArrayBase*> typed_array_create_same_type(VM& vm, TypedArr
// 1.2.2.1.2 CompareTypedArrayElements ( x, y, comparefn, buffer ), https://tc39.es/proposal-change-array-by-copy/#sec-comparetypedarrayelements
ThrowCompletionOr<double> compare_typed_array_elements(VM& vm, Value x, Value y, FunctionObject* comparefn, ArrayBuffer& buffer)
{
auto& realm = *vm.current_realm();
auto& global_object = realm.global_object();
// 1. Assert: Both Type(x) and Type(y) are Number or both are BigInt.
VERIFY(((x.is_number() && y.is_number()) || (x.is_bigint() && y.is_bigint())));
// 2. If comparefn is not undefined, then
if (comparefn != nullptr) {
// a. Let v be ? ToNumber(? Call(comparefn, undefined, « x, y »)).
auto value = TRY(call(global_object, comparefn, js_undefined(), x, y));
auto value = TRY(call(vm, comparefn, js_undefined(), x, y));
auto value_number = TRY(value.to_number(vm));
// b. If IsDetachedBuffer(buffer) is true, throw a TypeError exception.
@ -438,8 +429,7 @@ void TypedArrayBase::visit_edges(Visitor& visitor)
#define JS_DEFINE_TYPED_ARRAY(ClassName, snake_name, PrototypeName, ConstructorName, Type) \
ThrowCompletionOr<ClassName*> ClassName::create(Realm& realm, u32 length, FunctionObject& new_target) \
{ \
auto* prototype = TRY(get_prototype_from_constructor( \
realm.global_object(), new_target, &GlobalObject::snake_name##_prototype)); \
auto* prototype = TRY(get_prototype_from_constructor(realm.vm(), new_target, &GlobalObject::snake_name##_prototype)); \
auto* array_buffer = TRY(ArrayBuffer::create(realm, length * sizeof(UnderlyingBufferDataType))); \
return realm.heap().allocate<ClassName>(realm, *prototype, length, *array_buffer); \
} \

View file

@ -80,7 +80,7 @@ JS_DEFINE_NATIVE_FUNCTION(TypedArrayConstructor::from)
auto k_value = values[k];
Value mapped_value;
if (map_fn)
mapped_value = TRY(JS::call(global_object, *map_fn, this_arg, k_value, Value(k)));
mapped_value = TRY(JS::call(vm, *map_fn, this_arg, k_value, Value(k)));
else
mapped_value = k_value;
TRY(target_object->set(k, mapped_value, Object::ShouldThrowExceptions::Yes));
@ -90,7 +90,7 @@ JS_DEFINE_NATIVE_FUNCTION(TypedArrayConstructor::from)
}
auto array_like = MUST(source.to_object(vm));
auto length = TRY(length_of_array_like(global_object, *array_like));
auto length = TRY(length_of_array_like(vm, *array_like));
MarkedVector<Value> arguments(vm.heap());
arguments.empend(length);
@ -100,7 +100,7 @@ JS_DEFINE_NATIVE_FUNCTION(TypedArrayConstructor::from)
auto k_value = TRY(array_like->get(k));
Value mapped_value;
if (map_fn)
mapped_value = TRY(JS::call(global_object, *map_fn, this_arg, k_value, Value(k)));
mapped_value = TRY(JS::call(vm, *map_fn, this_arg, k_value, Value(k)));
else
mapped_value = k_value;
TRY(target_object->set(k, mapped_value, Object::ShouldThrowExceptions::Yes));

View file

@ -98,9 +98,6 @@ static ThrowCompletionOr<FunctionObject*> callback_from_args(VM& vm, String cons
static ThrowCompletionOr<void> for_each_item(VM& vm, String const& name, Function<IterationDecision(size_t index, Value value, Value callback_result)> callback)
{
auto& realm = *vm.current_realm();
auto& global_object = realm.global_object();
auto* typed_array = TRY(validate_typed_array_from_this(vm));
auto initial_length = typed_array->array_length();
@ -112,7 +109,7 @@ static ThrowCompletionOr<void> for_each_item(VM& vm, String const& name, Functio
for (size_t i = 0; i < initial_length; ++i) {
auto value = TRY(typed_array->get(i));
auto callback_result = TRY(call(global_object, *callback_function, this_value, value, Value((i32)i), typed_array));
auto callback_result = TRY(call(vm, *callback_function, this_value, value, Value((i32)i), typed_array));
if (callback(i, value, callback_result) == IterationDecision::Break)
break;
@ -123,9 +120,6 @@ static ThrowCompletionOr<void> for_each_item(VM& vm, String const& name, Functio
static ThrowCompletionOr<void> for_each_item_from_last(VM& vm, String const& name, Function<IterationDecision(size_t index, Value value, Value callback_result)> callback)
{
auto& realm = *vm.current_realm();
auto& global_object = realm.global_object();
auto* typed_array = TRY(validate_typed_array_from_this(vm));
auto initial_length = typed_array->array_length();
@ -137,7 +131,7 @@ static ThrowCompletionOr<void> for_each_item_from_last(VM& vm, String const& nam
for (ssize_t i = (ssize_t)initial_length - 1; i >= 0; --i) {
auto value = TRY(typed_array->get(i));
auto callback_result = TRY(call(global_object, *callback_function, this_value, value, Value((i32)i), typed_array));
auto callback_result = TRY(call(vm, *callback_function, this_value, value, Value((i32)i), typed_array));
if (callback(i, value, callback_result) == IterationDecision::Break)
break;
@ -156,7 +150,7 @@ static ThrowCompletionOr<TypedArrayBase*> typed_array_species_create(VM& vm, Typ
auto* default_constructor = (global_object.*exemplar.intrinsic_constructor())();
// 2. Let constructor be ? SpeciesConstructor(exemplar, defaultConstructor).
auto* constructor = TRY(species_constructor(global_object, exemplar, *default_constructor));
auto* constructor = TRY(species_constructor(vm, exemplar, *default_constructor));
// 3. Let result be ? TypedArrayCreate(constructor, argumentList).
auto* result = TRY(typed_array_create(vm, *constructor, move(arguments)));
@ -487,7 +481,7 @@ JS_DEFINE_NATIVE_FUNCTION(TypedArrayPrototype::filter)
auto value = MUST(typed_array->get(i));
// c. Let selected be ToBoolean(? Call(callbackfn, thisArg, « kValue, 𝔽(k), O »)).
auto callback_result = TRY(call(global_object, *callback_function, this_value, value, Value((i32)i), typed_array)).to_boolean();
auto callback_result = TRY(call(vm, *callback_function, this_value, value, Value((i32)i), typed_array)).to_boolean();
// d. If selected is true, then
if (callback_result) {
@ -782,7 +776,7 @@ JS_DEFINE_NATIVE_FUNCTION(TypedArrayPrototype::map)
auto value = MUST(typed_array->get(i));
// c. Let mappedValue be ? Call(callbackfn, thisArg, « kValue, 𝔽(k), O »).
auto mapped_value = TRY(call(global_object, *callback_function, this_value, value, Value((i32)i), typed_array));
auto mapped_value = TRY(call(vm, *callback_function, this_value, value, Value((i32)i), typed_array));
// d. Perform ? Set(A, Pk, mappedValue, true).
TRY(return_array->set(i, mapped_value, Object::ShouldThrowExceptions::Yes));
@ -818,7 +812,7 @@ JS_DEFINE_NATIVE_FUNCTION(TypedArrayPrototype::reduce)
for (; k < length; ++k) {
auto k_value = MUST(typed_array->get(k));
accumulator = TRY(call(global_object, *callback_function, js_undefined(), accumulator, k_value, Value(k), typed_array));
accumulator = TRY(call(vm, *callback_function, js_undefined(), accumulator, k_value, Value(k), typed_array));
}
return accumulator;
@ -848,7 +842,7 @@ JS_DEFINE_NATIVE_FUNCTION(TypedArrayPrototype::reduce_right)
for (; k >= 0; --k) {
auto k_value = MUST(typed_array->get(k));
accumulator = TRY(call(global_object, *callback_function, js_undefined(), accumulator, k_value, Value(k), typed_array));
accumulator = TRY(call(vm, *callback_function, js_undefined(), accumulator, k_value, Value(k), typed_array));
}
return accumulator;
@ -1017,9 +1011,6 @@ static ThrowCompletionOr<void> set_typed_array_from_typed_array(VM& vm, TypedArr
// 23.2.3.26.2 SetTypedArrayFromArrayLike ( target, targetOffset, source ), https://tc39.es/ecma262/#sec-settypedarrayfromarraylike
static ThrowCompletionOr<void> set_typed_array_from_array_like(VM& vm, TypedArrayBase& target, double target_offset, Value source)
{
auto& realm = *vm.current_realm();
auto& global_object = realm.global_object();
// 1. Let targetBuffer be target.[[ViewedArrayBuffer]].
auto* target_buffer = target.viewed_array_buffer();
@ -1034,7 +1025,7 @@ static ThrowCompletionOr<void> set_typed_array_from_array_like(VM& vm, TypedArra
auto* src = TRY(source.to_object(vm));
// 5. Let srcLength be ? LengthOfArrayLike(src).
auto source_length = TRY(length_of_array_like(global_object, *src));
auto source_length = TRY(length_of_array_like(vm, *src));
// 6. If targetOffset is +∞, throw a RangeError exception.
if (isinf(target_offset))
@ -1287,7 +1278,7 @@ JS_DEFINE_NATIVE_FUNCTION(TypedArrayPrototype::sort)
// b. If comparefn is not undefined, then
if (!compare_fn.is_undefined()) {
// i. Let v be ? ToNumber(? Call(comparefn, undefined, « x, y »)).
auto result = TRY(call(global_object, compare_fn.as_function(), js_undefined(), x, y));
auto result = TRY(call(vm, compare_fn.as_function(), js_undefined(), x, y));
auto value = TRY(result.to_number(vm));
// ii. If v is NaN, return +0𝔽.

View file

@ -86,11 +86,11 @@ VM::VM(OwnPtr<CustomData> custom_data)
NativeFunction::create(realm, "", [](auto&, auto&) -> ThrowCompletionOr<Value> {
VERIFY_NOT_REACHED();
}),
NativeFunction::create(realm, "", [reject = make_handle(promise_capability.reject)](auto& vm, auto& global_object) -> ThrowCompletionOr<Value> {
NativeFunction::create(realm, "", [reject = make_handle(promise_capability.reject)](auto& vm, auto&) -> ThrowCompletionOr<Value> {
auto error = vm.argument(0);
// a. Perform ! Call(promiseCapability.[[Reject]], undefined, « error »).
MUST(call(global_object, reject.cell(), js_undefined(), error));
MUST(call(vm, reject.cell(), js_undefined(), error));
// b. Return undefined.
return js_undefined();
@ -264,11 +264,11 @@ ThrowCompletionOr<void> VM::destructuring_assignment_evaluation(NonnullRefPtr<Bi
}
// 8.5.2 Runtime Semantics: BindingInitialization, https://tc39.es/ecma262/#sec-runtime-semantics-bindinginitialization
ThrowCompletionOr<void> VM::binding_initialization(FlyString const& target, Value value, Environment* environment, GlobalObject& global_object)
ThrowCompletionOr<void> VM::binding_initialization(FlyString const& target, Value value, Environment* environment, GlobalObject&)
{
// 1. Let name be StringValue of Identifier.
// 2. Return ? InitializeBoundName(name, value, environment).
return initialize_bound_name(global_object, target, value, environment);
return initialize_bound_name(*this, target, value, environment);
}
// 8.5.2 Runtime Semantics: BindingInitialization, https://tc39.es/ecma262/#sec-runtime-semantics-bindinginitialization
@ -279,7 +279,7 @@ ThrowCompletionOr<void> VM::binding_initialization(NonnullRefPtr<BindingPattern>
// BindingPattern : ObjectBindingPattern
if (target->kind == BindingPattern::Kind::Object) {
// 1. Perform ? RequireObjectCoercible(value).
TRY(require_object_coercible(global_object, value));
TRY(require_object_coercible(vm, value));
// 2. Return ? BindingInitialization of ObjectBindingPattern with arguments value and environment.
@ -1036,7 +1036,7 @@ void VM::finish_dynamic_import(ScriptOrModule referencing_script_or_module, Modu
auto& realm = *current_realm();
// 1. Let fulfilledClosure be a new Abstract Closure with parameters (result) that captures referencingScriptOrModule, specifier, and promiseCapability and performs the following steps when called:
auto fulfilled_closure = [referencing_script_or_module, module_request = move(module_request), resolve_function = make_handle(promise_capability.resolve), reject_function = make_handle(promise_capability.reject)](VM& vm, GlobalObject& global_object) -> ThrowCompletionOr<Value> {
auto fulfilled_closure = [referencing_script_or_module, module_request = move(module_request), resolve_function = make_handle(promise_capability.resolve), reject_function = make_handle(promise_capability.reject)](VM& vm, GlobalObject&) -> ThrowCompletionOr<Value> {
auto result = vm.argument(0);
// a. Assert: result is undefined.
VERIFY(result.is_undefined());
@ -1052,12 +1052,12 @@ void VM::finish_dynamic_import(ScriptOrModule referencing_script_or_module, Modu
// e. If namespace is an abrupt completion, then
if (namespace_.is_throw_completion()) {
// i. Perform ! Call(promiseCapability.[[Reject]], undefined, « namespace.[[Value]] »).
MUST(call(global_object, reject_function.cell(), js_undefined(), *namespace_.throw_completion().value()));
MUST(call(vm, reject_function.cell(), js_undefined(), *namespace_.throw_completion().value()));
}
// f. Else,
else {
// i. Perform ! Call(promiseCapability.[[Resolve]], undefined, « namespace.[[Value]] »).
MUST(call(global_object, resolve_function.cell(), js_undefined(), namespace_.release_value()));
MUST(call(vm, resolve_function.cell(), js_undefined(), namespace_.release_value()));
}
// g. Return unused.
// NOTE: We don't support returning an empty/optional/unused value here.
@ -1068,10 +1068,10 @@ void VM::finish_dynamic_import(ScriptOrModule referencing_script_or_module, Modu
auto* on_fulfilled = NativeFunction::create(realm, move(fulfilled_closure), 0, "");
// 3. Let rejectedClosure be a new Abstract Closure with parameters (error) that captures promiseCapability and performs the following steps when called:
auto rejected_closure = [rejected_function = make_handle(promise_capability.reject)](VM& vm, GlobalObject& global_object) -> ThrowCompletionOr<Value> {
auto rejected_closure = [rejected_function = make_handle(promise_capability.reject)](VM& vm, GlobalObject&) -> ThrowCompletionOr<Value> {
auto error = vm.argument(0);
// a. Perform ! Call(promiseCapability.[[Reject]], undefined, « error »).
MUST(call(global_object, rejected_function.cell(), js_undefined(), error));
MUST(call(vm, rejected_function.cell(), js_undefined(), error));
// b. Return unused.
// NOTE: We don't support returning an empty/optional/unused value here.

View file

@ -204,7 +204,7 @@ public:
CustomData* custom_data() { return m_custom_data; }
ThrowCompletionOr<void> destructuring_assignment_evaluation(NonnullRefPtr<BindingPattern> const& target, Value value, GlobalObject& global_object);
ThrowCompletionOr<void> binding_initialization(FlyString const& target, Value value, Environment* environment, GlobalObject& global_object);
ThrowCompletionOr<void> binding_initialization(FlyString const& target, Value value, Environment* environment, GlobalObject&);
ThrowCompletionOr<void> binding_initialization(NonnullRefPtr<BindingPattern> const& target, Value value, Environment* environment, GlobalObject& global_object);
ThrowCompletionOr<Value> named_evaluation_if_anonymous_function(ASTNode const& expression, FlyString const& name);
@ -239,8 +239,8 @@ public:
private:
explicit VM(OwnPtr<CustomData>);
ThrowCompletionOr<void> property_binding_initialization(BindingPattern const& binding, Value value, Environment* environment, GlobalObject& global_object);
ThrowCompletionOr<void> iterator_binding_initialization(BindingPattern const& binding, Iterator& iterator_record, Environment* environment, GlobalObject& global_object);
ThrowCompletionOr<void> property_binding_initialization(BindingPattern const& binding, Value value, Environment* environment, GlobalObject&);
ThrowCompletionOr<void> iterator_binding_initialization(BindingPattern const& binding, Iterator& iterator_record, Environment* environment, GlobalObject&);
ThrowCompletionOr<NonnullRefPtr<Module>> resolve_imported_module(ScriptOrModule referencing_script_or_module, ModuleRequest const& module_request);
ThrowCompletionOr<void> link_and_eval_module(Module& module);

View file

@ -419,12 +419,10 @@ ThrowCompletionOr<Value> Value::to_primitive(VM& vm, PreferredType preferred_typ
}
};
if (is_object()) {
auto& realm = *vm.current_realm();
auto& global_object = realm.global_object();
auto to_primitive_method = TRY(get_method(vm, *vm.well_known_symbol_to_primitive()));
if (to_primitive_method) {
auto hint = get_hint_for_preferred_type();
auto result = TRY(call(global_object, *to_primitive_method, *this, js_string(vm, hint)));
auto result = TRY(call(vm, *to_primitive_method, *this, js_string(vm, hint)));
if (!result.is_object())
return result;
return vm.throw_completion<TypeError>(ErrorType::ToPrimitiveReturnedObject, to_string_without_side_effects(), hint);
@ -1251,13 +1249,11 @@ ThrowCompletionOr<Value> in(VM& vm, Value lhs, Value rhs)
// 13.10.2 InstanceofOperator ( V, target ), https://tc39.es/ecma262/#sec-instanceofoperator
ThrowCompletionOr<Value> instance_of(VM& vm, Value lhs, Value rhs)
{
auto& realm = *vm.current_realm();
auto& global_object = realm.global_object();
if (!rhs.is_object())
return vm.throw_completion<TypeError>(ErrorType::NotAnObject, rhs.to_string_without_side_effects());
auto has_instance_method = TRY(rhs.get_method(vm, *vm.well_known_symbol_has_instance()));
if (has_instance_method) {
auto has_instance_result = TRY(call(global_object, *has_instance_method, rhs, lhs));
auto has_instance_result = TRY(call(vm, *has_instance_method, rhs, lhs));
return Value(has_instance_result.to_boolean());
}
if (!rhs.is_function())
@ -1568,13 +1564,11 @@ ThrowCompletionOr<TriState> is_less_than(VM& vm, Value lhs, Value rhs, bool left
// 7.3.21 Invoke ( V, P [ , argumentsList ] ), https://tc39.es/ecma262/#sec-invoke
ThrowCompletionOr<Value> Value::invoke_internal(VM& vm, PropertyKey const& property_key, Optional<MarkedVector<Value>> arguments)
{
auto& realm = *vm.current_realm();
auto& global_object = realm.global_object();
auto property = TRY(get(vm, property_key));
if (!property.is_function())
return vm.throw_completion<TypeError>(ErrorType::NotAFunction, property.to_string_without_side_effects());
return call(global_object, property.as_function(), *this, move(arguments));
return call(vm, property.as_function(), *this, move(arguments));
}
}

View file

@ -40,9 +40,8 @@ ThrowCompletionOr<Value> WeakMapConstructor::call()
ThrowCompletionOr<Object*> WeakMapConstructor::construct(FunctionObject& new_target)
{
auto& vm = this->vm();
auto& global_object = this->global_object();
auto* weak_map = TRY(ordinary_create_from_constructor<WeakMap>(global_object, new_target, &GlobalObject::weak_map_prototype));
auto* weak_map = TRY(ordinary_create_from_constructor<WeakMap>(vm, new_target, &GlobalObject::weak_map_prototype));
if (vm.argument(0).is_nullish())
return weak_map;
@ -57,7 +56,7 @@ ThrowCompletionOr<Object*> WeakMapConstructor::construct(FunctionObject& new_tar
auto key = TRY(iterator_value.as_object().get(0));
auto value = TRY(iterator_value.as_object().get(1));
TRY(JS::call(global_object, adder.as_function(), weak_map, key, value));
TRY(JS::call(vm, adder.as_function(), weak_map, key, value));
return {};
}));

View file

@ -39,16 +39,15 @@ ThrowCompletionOr<Value> WeakRefConstructor::call()
ThrowCompletionOr<Object*> WeakRefConstructor::construct(FunctionObject& new_target)
{
auto& vm = this->vm();
auto& global_object = this->global_object();
auto target = vm.argument(0);
if (!can_be_held_weakly(target))
return vm.throw_completion<TypeError>(ErrorType::CannotBeHeldWeakly, target.to_string_without_side_effects());
if (target.is_object())
return TRY(ordinary_create_from_constructor<WeakRef>(global_object, new_target, &GlobalObject::weak_ref_prototype, target.as_object()));
return TRY(ordinary_create_from_constructor<WeakRef>(vm, new_target, &GlobalObject::weak_ref_prototype, target.as_object()));
VERIFY(target.is_symbol());
return TRY(ordinary_create_from_constructor<WeakRef>(global_object, new_target, &GlobalObject::weak_ref_prototype, target.as_symbol()));
return TRY(ordinary_create_from_constructor<WeakRef>(vm, new_target, &GlobalObject::weak_ref_prototype, target.as_symbol()));
}
}

View file

@ -40,9 +40,8 @@ ThrowCompletionOr<Value> WeakSetConstructor::call()
ThrowCompletionOr<Object*> WeakSetConstructor::construct(FunctionObject& new_target)
{
auto& vm = this->vm();
auto& global_object = this->global_object();
auto* weak_set = TRY(ordinary_create_from_constructor<WeakSet>(global_object, new_target, &GlobalObject::weak_set_prototype));
auto* weak_set = TRY(ordinary_create_from_constructor<WeakSet>(vm, new_target, &GlobalObject::weak_set_prototype));
if (vm.argument(0).is_nullish())
return weak_set;
@ -52,7 +51,7 @@ ThrowCompletionOr<Object*> WeakSetConstructor::construct(FunctionObject& new_tar
return vm.throw_completion<TypeError>(ErrorType::NotAFunction, "'add' property of WeakSet");
(void)TRY(get_iterator_values(vm, vm.argument(0), [&](Value iterator_value) -> Optional<Completion> {
TRY(JS::call(global_object, adder.as_function(), weak_set, iterator_value));
TRY(JS::call(vm, adder.as_function(), weak_set, iterator_value));
return {};
}));

View file

@ -94,10 +94,10 @@ ThrowCompletionOr<Value> ordinary_wrapped_function_call(WrappedFunction const& f
auto* caller_realm = function.realm();
// 4. NOTE: Any exception objects produced after this point are associated with callerRealm.
auto& global_object = caller_realm->global_object();
VERIFY(vm.current_realm() == caller_realm);
// 5. Let targetRealm be ? GetFunctionRealm(target).
auto* target_realm = TRY(get_function_realm(global_object, target));
auto* target_realm = TRY(get_function_realm(vm, target));
// 6. Let wrappedArgs be a new empty List.
auto wrapped_args = MarkedVector<Value> { vm.heap() };
@ -116,7 +116,7 @@ ThrowCompletionOr<Value> ordinary_wrapped_function_call(WrappedFunction const& f
auto wrapped_this_argument = TRY(get_wrapped_value(vm, *target_realm, this_argument));
// 9. Let result be the Completion Record of Call(target, wrappedThisArgument, wrappedArgs).
auto result = call(global_object, &target, wrapped_this_argument, move(wrapped_args));
auto result = call(vm, &target, wrapped_this_argument, move(wrapped_args));
// 10. If result.[[Type]] is normal or result.[[Type]] is return, then
if (!result.is_throw_completion()) {

View file

@ -145,11 +145,13 @@ NonnullRefPtr<SyntheticModule> SyntheticModule::create_default_export_synthetic_
// 1.4 ParseJSONModule ( source ), https://tc39.es/proposal-json-modules/#sec-parse-json-module
ThrowCompletionOr<NonnullRefPtr<Module>> parse_json_module(StringView source_text, Realm& realm, StringView filename)
{
auto& vm = realm.vm();
// 1. Let jsonParse be realm's intrinsic object named "%JSON.parse%".
auto* json_parse = realm.global_object().json_parse_function();
// 2. Let json be ? Call(jsonParse, undefined, « sourceText »).
auto json = TRY(call(realm.global_object(), *json_parse, js_undefined(), js_string(realm.vm(), source_text)));
auto json = TRY(call(vm, *json_parse, js_undefined(), js_string(realm.vm(), source_text)));
// 3. Return CreateDefaultExportSyntheticModule(json, realm, hostDefined).
return SyntheticModule::create_default_export_synthetic_module(json, realm, filename);

View file

@ -128,8 +128,8 @@ Optional<JS::PropertyDescriptor> cross_origin_get_own_property_helper(Variant<Lo
// 2. If IsCallable(value) is true, then set value to an anonymous built-in function, created in the current Realm Record, that performs the same steps as the IDL operation P on object O.
if (value->is_function()) {
value = JS::NativeFunction::create(
realm, [function = JS::make_handle(*value)](auto&, auto& global_object) {
return JS::call(global_object, function.value(), JS::js_undefined());
realm, [function = JS::make_handle(*value)](auto& vm, auto&) {
return JS::call(vm, function.value(), JS::js_undefined());
},
0, "");
}
@ -145,8 +145,8 @@ Optional<JS::PropertyDescriptor> cross_origin_get_own_property_helper(Variant<Lo
// 2. If e.[[NeedsGet]] is true, then set crossOriginGet to an anonymous built-in function, created in the current Realm Record, that performs the same steps as the getter of the IDL attribute P on object O.
if (*entry.needs_get) {
cross_origin_get = JS::NativeFunction::create(
realm, [object_ptr, getter = JS::make_handle(*original_descriptor->get)](auto&, auto& global_object) {
return JS::call(global_object, getter.cell(), object_ptr);
realm, [object_ptr, getter = JS::make_handle(*original_descriptor->get)](auto& vm, auto&) {
return JS::call(vm, getter.cell(), object_ptr);
},
0, "");
}
@ -157,8 +157,8 @@ Optional<JS::PropertyDescriptor> cross_origin_get_own_property_helper(Variant<Lo
// If e.[[NeedsSet]] is true, then set crossOriginSet to an anonymous built-in function, created in the current Realm Record, that performs the same steps as the setter of the IDL attribute P on object O.
if (*entry.needs_set) {
cross_origin_set = JS::NativeFunction::create(
realm, [object_ptr, setter = JS::make_handle(*original_descriptor->set)](auto&, auto& global_object) {
return JS::call(global_object, setter.cell(), object_ptr);
realm, [object_ptr, setter = JS::make_handle(*original_descriptor->set)](auto& vm, auto&) {
return JS::call(vm, setter.cell(), object_ptr);
},
0, "");
}
@ -204,7 +204,7 @@ JS::ThrowCompletionOr<JS::Value> cross_origin_get(JS::GlobalObject& global_objec
return vm.throw_completion<DOMExceptionWrapper>(DOM::SecurityError::create(String::formatted("Can't get property '{}' on cross-origin object", property_key)));
// 7. Return ? Call(getter, Receiver).
return JS::call(global_object, *getter, receiver);
return JS::call(vm, *getter, receiver);
}
// 7.2.3.6 CrossOriginSet ( O, P, V, Receiver ), https://html.spec.whatwg.org/multipage/browsers.html#crossoriginset-(-o,-p,-v,-receiver-)
@ -222,7 +222,7 @@ JS::ThrowCompletionOr<bool> cross_origin_set(JS::GlobalObject& global_object, JS
if (descriptor->set.has_value() && *descriptor->set) {
// FIXME: Spec issue, `setter` isn't being defined.
// 1. Perform ? Call(setter, Receiver, «V»).
TRY(JS::call(global_object, *descriptor->set, receiver, value));
TRY(JS::call(vm, *descriptor->set, receiver, value));
// 2. Return true.
return true;

View file

@ -1,6 +1,6 @@
/*
* Copyright (c) 2021, Luke Wilde <lukew@serenityos.org>
* Copyright (c) 2021, Linus Groh <linusg@serenityos.org>
* Copyright (c) 2021-2022, Linus Groh <linusg@serenityos.org>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
@ -106,8 +106,7 @@ JS::Completion invoke_callback(Bindings::CallbackType& callback, Optional<JS::Va
// 5. Let realm be Fs associated Realm.
// See the comment about associated realm on step 4 of call_user_object_operation.
auto& global_object = function_object->global_object();
auto& realm = *global_object.associated_realm();
auto& realm = function_object->shape().realm();
// 6. Let relevant settings be realms settings object.
auto& relevant_settings = verify_cast<HTML::EnvironmentSettingsObject>(*realm.host_defined());
@ -125,7 +124,8 @@ JS::Completion invoke_callback(Bindings::CallbackType& callback, Optional<JS::Va
// For simplicity, we currently make the caller do this. However, this means we can't throw exceptions at this point like the spec wants us to.
// 11. Let callResult be Call(F, thisArg, esArgs).
auto call_result = JS::call(global_object, verify_cast<JS::FunctionObject>(*function_object), this_argument.value(), move(args));
auto& vm = function_object->vm();
auto call_result = JS::call(vm, verify_cast<JS::FunctionObject>(*function_object), this_argument.value(), move(args));
// 12. If callResult is an abrupt completion, set completion to callResult and jump to the step labeled return.
if (call_result.is_throw_completion()) {

View file

@ -57,8 +57,7 @@ JS::Completion call_user_object_operation(Bindings::CallbackType& callback, Stri
auto& object = *callback.callback.cell();
// 4. Let realm be Os associated Realm.
auto& global_object = object.global_object();
auto& realm = *global_object.associated_realm();
auto& realm = object.shape().realm();
// 5. Let relevant settings be realms settings object.
auto& relevant_settings = verify_cast<HTML::EnvironmentSettingsObject>(*realm.host_defined());
@ -105,7 +104,8 @@ JS::Completion call_user_object_operation(Bindings::CallbackType& callback, Stri
// 12. Let callResult be Call(X, thisArg, esArgs).
VERIFY(actual_function_object);
auto call_result = JS::call(global_object, verify_cast<JS::FunctionObject>(*actual_function_object), this_argument.value(), forward<Args>(args)...);
auto& vm = object.vm();
auto call_result = JS::call(vm, verify_cast<JS::FunctionObject>(*actual_function_object), this_argument.value(), forward<Args>(args)...);
// 13. If callResult is an abrupt completion, set completion to callResult and jump to the step labeled return.
if (call_result.is_throw_completion()) {

View file

@ -129,8 +129,6 @@ JS::VM& main_thread_vm()
// 8.1.5.3.1 HostCallJobCallback(callback, V, argumentsList), https://html.spec.whatwg.org/multipage/webappapis.html#hostcalljobcallback
vm->host_call_job_callback = [](JS::JobCallback& callback, JS::Value this_value, JS::MarkedVector<JS::Value> arguments_list) {
auto& realm = *vm->current_realm();
auto& global_object = realm.global_object();
auto& callback_host_defined = verify_cast<WebEngineCustomJobCallbackData>(*callback.custom_data);
// 1. Let incumbent settings be callback.[[HostDefined]].[[IncumbentSettings]]. (NOTE: Not necessary)
@ -144,7 +142,7 @@ JS::VM& main_thread_vm()
vm->push_execution_context(*callback_host_defined.active_script_context);
// 5. Let result be Call(callback.[[Callback]], V, argumentsList).
auto result = JS::call(global_object, *callback.callback.cell(), this_value, move(arguments_list));
auto result = JS::call(*vm, *callback.callback.cell(), this_value, move(arguments_list));
// 6. If script execution context is not null, then pop script execution context from the JavaScript execution context stack.
if (callback_host_defined.active_script_context) {

View file

@ -216,7 +216,7 @@ JS::ThrowCompletionOr<size_t> WebAssemblyObject::instantiate_module(Wasm::Module
for (auto& entry : arguments)
argument_values.append(to_js_value(global_object, entry));
auto result_or_error = JS::call(global_object, function, JS::js_undefined(), move(argument_values));
auto result_or_error = JS::call(vm, function, JS::js_undefined(), move(argument_values));
if (result_or_error.is_error()) {
return Wasm::Trap();
}

View file

@ -83,16 +83,17 @@ DOM::ExceptionOr<String> XMLHttpRequest::response_text() const
DOM::ExceptionOr<JS::Value> XMLHttpRequest::response()
{
auto& global_object = wrapper()->global_object();
auto& realm = *global_object.associated_realm();
auto& vm = wrapper()->vm();
auto& realm = *vm.current_realm();
// 1. If thiss response type is the empty string or "text", then:
if (m_response_type == Bindings::XMLHttpRequestResponseType::Empty || m_response_type == Bindings::XMLHttpRequestResponseType::Text) {
// 1. If thiss state is not loading or done, then return the empty string.
if (m_ready_state != ReadyState::Loading && m_ready_state != ReadyState::Done)
return JS::Value(JS::js_string(global_object.heap(), ""));
return JS::Value(JS::js_string(vm, ""));
// 2. Return the result of getting a text response for this.
return JS::Value(JS::js_string(global_object.heap(), get_text_response()));
return JS::Value(JS::js_string(vm, get_text_response()));
}
// 2. If thiss state is not done, then return null.
if (m_ready_state != ReadyState::Done)
@ -143,7 +144,7 @@ DOM::ExceptionOr<JS::Value> XMLHttpRequest::response()
// 3. Let jsonObject be the result of running parse JSON from bytes on thiss received bytes. If that threw an exception, then return null.
TextCodec::UTF8Decoder decoder;
auto json_object_result = JS::call(global_object, global_object.json_parse_function(), JS::js_undefined(), JS::js_string(global_object.heap(), decoder.to_utf8({ m_received_bytes.data(), m_received_bytes.size() })));
auto json_object_result = JS::call(vm, global_object.json_parse_function(), JS::js_undefined(), JS::js_string(global_object.heap(), decoder.to_utf8({ m_received_bytes.data(), m_received_bytes.size() })));
if (json_object_result.is_error())
return JS::Value(JS::js_null());

View file

@ -1262,9 +1262,9 @@ static bool parse_and_run(JS::Interpreter& interpreter, StringView source, Strin
return true;
}
static JS::ThrowCompletionOr<JS::Value> load_ini_impl(JS::VM& vm, JS::GlobalObject& global_object)
static JS::ThrowCompletionOr<JS::Value> load_ini_impl(JS::VM& vm)
{
auto& realm = *global_object.associated_realm();
auto& realm = *vm.current_realm();
auto filename = TRY(vm.argument(0).to_string(vm));
auto file = Core::File::construct(filename);
@ -1272,9 +1272,9 @@ static JS::ThrowCompletionOr<JS::Value> load_ini_impl(JS::VM& vm, JS::GlobalObje
return vm.throw_completion<JS::Error>(String::formatted("Failed to open '{}': {}", filename, file->error_string()));
auto config_file = MUST(Core::ConfigFile::open(filename, file->fd()));
auto* object = JS::Object::create(realm, global_object.object_prototype());
auto* object = JS::Object::create(realm, realm.global_object().object_prototype());
for (auto const& group : config_file->groups()) {
auto* group_object = JS::Object::create(realm, global_object.object_prototype());
auto* group_object = JS::Object::create(realm, realm.global_object().object_prototype());
for (auto const& key : config_file->keys(group)) {
auto entry = config_file->read_entry(group, key);
group_object->define_direct_property(key, js_string(vm, move(entry)), JS::Attribute::Enumerable | JS::Attribute::Configurable | JS::Attribute::Writable);
@ -1284,7 +1284,7 @@ static JS::ThrowCompletionOr<JS::Value> load_ini_impl(JS::VM& vm, JS::GlobalObje
return object;
}
static JS::ThrowCompletionOr<JS::Value> load_json_impl(JS::VM& vm, JS::GlobalObject& global_object)
static JS::ThrowCompletionOr<JS::Value> load_json_impl(JS::VM& vm)
{
auto filename = TRY(vm.argument(0).to_string(vm));
auto file = Core::File::construct(filename);
@ -1294,7 +1294,7 @@ static JS::ThrowCompletionOr<JS::Value> load_json_impl(JS::VM& vm, JS::GlobalObj
auto json = JsonValue::from_string(file_contents);
if (json.is_error())
return vm.throw_completion<JS::SyntaxError>(JS::ErrorType::JsonMalformed);
return JS::JSONObject::parse_json_value(global_object, json.value());
return JS::JSONObject::parse_json_value(vm, json.value());
}
void ReplObject::initialize_global_object()
@ -1360,12 +1360,12 @@ JS_DEFINE_NATIVE_FUNCTION(ReplObject::repl_help)
JS_DEFINE_NATIVE_FUNCTION(ReplObject::load_ini)
{
return load_ini_impl(vm, global_object);
return load_ini_impl(vm);
}
JS_DEFINE_NATIVE_FUNCTION(ReplObject::load_json)
{
return load_json_impl(vm, global_object);
return load_json_impl(vm);
}
JS_DEFINE_NATIVE_FUNCTION(ReplObject::print)
@ -1386,12 +1386,12 @@ void ScriptObject::initialize_global_object()
JS_DEFINE_NATIVE_FUNCTION(ScriptObject::load_ini)
{
return load_ini_impl(vm, global_object);
return load_ini_impl(vm);
}
JS_DEFINE_NATIVE_FUNCTION(ScriptObject::load_json)
{
return load_json_impl(vm, global_object);
return load_json_impl(vm);
}
JS_DEFINE_NATIVE_FUNCTION(ScriptObject::print)