1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-05-31 06:58:11 +00:00

LibJS: Replace GlobalObject with VM in Iterator AOs [Part 7/19]

This commit is contained in:
Linus Groh 2022-08-21 15:56:27 +01:00
parent ae9e031f56
commit ccdfa2320c
30 changed files with 171 additions and 182 deletions

View file

@ -1361,7 +1361,7 @@ void IDL::ParameterizedType::generate_sequence_from_iterable(SourceGenerator& ge
// 5. Set i to i + 1. // 5. Set i to i + 1.
sequence_generator.append(R"~~~( sequence_generator.append(R"~~~(
auto iterator@recursion_depth@ = TRY(JS::get_iterator(global_object, @iterable_cpp_name@, JS::IteratorHint::Sync, @iterator_method_cpp_name@)); auto iterator@recursion_depth@ = TRY(JS::get_iterator(vm, @iterable_cpp_name@, JS::IteratorHint::Sync, @iterator_method_cpp_name@));
)~~~"); )~~~");
if (sequence_cpp_type.sequence_storage_type == SequenceStorageType::Vector) { if (sequence_cpp_type.sequence_storage_type == SequenceStorageType::Vector) {
@ -1376,11 +1376,11 @@ void IDL::ParameterizedType::generate_sequence_from_iterable(SourceGenerator& ge
sequence_generator.append(R"~~~( sequence_generator.append(R"~~~(
for (;;) { for (;;) {
auto* next@recursion_depth@ = TRY(JS::iterator_step(global_object, iterator@recursion_depth@)); auto* next@recursion_depth@ = TRY(JS::iterator_step(vm, iterator@recursion_depth@));
if (!next@recursion_depth@) if (!next@recursion_depth@)
break; break;
auto next_item@recursion_depth@ = TRY(JS::iterator_value(global_object, *next@recursion_depth@)); auto next_item@recursion_depth@ = TRY(JS::iterator_value(vm, *next@recursion_depth@));
)~~~"); )~~~");
// FIXME: Sequences types should be TypeWithExtendedAttributes, which would allow us to get [LegacyNullToEmptyString] here. // FIXME: Sequences types should be TypeWithExtendedAttributes, which would allow us to get [LegacyNullToEmptyString] here.

View file

@ -363,13 +363,13 @@ ThrowCompletionOr<CallExpression::ThisAndCallee> CallExpression::compute_this_an
// 13.3.8.1 Runtime Semantics: ArgumentListEvaluation, https://tc39.es/ecma262/#sec-runtime-semantics-argumentlistevaluation // 13.3.8.1 Runtime Semantics: ArgumentListEvaluation, https://tc39.es/ecma262/#sec-runtime-semantics-argumentlistevaluation
static ThrowCompletionOr<void> argument_list_evaluation(Interpreter& interpreter, Vector<CallExpression::Argument> const& arguments, MarkedVector<Value>& list) static ThrowCompletionOr<void> argument_list_evaluation(Interpreter& interpreter, Vector<CallExpression::Argument> const& arguments, MarkedVector<Value>& list)
{ {
auto& global_object = interpreter.global_object(); auto& vm = interpreter.vm();
list.ensure_capacity(arguments.size()); list.ensure_capacity(arguments.size());
for (auto& argument : arguments) { for (auto& argument : arguments) {
auto value = TRY(argument.value->execute(interpreter)).release_value(); auto value = TRY(argument.value->execute(interpreter)).release_value();
if (argument.is_spread) { if (argument.is_spread) {
TRY(get_iterator_values(global_object, value, [&](Value iterator_value) -> Optional<Completion> { TRY(get_iterator_values(vm, value, [&](Value iterator_value) -> Optional<Completion> {
list.append(iterator_value); list.append(iterator_value);
return {}; return {};
})); }));
@ -1103,7 +1103,7 @@ Completion ForOfStatement::execute(Interpreter& interpreter) const
Completion ForOfStatement::loop_evaluation(Interpreter& interpreter, Vector<FlyString> const& label_set) const Completion ForOfStatement::loop_evaluation(Interpreter& interpreter, Vector<FlyString> const& label_set) const
{ {
InterpreterNodeScope node_scope { interpreter, *this }; InterpreterNodeScope node_scope { interpreter, *this };
auto& global_object = interpreter.global_object(); auto& vm = interpreter.vm();
auto for_of_head_state = TRY(for_in_of_head_execute(interpreter, m_lhs, m_rhs)); auto for_of_head_state = TRY(for_in_of_head_execute(interpreter, m_lhs, m_rhs));
@ -1115,7 +1115,7 @@ Completion ForOfStatement::loop_evaluation(Interpreter& interpreter, Vector<FlyS
// 2. Let oldEnv be the running execution context's LexicalEnvironment. // 2. Let oldEnv be the running execution context's LexicalEnvironment.
Environment* old_environment = interpreter.lexical_environment(); Environment* old_environment = interpreter.lexical_environment();
auto restore_scope = ScopeGuard([&] { auto restore_scope = ScopeGuard([&] {
interpreter.vm().running_execution_context().lexical_environment = old_environment; vm.running_execution_context().lexical_environment = old_environment;
}); });
// 3. Let V be undefined. // 3. Let V be undefined.
@ -1123,14 +1123,14 @@ Completion ForOfStatement::loop_evaluation(Interpreter& interpreter, Vector<FlyS
Optional<Completion> status; Optional<Completion> status;
(void)TRY(get_iterator_values(global_object, rhs_result, [&](Value value) -> Optional<Completion> { (void)TRY(get_iterator_values(vm, rhs_result, [&](Value value) -> Optional<Completion> {
TRY(for_of_head_state.execute_head(interpreter, value)); TRY(for_of_head_state.execute_head(interpreter, value));
// l. Let result be the result of evaluating stmt. // l. Let result be the result of evaluating stmt.
auto result = m_body->execute(interpreter); auto result = m_body->execute(interpreter);
// m. Set the running execution context's LexicalEnvironment to oldEnv. // m. Set the running execution context's LexicalEnvironment to oldEnv.
interpreter.vm().running_execution_context().lexical_environment = old_environment; vm.running_execution_context().lexical_environment = old_environment;
// n. If LoopContinues(result, labelSet) is false, then // n. If LoopContinues(result, labelSet) is false, then
if (!loop_continues(result, label_set)) { if (!loop_continues(result, label_set)) {
@ -1168,6 +1168,7 @@ Completion ForAwaitOfStatement::loop_evaluation(Interpreter& interpreter, Vector
{ {
InterpreterNodeScope node_scope { interpreter, *this }; InterpreterNodeScope node_scope { interpreter, *this };
auto& global_object = interpreter.global_object(); auto& global_object = interpreter.global_object();
auto& vm = interpreter.vm();
// 14.7.5.6 ForIn/OfHeadEvaluation ( uninitializedBoundNames, expr, iterationKind ), https://tc39.es/ecma262/#sec-runtime-semantics-forinofheadevaluation // 14.7.5.6 ForIn/OfHeadEvaluation ( uninitializedBoundNames, expr, iterationKind ), https://tc39.es/ecma262/#sec-runtime-semantics-forinofheadevaluation
// Note: Performs only steps 1 through 5. // Note: Performs only steps 1 through 5.
@ -1177,16 +1178,14 @@ Completion ForAwaitOfStatement::loop_evaluation(Interpreter& interpreter, Vector
// NOTE: Perform step 7 from ForIn/OfHeadEvaluation. And since this is always async we only have to do step 7.d. // NOTE: Perform step 7 from ForIn/OfHeadEvaluation. And since this is always async we only have to do step 7.d.
// d. Return ? GetIterator(exprValue, iteratorHint). // d. Return ? GetIterator(exprValue, iteratorHint).
auto iterator = TRY(get_iterator(global_object, rhs_result, IteratorHint::Async)); auto iterator = TRY(get_iterator(vm, rhs_result, IteratorHint::Async));
auto& vm = interpreter.vm();
// 14.7.5.7 ForIn/OfBodyEvaluation ( lhs, stmt, iteratorRecord, iterationKind, lhsKind, labelSet [ , iteratorKind ] ), https://tc39.es/ecma262/#sec-runtime-semantics-forin-div-ofbodyevaluation-lhs-stmt-iterator-lhskind-labelset // 14.7.5.7 ForIn/OfBodyEvaluation ( lhs, stmt, iteratorRecord, iterationKind, lhsKind, labelSet [ , iteratorKind ] ), https://tc39.es/ecma262/#sec-runtime-semantics-forin-div-ofbodyevaluation-lhs-stmt-iterator-lhskind-labelset
// NOTE: Here iteratorKind is always async. // NOTE: Here iteratorKind is always async.
// 2. Let oldEnv be the running execution context's LexicalEnvironment. // 2. Let oldEnv be the running execution context's LexicalEnvironment.
Environment* old_environment = interpreter.lexical_environment(); Environment* old_environment = interpreter.lexical_environment();
auto restore_scope = ScopeGuard([&] { auto restore_scope = ScopeGuard([&] {
interpreter.vm().running_execution_context().lexical_environment = old_environment; vm.running_execution_context().lexical_environment = old_environment;
}); });
// 3. Let V be undefined. // 3. Let V be undefined.
auto last_value = js_undefined(); auto last_value = js_undefined();
@ -1207,14 +1206,14 @@ Completion ForAwaitOfStatement::loop_evaluation(Interpreter& interpreter, Vector
return vm.throw_completion<TypeError>(ErrorType::IterableNextBadReturn); return vm.throw_completion<TypeError>(ErrorType::IterableNextBadReturn);
// d. Let done be ? IteratorComplete(nextResult). // d. Let done be ? IteratorComplete(nextResult).
auto done = TRY(iterator_complete(global_object, next_result.as_object())); auto done = TRY(iterator_complete(vm, next_result.as_object()));
// e. If done is true, return V. // e. If done is true, return V.
if (done) if (done)
return last_value; return last_value;
// f. Let nextValue be ? IteratorValue(nextResult). // f. Let nextValue be ? IteratorValue(nextResult).
auto next_value = TRY(iterator_value(global_object, next_result.as_object())); auto next_value = TRY(iterator_value(vm, next_result.as_object()));
// NOTE: This performs steps g. through to k. // NOTE: This performs steps g. through to k.
TRY(for_of_head_state.execute_head(interpreter, next_value)); TRY(for_of_head_state.execute_head(interpreter, next_value));
@ -1231,7 +1230,7 @@ Completion ForAwaitOfStatement::loop_evaluation(Interpreter& interpreter, Vector
auto status = result.update_empty(last_value); auto status = result.update_empty(last_value);
// 3. If iteratorKind is async, return ? AsyncIteratorClose(iteratorRecord, status). // 3. If iteratorKind is async, return ? AsyncIteratorClose(iteratorRecord, status).
return async_iterator_close(global_object, iterator, move(status)); return async_iterator_close(vm, iterator, move(status));
} }
// o. If result.[[Value]] is not empty, set V to result.[[Value]]. // o. If result.[[Value]] is not empty, set V to result.[[Value]].
@ -3541,6 +3540,7 @@ Completion ArrayExpression::execute(Interpreter& interpreter) const
{ {
InterpreterNodeScope node_scope { interpreter, *this }; InterpreterNodeScope node_scope { interpreter, *this };
auto& global_object = interpreter.global_object(); auto& global_object = interpreter.global_object();
auto& vm = interpreter.vm();
auto& realm = *global_object.associated_realm(); auto& realm = *global_object.associated_realm();
// 1. Let array be ! ArrayCreate(0). // 1. Let array be ! ArrayCreate(0).
@ -3556,7 +3556,7 @@ Completion ArrayExpression::execute(Interpreter& interpreter) const
value = TRY(element->execute(interpreter)).release_value(); value = TRY(element->execute(interpreter)).release_value();
if (is<SpreadExpression>(*element)) { if (is<SpreadExpression>(*element)) {
(void)TRY(get_iterator_values(global_object, value, [&](Value iterator_value) -> Optional<Completion> { (void)TRY(get_iterator_values(vm, value, [&](Value iterator_value) -> Optional<Completion> {
array->indexed_properties().put(index++, iterator_value, default_attributes); array->indexed_properties().put(index++, iterator_value, default_attributes);
return {}; return {};
})); }));

View file

@ -183,10 +183,9 @@ ThrowCompletionOr<void> NewArray::execute_impl(Bytecode::Interpreter& interprete
// FIXME: Since the accumulator is a Value, we store an object there and have to convert back and forth between that an Iterator records. Not great. // FIXME: Since the accumulator is a Value, we store an object there and have to convert back and forth between that an Iterator records. Not great.
// Make sure to put this into the accumulator before the iterator object disappears from the stack to prevent the members from being GC'd. // Make sure to put this into the accumulator before the iterator object disappears from the stack to prevent the members from being GC'd.
static Object* iterator_to_object(GlobalObject& global_object, Iterator iterator) static Object* iterator_to_object(VM& vm, Iterator iterator)
{ {
auto& vm = global_object.vm(); auto& realm = *vm.current_realm();
auto& realm = *global_object.associated_realm();
auto* object = Object::create(realm, nullptr); auto* object = Object::create(realm, nullptr);
object->define_direct_property(vm.names.iterator, iterator.iterator, 0); object->define_direct_property(vm.names.iterator, iterator.iterator, 0);
object->define_direct_property(vm.names.next, iterator.next_method, 0); object->define_direct_property(vm.names.next, iterator.next_method, 0);
@ -194,9 +193,8 @@ static Object* iterator_to_object(GlobalObject& global_object, Iterator iterator
return object; return object;
} }
static Iterator object_to_iterator(GlobalObject& global_object, Object& object) static Iterator object_to_iterator(VM& vm, Object& object)
{ {
auto& vm = global_object.vm();
return Iterator { return Iterator {
.iterator = &MUST(object.get(vm.names.iterator)).as_object(), .iterator = &MUST(object.get(vm.names.iterator)).as_object(),
.next_method = MUST(object.get(vm.names.next)), .next_method = MUST(object.get(vm.names.next)),
@ -206,25 +204,24 @@ static Iterator object_to_iterator(GlobalObject& global_object, Object& object)
ThrowCompletionOr<void> IteratorToArray::execute_impl(Bytecode::Interpreter& interpreter) const ThrowCompletionOr<void> IteratorToArray::execute_impl(Bytecode::Interpreter& interpreter) const
{ {
auto& global_object = interpreter.global_object();
auto& vm = interpreter.vm(); auto& vm = interpreter.vm();
auto iterator_object = TRY(interpreter.accumulator().to_object(vm)); auto iterator_object = TRY(interpreter.accumulator().to_object(vm));
auto iterator = object_to_iterator(global_object, *iterator_object); auto iterator = object_to_iterator(vm, *iterator_object);
auto* array = MUST(Array::create(interpreter.realm(), 0)); auto* array = MUST(Array::create(interpreter.realm(), 0));
size_t index = 0; size_t index = 0;
while (true) { while (true) {
auto* iterator_result = TRY(iterator_next(global_object, iterator)); auto* iterator_result = TRY(iterator_next(vm, iterator));
auto complete = TRY(iterator_complete(global_object, *iterator_result)); auto complete = TRY(iterator_complete(vm, *iterator_result));
if (complete) { if (complete) {
interpreter.accumulator() = array; interpreter.accumulator() = array;
return {}; return {};
} }
auto value = TRY(iterator_value(global_object, *iterator_result)); auto value = TRY(iterator_value(vm, *iterator_result));
MUST(array->create_data_property_or_throw(index, value)); MUST(array->create_data_property_or_throw(index, value));
index++; index++;
@ -677,8 +674,9 @@ ThrowCompletionOr<void> DeleteByValue::execute_impl(Bytecode::Interpreter& inter
ThrowCompletionOr<void> GetIterator::execute_impl(Bytecode::Interpreter& interpreter) const ThrowCompletionOr<void> GetIterator::execute_impl(Bytecode::Interpreter& interpreter) const
{ {
auto iterator = TRY(get_iterator(interpreter.global_object(), interpreter.accumulator())); auto& vm = interpreter.vm();
interpreter.accumulator() = iterator_to_object(interpreter.global_object(), iterator); auto iterator = TRY(get_iterator(vm, interpreter.accumulator()));
interpreter.accumulator() = iterator_to_object(vm, iterator);
return {}; return {};
} }
@ -748,7 +746,7 @@ ThrowCompletionOr<void> GetObjectPropertyIterator::execute_impl(Bytecode::Interp
if (key.is_number()) if (key.is_number())
result_object->define_direct_property(vm.names.value, JS::Value(key.as_number()), default_attributes); result_object->define_direct_property(vm.names.value, JS::Value(key.as_number()), default_attributes);
else if (key.is_string()) else if (key.is_string())
result_object->define_direct_property(vm.names.value, js_string(vm.heap(), key.as_string()), default_attributes); result_object->define_direct_property(vm.names.value, js_string(vm, key.as_string()), default_attributes);
else else
VERIFY_NOT_REACHED(); // We should not have non-string/number keys. VERIFY_NOT_REACHED(); // We should not have non-string/number keys.
@ -756,10 +754,10 @@ ThrowCompletionOr<void> GetObjectPropertyIterator::execute_impl(Bytecode::Interp
} }
}, },
1, 1,
interpreter.vm().names.next), vm.names.next),
.done = false, .done = false,
}; };
interpreter.accumulator() = iterator_to_object(interpreter.global_object(), move(iterator)); interpreter.accumulator() = iterator_to_object(vm, move(iterator));
return {}; return {};
} }
@ -767,9 +765,9 @@ ThrowCompletionOr<void> IteratorNext::execute_impl(Bytecode::Interpreter& interp
{ {
auto& vm = interpreter.vm(); auto& vm = interpreter.vm();
auto* iterator_object = TRY(interpreter.accumulator().to_object(vm)); auto* iterator_object = TRY(interpreter.accumulator().to_object(vm));
auto iterator = object_to_iterator(interpreter.global_object(), *iterator_object); auto iterator = object_to_iterator(vm, *iterator_object);
interpreter.accumulator() = TRY(iterator_next(interpreter.global_object(), iterator)); interpreter.accumulator() = TRY(iterator_next(vm, iterator));
return {}; return {};
} }
@ -778,7 +776,7 @@ ThrowCompletionOr<void> IteratorResultDone::execute_impl(Bytecode::Interpreter&
auto& vm = interpreter.vm(); auto& vm = interpreter.vm();
auto* iterator_result = TRY(interpreter.accumulator().to_object(vm)); auto* iterator_result = TRY(interpreter.accumulator().to_object(vm));
auto complete = TRY(iterator_complete(interpreter.global_object(), *iterator_result)); auto complete = TRY(iterator_complete(vm, *iterator_result));
interpreter.accumulator() = Value(complete); interpreter.accumulator() = Value(complete);
return {}; return {};
} }
@ -788,7 +786,7 @@ ThrowCompletionOr<void> IteratorResultValue::execute_impl(Bytecode::Interpreter&
auto& vm = interpreter.vm(); auto& vm = interpreter.vm();
auto* iterator_result = TRY(interpreter.accumulator().to_object(vm)); auto* iterator_result = TRY(interpreter.accumulator().to_object(vm));
interpreter.accumulator() = TRY(iterator_value(interpreter.global_object(), *iterator_result)); interpreter.accumulator() = TRY(iterator_value(vm, *iterator_result));
return {}; return {};
} }

View file

@ -52,7 +52,7 @@ ThrowCompletionOr<Object*> AggregateErrorConstructor::construct(FunctionObject&
TRY(aggregate_error->install_error_cause(vm.argument(2))); TRY(aggregate_error->install_error_cause(vm.argument(2)));
auto errors_list = TRY(iterable_to_list(global_object, vm.argument(0))); auto errors_list = TRY(iterable_to_list(vm, vm.argument(0)));
MUST(aggregate_error->define_property_or_throw(vm.names.errors, { .value = Array::create_from(realm, errors_list), .writable = true, .enumerable = false, .configurable = true })); MUST(aggregate_error->define_property_or_throw(vm.names.errors, { .value = Array::create_from(realm, errors_list), .writable = true, .enumerable = false, .configurable = true }));

View file

@ -107,28 +107,28 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayConstructor::from)
else else
array = MUST(Array::create(realm, 0)); array = MUST(Array::create(realm, 0));
auto iterator = TRY(get_iterator(global_object, items, IteratorHint::Sync, using_iterator)); auto iterator = TRY(get_iterator(vm, items, IteratorHint::Sync, using_iterator));
size_t k = 0; size_t k = 0;
while (true) { while (true) {
if (k >= MAX_ARRAY_LIKE_INDEX) { if (k >= MAX_ARRAY_LIKE_INDEX) {
auto error = vm.throw_completion<TypeError>(ErrorType::ArrayMaxSize); auto error = vm.throw_completion<TypeError>(ErrorType::ArrayMaxSize);
return TRY(iterator_close(global_object, iterator, move(error))); return TRY(iterator_close(vm, iterator, move(error)));
} }
auto* next = TRY(iterator_step(global_object, iterator)); auto* next = TRY(iterator_step(vm, iterator));
if (!next) { if (!next) {
TRY(array->set(vm.names.length, Value(k), Object::ShouldThrowExceptions::Yes)); TRY(array->set(vm.names.length, Value(k), Object::ShouldThrowExceptions::Yes));
return array; return array;
} }
auto next_value = TRY(iterator_value(global_object, *next)); auto next_value = TRY(iterator_value(vm, *next));
Value mapped_value; Value mapped_value;
if (map_fn) { 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(global_object, *map_fn, this_arg, next_value, Value(k));
if (mapped_value_or_error.is_error()) if (mapped_value_or_error.is_error())
return TRY(iterator_close(global_object, iterator, mapped_value_or_error.release_error())); return TRY(iterator_close(vm, iterator, mapped_value_or_error.release_error()));
mapped_value = mapped_value_or_error.release_value(); mapped_value = mapped_value_or_error.release_value();
} else { } else {
mapped_value = next_value; mapped_value = next_value;
@ -136,7 +136,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayConstructor::from)
auto result_or_error = array->create_data_property_or_throw(k, mapped_value); auto result_or_error = array->create_data_property_or_throw(k, mapped_value);
if (result_or_error.is_error()) if (result_or_error.is_error())
return TRY(iterator_close(global_object, iterator, result_or_error.release_error())); return TRY(iterator_close(vm, iterator, result_or_error.release_error()));
++k; ++k;
} }

View file

@ -39,7 +39,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayIteratorPrototype::next)
auto* iterator = TRY(typed_this_value(vm)); auto* iterator = TRY(typed_this_value(vm));
auto target_array = iterator->array(); auto target_array = iterator->array();
if (target_array.is_undefined()) if (target_array.is_undefined())
return create_iterator_result_object(global_object, js_undefined(), true); return create_iterator_result_object(vm, js_undefined(), true);
VERIFY(target_array.is_object()); VERIFY(target_array.is_object());
auto& array = target_array.as_object(); auto& array = target_array.as_object();
@ -61,19 +61,19 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayIteratorPrototype::next)
if (index >= length) { if (index >= length) {
iterator->m_array = js_undefined(); iterator->m_array = js_undefined();
return create_iterator_result_object(global_object, js_undefined(), true); return create_iterator_result_object(vm, js_undefined(), true);
} }
iterator->m_index++; iterator->m_index++;
if (iteration_kind == Object::PropertyKind::Key) if (iteration_kind == Object::PropertyKind::Key)
return create_iterator_result_object(global_object, Value(static_cast<i32>(index)), false); return create_iterator_result_object(vm, Value(static_cast<i32>(index)), false);
auto value = TRY(array.get(index)); auto value = TRY(array.get(index));
if (iteration_kind == Object::PropertyKind::Value) if (iteration_kind == Object::PropertyKind::Value)
return create_iterator_result_object(global_object, value, false); return create_iterator_result_object(vm, value, false);
return create_iterator_result_object(global_object, Array::create_from(realm, { Value(static_cast<i32>(index)), value }), false); return create_iterator_result_object(vm, Array::create_from(realm, { Value(static_cast<i32>(index)), value }), false);
} }
} }

View file

@ -31,27 +31,28 @@ void AsyncFromSyncIteratorPrototype::initialize(Realm& realm)
} }
// 27.1.4.4 AsyncFromSyncIteratorContinuation ( result, promiseCapability ), https://tc39.es/ecma262/#sec-asyncfromsynciteratorcontinuation // 27.1.4.4 AsyncFromSyncIteratorContinuation ( result, promiseCapability ), https://tc39.es/ecma262/#sec-asyncfromsynciteratorcontinuation
static Object* async_from_sync_iterator_continuation(GlobalObject& global_object, Object& result, PromiseCapability& promise_capability) static Object* async_from_sync_iterator_continuation(VM& vm, Object& result, PromiseCapability& promise_capability)
{ {
auto& realm = *global_object.associated_realm(); auto& realm = *vm.current_realm();
auto& global_object = realm.global_object();
// 1. NOTE: Because promiseCapability is derived from the intrinsic %Promise%, the calls to promiseCapability.[[Reject]] entailed by the use IfAbruptRejectPromise below are guaranteed not to throw. // 1. NOTE: Because promiseCapability is derived from the intrinsic %Promise%, the calls to promiseCapability.[[Reject]] entailed by the use IfAbruptRejectPromise below are guaranteed not to throw.
// 2. Let done be Completion(IteratorComplete(result)). // 2. Let done be Completion(IteratorComplete(result)).
// 3. IfAbruptRejectPromise(done, promiseCapability). // 3. IfAbruptRejectPromise(done, promiseCapability).
auto done = TRY_OR_MUST_REJECT(global_object, promise_capability, iterator_complete(global_object, result)); auto done = TRY_OR_MUST_REJECT(global_object, promise_capability, iterator_complete(vm, result));
// 4. Let value be Completion(IteratorValue(result)). // 4. Let value be Completion(IteratorValue(result)).
// 5. IfAbruptRejectPromise(value, promiseCapability). // 5. IfAbruptRejectPromise(value, promiseCapability).
auto value = TRY_OR_MUST_REJECT(global_object, promise_capability, iterator_value(global_object, result)); auto value = TRY_OR_MUST_REJECT(global_object, promise_capability, iterator_value(vm, result));
// 6. Let valueWrapper be PromiseResolve(%Promise%, value). // 6. Let valueWrapper be PromiseResolve(%Promise%, value).
// 7. IfAbruptRejectPromise(valueWrapper, promiseCapability). // 7. IfAbruptRejectPromise(valueWrapper, promiseCapability).
auto value_wrapper = TRY_OR_MUST_REJECT(global_object, promise_capability, promise_resolve(global_object, *global_object.promise_constructor(), value)); auto value_wrapper = TRY_OR_MUST_REJECT(global_object, promise_capability, promise_resolve(global_object, *global_object.promise_constructor(), value));
// 8. Let unwrap be a new Abstract Closure with parameters (value) that captures done and performs the following steps when called: // 8. Let unwrap be a new Abstract Closure with parameters (value) that captures done and performs the following steps when called:
auto unwrap = [done](VM& vm, GlobalObject& global_object) -> ThrowCompletionOr<Value> { auto unwrap = [done](VM& vm, GlobalObject&) -> ThrowCompletionOr<Value> {
// a. Return CreateIterResultObject(value, done). // a. Return CreateIterResultObject(value, done).
return create_iterator_result_object(global_object, vm.argument(0), done); return create_iterator_result_object(vm, vm.argument(0), done);
}; };
// 9. Let onFulfilled be CreateBuiltinFunction(unwrap, 1, "", « »). // 9. Let onFulfilled be CreateBuiltinFunction(unwrap, 1, "", « »).
@ -84,11 +85,11 @@ JS_DEFINE_NATIVE_FUNCTION(AsyncFromSyncIteratorPrototype::next)
// a. Let result be Completion(IteratorNext(syncIteratorRecord)). // a. Let result be Completion(IteratorNext(syncIteratorRecord)).
// 7. IfAbruptRejectPromise(result, promiseCapability). // 7. IfAbruptRejectPromise(result, promiseCapability).
auto* result = TRY_OR_REJECT(global_object, promise_capability, auto* result = TRY_OR_REJECT(global_object, promise_capability,
(vm.argument_count() > 0 ? iterator_next(global_object, sync_iterator_record, vm.argument(0)) (vm.argument_count() > 0 ? iterator_next(vm, sync_iterator_record, vm.argument(0))
: iterator_next(global_object, sync_iterator_record))); : iterator_next(vm, sync_iterator_record)));
// 8. Return AsyncFromSyncIteratorContinuation(result, promiseCapability). // 8. Return AsyncFromSyncIteratorContinuation(result, promiseCapability).
return async_from_sync_iterator_continuation(global_object, *result, promise_capability); return async_from_sync_iterator_continuation(vm, *result, promise_capability);
} }
// 27.1.4.2.2 %AsyncFromSyncIteratorPrototype%.return ( [ value ] ), https://tc39.es/ecma262/#sec-%asyncfromsynciteratorprototype%.return // 27.1.4.2.2 %AsyncFromSyncIteratorPrototype%.return ( [ value ] ), https://tc39.es/ecma262/#sec-%asyncfromsynciteratorprototype%.return
@ -113,7 +114,7 @@ JS_DEFINE_NATIVE_FUNCTION(AsyncFromSyncIteratorPrototype::return_)
// 7. If return is undefined, then // 7. If return is undefined, then
if (return_method == nullptr) { if (return_method == nullptr) {
// a. Let iterResult be CreateIterResultObject(value, true). // a. Let iterResult be CreateIterResultObject(value, true).
auto* iter_result = create_iterator_result_object(global_object, vm.argument(0), true); auto* iter_result = create_iterator_result_object(vm, vm.argument(0), true);
// b. Perform ! Call(promiseCapability.[[Resolve]], undefined, « iterResult »). // b. Perform ! Call(promiseCapability.[[Resolve]], undefined, « iterResult »).
MUST(call(global_object, *promise_capability.reject, js_undefined(), iter_result)); MUST(call(global_object, *promise_capability.reject, js_undefined(), iter_result));
@ -141,7 +142,7 @@ JS_DEFINE_NATIVE_FUNCTION(AsyncFromSyncIteratorPrototype::return_)
} }
// 12. Return AsyncFromSyncIteratorContinuation(result, promiseCapability). // 12. Return AsyncFromSyncIteratorContinuation(result, promiseCapability).
return async_from_sync_iterator_continuation(global_object, result.as_object(), promise_capability); return async_from_sync_iterator_continuation(vm, result.as_object(), promise_capability);
} }
// 27.1.4.2.3 %AsyncFromSyncIteratorPrototype%.throw ( [ value ] ), https://tc39.es/ecma262/#sec-%asyncfromsynciteratorprototype%.throw // 27.1.4.2.3 %AsyncFromSyncIteratorPrototype%.throw ( [ value ] ), https://tc39.es/ecma262/#sec-%asyncfromsynciteratorprototype%.throw
@ -190,14 +191,13 @@ JS_DEFINE_NATIVE_FUNCTION(AsyncFromSyncIteratorPrototype::throw_)
} }
// 12. Return AsyncFromSyncIteratorContinuation(result, promiseCapability). // 12. Return AsyncFromSyncIteratorContinuation(result, promiseCapability).
return async_from_sync_iterator_continuation(global_object, result.as_object(), promise_capability); return async_from_sync_iterator_continuation(vm, result.as_object(), promise_capability);
} }
// 27.1.4.1 CreateAsyncFromSyncIterator ( syncIteratorRecord ), https://tc39.es/ecma262/#sec-createasyncfromsynciterator // 27.1.4.1 CreateAsyncFromSyncIterator ( syncIteratorRecord ), https://tc39.es/ecma262/#sec-createasyncfromsynciterator
Iterator create_async_from_sync_iterator(GlobalObject& global_object, Iterator sync_iterator_record) Iterator create_async_from_sync_iterator(VM& vm, Iterator sync_iterator_record)
{ {
auto& vm = global_object.vm(); auto& realm = *vm.current_realm();
auto& realm = *global_object.associated_realm();
// 1. Let asyncIterator be OrdinaryObjectCreate(%AsyncFromSyncIteratorPrototype%, « [[SyncIteratorRecord]] »). // 1. Let asyncIterator be OrdinaryObjectCreate(%AsyncFromSyncIteratorPrototype%, « [[SyncIteratorRecord]] »).
// 2. Set asyncIterator.[[SyncIteratorRecord]] to syncIteratorRecord. // 2. Set asyncIterator.[[SyncIteratorRecord]] to syncIteratorRecord.

View file

@ -29,6 +29,6 @@ private:
JS_DECLARE_NATIVE_FUNCTION(throw_); JS_DECLARE_NATIVE_FUNCTION(throw_);
}; };
Iterator create_async_from_sync_iterator(GlobalObject&, Iterator sync_iterator); Iterator create_async_from_sync_iterator(VM&, Iterator sync_iterator);
} }

View file

@ -240,9 +240,6 @@ Array* format_list_to_parts(VM& vm, ListFormat const& list_format, Vector<String
// 13.5.5 StringListFromIterable ( iterable ), https://tc39.es/ecma402/#sec-createstringlistfromiterable // 13.5.5 StringListFromIterable ( iterable ), https://tc39.es/ecma402/#sec-createstringlistfromiterable
ThrowCompletionOr<Vector<String>> string_list_from_iterable(VM& vm, Value iterable) ThrowCompletionOr<Vector<String>> string_list_from_iterable(VM& vm, Value iterable)
{ {
auto& realm = *vm.current_realm();
auto& global_object = realm.global_object();
// 1. If iterable is undefined, then // 1. If iterable is undefined, then
if (iterable.is_undefined()) { if (iterable.is_undefined()) {
// a. Return a new empty List. // a. Return a new empty List.
@ -250,7 +247,7 @@ ThrowCompletionOr<Vector<String>> string_list_from_iterable(VM& vm, Value iterab
} }
// 2. Let iteratorRecord be ? GetIterator(iterable). // 2. Let iteratorRecord be ? GetIterator(iterable).
auto iterator_record = TRY(get_iterator(global_object, iterable)); auto iterator_record = TRY(get_iterator(vm, iterable));
// 3. Let list be a new empty List. // 3. Let list be a new empty List.
Vector<String> list; Vector<String> list;
@ -261,12 +258,12 @@ ThrowCompletionOr<Vector<String>> string_list_from_iterable(VM& vm, Value iterab
// 5. Repeat, while next is not false, // 5. Repeat, while next is not false,
do { do {
// a. Set next to ? IteratorStep(iteratorRecord). // a. Set next to ? IteratorStep(iteratorRecord).
next = TRY(iterator_step(global_object, iterator_record)); next = TRY(iterator_step(vm, iterator_record));
// b. If next is not false, then // b. If next is not false, then
if (next != nullptr) { if (next != nullptr) {
// i. Let nextValue be ? IteratorValue(next). // i. Let nextValue be ? IteratorValue(next).
auto next_value = TRY(iterator_value(global_object, *next)); auto next_value = TRY(iterator_value(vm, *next));
// ii. If Type(nextValue) is not String, then // ii. If Type(nextValue) is not String, then
if (!next_value.is_string()) { if (!next_value.is_string()) {
@ -274,7 +271,7 @@ ThrowCompletionOr<Vector<String>> string_list_from_iterable(VM& vm, Value iterab
auto error = vm.throw_completion<TypeError>(ErrorType::NotAString, next_value); auto error = vm.throw_completion<TypeError>(ErrorType::NotAString, next_value);
// 2. Return ? IteratorClose(iteratorRecord, error). // 2. Return ? IteratorClose(iteratorRecord, error).
return iterator_close(global_object, iterator_record, move(error)); return iterator_close(vm, iterator_record, move(error));
} }
// iii. Append nextValue to the end of the List list. // iii. Append nextValue to the end of the List list.

View file

@ -53,7 +53,7 @@ JS_DEFINE_NATIVE_FUNCTION(SegmentIteratorPrototype::next)
// 7. If endIndex is not finite, then // 7. If endIndex is not finite, then
if (!Value(end_index).is_finite_number()) { if (!Value(end_index).is_finite_number()) {
// a. Return CreateIterResultObject(undefined, true). // a. Return CreateIterResultObject(undefined, true).
return create_iterator_result_object(global_object, js_undefined(), true); return create_iterator_result_object(vm, js_undefined(), true);
} }
// 8. Set iterator.[[IteratedStringNextSegmentCodeUnitIndex]] to endIndex. // 8. Set iterator.[[IteratedStringNextSegmentCodeUnitIndex]] to endIndex.
@ -63,7 +63,7 @@ JS_DEFINE_NATIVE_FUNCTION(SegmentIteratorPrototype::next)
auto* segment_data = create_segment_data_object(vm, segmenter, string, start_index, end_index); auto* segment_data = create_segment_data_object(vm, segmenter, string, start_index, end_index);
// 10. Return CreateIterResultObject(segmentData, false). // 10. Return CreateIterResultObject(segmentData, false).
return create_iterator_result_object(global_object, segment_data, false); return create_iterator_result_object(vm, segment_data, false);
} }
} }

View file

@ -15,9 +15,10 @@
namespace JS { namespace JS {
// 7.4.2 GetIterator ( obj [ , hint [ , method ] ] ), https://tc39.es/ecma262/#sec-getiterator // 7.4.2 GetIterator ( obj [ , hint [ , method ] ] ), https://tc39.es/ecma262/#sec-getiterator
ThrowCompletionOr<Iterator> get_iterator(GlobalObject& global_object, Value value, IteratorHint hint, Optional<Value> method) ThrowCompletionOr<Iterator> get_iterator(VM& vm, Value value, IteratorHint hint, Optional<Value> method)
{ {
auto& vm = global_object.vm(); auto& realm = *vm.current_realm();
auto& global_object = realm.global_object();
// 1. If hint is not present, set hint to sync. // 1. If hint is not present, set hint to sync.
@ -34,10 +35,10 @@ ThrowCompletionOr<Iterator> get_iterator(GlobalObject& global_object, Value valu
auto* sync_method = TRY(value.get_method(vm, *vm.well_known_symbol_iterator())); auto* sync_method = TRY(value.get_method(vm, *vm.well_known_symbol_iterator()));
// 2. Let syncIteratorRecord be ? GetIterator(obj, sync, syncMethod). // 2. Let syncIteratorRecord be ? GetIterator(obj, sync, syncMethod).
auto sync_iterator_record = TRY(get_iterator(global_object, value, IteratorHint::Sync, sync_method)); auto sync_iterator_record = TRY(get_iterator(vm, value, IteratorHint::Sync, sync_method));
// 3. Return CreateAsyncFromSyncIterator(syncIteratorRecord). // 3. Return CreateAsyncFromSyncIterator(syncIteratorRecord).
return create_async_from_sync_iterator(global_object, sync_iterator_record); return create_async_from_sync_iterator(vm, sync_iterator_record);
} }
method = Value(async_method); method = Value(async_method);
@ -70,9 +71,10 @@ ThrowCompletionOr<Iterator> get_iterator(GlobalObject& global_object, Value valu
} }
// 7.4.3 IteratorNext ( iteratorRecord [ , value ] ), https://tc39.es/ecma262/#sec-iteratornext // 7.4.3 IteratorNext ( iteratorRecord [ , value ] ), https://tc39.es/ecma262/#sec-iteratornext
ThrowCompletionOr<Object*> iterator_next(GlobalObject& global_object, Iterator const& iterator_record, Optional<Value> value) ThrowCompletionOr<Object*> iterator_next(VM& vm, Iterator const& iterator_record, Optional<Value> value)
{ {
auto& vm = global_object.vm(); auto& realm = *vm.current_realm();
auto& global_object = realm.global_object();
Value result; Value result;
@ -94,31 +96,27 @@ ThrowCompletionOr<Object*> iterator_next(GlobalObject& global_object, Iterator c
} }
// 7.4.4 IteratorComplete ( iterResult ), https://tc39.es/ecma262/#sec-iteratorcomplete // 7.4.4 IteratorComplete ( iterResult ), https://tc39.es/ecma262/#sec-iteratorcomplete
ThrowCompletionOr<bool> iterator_complete(GlobalObject& global_object, Object& iterator_result) ThrowCompletionOr<bool> iterator_complete(VM& vm, Object& iterator_result)
{ {
auto& vm = global_object.vm();
// 1. Return ToBoolean(? Get(iterResult, "done")). // 1. Return ToBoolean(? Get(iterResult, "done")).
return TRY(iterator_result.get(vm.names.done)).to_boolean(); return TRY(iterator_result.get(vm.names.done)).to_boolean();
} }
// 7.4.5 IteratorValue ( iterResult ), https://tc39.es/ecma262/#sec-iteratorvalue // 7.4.5 IteratorValue ( iterResult ), https://tc39.es/ecma262/#sec-iteratorvalue
ThrowCompletionOr<Value> iterator_value(GlobalObject& global_object, Object& iterator_result) ThrowCompletionOr<Value> iterator_value(VM& vm, Object& iterator_result)
{ {
auto& vm = global_object.vm();
// 1. Return ? Get(iterResult, "value"). // 1. Return ? Get(iterResult, "value").
return TRY(iterator_result.get(vm.names.value)); return TRY(iterator_result.get(vm.names.value));
} }
// 7.4.6 IteratorStep ( iteratorRecord ), https://tc39.es/ecma262/#sec-iteratorstep // 7.4.6 IteratorStep ( iteratorRecord ), https://tc39.es/ecma262/#sec-iteratorstep
ThrowCompletionOr<Object*> iterator_step(GlobalObject& global_object, Iterator const& iterator_record) ThrowCompletionOr<Object*> iterator_step(VM& vm, Iterator const& iterator_record)
{ {
// 1. Let result be ? IteratorNext(iteratorRecord). // 1. Let result be ? IteratorNext(iteratorRecord).
auto* result = TRY(iterator_next(global_object, iterator_record)); auto* result = TRY(iterator_next(vm, iterator_record));
// 2. Let done be ? IteratorComplete(result). // 2. Let done be ? IteratorComplete(result).
auto done = TRY(iterator_complete(global_object, *result)); auto done = TRY(iterator_complete(vm, *result));
// 3. If done is true, return false. // 3. If done is true, return false.
if (done) if (done)
@ -131,9 +129,10 @@ ThrowCompletionOr<Object*> iterator_step(GlobalObject& global_object, Iterator c
// 7.4.7 IteratorClose ( iteratorRecord, completion ), https://tc39.es/ecma262/#sec-iteratorclose // 7.4.7 IteratorClose ( iteratorRecord, completion ), https://tc39.es/ecma262/#sec-iteratorclose
// 7.4.9 AsyncIteratorClose ( iteratorRecord, completion ), https://tc39.es/ecma262/#sec-asynciteratorclose // 7.4.9 AsyncIteratorClose ( iteratorRecord, completion ), https://tc39.es/ecma262/#sec-asynciteratorclose
// NOTE: These only differ in that async awaits the inner value after the call. // NOTE: These only differ in that async awaits the inner value after the call.
static Completion iterator_close_impl(GlobalObject& global_object, Iterator const& iterator_record, Completion completion, IteratorHint iterator_hint) static Completion iterator_close_impl(VM& vm, Iterator const& iterator_record, Completion completion, IteratorHint iterator_hint)
{ {
auto& vm = global_object.vm(); auto& realm = *vm.current_realm();
auto& global_object = realm.global_object();
// 1. Assert: Type(iteratorRecord.[[Iterator]]) is Object. // 1. Assert: Type(iteratorRecord.[[Iterator]]) is Object.
@ -182,22 +181,22 @@ static Completion iterator_close_impl(GlobalObject& global_object, Iterator cons
} }
// 7.4.7 IteratorClose ( iteratorRecord, completion ), https://tc39.es/ecma262/#sec-iteratorclose // 7.4.7 IteratorClose ( iteratorRecord, completion ), https://tc39.es/ecma262/#sec-iteratorclose
Completion iterator_close(GlobalObject& global_object, Iterator const& iterator_record, Completion completion) Completion iterator_close(VM& vm, Iterator const& iterator_record, Completion completion)
{ {
return iterator_close_impl(global_object, iterator_record, move(completion), IteratorHint::Sync); return iterator_close_impl(vm, iterator_record, move(completion), IteratorHint::Sync);
} }
// 7.4.9 AsyncIteratorClose ( iteratorRecord, completion ), https://tc39.es/ecma262/#sec-asynciteratorclose // 7.4.9 AsyncIteratorClose ( iteratorRecord, completion ), https://tc39.es/ecma262/#sec-asynciteratorclose
Completion async_iterator_close(GlobalObject& global_object, Iterator const& iterator_record, Completion completion) Completion async_iterator_close(VM& vm, Iterator const& iterator_record, Completion completion)
{ {
return iterator_close_impl(global_object, iterator_record, move(completion), IteratorHint::Async); return iterator_close_impl(vm, iterator_record, move(completion), IteratorHint::Async);
} }
// 7.4.10 CreateIterResultObject ( value, done ), https://tc39.es/ecma262/#sec-createiterresultobject // 7.4.10 CreateIterResultObject ( value, done ), https://tc39.es/ecma262/#sec-createiterresultobject
Object* create_iterator_result_object(GlobalObject& global_object, Value value, bool done) Object* create_iterator_result_object(VM& vm, Value value, bool done)
{ {
auto& vm = global_object.vm(); auto& realm = *vm.current_realm();
auto& realm = *global_object.associated_realm(); auto& global_object = realm.global_object();
// 1. Let obj be OrdinaryObjectCreate(%Object.prototype%). // 1. Let obj be OrdinaryObjectCreate(%Object.prototype%).
auto* object = Object::create(realm, global_object.object_prototype()); auto* object = Object::create(realm, global_object.object_prototype());
@ -213,13 +212,12 @@ Object* create_iterator_result_object(GlobalObject& global_object, Value value,
} }
// 7.4.12 IterableToList ( items [ , method ] ), https://tc39.es/ecma262/#sec-iterabletolist // 7.4.12 IterableToList ( items [ , method ] ), https://tc39.es/ecma262/#sec-iterabletolist
ThrowCompletionOr<MarkedVector<Value>> iterable_to_list(GlobalObject& global_object, Value iterable, Optional<Value> method) ThrowCompletionOr<MarkedVector<Value>> iterable_to_list(VM& vm, Value iterable, Optional<Value> method)
{ {
auto& vm = global_object.vm();
MarkedVector<Value> values(vm.heap()); MarkedVector<Value> values(vm.heap());
(void)TRY(get_iterator_values( (void)TRY(get_iterator_values(
global_object, iterable, [&](auto value) -> Optional<Completion> { vm, iterable, [&](auto value) -> Optional<Completion> {
values.append(value); values.append(value);
return {}; return {};
}, },
@ -229,19 +227,19 @@ ThrowCompletionOr<MarkedVector<Value>> iterable_to_list(GlobalObject& global_obj
} }
// Non-standard // Non-standard
Completion get_iterator_values(GlobalObject& global_object, Value iterable, IteratorValueCallback callback, Optional<Value> method) Completion get_iterator_values(VM& vm, Value iterable, IteratorValueCallback callback, Optional<Value> method)
{ {
auto iterator_record = TRY(get_iterator(global_object, iterable, IteratorHint::Sync, move(method))); auto iterator_record = TRY(get_iterator(vm, iterable, IteratorHint::Sync, move(method)));
while (true) { while (true) {
auto* next_object = TRY(iterator_step(global_object, iterator_record)); auto* next_object = TRY(iterator_step(vm, iterator_record));
if (!next_object) if (!next_object)
return {}; return {};
auto next_value = TRY(iterator_value(global_object, *next_object)); auto next_value = TRY(iterator_value(vm, *next_object));
if (auto completion = callback(next_value); completion.has_value()) if (auto completion = callback(next_value); completion.has_value())
return iterator_close(global_object, iterator_record, completion.release_value()); return iterator_close(vm, iterator_record, completion.release_value());
} }
} }

View file

@ -22,17 +22,17 @@ enum class IteratorHint {
Async, Async,
}; };
ThrowCompletionOr<Iterator> get_iterator(GlobalObject&, Value, IteratorHint = IteratorHint::Sync, Optional<Value> method = {}); ThrowCompletionOr<Iterator> get_iterator(VM&, Value, IteratorHint = IteratorHint::Sync, Optional<Value> method = {});
ThrowCompletionOr<Object*> iterator_next(GlobalObject&, Iterator const&, Optional<Value> = {}); ThrowCompletionOr<Object*> iterator_next(VM&, Iterator const&, Optional<Value> = {});
ThrowCompletionOr<Object*> iterator_step(GlobalObject&, Iterator const&); ThrowCompletionOr<Object*> iterator_step(VM&, Iterator const&);
ThrowCompletionOr<bool> iterator_complete(GlobalObject&, Object& iterator_result); ThrowCompletionOr<bool> iterator_complete(VM&, Object& iterator_result);
ThrowCompletionOr<Value> iterator_value(GlobalObject&, Object& iterator_result); ThrowCompletionOr<Value> iterator_value(VM&, Object& iterator_result);
Completion iterator_close(GlobalObject&, Iterator const&, Completion); Completion iterator_close(VM&, Iterator const&, Completion);
Completion async_iterator_close(GlobalObject&, Iterator const&, Completion); Completion async_iterator_close(VM&, Iterator const&, Completion);
Object* create_iterator_result_object(GlobalObject&, Value, bool done); Object* create_iterator_result_object(VM&, Value, bool done);
ThrowCompletionOr<MarkedVector<Value>> iterable_to_list(GlobalObject&, Value iterable, Optional<Value> method = {}); ThrowCompletionOr<MarkedVector<Value>> iterable_to_list(VM&, Value iterable, Optional<Value> method = {});
using IteratorValueCallback = Function<Optional<Completion>(Value)>; using IteratorValueCallback = Function<Optional<Completion>(Value)>;
Completion get_iterator_values(GlobalObject&, Value iterable, IteratorValueCallback callback, Optional<Value> method = {}); Completion get_iterator_values(VM&, Value iterable, IteratorValueCallback callback, Optional<Value> method = {});
} }

View file

@ -53,7 +53,7 @@ ThrowCompletionOr<Object*> MapConstructor::construct(FunctionObject& new_target)
if (!adder.is_function()) if (!adder.is_function())
return vm.throw_completion<TypeError>(ErrorType::NotAFunction, "'set' property of Map"); return vm.throw_completion<TypeError>(ErrorType::NotAFunction, "'set' property of Map");
(void)TRY(get_iterator_values(global_object, vm.argument(0), [&](Value iterator_value) -> Optional<Completion> { (void)TRY(get_iterator_values(vm, vm.argument(0), [&](Value iterator_value) -> Optional<Completion> {
if (!iterator_value.is_object()) if (!iterator_value.is_object())
return vm.throw_completion<TypeError>(ErrorType::NotAnObject, String::formatted("Iterator value {}", iterator_value.to_string_without_side_effects())); return vm.throw_completion<TypeError>(ErrorType::NotAnObject, String::formatted("Iterator value {}", iterator_value.to_string_without_side_effects()));

View file

@ -34,11 +34,11 @@ JS_DEFINE_NATIVE_FUNCTION(MapIteratorPrototype::next)
auto* map_iterator = TRY(typed_this_value(vm)); auto* map_iterator = TRY(typed_this_value(vm));
if (map_iterator->done()) if (map_iterator->done())
return create_iterator_result_object(global_object, js_undefined(), true); return create_iterator_result_object(vm, js_undefined(), true);
if (map_iterator->m_iterator.is_end()) { if (map_iterator->m_iterator.is_end()) {
map_iterator->m_done = true; map_iterator->m_done = true;
return create_iterator_result_object(global_object, js_undefined(), true); return create_iterator_result_object(vm, js_undefined(), true);
} }
auto iteration_kind = map_iterator->iteration_kind(); auto iteration_kind = map_iterator->iteration_kind();
@ -46,11 +46,11 @@ JS_DEFINE_NATIVE_FUNCTION(MapIteratorPrototype::next)
auto entry = *map_iterator->m_iterator; auto entry = *map_iterator->m_iterator;
++map_iterator->m_iterator; ++map_iterator->m_iterator;
if (iteration_kind == Object::PropertyKind::Key) if (iteration_kind == Object::PropertyKind::Key)
return create_iterator_result_object(global_object, entry.key, false); return create_iterator_result_object(vm, entry.key, false);
if (iteration_kind == Object::PropertyKind::Value) if (iteration_kind == Object::PropertyKind::Value)
return create_iterator_result_object(global_object, entry.value, false); return create_iterator_result_object(vm, entry.value, false);
return create_iterator_result_object(global_object, Array::create_from(realm, { entry.key, entry.value }), false); return create_iterator_result_object(vm, Array::create_from(realm, { entry.key, entry.value }), false);
} }
} }

View file

@ -228,7 +228,7 @@ JS_DEFINE_NATIVE_FUNCTION(ObjectConstructor::from_entries)
auto* object = Object::create(realm, global_object.object_prototype()); auto* object = Object::create(realm, global_object.object_prototype());
(void)TRY(get_iterator_values(global_object, iterable, [&](Value iterator_value) -> Optional<Completion> { (void)TRY(get_iterator_values(vm, iterable, [&](Value iterator_value) -> Optional<Completion> {
if (!iterator_value.is_object()) if (!iterator_value.is_object())
return vm.throw_completion<TypeError>(ErrorType::NotAnObject, String::formatted("Iterator value {}", iterator_value.to_string_without_side_effects())); return vm.throw_completion<TypeError>(ErrorType::NotAnObject, String::formatted("Iterator value {}", iterator_value.to_string_without_side_effects()));

View file

@ -59,7 +59,7 @@ static ThrowCompletionOr<Value> perform_promise_common(GlobalObject& global_obje
// 4. Repeat, // 4. Repeat,
while (true) { while (true) {
// a. Let next be Completion(IteratorStep(iteratorRecord)). // a. Let next be Completion(IteratorStep(iteratorRecord)).
auto next_or_error = iterator_step(global_object, iterator_record); auto next_or_error = iterator_step(vm, iterator_record);
// b. If next is an abrupt completion, set iteratorRecord.[[Done]] to true. // b. If next is an abrupt completion, set iteratorRecord.[[Done]] to true.
// c. ReturnIfAbrupt(next). // c. ReturnIfAbrupt(next).
@ -86,7 +86,7 @@ static ThrowCompletionOr<Value> perform_promise_common(GlobalObject& global_obje
} }
// e. Let nextValue be Completion(IteratorValue(next)). // e. Let nextValue be Completion(IteratorValue(next)).
auto next_value_or_error = iterator_value(global_object, *next); auto next_value_or_error = iterator_value(vm, *next);
// f. If nextValue is an abrupt completion, set iteratorRecord.[[Done]] to true. // f. If nextValue is an abrupt completion, set iteratorRecord.[[Done]] to true.
// g. ReturnIfAbrupt(nextValue). // g. ReturnIfAbrupt(nextValue).
@ -332,7 +332,7 @@ JS_DEFINE_NATIVE_FUNCTION(PromiseConstructor::all)
// 5. Let iteratorRecord be Completion(GetIterator(iterable)). // 5. Let iteratorRecord be Completion(GetIterator(iterable)).
// 6. IfAbruptRejectPromise(iteratorRecord, promiseCapability). // 6. IfAbruptRejectPromise(iteratorRecord, promiseCapability).
auto iterator_record = TRY_OR_REJECT(global_object, promise_capability, get_iterator(global_object, vm.argument(0))); auto iterator_record = TRY_OR_REJECT(global_object, promise_capability, get_iterator(vm, vm.argument(0)));
// 7. Let result be Completion(PerformPromiseAll(iteratorRecord, C, promiseCapability, promiseResolve)). // 7. Let result be Completion(PerformPromiseAll(iteratorRecord, C, promiseCapability, promiseResolve)).
auto result = perform_promise_all(global_object, iterator_record, constructor, promise_capability, promise_resolve); auto result = perform_promise_all(global_object, iterator_record, constructor, promise_capability, promise_resolve);
@ -341,7 +341,7 @@ JS_DEFINE_NATIVE_FUNCTION(PromiseConstructor::all)
if (result.is_error()) { if (result.is_error()) {
// a. If iteratorRecord.[[Done]] is false, set result to Completion(IteratorClose(iteratorRecord, result)). // a. If iteratorRecord.[[Done]] is false, set result to Completion(IteratorClose(iteratorRecord, result)).
if (!iterator_record.done) if (!iterator_record.done)
result = iterator_close(global_object, iterator_record, result.release_error()); result = iterator_close(vm, iterator_record, result.release_error());
// b. IfAbruptRejectPromise(result, promiseCapability). // b. IfAbruptRejectPromise(result, promiseCapability).
TRY_OR_REJECT(global_object, promise_capability, result); TRY_OR_REJECT(global_object, promise_capability, result);
@ -366,7 +366,7 @@ JS_DEFINE_NATIVE_FUNCTION(PromiseConstructor::all_settled)
// 5. Let iteratorRecord be Completion(GetIterator(iterable)). // 5. Let iteratorRecord be Completion(GetIterator(iterable)).
// 6. IfAbruptRejectPromise(iteratorRecord, promiseCapability). // 6. IfAbruptRejectPromise(iteratorRecord, promiseCapability).
auto iterator_record = TRY_OR_REJECT(global_object, promise_capability, get_iterator(global_object, vm.argument(0))); auto iterator_record = TRY_OR_REJECT(global_object, promise_capability, get_iterator(vm, vm.argument(0)));
// 7. Let result be Completion(PerformPromiseAllSettled(iteratorRecord, C, promiseCapability, promiseResolve)). // 7. Let result be Completion(PerformPromiseAllSettled(iteratorRecord, C, promiseCapability, promiseResolve)).
auto result = perform_promise_all_settled(global_object, iterator_record, constructor, promise_capability, promise_resolve); auto result = perform_promise_all_settled(global_object, iterator_record, constructor, promise_capability, promise_resolve);
@ -375,7 +375,7 @@ JS_DEFINE_NATIVE_FUNCTION(PromiseConstructor::all_settled)
if (result.is_error()) { if (result.is_error()) {
// a. If iteratorRecord.[[Done]] is false, set result to Completion(IteratorClose(iteratorRecord, result)). // a. If iteratorRecord.[[Done]] is false, set result to Completion(IteratorClose(iteratorRecord, result)).
if (!iterator_record.done) if (!iterator_record.done)
result = iterator_close(global_object, iterator_record, result.release_error()); result = iterator_close(vm, iterator_record, result.release_error());
// b. IfAbruptRejectPromise(result, promiseCapability). // b. IfAbruptRejectPromise(result, promiseCapability).
TRY_OR_REJECT(global_object, promise_capability, result); TRY_OR_REJECT(global_object, promise_capability, result);
@ -400,7 +400,7 @@ JS_DEFINE_NATIVE_FUNCTION(PromiseConstructor::any)
// 5. Let iteratorRecord be Completion(GetIterator(iterable)). // 5. Let iteratorRecord be Completion(GetIterator(iterable)).
// 6. IfAbruptRejectPromise(iteratorRecord, promiseCapability). // 6. IfAbruptRejectPromise(iteratorRecord, promiseCapability).
auto iterator_record = TRY_OR_REJECT(global_object, promise_capability, get_iterator(global_object, vm.argument(0))); auto iterator_record = TRY_OR_REJECT(global_object, promise_capability, get_iterator(vm, vm.argument(0)));
// 7. Let result be Completion(PerformPromiseAny(iteratorRecord, C, promiseCapability, promiseResolve)). // 7. Let result be Completion(PerformPromiseAny(iteratorRecord, C, promiseCapability, promiseResolve)).
auto result = perform_promise_any(global_object, iterator_record, constructor, promise_capability, promise_resolve); auto result = perform_promise_any(global_object, iterator_record, constructor, promise_capability, promise_resolve);
@ -409,7 +409,7 @@ JS_DEFINE_NATIVE_FUNCTION(PromiseConstructor::any)
if (result.is_error()) { if (result.is_error()) {
// a. If iteratorRecord.[[Done]] is false, set result to Completion(IteratorClose(iteratorRecord, result)). // a. If iteratorRecord.[[Done]] is false, set result to Completion(IteratorClose(iteratorRecord, result)).
if (!iterator_record.done) if (!iterator_record.done)
result = iterator_close(global_object, iterator_record, result.release_error()); result = iterator_close(vm, iterator_record, result.release_error());
// b. IfAbruptRejectPromise(result, promiseCapability). // b. IfAbruptRejectPromise(result, promiseCapability).
TRY_OR_REJECT(global_object, promise_capability, result); TRY_OR_REJECT(global_object, promise_capability, result);
@ -434,7 +434,7 @@ JS_DEFINE_NATIVE_FUNCTION(PromiseConstructor::race)
// 5. Let iteratorRecord be Completion(GetIterator(iterable)). // 5. Let iteratorRecord be Completion(GetIterator(iterable)).
// 6. IfAbruptRejectPromise(iteratorRecord, promiseCapability). // 6. IfAbruptRejectPromise(iteratorRecord, promiseCapability).
auto iterator_record = TRY_OR_REJECT(global_object, promise_capability, get_iterator(global_object, vm.argument(0))); auto iterator_record = TRY_OR_REJECT(global_object, promise_capability, get_iterator(vm, vm.argument(0)));
// 7. Let result be Completion(PerformPromiseRace(iteratorRecord, C, promiseCapability, promiseResolve)). // 7. Let result be Completion(PerformPromiseRace(iteratorRecord, C, promiseCapability, promiseResolve)).
auto result = perform_promise_race(global_object, iterator_record, constructor, promise_capability, promise_resolve); auto result = perform_promise_race(global_object, iterator_record, constructor, promise_capability, promise_resolve);
@ -443,7 +443,7 @@ JS_DEFINE_NATIVE_FUNCTION(PromiseConstructor::race)
if (result.is_error()) { if (result.is_error()) {
// a. If iteratorRecord.[[Done]] is false, set result to Completion(IteratorClose(iteratorRecord, result)). // a. If iteratorRecord.[[Done]] is false, set result to Completion(IteratorClose(iteratorRecord, result)).
if (!iterator_record.done) if (!iterator_record.done)
result = iterator_close(global_object, iterator_record, result.release_error()); result = iterator_close(vm, iterator_record, result.release_error());
// b. IfAbruptRejectPromise(result, promiseCapability). // b. IfAbruptRejectPromise(result, promiseCapability).
TRY_OR_REJECT(global_object, promise_capability, result); TRY_OR_REJECT(global_object, promise_capability, result);

View file

@ -35,18 +35,18 @@ JS_DEFINE_NATIVE_FUNCTION(RegExpStringIteratorPrototype::next)
// For details, see the 'closure' of: https://tc39.es/ecma262/#sec-createregexpstringiterator // For details, see the 'closure' of: https://tc39.es/ecma262/#sec-createregexpstringiterator
auto* iterator = TRY(typed_this_value(vm)); auto* iterator = TRY(typed_this_value(vm));
if (iterator->done()) if (iterator->done())
return create_iterator_result_object(global_object, js_undefined(), true); return create_iterator_result_object(vm, js_undefined(), true);
auto match = TRY(regexp_exec(global_object, iterator->regexp_object(), iterator->string())); auto match = TRY(regexp_exec(global_object, iterator->regexp_object(), iterator->string()));
if (match.is_null()) { if (match.is_null()) {
iterator->set_done(); iterator->set_done();
return create_iterator_result_object(global_object, js_undefined(), true); return create_iterator_result_object(vm, js_undefined(), true);
} }
if (!iterator->global()) { if (!iterator->global()) {
iterator->set_done(); iterator->set_done();
return create_iterator_result_object(global_object, match, false); return create_iterator_result_object(vm, match, false);
} }
auto* match_object = TRY(match.to_object(vm)); auto* match_object = TRY(match.to_object(vm));
@ -61,7 +61,7 @@ JS_DEFINE_NATIVE_FUNCTION(RegExpStringIteratorPrototype::next)
TRY(iterator->regexp_object().set(vm.names.lastIndex, Value(last_index), Object::ShouldThrowExceptions::Yes)); TRY(iterator->regexp_object().set(vm.names.lastIndex, Value(last_index), Object::ShouldThrowExceptions::Yes));
} }
return create_iterator_result_object(global_object, match, false); return create_iterator_result_object(vm, match, false);
} }
} }

View file

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

View file

@ -36,12 +36,12 @@ JS_DEFINE_NATIVE_FUNCTION(SetIteratorPrototype::next)
auto* set_iterator = TRY(typed_this_value(vm)); auto* set_iterator = TRY(typed_this_value(vm));
if (set_iterator->done()) if (set_iterator->done())
return create_iterator_result_object(global_object, js_undefined(), true); return create_iterator_result_object(vm, js_undefined(), true);
auto& set = set_iterator->set(); auto& set = set_iterator->set();
if (set_iterator->m_iterator == set.end()) { if (set_iterator->m_iterator == set.end()) {
set_iterator->m_done = true; set_iterator->m_done = true;
return create_iterator_result_object(global_object, js_undefined(), true); return create_iterator_result_object(vm, js_undefined(), true);
} }
auto iteration_kind = set_iterator->iteration_kind(); auto iteration_kind = set_iterator->iteration_kind();
@ -50,9 +50,9 @@ JS_DEFINE_NATIVE_FUNCTION(SetIteratorPrototype::next)
auto value = (*set_iterator->m_iterator).key; auto value = (*set_iterator->m_iterator).key;
++set_iterator->m_iterator; ++set_iterator->m_iterator;
if (iteration_kind == Object::PropertyKind::Value) if (iteration_kind == Object::PropertyKind::Value)
return create_iterator_result_object(global_object, value, false); return create_iterator_result_object(vm, value, false);
return create_iterator_result_object(global_object, Array::create_from(realm, { value, value }), false); return create_iterator_result_object(vm, Array::create_from(realm, { value, value }), false);
} }
} }

View file

@ -33,20 +33,20 @@ JS_DEFINE_NATIVE_FUNCTION(StringIteratorPrototype::next)
{ {
auto* iterator = TRY(typed_this_value(vm)); auto* iterator = TRY(typed_this_value(vm));
if (iterator->done()) if (iterator->done())
return create_iterator_result_object(global_object, js_undefined(), true); return create_iterator_result_object(vm, js_undefined(), true);
auto& utf8_iterator = iterator->iterator(); auto& utf8_iterator = iterator->iterator();
if (utf8_iterator.done()) { if (utf8_iterator.done()) {
iterator->m_done = true; iterator->m_done = true;
return create_iterator_result_object(global_object, js_undefined(), true); return create_iterator_result_object(vm, js_undefined(), true);
} }
StringBuilder builder; StringBuilder builder;
builder.append_code_point(*utf8_iterator); builder.append_code_point(*utf8_iterator);
++utf8_iterator; ++utf8_iterator;
return create_iterator_result_object(global_object, js_string(vm, builder.to_string()), false); return create_iterator_result_object(vm, js_string(vm, builder.to_string()), false);
} }
} }

View file

@ -41,11 +41,8 @@ static Optional<OptionType> to_option_type(Value value)
// 13.1 IterableToListOfType ( items, elementTypes ), https://tc39.es/proposal-temporal/#sec-iterabletolistoftype // 13.1 IterableToListOfType ( items, elementTypes ), https://tc39.es/proposal-temporal/#sec-iterabletolistoftype
ThrowCompletionOr<MarkedVector<Value>> iterable_to_list_of_type(VM& vm, Value items, Vector<OptionType> const& element_types) ThrowCompletionOr<MarkedVector<Value>> iterable_to_list_of_type(VM& vm, Value items, Vector<OptionType> const& element_types)
{ {
auto& realm = *vm.current_realm();
auto& global_object = realm.global_object();
// 1. Let iteratorRecord be ? GetIterator(items, sync). // 1. Let iteratorRecord be ? GetIterator(items, sync).
auto iterator_record = TRY(get_iterator(global_object, items, IteratorHint::Sync)); auto iterator_record = TRY(get_iterator(vm, items, IteratorHint::Sync));
// 2. Let values be a new empty List. // 2. Let values be a new empty List.
MarkedVector<Value> values(vm.heap()); MarkedVector<Value> values(vm.heap());
@ -55,19 +52,19 @@ ThrowCompletionOr<MarkedVector<Value>> iterable_to_list_of_type(VM& vm, Value it
// 4. Repeat, while next is not false, // 4. Repeat, while next is not false,
while (next) { while (next) {
// a. Set next to ? IteratorStep(iteratorRecord). // a. Set next to ? IteratorStep(iteratorRecord).
auto* iterator_result = TRY(iterator_step(global_object, iterator_record)); auto* iterator_result = TRY(iterator_step(vm, iterator_record));
next = iterator_result; next = iterator_result;
// b. If next is not false, then // b. If next is not false, then
if (next) { if (next) {
// i. Let nextValue be ? IteratorValue(next). // i. Let nextValue be ? IteratorValue(next).
auto next_value = TRY(iterator_value(global_object, *iterator_result)); auto next_value = TRY(iterator_value(vm, *iterator_result));
// ii. If Type(nextValue) is not an element of elementTypes, then // ii. If Type(nextValue) is not an element of elementTypes, then
if (auto type = to_option_type(next_value); !type.has_value() || !element_types.contains_slow(*type)) { if (auto type = to_option_type(next_value); !type.has_value() || !element_types.contains_slow(*type)) {
// 1. Let completion be ThrowCompletion(a newly created TypeError object). // 1. Let completion be ThrowCompletion(a newly created TypeError object).
auto completion = vm.throw_completion<TypeError>(ErrorType::IterableToListOfTypeInvalidValue, next_value.to_string_without_side_effects()); auto completion = vm.throw_completion<TypeError>(ErrorType::IterableToListOfTypeInvalidValue, next_value.to_string_without_side_effects());
// 2. Return ? IteratorClose(iteratorRecord, completion). // 2. Return ? IteratorClose(iteratorRecord, completion).
return iterator_close(global_object, iterator_record, move(completion)); return iterator_close(vm, iterator_record, move(completion));
} }
// iii. Append nextValue to the end of the List values. // iii. Append nextValue to the end of the List values.
values.append(next_value); values.append(next_value);

View file

@ -513,7 +513,7 @@ JS_DEFINE_NATIVE_FUNCTION(CalendarPrototype::fields)
VERIFY(calendar->identifier() == "iso8601"sv); VERIFY(calendar->identifier() == "iso8601"sv);
// 4. Let iteratorRecord be ? GetIterator(fields, sync). // 4. Let iteratorRecord be ? GetIterator(fields, sync).
auto iterator_record = TRY(get_iterator(global_object, fields, IteratorHint::Sync)); auto iterator_record = TRY(get_iterator(vm, fields, IteratorHint::Sync));
// 5. Let fieldNames be a new empty List. // 5. Let fieldNames be a new empty List.
auto field_names = MarkedVector<Value> { vm.heap() }; auto field_names = MarkedVector<Value> { vm.heap() };
@ -522,14 +522,14 @@ JS_DEFINE_NATIVE_FUNCTION(CalendarPrototype::fields)
// 7. Repeat, while next is not false, // 7. Repeat, while next is not false,
while (true) { while (true) {
// a. Set next to ? IteratorStep(iteratorRecord). // a. Set next to ? IteratorStep(iteratorRecord).
auto* next = TRY(iterator_step(global_object, iterator_record)); auto* next = TRY(iterator_step(vm, iterator_record));
// b. If next is not false, then // b. If next is not false, then
if (!next) if (!next)
break; break;
// i. Let nextValue be ? IteratorValue(next). // i. Let nextValue be ? IteratorValue(next).
auto next_value = TRY(iterator_value(global_object, *next)); auto next_value = TRY(iterator_value(vm, *next));
// ii. If Type(nextValue) is not String, then // ii. If Type(nextValue) is not String, then
if (!next_value.is_string()) { if (!next_value.is_string()) {
@ -537,7 +537,7 @@ JS_DEFINE_NATIVE_FUNCTION(CalendarPrototype::fields)
auto completion = vm.throw_completion<TypeError>(ErrorType::TemporalInvalidCalendarFieldValue, next_value.to_string_without_side_effects()); auto completion = vm.throw_completion<TypeError>(ErrorType::TemporalInvalidCalendarFieldValue, next_value.to_string_without_side_effects());
// 2. Return ? IteratorClose(iteratorRecord, completion). // 2. Return ? IteratorClose(iteratorRecord, completion).
return TRY(iterator_close(global_object, iterator_record, move(completion))); return TRY(iterator_close(vm, iterator_record, move(completion)));
} }
// iii. If fieldNames contains nextValue, then // iii. If fieldNames contains nextValue, then
@ -546,7 +546,7 @@ JS_DEFINE_NATIVE_FUNCTION(CalendarPrototype::fields)
auto completion = vm.throw_completion<RangeError>(ErrorType::TemporalDuplicateCalendarField, next_value.as_string().string()); auto completion = vm.throw_completion<RangeError>(ErrorType::TemporalDuplicateCalendarField, next_value.as_string().string());
// 2. Return ? IteratorClose(iteratorRecord, completion). // 2. Return ? IteratorClose(iteratorRecord, completion).
return TRY(iterator_close(global_object, iterator_record, move(completion))); return TRY(iterator_close(vm, iterator_record, move(completion)));
} }
// iv. If nextValue is not one of "year", "month", "monthCode", "day", "hour", "minute", "second", "millisecond", "microsecond", "nanosecond", then // iv. If nextValue is not one of "year", "month", "monthCode", "day", "hour", "minute", "second", "millisecond", "microsecond", "nanosecond", then
@ -555,7 +555,7 @@ JS_DEFINE_NATIVE_FUNCTION(CalendarPrototype::fields)
auto completion = vm.throw_completion<RangeError>(ErrorType::TemporalInvalidCalendarFieldName, next_value.as_string().string()); auto completion = vm.throw_completion<RangeError>(ErrorType::TemporalInvalidCalendarFieldName, next_value.as_string().string());
// 2. Return ? IteratorClose(iteratorRecord, completion). // 2. Return ? IteratorClose(iteratorRecord, completion).
return TRY(iterator_close(global_object, iterator_record, move(completion))); return TRY(iterator_close(vm, iterator_record, move(completion)));
} }
// v. Append nextValue to the end of the List fieldNames. // v. Append nextValue to the end of the List fieldNames.

View file

@ -665,16 +665,13 @@ ThrowCompletionOr<Instant*> disambiguate_possible_instants(VM& vm, MarkedVector<
// 11.6.16 GetPossibleInstantsFor ( timeZone, dateTime ), https://tc39.es/proposal-temporal/#sec-temporal-getpossibleinstantsfor // 11.6.16 GetPossibleInstantsFor ( timeZone, dateTime ), https://tc39.es/proposal-temporal/#sec-temporal-getpossibleinstantsfor
ThrowCompletionOr<MarkedVector<Instant*>> get_possible_instants_for(VM& vm, Value time_zone, PlainDateTime& date_time) ThrowCompletionOr<MarkedVector<Instant*>> get_possible_instants_for(VM& vm, Value time_zone, PlainDateTime& date_time)
{ {
auto& realm = *vm.current_realm();
auto& global_object = realm.global_object();
// 1. Assert: dateTime has an [[InitializedTemporalDateTime]] internal slot. // 1. Assert: dateTime has an [[InitializedTemporalDateTime]] internal slot.
// 2. Let possibleInstants be ? Invoke(timeZone, "getPossibleInstantsFor", « dateTime »). // 2. Let possibleInstants be ? Invoke(timeZone, "getPossibleInstantsFor", « dateTime »).
auto possible_instants = TRY(time_zone.invoke(vm, vm.names.getPossibleInstantsFor, &date_time)); auto possible_instants = TRY(time_zone.invoke(vm, vm.names.getPossibleInstantsFor, &date_time));
// 3. Let iteratorRecord be ? GetIterator(possibleInstants, sync). // 3. Let iteratorRecord be ? GetIterator(possibleInstants, sync).
auto iterator = TRY(get_iterator(global_object, possible_instants, IteratorHint::Sync)); auto iterator = TRY(get_iterator(vm, possible_instants, IteratorHint::Sync));
// 4. Let list be a new empty List. // 4. Let list be a new empty List.
auto list = MarkedVector<Instant*> { vm.heap() }; auto list = MarkedVector<Instant*> { vm.heap() };
@ -685,12 +682,12 @@ ThrowCompletionOr<MarkedVector<Instant*>> get_possible_instants_for(VM& vm, Valu
// 6. Repeat, while next is not false, // 6. Repeat, while next is not false,
do { do {
// a. Set next to ? IteratorStep(iteratorRecord). // a. Set next to ? IteratorStep(iteratorRecord).
next = TRY(iterator_step(global_object, iterator)); next = TRY(iterator_step(vm, iterator));
// b. If next is not false, then // b. If next is not false, then
if (next) { if (next) {
// i. Let nextValue be ? IteratorValue(next). // i. Let nextValue be ? IteratorValue(next).
auto next_value = TRY(iterator_value(global_object, *next)); auto next_value = TRY(iterator_value(vm, *next));
// ii. If Type(nextValue) is not Object or nextValue does not have an [[InitializedTemporalInstant]] internal slot, then // ii. If Type(nextValue) is not Object or nextValue does not have an [[InitializedTemporalInstant]] internal slot, then
if (!next_value.is_object() || !is<Instant>(next_value.as_object())) { if (!next_value.is_object() || !is<Instant>(next_value.as_object())) {
@ -698,7 +695,7 @@ ThrowCompletionOr<MarkedVector<Instant*>> get_possible_instants_for(VM& vm, Valu
auto completion = vm.throw_completion<TypeError>(ErrorType::NotAnObjectOfType, "Temporal.Instant"); auto completion = vm.throw_completion<TypeError>(ErrorType::NotAnObjectOfType, "Temporal.Instant");
// 2. Return ? IteratorClose(iteratorRecord, completion). // 2. Return ? IteratorClose(iteratorRecord, completion).
return iterator_close(global_object, iterator, move(completion)); return iterator_close(vm, iterator, move(completion));
} }
// iii. Append nextValue to the end of the List list. // iii. Append nextValue to the end of the List list.

View file

@ -538,7 +538,7 @@ void TypedArrayBase::visit_edges(Visitor& visitor)
} else { \ } else { \
auto iterator = TRY(first_argument.get_method(vm, *vm.well_known_symbol_iterator())); \ auto iterator = TRY(first_argument.get_method(vm, *vm.well_known_symbol_iterator())); \
if (iterator) { \ if (iterator) { \
auto values = TRY(iterable_to_list(global_object, first_argument, iterator)); \ auto values = TRY(iterable_to_list(vm, first_argument, iterator)); \
TRY(initialize_typed_array_from_list(global_object, *typed_array, values)); \ TRY(initialize_typed_array_from_list(global_object, *typed_array, values)); \
} else { \ } else { \
TRY(initialize_typed_array_from_array_like(global_object, *typed_array, first_argument.as_object())); \ TRY(initialize_typed_array_from_array_like(global_object, *typed_array, first_argument.as_object())); \

View file

@ -70,7 +70,7 @@ JS_DEFINE_NATIVE_FUNCTION(TypedArrayConstructor::from)
auto using_iterator = TRY(source.get_method(vm, *vm.well_known_symbol_iterator())); auto using_iterator = TRY(source.get_method(vm, *vm.well_known_symbol_iterator()));
if (using_iterator) { if (using_iterator) {
auto values = TRY(iterable_to_list(global_object, source, using_iterator)); auto values = TRY(iterable_to_list(vm, source, using_iterator));
MarkedVector<Value> arguments(vm.heap()); MarkedVector<Value> arguments(vm.heap());
arguments.empend(values.size()); arguments.empend(values.size());

View file

@ -274,6 +274,8 @@ ThrowCompletionOr<void> VM::binding_initialization(FlyString const& target, Valu
// 8.5.2 Runtime Semantics: BindingInitialization, https://tc39.es/ecma262/#sec-runtime-semantics-bindinginitialization // 8.5.2 Runtime Semantics: BindingInitialization, https://tc39.es/ecma262/#sec-runtime-semantics-bindinginitialization
ThrowCompletionOr<void> VM::binding_initialization(NonnullRefPtr<BindingPattern> const& target, Value value, Environment* environment, GlobalObject& global_object) ThrowCompletionOr<void> VM::binding_initialization(NonnullRefPtr<BindingPattern> const& target, Value value, Environment* environment, GlobalObject& global_object)
{ {
auto& vm = *this;
// BindingPattern : ObjectBindingPattern // BindingPattern : ObjectBindingPattern
if (target->kind == BindingPattern::Kind::Object) { if (target->kind == BindingPattern::Kind::Object) {
// 1. Perform ? RequireObjectCoercible(value). // 1. Perform ? RequireObjectCoercible(value).
@ -291,7 +293,7 @@ ThrowCompletionOr<void> VM::binding_initialization(NonnullRefPtr<BindingPattern>
// BindingPattern : ArrayBindingPattern // BindingPattern : ArrayBindingPattern
else { else {
// 1. Let iteratorRecord be ? GetIterator(value). // 1. Let iteratorRecord be ? GetIterator(value).
auto iterator_record = TRY(get_iterator(global_object, value)); auto iterator_record = TRY(get_iterator(vm, value));
// 2. Let result be Completion(IteratorBindingInitialization of ArrayBindingPattern with arguments iteratorRecord and environment). // 2. Let result be Completion(IteratorBindingInitialization of ArrayBindingPattern with arguments iteratorRecord and environment).
auto result = iterator_binding_initialization(*target, iterator_record, environment, global_object); auto result = iterator_binding_initialization(*target, iterator_record, environment, global_object);
@ -301,7 +303,7 @@ ThrowCompletionOr<void> VM::binding_initialization(NonnullRefPtr<BindingPattern>
// iterator_close() always returns a Completion, which ThrowCompletionOr will interpret as a throw // iterator_close() always returns a Completion, which ThrowCompletionOr will interpret as a throw
// completion. So only return the result of iterator_close() if it is indeed a throw completion. // completion. So only return the result of iterator_close() if it is indeed a throw completion.
auto completion = result.is_throw_completion() ? result.release_error() : normal_completion({}); auto completion = result.is_throw_completion() ? result.release_error() : normal_completion({});
if (completion = iterator_close(global_object, iterator_record, move(completion)); completion.is_error()) if (completion = iterator_close(vm, iterator_record, move(completion)); completion.is_error())
return completion.release_error(); return completion.release_error();
} }
@ -442,7 +444,7 @@ ThrowCompletionOr<void> VM::iterator_binding_initialization(BindingPattern const
// a. If iteratorRecord.[[Done]] is false, then // a. If iteratorRecord.[[Done]] is false, then
if (!iterator_record.done) { if (!iterator_record.done) {
// i. Let next be Completion(IteratorStep(iteratorRecord)). // i. Let next be Completion(IteratorStep(iteratorRecord)).
next = iterator_step(global_object, iterator_record); next = iterator_step(vm, iterator_record);
// ii. If next is an abrupt completion, set iteratorRecord.[[Done]] to true. // ii. If next is an abrupt completion, set iteratorRecord.[[Done]] to true.
// iii. ReturnIfAbrupt(next). // iii. ReturnIfAbrupt(next).
@ -463,7 +465,7 @@ ThrowCompletionOr<void> VM::iterator_binding_initialization(BindingPattern const
} }
// c. Let nextValue be Completion(IteratorValue(next)). // c. Let nextValue be Completion(IteratorValue(next)).
auto next_value = iterator_value(global_object, *next.value()); auto next_value = iterator_value(vm, *next.value());
// d. If nextValue is an abrupt completion, set iteratorRecord.[[Done]] to true. // d. If nextValue is an abrupt completion, set iteratorRecord.[[Done]] to true.
// e. ReturnIfAbrupt(nextValue). // e. ReturnIfAbrupt(nextValue).
@ -488,7 +490,7 @@ ThrowCompletionOr<void> VM::iterator_binding_initialization(BindingPattern const
// 2. If iteratorRecord.[[Done]] is false, then // 2. If iteratorRecord.[[Done]] is false, then
if (!iterator_record.done) { if (!iterator_record.done) {
// a. Let next be Completion(IteratorStep(iteratorRecord)). // a. Let next be Completion(IteratorStep(iteratorRecord)).
auto next = iterator_step(global_object, iterator_record); auto next = iterator_step(vm, iterator_record);
// b. If next is an abrupt completion, set iteratorRecord.[[Done]] to true. // b. If next is an abrupt completion, set iteratorRecord.[[Done]] to true.
// c. ReturnIfAbrupt(next). // c. ReturnIfAbrupt(next).
@ -504,7 +506,7 @@ ThrowCompletionOr<void> VM::iterator_binding_initialization(BindingPattern const
// e. Else, // e. Else,
else { else {
// i. Set v to Completion(IteratorValue(next)). // i. Set v to Completion(IteratorValue(next)).
auto value_or_error = iterator_value(global_object, *next.value()); auto value_or_error = iterator_value(vm, *next.value());
// ii. If v is an abrupt completion, set iteratorRecord.[[Done]] to true. // ii. If v is an abrupt completion, set iteratorRecord.[[Done]] to true.
// iii. ReturnIfAbrupt(v). // iii. ReturnIfAbrupt(v).

View file

@ -51,7 +51,7 @@ ThrowCompletionOr<Object*> WeakMapConstructor::construct(FunctionObject& new_tar
if (!adder.is_function()) if (!adder.is_function())
return vm.throw_completion<TypeError>(ErrorType::NotAFunction, "'set' property of WeakMap"); return vm.throw_completion<TypeError>(ErrorType::NotAFunction, "'set' property of WeakMap");
(void)TRY(get_iterator_values(global_object, vm.argument(0), [&](Value iterator_value) -> Optional<Completion> { (void)TRY(get_iterator_values(vm, vm.argument(0), [&](Value iterator_value) -> Optional<Completion> {
if (!iterator_value.is_object()) if (!iterator_value.is_object())
return vm.throw_completion<TypeError>(ErrorType::NotAnObject, String::formatted("Iterator value {}", iterator_value.to_string_without_side_effects())); return vm.throw_completion<TypeError>(ErrorType::NotAnObject, String::formatted("Iterator value {}", iterator_value.to_string_without_side_effects()));

View file

@ -51,7 +51,7 @@ ThrowCompletionOr<Object*> WeakSetConstructor::construct(FunctionObject& new_tar
if (!adder.is_function()) if (!adder.is_function())
return vm.throw_completion<TypeError>(ErrorType::NotAFunction, "'add' property of WeakSet"); return vm.throw_completion<TypeError>(ErrorType::NotAFunction, "'add' property of WeakSet");
(void)TRY(get_iterator_values(global_object, vm.argument(0), [&](Value iterator_value) -> Optional<Completion> { (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(global_object, adder.as_function(), weak_set, iterator_value));
return {}; return {};
})); }));

View file

@ -30,18 +30,18 @@ JS::ThrowCompletionOr<JS::Object*> HeadersIterator::next()
auto pairs = TRY(value_pairs_to_iterate_over()); auto pairs = TRY(value_pairs_to_iterate_over());
if (m_index >= pairs.size()) if (m_index >= pairs.size())
return create_iterator_result_object(global_object, JS::js_undefined(), true); return create_iterator_result_object(vm, JS::js_undefined(), true);
auto const& pair = pairs[m_index++]; auto const& pair = pairs[m_index++];
switch (m_iteration_kind) { switch (m_iteration_kind) {
case JS::Object::PropertyKind::Key: case JS::Object::PropertyKind::Key:
return create_iterator_result_object(global_object, JS::js_string(vm, StringView { pair.name }), false); return create_iterator_result_object(vm, JS::js_string(vm, StringView { pair.name }), false);
case JS::Object::PropertyKind::Value: case JS::Object::PropertyKind::Value:
return create_iterator_result_object(global_object, JS::js_string(vm, StringView { pair.value }), false); return create_iterator_result_object(vm, JS::js_string(vm, StringView { pair.value }), false);
case JS::Object::PropertyKind::KeyAndValue: { case JS::Object::PropertyKind::KeyAndValue: {
auto* array = JS::Array::create_from(realm, { JS::js_string(vm, StringView { pair.name }), JS::js_string(vm, StringView { pair.value }) }); auto* array = JS::Array::create_from(realm, { JS::js_string(vm, StringView { pair.name }), JS::js_string(vm, StringView { pair.value }) });
return create_iterator_result_object(global_object, array, false); return create_iterator_result_object(vm, array, false);
} }
default: default:
VERIFY_NOT_REACHED(); VERIFY_NOT_REACHED();

View file

@ -19,15 +19,15 @@ JS::Object* URLSearchParamsIterator::next()
auto& realm = *global_object.associated_realm(); auto& realm = *global_object.associated_realm();
if (m_index >= m_url_search_params.m_list.size()) if (m_index >= m_url_search_params.m_list.size())
return create_iterator_result_object(global_object, JS::js_undefined(), true); return create_iterator_result_object(vm, JS::js_undefined(), true);
auto& entry = m_url_search_params.m_list[m_index++]; auto& entry = m_url_search_params.m_list[m_index++];
if (m_iteration_kind == JS::Object::PropertyKind::Key) if (m_iteration_kind == JS::Object::PropertyKind::Key)
return create_iterator_result_object(global_object, JS::js_string(vm, entry.name), false); return create_iterator_result_object(vm, JS::js_string(vm, entry.name), false);
else if (m_iteration_kind == JS::Object::PropertyKind::Value) else if (m_iteration_kind == JS::Object::PropertyKind::Value)
return create_iterator_result_object(global_object, JS::js_string(vm, entry.value), false); return create_iterator_result_object(vm, JS::js_string(vm, entry.value), false);
return create_iterator_result_object(global_object, JS::Array::create_from(realm, { JS::js_string(vm, entry.name), JS::js_string(vm, entry.value) }), false); return create_iterator_result_object(vm, JS::Array::create_from(realm, { JS::js_string(vm, entry.name), JS::js_string(vm, entry.value) }), false);
} }
void URLSearchParamsIterator::visit_edges(JS::Cell::Visitor& visitor) void URLSearchParamsIterator::visit_edges(JS::Cell::Visitor& visitor)