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