1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-27 07:37:46 +00:00

LibJS: Implement the IteratorStepValue AO

This is an editorial change in the ECMA-262 spec. See:
12d3687

This AO is meant to replace usages of IteratorNext followed by
IteratorValue with a single operation.
This commit is contained in:
Timothy Flynn 2024-02-01 14:52:07 -05:00 committed by Tim Flynn
parent 3ca86cd044
commit 2b96e732dd
2 changed files with 62 additions and 6 deletions

View file

@ -195,8 +195,63 @@ ThrowCompletionOr<GCPtr<Object>> iterator_step(VM& vm, IteratorRecord const& ite
return result; return result;
} }
// 7.4.8 IteratorClose ( iteratorRecord, completion ), https://tc39.es/ecma262/#sec-iteratorclose // 7.4.8 IteratorStepValue ( iteratorRecord ), https://tc39.es/ecma262/#sec-iteratorstepvalue
// 7.4.10 AsyncIteratorClose ( iteratorRecord, completion ), https://tc39.es/ecma262/#sec-asynciteratorclose ThrowCompletionOr<Optional<Value>> iterator_step_value(VM& vm, IteratorRecord& iterator_record)
{
// 1. Let result be Completion(IteratorNext(iteratorRecord)).
auto result = iterator_next(vm, iterator_record);
// 2. If result is a throw completion, then
if (result.is_throw_completion()) {
// a. Set iteratorRecord.[[Done]] to true.
iterator_record.done = true;
// b. Return ? result.
return result.release_error();
}
// 3. Set result to ! result.
auto result_value = result.release_value();
// 4. Let done be Completion(IteratorComplete(result)).
auto done = iterator_complete(vm, result_value);
// 5. If done is a throw completion, then
if (done.is_throw_completion()) {
// a. Set iteratorRecord.[[Done]] to true.
iterator_record.done = true;
// b. Return ? done.
return done.release_error();
}
// 6. Set done to ! done.
auto done_value = done.release_value();
// 7. If done is true, then
if (done_value) {
// a. Set iteratorRecord.[[Done]] to true.
iterator_record.done = true;
// b. Return DONE.
return OptionalNone {};
}
// 8. Let value be Completion(Get(result, "value")).
auto value = result_value->get(vm.names.value);
// 9. If value is a throw completion, then
if (value.is_throw_completion()) {
// a. Set iteratorRecord.[[Done]] to true.
iterator_record.done = true;
}
// 10. Return ? value.
return TRY(value);
}
// 7.4.9 IteratorClose ( iteratorRecord, completion ), https://tc39.es/ecma262/#sec-iteratorclose
// 7.4.11 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(VM& vm, IteratorRecord const& iterator_record, Completion completion, IteratorHint iterator_hint) static Completion iterator_close_impl(VM& vm, IteratorRecord const& iterator_record, Completion completion, IteratorHint iterator_hint)
{ {
@ -246,19 +301,19 @@ static Completion iterator_close_impl(VM& vm, IteratorRecord const& iterator_rec
return completion; return completion;
} }
// 7.4.8 IteratorClose ( iteratorRecord, completion ), https://tc39.es/ecma262/#sec-iteratorclose // 7.4.9 IteratorClose ( iteratorRecord, completion ), https://tc39.es/ecma262/#sec-iteratorclose
Completion iterator_close(VM& vm, IteratorRecord const& iterator_record, Completion completion) Completion iterator_close(VM& vm, IteratorRecord const& iterator_record, Completion completion)
{ {
return iterator_close_impl(vm, iterator_record, move(completion), IteratorHint::Sync); return iterator_close_impl(vm, iterator_record, move(completion), IteratorHint::Sync);
} }
// 7.4.10 AsyncIteratorClose ( iteratorRecord, completion ), https://tc39.es/ecma262/#sec-asynciteratorclose // 7.4.11 AsyncIteratorClose ( iteratorRecord, completion ), https://tc39.es/ecma262/#sec-asynciteratorclose
Completion async_iterator_close(VM& vm, IteratorRecord const& iterator_record, Completion completion) Completion async_iterator_close(VM& vm, IteratorRecord const& iterator_record, Completion completion)
{ {
return iterator_close_impl(vm, iterator_record, move(completion), IteratorHint::Async); return iterator_close_impl(vm, iterator_record, move(completion), IteratorHint::Async);
} }
// 7.4.11 CreateIterResultObject ( value, done ), https://tc39.es/ecma262/#sec-createiterresultobject // 7.4.12 CreateIterResultObject ( value, done ), https://tc39.es/ecma262/#sec-createiterresultobject
NonnullGCPtr<Object> create_iterator_result_object(VM& vm, Value value, bool done) NonnullGCPtr<Object> create_iterator_result_object(VM& vm, Value value, bool done)
{ {
auto& realm = *vm.current_realm(); auto& realm = *vm.current_realm();
@ -276,7 +331,7 @@ NonnullGCPtr<Object> create_iterator_result_object(VM& vm, Value value, bool don
return object; return object;
} }
// 7.4.13 IteratorToList ( iteratorRecord ), https://tc39.es/ecma262/#sec-iteratortolist // 7.4.14 IteratorToList ( iteratorRecord ), https://tc39.es/ecma262/#sec-iteratortolist
ThrowCompletionOr<MarkedVector<Value>> iterator_to_list(VM& vm, IteratorRecord const& iterator_record) ThrowCompletionOr<MarkedVector<Value>> iterator_to_list(VM& vm, IteratorRecord const& iterator_record)
{ {
// 1. Let values be a new empty List. // 1. Let values be a new empty List.

View file

@ -76,6 +76,7 @@ ThrowCompletionOr<NonnullGCPtr<IteratorRecord>> get_iterator_direct(VM&, Object&
ThrowCompletionOr<NonnullGCPtr<IteratorRecord>> get_iterator_flattenable(VM&, Value, StringHandling); ThrowCompletionOr<NonnullGCPtr<IteratorRecord>> get_iterator_flattenable(VM&, Value, StringHandling);
ThrowCompletionOr<NonnullGCPtr<Object>> iterator_next(VM&, IteratorRecord const&, Optional<Value> = {}); ThrowCompletionOr<NonnullGCPtr<Object>> iterator_next(VM&, IteratorRecord const&, Optional<Value> = {});
ThrowCompletionOr<GCPtr<Object>> iterator_step(VM&, IteratorRecord const&); ThrowCompletionOr<GCPtr<Object>> iterator_step(VM&, IteratorRecord const&);
ThrowCompletionOr<Optional<Value>> iterator_step_value(VM&, IteratorRecord&);
ThrowCompletionOr<bool> iterator_complete(VM&, Object& iterator_result); ThrowCompletionOr<bool> iterator_complete(VM&, Object& iterator_result);
ThrowCompletionOr<Value> iterator_value(VM&, Object& iterator_result); ThrowCompletionOr<Value> iterator_value(VM&, Object& iterator_result);
Completion iterator_close(VM&, IteratorRecord const&, Completion); Completion iterator_close(VM&, IteratorRecord const&, Completion);