mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-09-19 07:49:05 +00:00
LibJS: Close iterator records inside the Iterator{Next,Step} AOs
This is an editorial change in the ECMA-262 spec. See:
c4c55b6
This commit is contained in:
parent
3aca12d2fa
commit
896c2e2f0f
Notes:
github-actions[bot]
2024-10-23 21:27:30 +00:00
Author: https://github.com/trflynn89
Commit: 896c2e2f0f
Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/1936
2 changed files with 61 additions and 55 deletions
|
@ -143,25 +143,44 @@ ThrowCompletionOr<NonnullGCPtr<IteratorRecord>> get_iterator_flattenable(VM& vm,
|
|||
}
|
||||
|
||||
// 7.4.4 IteratorNext ( iteratorRecord [ , value ] ), https://tc39.es/ecma262/#sec-iteratornext
|
||||
ThrowCompletionOr<NonnullGCPtr<Object>> iterator_next(VM& vm, IteratorRecord const& iterator_record, Optional<Value> value)
|
||||
ThrowCompletionOr<NonnullGCPtr<Object>> iterator_next(VM& vm, IteratorRecord& iterator_record, Optional<Value> value)
|
||||
{
|
||||
Value result;
|
||||
auto result = [&]() {
|
||||
// 1. If value is not present, then
|
||||
if (!value.has_value()) {
|
||||
// a. Let result be Completion(Call(iteratorRecord.[[NextMethod]], iteratorRecord.[[Iterator]])).
|
||||
return call(vm, iterator_record.next_method, iterator_record.iterator);
|
||||
}
|
||||
// 2. Else,
|
||||
else {
|
||||
// a. Let result be Completion(Call(iteratorRecord.[[NextMethod]], iteratorRecord.[[Iterator]], « value »)).
|
||||
return call(vm, iterator_record.next_method, iterator_record.iterator, *value);
|
||||
}
|
||||
}();
|
||||
|
||||
// 1. If value is not present, then
|
||||
if (!value.has_value()) {
|
||||
// a. Let result be ? Call(iteratorRecord.[[NextMethod]], iteratorRecord.[[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(vm, iterator_record.next_method, iterator_record.iterator, *value));
|
||||
// 3. 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. If Type(result) is not Object, throw a TypeError exception.
|
||||
if (!result.is_object())
|
||||
return vm.throw_completion<TypeError>(ErrorType::IterableNextBadReturn);
|
||||
// 4. Set result to ! result.
|
||||
auto result_value = result.release_value();
|
||||
|
||||
// 4. Return result.
|
||||
return result.as_object();
|
||||
// 5. If result is not an Object, then
|
||||
if (!result_value.is_object()) {
|
||||
// a. Set iteratorRecord.[[Done]] to true.
|
||||
iterator_record.done = true;
|
||||
|
||||
// b. Throw a TypeError exception.
|
||||
return vm.throw_completion<TypeError>(ErrorType::IterableNextBadReturn);
|
||||
}
|
||||
|
||||
// 6. Return result.
|
||||
return result_value.as_object();
|
||||
}
|
||||
|
||||
// 7.4.5 IteratorComplete ( iterResult ), https://tc39.es/ecma262/#sec-iteratorcomplete
|
||||
|
@ -179,44 +198,15 @@ ThrowCompletionOr<Value> iterator_value(VM& vm, Object& iterator_result)
|
|||
}
|
||||
|
||||
// 7.4.7 IteratorStep ( iteratorRecord ), https://tc39.es/ecma262/#sec-iteratorstep
|
||||
ThrowCompletionOr<GCPtr<Object>> iterator_step(VM& vm, IteratorRecord const& iterator_record)
|
||||
ThrowCompletionOr<GCPtr<Object>> iterator_step(VM& vm, IteratorRecord& iterator_record)
|
||||
{
|
||||
// 1. Let result be ? IteratorNext(iteratorRecord).
|
||||
auto result = TRY(iterator_next(vm, iterator_record));
|
||||
|
||||
// 2. Let done be ? IteratorComplete(result).
|
||||
auto done = TRY(iterator_complete(vm, result));
|
||||
// 2. Let done be Completion(IteratorComplete(result)).
|
||||
auto done = iterator_complete(vm, result);
|
||||
|
||||
// 3. If done is true, return false.
|
||||
if (done)
|
||||
return nullptr;
|
||||
|
||||
// 4. Return result.
|
||||
return result;
|
||||
}
|
||||
|
||||
// 7.4.8 IteratorStepValue ( iteratorRecord ), https://tc39.es/ecma262/#sec-iteratorstepvalue
|
||||
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
|
||||
// 3. If done is a throw completion, then
|
||||
if (done.is_throw_completion()) {
|
||||
// a. Set iteratorRecord.[[Done]] to true.
|
||||
iterator_record.done = true;
|
||||
|
@ -225,28 +215,44 @@ ThrowCompletionOr<Optional<Value>> iterator_step_value(VM& vm, IteratorRecord& i
|
|||
return done.release_error();
|
||||
}
|
||||
|
||||
// 6. Set done to ! done.
|
||||
// 4. Set done to ! done.
|
||||
auto done_value = done.release_value();
|
||||
|
||||
// 7. If done is true, then
|
||||
// 5. If done is true, then
|
||||
if (done_value) {
|
||||
// a. Set iteratorRecord.[[Done]] to true.
|
||||
iterator_record.done = true;
|
||||
|
||||
// b. Return DONE.
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// 6. Return result.
|
||||
return result;
|
||||
}
|
||||
|
||||
// 7.4.8 IteratorStepValue ( iteratorRecord ), https://tc39.es/ecma262/#sec-iteratorstepvalue
|
||||
ThrowCompletionOr<Optional<Value>> iterator_step_value(VM& vm, IteratorRecord& iterator_record)
|
||||
{
|
||||
// 1. Let result be ? IteratorStep(iteratorRecord).
|
||||
auto result = TRY(iterator_step(vm, iterator_record));
|
||||
|
||||
// 2. If result is done, then
|
||||
if (!result) {
|
||||
// a. Return DONE.
|
||||
return OptionalNone {};
|
||||
}
|
||||
|
||||
// 8. Let value be Completion(Get(result, "value")).
|
||||
auto value = result_value->get(vm.names.value);
|
||||
// 3. Let value be Completion(IteratorValue(result)).
|
||||
auto value = iterator_value(vm, *result);
|
||||
|
||||
// 9. If value is a throw completion, then
|
||||
// 4. 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.
|
||||
// 5. Return ? value.
|
||||
return TRY(value);
|
||||
}
|
||||
|
||||
|
|
|
@ -74,8 +74,8 @@ ThrowCompletionOr<NonnullGCPtr<IteratorRecord>> get_iterator_from_method(VM&, Va
|
|||
ThrowCompletionOr<NonnullGCPtr<IteratorRecord>> get_iterator(VM&, Value, IteratorHint);
|
||||
ThrowCompletionOr<NonnullGCPtr<IteratorRecord>> get_iterator_direct(VM&, Object&);
|
||||
ThrowCompletionOr<NonnullGCPtr<IteratorRecord>> get_iterator_flattenable(VM&, Value, StringHandling);
|
||||
ThrowCompletionOr<NonnullGCPtr<Object>> iterator_next(VM&, IteratorRecord const&, Optional<Value> = {});
|
||||
ThrowCompletionOr<GCPtr<Object>> iterator_step(VM&, IteratorRecord const&);
|
||||
ThrowCompletionOr<NonnullGCPtr<Object>> iterator_next(VM&, IteratorRecord&, Optional<Value> = {});
|
||||
ThrowCompletionOr<GCPtr<Object>> iterator_step(VM&, IteratorRecord&);
|
||||
ThrowCompletionOr<Optional<Value>> iterator_step_value(VM&, IteratorRecord&);
|
||||
ThrowCompletionOr<bool> iterator_complete(VM&, Object& iterator_result);
|
||||
ThrowCompletionOr<Value> iterator_value(VM&, Object& iterator_result);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue