11cb0ef41Sopenharmony_ci// Copyright 2018 the V8 project authors. All rights reserved.
21cb0ef41Sopenharmony_ci// Use of this source code is governed by a BSD-style license that can be
31cb0ef41Sopenharmony_ci// found in the LICENSE file.
41cb0ef41Sopenharmony_ci
51cb0ef41Sopenharmony_ci#include 'src/builtins/builtins-iterator-gen.h'
61cb0ef41Sopenharmony_ci
71cb0ef41Sopenharmony_cinamespace iterator {
81cb0ef41Sopenharmony_ci// Returned from IteratorBuiltinsAssembler::GetIterator().
91cb0ef41Sopenharmony_ci@export
101cb0ef41Sopenharmony_cistruct IteratorRecord {
111cb0ef41Sopenharmony_ci  // iteratorRecord.[[Iterator]]
121cb0ef41Sopenharmony_ci  object: JSReceiver;
131cb0ef41Sopenharmony_ci
141cb0ef41Sopenharmony_ci  // iteratorRecord.[[NextMethod]]
151cb0ef41Sopenharmony_ci  next: JSAny;
161cb0ef41Sopenharmony_ci}
171cb0ef41Sopenharmony_ci
181cb0ef41Sopenharmony_ciextern macro IteratorBuiltinsAssembler::FastIterableToList(
191cb0ef41Sopenharmony_ci    implicit context: Context)(JSAny): JSArray labels Slow;
201cb0ef41Sopenharmony_ci
211cb0ef41Sopenharmony_ciextern macro IteratorBuiltinsAssembler::GetIteratorMethod(
221cb0ef41Sopenharmony_ci    implicit context: Context)(JSAny): JSAny;
231cb0ef41Sopenharmony_ciextern macro IteratorBuiltinsAssembler::GetIterator(implicit context: Context)(
241cb0ef41Sopenharmony_ci    JSAny): IteratorRecord;
251cb0ef41Sopenharmony_ciextern macro IteratorBuiltinsAssembler::GetIterator(implicit context: Context)(
261cb0ef41Sopenharmony_ci    JSAny, JSAny): IteratorRecord;
271cb0ef41Sopenharmony_ci
281cb0ef41Sopenharmony_ciextern macro IteratorBuiltinsAssembler::IteratorStep(implicit context: Context)(
291cb0ef41Sopenharmony_ci    IteratorRecord): JSReceiver
301cb0ef41Sopenharmony_ci    labels Done;
311cb0ef41Sopenharmony_ciextern macro IteratorBuiltinsAssembler::IteratorStep(implicit context: Context)(
321cb0ef41Sopenharmony_ci    IteratorRecord, Map): JSReceiver
331cb0ef41Sopenharmony_ci    labels Done;
341cb0ef41Sopenharmony_ci
351cb0ef41Sopenharmony_ciextern macro IteratorBuiltinsAssembler::IteratorValue(
361cb0ef41Sopenharmony_ci    implicit context: Context)(JSReceiver): JSAny;
371cb0ef41Sopenharmony_ciextern macro IteratorBuiltinsAssembler::IteratorValue(
381cb0ef41Sopenharmony_ci    implicit context: Context)(JSReceiver, Map): JSAny;
391cb0ef41Sopenharmony_ci
401cb0ef41Sopenharmony_ciextern macro IteratorBuiltinsAssembler::IterableToList(
411cb0ef41Sopenharmony_ci    implicit context: Context)(JSAny, JSAny): JSArray;
421cb0ef41Sopenharmony_ci
431cb0ef41Sopenharmony_ciextern macro IteratorBuiltinsAssembler::StringListFromIterable(
441cb0ef41Sopenharmony_ci    implicit context: Context)(JSAny): JSArray;
451cb0ef41Sopenharmony_ci
461cb0ef41Sopenharmony_ciextern builtin IterableToListWithSymbolLookup(implicit context: Context)(JSAny):
471cb0ef41Sopenharmony_ci    JSArray;
481cb0ef41Sopenharmony_ciextern builtin IterableToFixedArrayWithSymbolLookupSlow(
491cb0ef41Sopenharmony_ci    implicit context: Context)(JSAny): FixedArray;
501cb0ef41Sopenharmony_ci
511cb0ef41Sopenharmony_citransitioning builtin GetIteratorWithFeedback(
521cb0ef41Sopenharmony_ci    context: Context, receiver: JSAny, loadSlot: TaggedIndex,
531cb0ef41Sopenharmony_ci    callSlot: TaggedIndex,
541cb0ef41Sopenharmony_ci    maybeFeedbackVector: Undefined|FeedbackVector): JSAny {
551cb0ef41Sopenharmony_ci  // TODO(v8:9891): Remove this dcheck once all callers are ported to Torque.
561cb0ef41Sopenharmony_ci  // This dcheck ensures correctness of maybeFeedbackVector's type which can
571cb0ef41Sopenharmony_ci  // be easily broken for calls from CSA.
581cb0ef41Sopenharmony_ci  dcheck(
591cb0ef41Sopenharmony_ci      IsUndefined(maybeFeedbackVector) ||
601cb0ef41Sopenharmony_ci      Is<FeedbackVector>(maybeFeedbackVector));
611cb0ef41Sopenharmony_ci  let iteratorMethod: JSAny;
621cb0ef41Sopenharmony_ci  typeswitch (maybeFeedbackVector) {
631cb0ef41Sopenharmony_ci    case (Undefined): {
641cb0ef41Sopenharmony_ci      iteratorMethod = GetProperty(receiver, IteratorSymbolConstant());
651cb0ef41Sopenharmony_ci    }
661cb0ef41Sopenharmony_ci    case (feedback: FeedbackVector): {
671cb0ef41Sopenharmony_ci      iteratorMethod = LoadIC(
681cb0ef41Sopenharmony_ci          context, receiver, IteratorSymbolConstant(), loadSlot, feedback);
691cb0ef41Sopenharmony_ci    }
701cb0ef41Sopenharmony_ci  }
711cb0ef41Sopenharmony_ci  // TODO(v8:10047): Use TaggedIndex here once TurboFan supports it.
721cb0ef41Sopenharmony_ci  const callSlotSmi: Smi = TaggedIndexToSmi(callSlot);
731cb0ef41Sopenharmony_ci  return CallIteratorWithFeedback(
741cb0ef41Sopenharmony_ci      context, receiver, iteratorMethod, callSlotSmi, maybeFeedbackVector);
751cb0ef41Sopenharmony_ci}
761cb0ef41Sopenharmony_ci
771cb0ef41Sopenharmony_ciextern macro LoadContextFromBaseline(): Context;
781cb0ef41Sopenharmony_ciextern macro LoadFeedbackVectorFromBaseline(): FeedbackVector;
791cb0ef41Sopenharmony_ci
801cb0ef41Sopenharmony_citransitioning builtin GetIteratorBaseline(
811cb0ef41Sopenharmony_ci    receiver: JSAny, loadSlot: TaggedIndex, callSlot: TaggedIndex): JSAny {
821cb0ef41Sopenharmony_ci  const context: Context = LoadContextFromBaseline();
831cb0ef41Sopenharmony_ci  const feedback: FeedbackVector = LoadFeedbackVectorFromBaseline();
841cb0ef41Sopenharmony_ci  const iteratorMethod: JSAny =
851cb0ef41Sopenharmony_ci      LoadIC(context, receiver, IteratorSymbolConstant(), loadSlot, feedback);
861cb0ef41Sopenharmony_ci  // TODO(v8:10047): Use TaggedIndex here once TurboFan supports it.
871cb0ef41Sopenharmony_ci  const callSlotSmi: Smi = TaggedIndexToSmi(callSlot);
881cb0ef41Sopenharmony_ci  return CallIteratorWithFeedback(
891cb0ef41Sopenharmony_ci      context, receiver, iteratorMethod, callSlotSmi, feedback);
901cb0ef41Sopenharmony_ci}
911cb0ef41Sopenharmony_ci
921cb0ef41Sopenharmony_ciextern macro CreateAsyncFromSyncIterator(Context, JSAny): JSAny;
931cb0ef41Sopenharmony_ci
941cb0ef41Sopenharmony_citransitioning builtin CreateAsyncFromSyncIteratorBaseline(syncIterator: JSAny):
951cb0ef41Sopenharmony_ci    JSAny {
961cb0ef41Sopenharmony_ci  const context: Context = LoadContextFromBaseline();
971cb0ef41Sopenharmony_ci  return CreateAsyncFromSyncIterator(context, syncIterator);
981cb0ef41Sopenharmony_ci}
991cb0ef41Sopenharmony_ci
1001cb0ef41Sopenharmony_cimacro GetLazyReceiver(receiver: JSAny): JSAny {
1011cb0ef41Sopenharmony_ci  return receiver;
1021cb0ef41Sopenharmony_ci}
1031cb0ef41Sopenharmony_ci
1041cb0ef41Sopenharmony_citransitioning builtin CallIteratorWithFeedback(
1051cb0ef41Sopenharmony_ci    context: Context, receiver: JSAny, iteratorMethod: JSAny, callSlot: Smi,
1061cb0ef41Sopenharmony_ci    feedback: Undefined|FeedbackVector): JSAny {
1071cb0ef41Sopenharmony_ci  // TODO(v8:10047): Use TaggedIndex here once TurboFan supports it.
1081cb0ef41Sopenharmony_ci  const callSlotUnTagged: uintptr = Unsigned(SmiUntag(callSlot));
1091cb0ef41Sopenharmony_ci  ic::CollectCallFeedback(
1101cb0ef41Sopenharmony_ci      iteratorMethod, %MakeLazy<JSAny, JSAny>('GetLazyReceiver', receiver),
1111cb0ef41Sopenharmony_ci      context, feedback, callSlotUnTagged);
1121cb0ef41Sopenharmony_ci  const iteratorCallable: Callable = Cast<Callable>(iteratorMethod)
1131cb0ef41Sopenharmony_ci      otherwise ThrowIteratorError(receiver);
1141cb0ef41Sopenharmony_ci  return Call(context, iteratorCallable, receiver);
1151cb0ef41Sopenharmony_ci}
1161cb0ef41Sopenharmony_ci
1171cb0ef41Sopenharmony_ci// https://tc39.es/ecma262/#sec-iteratorclose
1181cb0ef41Sopenharmony_ci@export
1191cb0ef41Sopenharmony_citransitioning macro IteratorCloseOnException(implicit context: Context)(
1201cb0ef41Sopenharmony_ci    iterator: IteratorRecord): void {
1211cb0ef41Sopenharmony_ci  try {
1221cb0ef41Sopenharmony_ci    // 4. Let innerResult be GetMethod(iterator, "return").
1231cb0ef41Sopenharmony_ci    const method = GetProperty(iterator.object, kReturnString);
1241cb0ef41Sopenharmony_ci
1251cb0ef41Sopenharmony_ci    // 5. If innerResult.[[Type]] is normal, then
1261cb0ef41Sopenharmony_ci    //   a. Let return be innerResult.[[Value]].
1271cb0ef41Sopenharmony_ci    //   b. If return is undefined, return Completion(completion).
1281cb0ef41Sopenharmony_ci    if (method == Undefined || method == Null) return;
1291cb0ef41Sopenharmony_ci
1301cb0ef41Sopenharmony_ci    //   c. Set innerResult to Call(return, iterator).
1311cb0ef41Sopenharmony_ci    // If an exception occurs, the original exception remains bound
1321cb0ef41Sopenharmony_ci    Call(context, method, iterator.object);
1331cb0ef41Sopenharmony_ci  } catch (_e, _message) {
1341cb0ef41Sopenharmony_ci    // Swallow the exception.
1351cb0ef41Sopenharmony_ci  }
1361cb0ef41Sopenharmony_ci
1371cb0ef41Sopenharmony_ci  // (If completion.[[Type]] is throw) return Completion(completion).
1381cb0ef41Sopenharmony_ci}
1391cb0ef41Sopenharmony_ci}
140