1 // Copyright 2013 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 (function(global, utils) { 6 7 "use strict"; 8 9 %CheckIsBootstrapping(); 10 11 // ----------------------------------------------------------------------- 12 // Imports 13 14 var arrayIterationKindSymbol = 15 utils.ImportNow("array_iteration_kind_symbol"); 16 var arrayIteratorNextIndexSymbol = 17 utils.ImportNow("array_iterator_next_symbol"); 18 var arrayIteratorObjectSymbol = 19 utils.ImportNow("array_iterator_object_symbol"); 20 var GlobalArray = global.Array; 21 var IteratorPrototype = utils.ImportNow("IteratorPrototype"); 22 var iteratorSymbol = utils.ImportNow("iterator_symbol"); 23 var MakeTypeError; 24 var toStringTagSymbol = utils.ImportNow("to_string_tag_symbol"); 25 var GlobalTypedArray = %object_get_prototype_of(global.Uint8Array); 26 27 utils.Import(function(from) { 28 MakeTypeError = from.MakeTypeError; 29 }) 30 31 // ----------------------------------------------------------------------- 32 33 function ArrayIterator() {} 34 35 36 // TODO(wingo): Update section numbers when ES6 has stabilized. The 37 // section numbers below are already out of date as of the May 2014 38 // draft. 39 40 41 // 15.4.5.1 CreateArrayIterator Abstract Operation 42 function CreateArrayIterator(array, kind) { 43 var object = TO_OBJECT(array); 44 var iterator = new ArrayIterator; 45 SET_PRIVATE(iterator, arrayIteratorObjectSymbol, object); 46 SET_PRIVATE(iterator, arrayIteratorNextIndexSymbol, 0); 47 SET_PRIVATE(iterator, arrayIterationKindSymbol, kind); 48 return iterator; 49 } 50 51 52 // 22.1.5.2.2 %ArrayIteratorPrototype%[@@iterator] 53 function ArrayIteratorIterator() { 54 return this; 55 } 56 57 58 // ES6 section 22.1.5.2.1 %ArrayIteratorPrototype%.next( ) 59 function ArrayIteratorNext() { 60 var iterator = this; 61 var value = UNDEFINED; 62 var done = true; 63 64 if (!IS_RECEIVER(iterator) || 65 !HAS_DEFINED_PRIVATE(iterator, arrayIteratorNextIndexSymbol)) { 66 throw MakeTypeError(kIncompatibleMethodReceiver, 67 'Array Iterator.prototype.next', this); 68 } 69 70 var array = GET_PRIVATE(iterator, arrayIteratorObjectSymbol); 71 if (!IS_UNDEFINED(array)) { 72 var index = GET_PRIVATE(iterator, arrayIteratorNextIndexSymbol); 73 var itemKind = GET_PRIVATE(iterator, arrayIterationKindSymbol); 74 var length = TO_UINT32(array.length); 75 76 // "sparse" is never used. 77 78 if (index >= length) { 79 SET_PRIVATE(iterator, arrayIteratorObjectSymbol, UNDEFINED); 80 } else { 81 SET_PRIVATE(iterator, arrayIteratorNextIndexSymbol, index + 1); 82 83 if (itemKind == ITERATOR_KIND_VALUES) { 84 value = array[index]; 85 } else if (itemKind == ITERATOR_KIND_ENTRIES) { 86 value = [index, array[index]]; 87 } else { 88 value = index; 89 } 90 done = false; 91 } 92 } 93 94 return %_CreateIterResultObject(value, done); 95 } 96 97 98 function ArrayEntries() { 99 return CreateArrayIterator(this, ITERATOR_KIND_ENTRIES); 100 } 101 102 103 function ArrayValues() { 104 return CreateArrayIterator(this, ITERATOR_KIND_VALUES); 105 } 106 107 108 function ArrayKeys() { 109 return CreateArrayIterator(this, ITERATOR_KIND_KEYS); 110 } 111 112 // TODO(littledan): Check for detached TypedArray in these three methods 113 function TypedArrayEntries() { 114 if (!IS_TYPEDARRAY(this)) throw MakeTypeError(kNotTypedArray); 115 return %_Call(ArrayEntries, this); 116 } 117 118 119 function TypedArrayValues() { 120 if (!IS_TYPEDARRAY(this)) throw MakeTypeError(kNotTypedArray); 121 return %_Call(ArrayValues, this); 122 } 123 124 125 function TypedArrayKeys() { 126 if (!IS_TYPEDARRAY(this)) throw MakeTypeError(kNotTypedArray); 127 return %_Call(ArrayKeys, this); 128 } 129 130 131 %FunctionSetPrototype(ArrayIterator, {__proto__: IteratorPrototype}); 132 %FunctionSetInstanceClassName(ArrayIterator, 'Array Iterator'); 133 134 utils.InstallFunctions(ArrayIterator.prototype, DONT_ENUM, [ 135 'next', ArrayIteratorNext 136 ]); 137 utils.SetFunctionName(ArrayIteratorIterator, iteratorSymbol); 138 %AddNamedProperty(ArrayIterator.prototype, toStringTagSymbol, 139 "Array Iterator", READ_ONLY | DONT_ENUM); 140 141 utils.InstallFunctions(GlobalArray.prototype, DONT_ENUM, [ 142 // No 'values' since it breaks webcompat: http://crbug.com/409858 143 'entries', ArrayEntries, 144 'keys', ArrayKeys 145 ]); 146 147 // TODO(adam): Remove this call once 'values' is in the above 148 // InstallFunctions block, as it'll be redundant. 149 utils.SetFunctionName(ArrayValues, 'values'); 150 151 %AddNamedProperty(GlobalArray.prototype, iteratorSymbol, ArrayValues, 152 DONT_ENUM); 153 154 utils.InstallFunctions(GlobalTypedArray.prototype, DONT_ENUM, [ 155 'entries', TypedArrayEntries, 156 'keys', TypedArrayKeys, 157 'values', TypedArrayValues 158 ]); 159 %AddNamedProperty(GlobalTypedArray.prototype, 160 iteratorSymbol, TypedArrayValues, DONT_ENUM); 161 162 // ------------------------------------------------------------------- 163 // Exports 164 165 utils.Export(function(to) { 166 to.ArrayValues = ArrayValues; 167 }); 168 169 %InstallToContext(["array_values_iterator", ArrayValues]); 170 171 }) 172