1// Copyright 2014 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 $Set = global.Set;
11// var $Map = global.Map;
12
13
14function SetIteratorConstructor(set, kind) {
15  %SetIteratorInitialize(this, set, kind);
16}
17
18
19function SetIteratorNextJS() {
20  if (!IS_SET_ITERATOR(this)) {
21    throw MakeTypeError('incompatible_method_receiver',
22                        ['Set Iterator.prototype.next', this]);
23  }
24
25  var value_array = [UNDEFINED, UNDEFINED];
26  var entry = {value: value_array, done: false};
27  switch (%SetIteratorNext(this, value_array)) {
28    case 0:
29      entry.value = UNDEFINED;
30      entry.done = true;
31      break;
32    case ITERATOR_KIND_VALUES:
33      entry.value = value_array[0];
34      break;
35    case ITERATOR_KIND_ENTRIES:
36      value_array[1] = value_array[0];
37      break;
38  }
39
40  return entry;
41}
42
43
44function SetIteratorSymbolIterator() {
45  return this;
46}
47
48
49function SetEntries() {
50  if (!IS_SET(this)) {
51    throw MakeTypeError('incompatible_method_receiver',
52                        ['Set.prototype.entries', this]);
53  }
54  return new SetIterator(this, ITERATOR_KIND_ENTRIES);
55}
56
57
58function SetValues() {
59  if (!IS_SET(this)) {
60    throw MakeTypeError('incompatible_method_receiver',
61                        ['Set.prototype.values', this]);
62  }
63  return new SetIterator(this, ITERATOR_KIND_VALUES);
64}
65
66
67function SetUpSetIterator() {
68  %CheckIsBootstrapping();
69
70  %SetCode(SetIterator, SetIteratorConstructor);
71  %FunctionSetPrototype(SetIterator, new $Object());
72  %FunctionSetInstanceClassName(SetIterator, 'Set Iterator');
73  InstallFunctions(SetIterator.prototype, DONT_ENUM, $Array(
74    'next', SetIteratorNextJS
75  ));
76
77  %FunctionSetName(SetIteratorSymbolIterator, '[Symbol.iterator]');
78  %AddNamedProperty(SetIterator.prototype, symbolIterator,
79      SetIteratorSymbolIterator, DONT_ENUM);
80}
81
82SetUpSetIterator();
83
84
85function ExtendSetPrototype() {
86  %CheckIsBootstrapping();
87
88  InstallFunctions($Set.prototype, DONT_ENUM, $Array(
89    'entries', SetEntries,
90    'keys', SetValues,
91    'values', SetValues
92  ));
93
94  %AddNamedProperty($Set.prototype, symbolIterator, SetValues, DONT_ENUM);
95}
96
97ExtendSetPrototype();
98
99
100
101function MapIteratorConstructor(map, kind) {
102  %MapIteratorInitialize(this, map, kind);
103}
104
105
106function MapIteratorSymbolIterator() {
107  return this;
108}
109
110
111function MapIteratorNextJS() {
112  if (!IS_MAP_ITERATOR(this)) {
113    throw MakeTypeError('incompatible_method_receiver',
114                        ['Map Iterator.prototype.next', this]);
115  }
116
117  var value_array = [UNDEFINED, UNDEFINED];
118  var entry = {value: value_array, done: false};
119  switch (%MapIteratorNext(this, value_array)) {
120    case 0:
121      entry.value = UNDEFINED;
122      entry.done = true;
123      break;
124    case ITERATOR_KIND_KEYS:
125      entry.value = value_array[0];
126      break;
127    case ITERATOR_KIND_VALUES:
128      entry.value = value_array[1];
129      break;
130    // ITERATOR_KIND_ENTRIES does not need any processing.
131  }
132
133  return entry;
134}
135
136
137function MapEntries() {
138  if (!IS_MAP(this)) {
139    throw MakeTypeError('incompatible_method_receiver',
140                        ['Map.prototype.entries', this]);
141  }
142  return new MapIterator(this, ITERATOR_KIND_ENTRIES);
143}
144
145
146function MapKeys() {
147  if (!IS_MAP(this)) {
148    throw MakeTypeError('incompatible_method_receiver',
149                        ['Map.prototype.keys', this]);
150  }
151  return new MapIterator(this, ITERATOR_KIND_KEYS);
152}
153
154
155function MapValues() {
156  if (!IS_MAP(this)) {
157    throw MakeTypeError('incompatible_method_receiver',
158                        ['Map.prototype.values', this]);
159  }
160  return new MapIterator(this, ITERATOR_KIND_VALUES);
161}
162
163
164function SetUpMapIterator() {
165  %CheckIsBootstrapping();
166
167  %SetCode(MapIterator, MapIteratorConstructor);
168  %FunctionSetPrototype(MapIterator, new $Object());
169  %FunctionSetInstanceClassName(MapIterator, 'Map Iterator');
170  InstallFunctions(MapIterator.prototype, DONT_ENUM, $Array(
171    'next', MapIteratorNextJS
172  ));
173
174  %FunctionSetName(MapIteratorSymbolIterator, '[Symbol.iterator]');
175  %AddNamedProperty(MapIterator.prototype, symbolIterator,
176      MapIteratorSymbolIterator, DONT_ENUM);
177}
178
179SetUpMapIterator();
180
181
182function ExtendMapPrototype() {
183  %CheckIsBootstrapping();
184
185  InstallFunctions($Map.prototype, DONT_ENUM, $Array(
186    'entries', MapEntries,
187    'keys', MapKeys,
188    'values', MapValues
189  ));
190
191  %AddNamedProperty($Map.prototype, symbolIterator, MapEntries, DONT_ENUM);
192}
193
194ExtendMapPrototype();
195