Home | History | Annotate | Download | only in src
      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 
     13 var arrayIteratorObjectSymbol = GLOBAL_PRIVATE("ArrayIterator#object");
     14 var arrayIteratorNextIndexSymbol = GLOBAL_PRIVATE("ArrayIterator#next");
     15 var arrayIterationKindSymbol = GLOBAL_PRIVATE("ArrayIterator#kind");
     16 
     17 
     18 function 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
     27 function 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
     38 function CreateIteratorResultObject(value, done) {
     39   return {value: value, done: done};
     40 }
     41 
     42 
     43 // 22.1.5.2.2 %ArrayIteratorPrototype%[@@iterator]
     44 function ArrayIteratorIterator() {
     45     return this;
     46 }
     47 
     48 
     49 // 15.4.5.2.2 ArrayIterator.prototype.next( )
     50 function ArrayIteratorNext() {
     51   var iterator = ToObject(this);
     52 
     53   if (!HAS_DEFINED_PRIVATE(iterator, arrayIteratorNextIndexSymbol)) {
     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 
     88 function ArrayEntries() {
     89   return CreateArrayIterator(this, ITERATOR_KIND_ENTRIES);
     90 }
     91 
     92 
     93 function ArrayValues() {
     94   return CreateArrayIterator(this, ITERATOR_KIND_VALUES);
     95 }
     96 
     97 
     98 function ArrayKeys() {
     99   return CreateArrayIterator(this, ITERATOR_KIND_KEYS);
    100 }
    101 
    102 
    103 function 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   %AddNamedProperty(ArrayIterator.prototype, symbolIterator,
    114                     ArrayIteratorIterator, DONT_ENUM);
    115 }
    116 SetUpArrayIterator();
    117 
    118 
    119 function ExtendArrayPrototype() {
    120   %CheckIsBootstrapping();
    121 
    122   InstallFunctions($Array.prototype, DONT_ENUM, $Array(
    123     // No 'values' since it breaks webcompat: http://crbug.com/409858
    124     'entries', ArrayEntries,
    125     'keys', ArrayKeys
    126   ));
    127 
    128   %AddNamedProperty($Array.prototype, symbolIterator, ArrayValues, DONT_ENUM);
    129 }
    130 ExtendArrayPrototype();
    131 
    132 
    133 function ExtendTypedArrayPrototypes() {
    134   %CheckIsBootstrapping();
    135 
    136 macro TYPED_ARRAYS(FUNCTION)
    137   FUNCTION(Uint8Array)
    138   FUNCTION(Int8Array)
    139   FUNCTION(Uint16Array)
    140   FUNCTION(Int16Array)
    141   FUNCTION(Uint32Array)
    142   FUNCTION(Int32Array)
    143   FUNCTION(Float32Array)
    144   FUNCTION(Float64Array)
    145   FUNCTION(Uint8ClampedArray)
    146 endmacro
    147 
    148 macro EXTEND_TYPED_ARRAY(NAME)
    149   %AddNamedProperty($NAME.prototype, 'entries', ArrayEntries, DONT_ENUM);
    150   %AddNamedProperty($NAME.prototype, 'values', ArrayValues, DONT_ENUM);
    151   %AddNamedProperty($NAME.prototype, 'keys', ArrayKeys, DONT_ENUM);
    152   %AddNamedProperty($NAME.prototype, symbolIterator, ArrayValues, DONT_ENUM);
    153 endmacro
    154 
    155   TYPED_ARRAYS(EXTEND_TYPED_ARRAY)
    156 }
    157 ExtendTypedArrayPrototypes();
    158