• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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