blob: 8203f1f9f5933e46727f4fab187c5e24665f2af2 [file] [log] [blame]
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001// 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
14var arrayIterationKindSymbol =
15 utils.ImportNow("array_iteration_kind_symbol");
16var arrayIteratorNextIndexSymbol =
17 utils.ImportNow("array_iterator_next_symbol");
18var arrayIteratorObjectSymbol =
19 utils.ImportNow("array_iterator_object_symbol");
20var GlobalArray = global.Array;
21var IteratorPrototype = utils.ImportNow("IteratorPrototype");
22var iteratorSymbol = utils.ImportNow("iterator_symbol");
23var MakeTypeError;
24var toStringTagSymbol = utils.ImportNow("to_string_tag_symbol");
Ben Murdoch61f157c2016-09-16 13:49:30 +010025var GlobalTypedArray = %object_get_prototype_of(global.Uint8Array);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000026
27utils.Import(function(from) {
28 MakeTypeError = from.MakeTypeError;
29})
30
31// -----------------------------------------------------------------------
32
33function 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
42function 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]
53function ArrayIteratorIterator() {
54 return this;
55}
56
57
58// ES6 section 22.1.5.2.1 %ArrayIteratorPrototype%.next( )
59function 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
98function ArrayEntries() {
99 return CreateArrayIterator(this, ITERATOR_KIND_ENTRIES);
100}
101
102
103function ArrayValues() {
104 return CreateArrayIterator(this, ITERATOR_KIND_VALUES);
105}
106
107
108function ArrayKeys() {
109 return CreateArrayIterator(this, ITERATOR_KIND_KEYS);
110}
111
Ben Murdochda12d292016-06-02 14:46:10 +0100112// TODO(littledan): Check for detached TypedArray in these three methods
113function TypedArrayEntries() {
114 if (!IS_TYPEDARRAY(this)) throw MakeTypeError(kNotTypedArray);
115 return %_Call(ArrayEntries, this);
116}
117
118
119function TypedArrayValues() {
120 if (!IS_TYPEDARRAY(this)) throw MakeTypeError(kNotTypedArray);
121 return %_Call(ArrayValues, this);
122}
123
124
125function TypedArrayKeys() {
126 if (!IS_TYPEDARRAY(this)) throw MakeTypeError(kNotTypedArray);
127 return %_Call(ArrayKeys, this);
128}
129
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000130
131%FunctionSetPrototype(ArrayIterator, {__proto__: IteratorPrototype});
132%FunctionSetInstanceClassName(ArrayIterator, 'Array Iterator');
133
134utils.InstallFunctions(ArrayIterator.prototype, DONT_ENUM, [
135 'next', ArrayIteratorNext
136]);
137utils.SetFunctionName(ArrayIteratorIterator, iteratorSymbol);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000138%AddNamedProperty(ArrayIterator.prototype, toStringTagSymbol,
139 "Array Iterator", READ_ONLY | DONT_ENUM);
140
141utils.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.
149utils.SetFunctionName(ArrayValues, 'values');
150
151%AddNamedProperty(GlobalArray.prototype, iteratorSymbol, ArrayValues,
152 DONT_ENUM);
153
Ben Murdochda12d292016-06-02 14:46:10 +0100154utils.InstallFunctions(GlobalTypedArray.prototype, DONT_ENUM, [
155 'entries', TypedArrayEntries,
156 'keys', TypedArrayKeys,
157 'values', TypedArrayValues
158]);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000159%AddNamedProperty(GlobalTypedArray.prototype,
Ben Murdochda12d292016-06-02 14:46:10 +0100160 iteratorSymbol, TypedArrayValues, DONT_ENUM);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000161
162// -------------------------------------------------------------------
163// Exports
164
165utils.Export(function(to) {
166 to.ArrayValues = ArrayValues;
167});
168
169%InstallToContext(["array_values_iterator", ArrayValues]);
170
171})