Home | History | Annotate | Download | only in js
      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