summaryrefslogtreecommitdiff
path: root/deps/v8/src/builtins/iterator-from.tq
diff options
context:
space:
mode:
Diffstat (limited to 'deps/v8/src/builtins/iterator-from.tq')
-rw-r--r--deps/v8/src/builtins/iterator-from.tq182
1 files changed, 182 insertions, 0 deletions
diff --git a/deps/v8/src/builtins/iterator-from.tq b/deps/v8/src/builtins/iterator-from.tq
new file mode 100644
index 0000000000..b711c28971
--- /dev/null
+++ b/deps/v8/src/builtins/iterator-from.tq
@@ -0,0 +1,182 @@
+// Copyright 2023 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+namespace iterator {
+
+macro NewJSValidIteratorWrapper(implicit context: Context)(
+ underlying: IteratorRecord): JSValidIteratorWrapper {
+ return new JSValidIteratorWrapper{
+ map: *NativeContextSlot(ContextSlot::VALID_ITERATOR_WRAPPER_MAP_INDEX),
+ properties_or_hash: kEmptyFixedArray,
+ elements: kEmptyFixedArray,
+ underlying: underlying
+ };
+}
+
+// https://tc39.es/proposal-iterator-helpers/#sec-getiteratorflattenable
+//
+// Currently never used with the async hint, so only the sync path is
+// implemented.
+transitioning macro GetIteratorFlattenable(implicit context: Context)(
+ obj: JSReceiver): IteratorRecord {
+ try {
+ // 1. If obj is not an Object, throw a TypeError exception.
+ // (Done by caller.)
+
+ // 2. Let alreadyAsync be false.
+ //
+ // (Unimplemented because the async path is unused.)
+
+ // 3. Let method be undefined.
+ //
+ // (Done below.)
+
+ // 4. If hint is async, then
+ // a. Set method to ? Get(obj, @@asyncIterator).
+ // b. Set alreadyAsync to true.
+ //
+ // (Unimplemented because unused.)
+
+ // 5. If IsCallable(method) is false, then
+ // a. Set method to ? Get(obj, @@iterator).
+ const method = GetProperty(obj, IteratorSymbolConstant());
+
+ // b. Set alreadyAsync to false.
+ //
+ // (Unimplemented because unused.)
+
+ let iterator: JSAny;
+
+ // 6. If IsCallable(method) is false, then
+ if (!Is<Callable>(method)) {
+ // a. Let iterator be obj.
+ iterator = obj;
+
+ // b. Set alreadyAsync to true.
+ //
+ // (Unimplemented because unused.)
+ } else {
+ // 7. Else,
+ // a. Let iterator be ? Call(method, obj).
+ iterator = Call(context, UnsafeCast<Callable>(method), obj);
+ }
+
+ // 8. If iterator is not an Object, throw a TypeError exception.
+ const iteratorObj = Cast<JSReceiver>(iterator)
+ otherwise goto IteratorNotObject(obj, method);
+
+ // 9. Let nextMethod be ? Get(iterator, "next").
+ const nextMethod = GetProperty(iteratorObj, kNextString);
+
+ // 10. If IsCallable(nextMethod) is false, throw a TypeError exception.
+ if (!Is<Callable>(nextMethod)) {
+ ThrowTypeError(
+ MessageTemplate::kPropertyNotFunction, nextMethod, kNextString, obj);
+ }
+
+ // 11. Let iteratorRecord be the Iterator Record { [[Iterator]]: iterator,
+ // [[NextMethod]]: nextMethod, [[Done]]: false }.
+ const iteratorRecord =
+ IteratorRecord{object: iteratorObj, next: nextMethod};
+
+ // 12. If hint is async and alreadyAsync is false, then
+ // a. Return CreateAsyncFromSyncIterator(iteratorRecord).
+ //
+ // (Unimplemented because unused.)
+
+ // 13. Return iteratorRecord.
+ return iteratorRecord;
+ } label IteratorNotObject(obj: JSAny, method: JSAny) deferred {
+ if (Is<Callable>(method)) {
+ ThrowTypeError(MessageTemplate::kSymbolIteratorInvalid);
+ } else {
+ ThrowTypeError(MessageTemplate::kNotIterable, obj);
+ }
+ }
+}
+
+// https://tc39.es/proposal-iterator-helpers/#sec-iterator.from
+transitioning javascript builtin IteratorFrom(
+ js-implicit context: NativeContext,
+ receiver: JSAny)(objArg: JSAny): JSReceiver {
+ // 1. If O is a String, set O to ! ToObject(O).
+ let obj: JSReceiver;
+ typeswitch (objArg) {
+ case (o: String): {
+ obj = ToObject_Inline(context, o);
+ }
+ case (o: JSReceiver): {
+ obj = o;
+ }
+ case (JSAny): {
+ ThrowTypeError(MessageTemplate::kCalledOnNonObject, 'Iterator.from');
+ }
+ }
+
+ // 2. Let iteratorRecord be ? GetIteratorFlattenable(O, sync).
+ const iteratorRecord = GetIteratorFlattenable(obj);
+
+ // 3. Let hasInstance be ? OrdinaryHasInstance(%Iterator%,
+ // iteratorRecord.[[Iterator]]).
+ const hasInstance = function::OrdinaryHasInstance(
+ context, GetIteratorFunction(), iteratorRecord.object);
+
+ // 4. If hasInstance is true, then
+ if (hasInstance == True) {
+ // a. Return iteratorRecord.[[Iterator]].
+ return iteratorRecord.object;
+ }
+
+ // 5. Let wrapper be OrdinaryObjectCreate(%WrapForValidIteratorPrototype%, «
+ // [[Iterated]] »).
+ // 6. Set wrapper.[[Iterated]] to iteratorRecord.
+ // 7. Return wrapper.
+ return NewJSValidIteratorWrapper(iteratorRecord);
+}
+
+// https://tc39.es/proposal-iterator-helpers/#sec-wrapforvaliditeratorprototype.next
+transitioning javascript builtin WrapForValidIteratorPrototypeNext(
+ js-implicit context: NativeContext, receiver: JSAny)(): JSAny {
+ // 1. Let O be this value.
+ // 2. Perform ? RequireInternalSlot(O, [[Iterated]]).
+ const o = Cast<JSValidIteratorWrapper>(receiver) otherwise ThrowTypeError(
+ MessageTemplate::kIncompatibleMethodReceiver,
+ '%WrapForValidIteratorPrototype%.next', receiver);
+
+ // 3. Let iteratorRecord be O.[[Iterated]].
+ const iteratorRecord = o.underlying;
+
+ // 4. Return ? Call(iteratorRecord.[[NextMethod]],
+ // iteratorRecord.[[Iterator]]).
+ return Call(context, iteratorRecord.next, iteratorRecord.object);
+}
+
+// https://tc39.es/proposal-iterator-helpers/#sec-wrapforvaliditeratorprototype.return
+transitioning javascript builtin WrapForValidIteratorPrototypeReturn(
+ js-implicit context: NativeContext, receiver: JSAny)(): JSAny {
+ try {
+ // 1. Let O be this value.
+ // 2. Perform ? RequireInternalSlot(O, [[Iterated]]).
+ const o = Cast<JSValidIteratorWrapper>(receiver) otherwise ThrowTypeError(
+ MessageTemplate::kIncompatibleMethodReceiver,
+ '%WrapForValidIteratorPrototype%.return', receiver);
+
+ // 3. Let iterator be O.[[Iterated]].[[Iterator]].
+ const iterator = o.underlying.object;
+
+ // 4. Assert: iterator is an Object.
+ // 5. Let returnMethod be ? GetMethod(iterator, "return").
+ const returnMethod =
+ GetMethod(iterator, kReturnString) otherwise ReturnMethodUndefined;
+
+ // 7. Return ? Call(returnMethod, iterator).
+ return Call(context, returnMethod, iterator);
+ } label ReturnMethodUndefined {
+ // 6. If returnMethod is undefined, then
+ // a. Return CreateIterResultObject(undefined, true).
+ return AllocateJSIteratorResult(Undefined, True);
+ }
+}
+
+} // namespace iterator