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

LibJS: Implement proper Iterator records

Instead of using plain objects as Iterator records, causes confusion
about the object itself actually being its [[Iterator]] slot, and
requires non-standard type conversion shenanigans fpr the [[NextValue]]
and [[Done]] internal slots,  implement a proper Iterator record struct
and use it throughout.

Also annotate the remaining Iterator AOs with spec comments while we're
here.
This commit is contained in:
Linus Groh 2022-01-09 19:12:24 +01:00
parent e141f1e976
commit 09a11fa6ea
17 changed files with 337 additions and 209 deletions

View file

@ -1,6 +1,6 @@
/*
* Copyright (c) 2021, Idan Horowitz <idan.horowitz@serenityos.org>
* Copyright (c) 2021, Linus Groh <linusg@serenityos.org>
* Copyright (c) 2021-2022, Linus Groh <linusg@serenityos.org>
* Copyright (c) 2021, Luke Wilde <lukew@serenityos.org>
*
* SPDX-License-Identifier: BSD-2-Clause
@ -54,7 +54,7 @@ ThrowCompletionOr<MarkedValueList> iterable_to_list_of_type(GlobalObject& global
// 4. Repeat, while next is not false,
while (next) {
// a. Set next to ? IteratorStep(iteratorRecord).
auto* iterator_result = TRY(iterator_step(global_object, *iterator_record));
auto* iterator_result = TRY(iterator_step(global_object, iterator_record));
next = iterator_result;
// b. If next is not false, then
@ -66,7 +66,7 @@ ThrowCompletionOr<MarkedValueList> iterable_to_list_of_type(GlobalObject& global
// 1. Let completion be ThrowCompletion(a newly created TypeError object).
auto completion = vm.throw_completion<TypeError>(global_object, ErrorType::IterableToListOfTypeInvalidValue, next_value.to_string_without_side_effects());
// 2. Return ? IteratorClose(iteratorRecord, completion).
return iterator_close(*iterator_record, move(completion));
return iterator_close(global_object, iterator_record, move(completion));
}
// iii. Append nextValue to the end of the List values.
values.append(next_value);

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2021, Linus Groh <linusg@serenityos.org>
* Copyright (c) 2021-2022, Linus Groh <linusg@serenityos.org>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
@ -486,7 +486,7 @@ JS_DEFINE_NATIVE_FUNCTION(CalendarPrototype::fields)
VERIFY(calendar->identifier() == "iso8601"sv);
// 4. Let iteratorRecord be ? Getiterator(fields, sync).
auto* iterator_record = TRY(get_iterator(global_object, fields, IteratorHint::Sync));
auto iterator_record = TRY(get_iterator(global_object, fields, IteratorHint::Sync));
// 5. Let fieldNames be a new empty List.
auto field_names = MarkedValueList { vm.heap() };
@ -495,7 +495,7 @@ JS_DEFINE_NATIVE_FUNCTION(CalendarPrototype::fields)
// 7. Repeat, while next is not false,
while (true) {
// a. Set next to ? IteratorStep(iteratorRecord).
auto* next = TRY(iterator_step(global_object, *iterator_record));
auto* next = TRY(iterator_step(global_object, iterator_record));
// b. If next is not false, then
if (!next)
@ -510,7 +510,7 @@ JS_DEFINE_NATIVE_FUNCTION(CalendarPrototype::fields)
auto completion = vm.throw_completion<TypeError>(global_object, ErrorType::TemporalInvalidCalendarFieldValue, next_value.to_string_without_side_effects());
// 2. Return ? IteratorClose(iteratorRecord, completion).
return TRY(iterator_close(*iterator_record, move(completion)));
return TRY(iterator_close(global_object, iterator_record, move(completion)));
}
// iii. If fieldNames contains nextValue, then
@ -519,7 +519,7 @@ JS_DEFINE_NATIVE_FUNCTION(CalendarPrototype::fields)
auto completion = vm.throw_completion<RangeError>(global_object, ErrorType::TemporalDuplicateCalendarField, next_value.as_string().string());
// 2. Return ? IteratorClose(iteratorRecord, completion).
return TRY(iterator_close(*iterator_record, move(completion)));
return TRY(iterator_close(global_object, iterator_record, move(completion)));
}
// iv. If nextValue is not one of "year", "month", "monthCode", "day", "hour", "minute", "second", "millisecond", "microsecond", "nanosecond", then
@ -528,7 +528,7 @@ JS_DEFINE_NATIVE_FUNCTION(CalendarPrototype::fields)
auto completion = vm.throw_completion<RangeError>(global_object, ErrorType::TemporalInvalidCalendarFieldName, next_value.as_string().string());
// 2. Return ? IteratorClose(iteratorRecord, completion).
return TRY(iterator_close(*iterator_record, move(completion)));
return TRY(iterator_close(global_object, iterator_record, move(completion)));
}
// v. Append nextValue to the end of the List fieldNames.

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2021, Linus Groh <linusg@serenityos.org>
* Copyright (c) 2021-2022, Linus Groh <linusg@serenityos.org>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
@ -612,7 +612,7 @@ ThrowCompletionOr<MarkedValueList> get_possible_instants_for(GlobalObject& globa
auto possible_instants = TRY(time_zone.invoke(global_object, vm.names.getPossibleInstantsFor, &date_time));
// 3. Let iteratorRecord be ? GetIterator(possibleInstants, sync).
auto* iterator = TRY(get_iterator(global_object, possible_instants, IteratorHint::Sync));
auto iterator = TRY(get_iterator(global_object, possible_instants, IteratorHint::Sync));
// 4. Let list be a new empty List.
auto list = MarkedValueList { vm.heap() };
@ -623,7 +623,7 @@ ThrowCompletionOr<MarkedValueList> get_possible_instants_for(GlobalObject& globa
// 6. Repeat, while next is not false,
do {
// a. Set next to ? IteratorStep(iteratorRecord).
next = TRY(iterator_step(global_object, *iterator));
next = TRY(iterator_step(global_object, iterator));
// b. If next is not false, then
if (next) {
@ -636,7 +636,7 @@ ThrowCompletionOr<MarkedValueList> get_possible_instants_for(GlobalObject& globa
auto completion = vm.throw_completion<TypeError>(global_object, ErrorType::NotAnObjectOfType, "Temporal.Instant");
// 2. Return ? IteratorClose(iteratorRecord, completion).
return iterator_close(*iterator, move(completion));
return iterator_close(global_object, iterator, move(completion));
}
// iii. Append nextValue to the end of the List list.