• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1// Copyright 2018 the V8 project authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include 'src/builtins/builtins-iterator-gen.h'
6
7namespace iterator {
8// Returned from IteratorBuiltinsAssembler::GetIterator().
9@export
10struct IteratorRecord {
11  // iteratorRecord.[[Iterator]]
12  object: JSReceiver;
13
14  // iteratorRecord.[[NextMethod]]
15  next: JSAny;
16}
17
18extern macro IteratorBuiltinsAssembler::FastIterableToList(
19    implicit context: Context)(JSAny): JSArray labels Slow;
20
21extern macro IteratorBuiltinsAssembler::GetIteratorMethod(
22    implicit context: Context)(JSAny): JSAny;
23extern macro IteratorBuiltinsAssembler::GetIterator(implicit context: Context)(
24    JSAny): IteratorRecord;
25extern macro IteratorBuiltinsAssembler::GetIterator(implicit context: Context)(
26    JSAny, JSAny): IteratorRecord;
27
28extern macro IteratorBuiltinsAssembler::IteratorStep(implicit context: Context)(
29    IteratorRecord): JSReceiver
30    labels Done;
31extern macro IteratorBuiltinsAssembler::IteratorStep(implicit context: Context)(
32    IteratorRecord, Map): JSReceiver
33    labels Done;
34
35extern macro IteratorBuiltinsAssembler::IteratorValue(
36    implicit context: Context)(JSReceiver): JSAny;
37extern macro IteratorBuiltinsAssembler::IteratorValue(
38    implicit context: Context)(JSReceiver, Map): JSAny;
39
40extern macro IteratorBuiltinsAssembler::IterableToList(
41    implicit context: Context)(JSAny, JSAny): JSArray;
42
43extern macro IteratorBuiltinsAssembler::StringListFromIterable(
44    implicit context: Context)(JSAny): JSArray;
45
46extern builtin IterableToListWithSymbolLookup(implicit context: Context)(JSAny):
47    JSArray;
48extern builtin IterableToFixedArrayWithSymbolLookupSlow(
49    implicit context: Context)(JSAny): FixedArray;
50
51transitioning builtin GetIteratorWithFeedback(
52    context: Context, receiver: JSAny, loadSlot: TaggedIndex,
53    callSlot: TaggedIndex,
54    maybeFeedbackVector: Undefined|FeedbackVector): JSAny {
55  // TODO(v8:9891): Remove this dcheck once all callers are ported to Torque.
56  // This dcheck ensures correctness of maybeFeedbackVector's type which can
57  // be easily broken for calls from CSA.
58  dcheck(
59      IsUndefined(maybeFeedbackVector) ||
60      Is<FeedbackVector>(maybeFeedbackVector));
61  let iteratorMethod: JSAny;
62  typeswitch (maybeFeedbackVector) {
63    case (Undefined): {
64      iteratorMethod = GetProperty(receiver, IteratorSymbolConstant());
65    }
66    case (feedback: FeedbackVector): {
67      iteratorMethod = LoadIC(
68          context, receiver, IteratorSymbolConstant(), loadSlot, feedback);
69    }
70  }
71  // TODO(v8:10047): Use TaggedIndex here once TurboFan supports it.
72  const callSlotSmi: Smi = TaggedIndexToSmi(callSlot);
73  return CallIteratorWithFeedback(
74      context, receiver, iteratorMethod, callSlotSmi, maybeFeedbackVector);
75}
76
77extern macro LoadContextFromBaseline(): Context;
78extern macro LoadFeedbackVectorFromBaseline(): FeedbackVector;
79
80transitioning builtin GetIteratorBaseline(
81    receiver: JSAny, loadSlot: TaggedIndex, callSlot: TaggedIndex): JSAny {
82  const context: Context = LoadContextFromBaseline();
83  const feedback: FeedbackVector = LoadFeedbackVectorFromBaseline();
84  const iteratorMethod: JSAny =
85      LoadIC(context, receiver, IteratorSymbolConstant(), loadSlot, feedback);
86  // TODO(v8:10047): Use TaggedIndex here once TurboFan supports it.
87  const callSlotSmi: Smi = TaggedIndexToSmi(callSlot);
88  return CallIteratorWithFeedback(
89      context, receiver, iteratorMethod, callSlotSmi, feedback);
90}
91
92extern macro CreateAsyncFromSyncIterator(Context, JSAny): JSAny;
93
94transitioning builtin CreateAsyncFromSyncIteratorBaseline(syncIterator: JSAny):
95    JSAny {
96  const context: Context = LoadContextFromBaseline();
97  return CreateAsyncFromSyncIterator(context, syncIterator);
98}
99
100macro GetLazyReceiver(receiver: JSAny): JSAny {
101  return receiver;
102}
103
104transitioning builtin CallIteratorWithFeedback(
105    context: Context, receiver: JSAny, iteratorMethod: JSAny, callSlot: Smi,
106    feedback: Undefined|FeedbackVector): JSAny {
107  // TODO(v8:10047): Use TaggedIndex here once TurboFan supports it.
108  const callSlotUnTagged: uintptr = Unsigned(SmiUntag(callSlot));
109  ic::CollectCallFeedback(
110      iteratorMethod, %MakeLazy<JSAny, JSAny>('GetLazyReceiver', receiver),
111      context, feedback, callSlotUnTagged);
112  const iteratorCallable: Callable = Cast<Callable>(iteratorMethod)
113      otherwise ThrowIteratorError(receiver);
114  return Call(context, iteratorCallable, receiver);
115}
116
117// https://tc39.es/ecma262/#sec-iteratorclose
118@export
119transitioning macro IteratorCloseOnException(implicit context: Context)(
120    iterator: IteratorRecord): void {
121  try {
122    // 4. Let innerResult be GetMethod(iterator, "return").
123    const method = GetProperty(iterator.object, kReturnString);
124
125    // 5. If innerResult.[[Type]] is normal, then
126    //   a. Let return be innerResult.[[Value]].
127    //   b. If return is undefined, return Completion(completion).
128    if (method == Undefined || method == Null) return;
129
130    //   c. Set innerResult to Call(return, iterator).
131    // If an exception occurs, the original exception remains bound
132    Call(context, method, iterator.object);
133  } catch (_e, _message) {
134    // Swallow the exception.
135  }
136
137  // (If completion.[[Type]] is throw) return Completion(completion).
138}
139}
140