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'use strict'; 6 7 8// This file relies on the fact that the following declaration has been made 9// in runtime.js: 10// var $Array = global.Array; 11 12 13var arrayIteratorObjectSymbol = GLOBAL_PRIVATE("ArrayIterator#object"); 14var arrayIteratorNextIndexSymbol = GLOBAL_PRIVATE("ArrayIterator#next"); 15var arrayIterationKindSymbol = GLOBAL_PRIVATE("ArrayIterator#kind"); 16 17 18function ArrayIterator() {} 19 20 21// TODO(wingo): Update section numbers when ES6 has stabilized. The 22// section numbers below are already out of date as of the May 2014 23// draft. 24 25 26// 15.4.5.1 CreateArrayIterator Abstract Operation 27function CreateArrayIterator(array, kind) { 28 var object = ToObject(array); 29 var iterator = new ArrayIterator; 30 SET_PRIVATE(iterator, arrayIteratorObjectSymbol, object); 31 SET_PRIVATE(iterator, arrayIteratorNextIndexSymbol, 0); 32 SET_PRIVATE(iterator, arrayIterationKindSymbol, kind); 33 return iterator; 34} 35 36 37// 15.19.4.3.4 CreateItrResultObject 38function CreateIteratorResultObject(value, done) { 39 return {value: value, done: done}; 40} 41 42 43// 22.1.5.2.2 %ArrayIteratorPrototype%[@@iterator] 44function ArrayIteratorIterator() { 45 return this; 46} 47 48 49// 15.4.5.2.2 ArrayIterator.prototype.next( ) 50function ArrayIteratorNext() { 51 var iterator = ToObject(this); 52 53 if (!HAS_PRIVATE(iterator, arrayIteratorObjectSymbol)) { 54 throw MakeTypeError('incompatible_method_receiver', 55 ['Array Iterator.prototype.next']); 56 } 57 58 var array = GET_PRIVATE(iterator, arrayIteratorObjectSymbol); 59 if (IS_UNDEFINED(array)) { 60 return CreateIteratorResultObject(UNDEFINED, true); 61 } 62 63 var index = GET_PRIVATE(iterator, arrayIteratorNextIndexSymbol); 64 var itemKind = GET_PRIVATE(iterator, arrayIterationKindSymbol); 65 var length = TO_UINT32(array.length); 66 67 // "sparse" is never used. 68 69 if (index >= length) { 70 SET_PRIVATE(iterator, arrayIteratorObjectSymbol, UNDEFINED); 71 return CreateIteratorResultObject(UNDEFINED, true); 72 } 73 74 SET_PRIVATE(iterator, arrayIteratorNextIndexSymbol, index + 1); 75 76 if (itemKind == ITERATOR_KIND_VALUES) { 77 return CreateIteratorResultObject(array[index], false); 78 } 79 80 if (itemKind == ITERATOR_KIND_ENTRIES) { 81 return CreateIteratorResultObject([index, array[index]], false); 82 } 83 84 return CreateIteratorResultObject(index, false); 85} 86 87 88function ArrayEntries() { 89 return CreateArrayIterator(this, ITERATOR_KIND_ENTRIES); 90} 91 92 93function ArrayValues() { 94 return CreateArrayIterator(this, ITERATOR_KIND_VALUES); 95} 96 97 98function ArrayKeys() { 99 return CreateArrayIterator(this, ITERATOR_KIND_KEYS); 100} 101 102 103function SetUpArrayIterator() { 104 %CheckIsBootstrapping(); 105 106 %FunctionSetPrototype(ArrayIterator, new $Object()); 107 %FunctionSetInstanceClassName(ArrayIterator, 'Array Iterator'); 108 109 InstallFunctions(ArrayIterator.prototype, DONT_ENUM, $Array( 110 'next', ArrayIteratorNext 111 )); 112 %FunctionSetName(ArrayIteratorIterator, '[Symbol.iterator]'); 113 %SetProperty(ArrayIterator.prototype, symbolIterator, ArrayIteratorIterator, 114 DONT_ENUM | DONT_DELETE | READ_ONLY); 115} 116SetUpArrayIterator(); 117 118 119function ExtendArrayPrototype() { 120 %CheckIsBootstrapping(); 121 122 InstallFunctions($Array.prototype, DONT_ENUM, $Array( 123 'entries', ArrayEntries, 124 'values', ArrayValues, 125 'keys', ArrayKeys 126 )); 127} 128ExtendArrayPrototype(); 129