deps: update v8 to 4.3.61.21
[platform/upstream/nodejs.git] / deps / v8 / src / collection.js
1 // Copyright 2012 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 // This file relies on the fact that the following declaration has been made
8 // in runtime.js:
9 // var $Array = global.Array;
10
11 var $Set = global.Set;
12 var $Map = global.Map;
13
14
15 // -------------------------------------------------------------------
16 // Harmony Set
17
18 function SetConstructor(iterable) {
19   if (!%_IsConstructCall()) {
20     throw MakeTypeError('constructor_not_function', ['Set']);
21   }
22
23   %_SetInitialize(this);
24
25   if (!IS_NULL_OR_UNDEFINED(iterable)) {
26     var adder = this.add;
27     if (!IS_SPEC_FUNCTION(adder)) {
28       throw MakeTypeError('property_not_function', ['add', this]);
29     }
30
31     for (var value of iterable) {
32       %_CallFunction(this, value, adder);
33     }
34   }
35 }
36
37
38 function SetAddJS(key) {
39   if (!IS_SET(this)) {
40     throw MakeTypeError('incompatible_method_receiver',
41                         ['Set.prototype.add', this]);
42   }
43   // Normalize -0 to +0 as required by the spec.
44   // Even though we use SameValueZero as the comparison for the keys we don't
45   // want to ever store -0 as the key since the key is directly exposed when
46   // doing iteration.
47   if (key === 0) {
48     key = 0;
49   }
50   return %_SetAdd(this, key);
51 }
52
53
54 function SetHasJS(key) {
55   if (!IS_SET(this)) {
56     throw MakeTypeError('incompatible_method_receiver',
57                         ['Set.prototype.has', this]);
58   }
59   return %_SetHas(this, key);
60 }
61
62
63 function SetDeleteJS(key) {
64   if (!IS_SET(this)) {
65     throw MakeTypeError('incompatible_method_receiver',
66                         ['Set.prototype.delete', this]);
67   }
68   return %_SetDelete(this, key);
69 }
70
71
72 function SetGetSizeJS() {
73   if (!IS_SET(this)) {
74     throw MakeTypeError('incompatible_method_receiver',
75                         ['Set.prototype.size', this]);
76   }
77   return %_SetGetSize(this);
78 }
79
80
81 function SetClearJS() {
82   if (!IS_SET(this)) {
83     throw MakeTypeError('incompatible_method_receiver',
84                         ['Set.prototype.clear', this]);
85   }
86   %_SetClear(this);
87 }
88
89
90 function SetForEach(f, receiver) {
91   if (!IS_SET(this)) {
92     throw MakeTypeError('incompatible_method_receiver',
93                         ['Set.prototype.forEach', this]);
94   }
95
96   if (!IS_SPEC_FUNCTION(f)) {
97     throw MakeTypeError('called_non_callable', [f]);
98   }
99   var needs_wrapper = false;
100   if (IS_NULL_OR_UNDEFINED(receiver)) {
101     receiver = %GetDefaultReceiver(f) || receiver;
102   } else {
103     needs_wrapper = SHOULD_CREATE_WRAPPER(f, receiver);
104   }
105
106   var iterator = new SetIterator(this, ITERATOR_KIND_VALUES);
107   var key;
108   var stepping = DEBUG_IS_ACTIVE && %DebugCallbackSupportsStepping(f);
109   var value_array = [UNDEFINED];
110   while (%SetIteratorNext(iterator, value_array)) {
111     if (stepping) %DebugPrepareStepInIfStepping(f);
112     key = value_array[0];
113     var new_receiver = needs_wrapper ? ToObject(receiver) : receiver;
114     %_CallFunction(new_receiver, key, key, this, f);
115   }
116 }
117
118
119 // -------------------------------------------------------------------
120
121 function SetUpSet() {
122   %CheckIsBootstrapping();
123
124   %SetCode($Set, SetConstructor);
125   %FunctionSetPrototype($Set, new $Object());
126   %AddNamedProperty($Set.prototype, "constructor", $Set, DONT_ENUM);
127   %AddNamedProperty(
128       $Set.prototype, symbolToStringTag, "Set", DONT_ENUM | READ_ONLY);
129
130   %FunctionSetLength(SetForEach, 1);
131
132   // Set up the non-enumerable functions on the Set prototype object.
133   InstallGetter($Set.prototype, "size", SetGetSizeJS);
134   InstallFunctions($Set.prototype, DONT_ENUM, $Array(
135     "add", SetAddJS,
136     "has", SetHasJS,
137     "delete", SetDeleteJS,
138     "clear", SetClearJS,
139     "forEach", SetForEach
140   ));
141 }
142
143 SetUpSet();
144
145
146 // -------------------------------------------------------------------
147 // Harmony Map
148
149 function MapConstructor(iterable) {
150   if (!%_IsConstructCall()) {
151     throw MakeTypeError('constructor_not_function', ['Map']);
152   }
153
154   %_MapInitialize(this);
155
156   if (!IS_NULL_OR_UNDEFINED(iterable)) {
157     var adder = this.set;
158     if (!IS_SPEC_FUNCTION(adder)) {
159       throw MakeTypeError('property_not_function', ['set', this]);
160     }
161
162     for (var nextItem of iterable) {
163       if (!IS_SPEC_OBJECT(nextItem)) {
164         throw MakeTypeError('iterator_value_not_an_object', [nextItem]);
165       }
166       %_CallFunction(this, nextItem[0], nextItem[1], adder);
167     }
168   }
169 }
170
171
172 function MapGetJS(key) {
173   if (!IS_MAP(this)) {
174     throw MakeTypeError('incompatible_method_receiver',
175                         ['Map.prototype.get', this]);
176   }
177   return %_MapGet(this, key);
178 }
179
180
181 function MapSetJS(key, value) {
182   if (!IS_MAP(this)) {
183     throw MakeTypeError('incompatible_method_receiver',
184                         ['Map.prototype.set', this]);
185   }
186   // Normalize -0 to +0 as required by the spec.
187   // Even though we use SameValueZero as the comparison for the keys we don't
188   // want to ever store -0 as the key since the key is directly exposed when
189   // doing iteration.
190   if (key === 0) {
191     key = 0;
192   }
193   return %_MapSet(this, key, value);
194 }
195
196
197 function MapHasJS(key) {
198   if (!IS_MAP(this)) {
199     throw MakeTypeError('incompatible_method_receiver',
200                         ['Map.prototype.has', this]);
201   }
202   return %_MapHas(this, key);
203 }
204
205
206 function MapDeleteJS(key) {
207   if (!IS_MAP(this)) {
208     throw MakeTypeError('incompatible_method_receiver',
209                         ['Map.prototype.delete', this]);
210   }
211   return %_MapDelete(this, key);
212 }
213
214
215 function MapGetSizeJS() {
216   if (!IS_MAP(this)) {
217     throw MakeTypeError('incompatible_method_receiver',
218                         ['Map.prototype.size', this]);
219   }
220   return %_MapGetSize(this);
221 }
222
223
224 function MapClearJS() {
225   if (!IS_MAP(this)) {
226     throw MakeTypeError('incompatible_method_receiver',
227                         ['Map.prototype.clear', this]);
228   }
229   %_MapClear(this);
230 }
231
232
233 function MapForEach(f, receiver) {
234   if (!IS_MAP(this)) {
235     throw MakeTypeError('incompatible_method_receiver',
236                         ['Map.prototype.forEach', this]);
237   }
238
239   if (!IS_SPEC_FUNCTION(f)) {
240     throw MakeTypeError('called_non_callable', [f]);
241   }
242   var needs_wrapper = false;
243   if (IS_NULL_OR_UNDEFINED(receiver)) {
244     receiver = %GetDefaultReceiver(f) || receiver;
245   } else {
246     needs_wrapper = SHOULD_CREATE_WRAPPER(f, receiver);
247   }
248
249   var iterator = new MapIterator(this, ITERATOR_KIND_ENTRIES);
250   var stepping = DEBUG_IS_ACTIVE && %DebugCallbackSupportsStepping(f);
251   var value_array = [UNDEFINED, UNDEFINED];
252   while (%MapIteratorNext(iterator, value_array)) {
253     if (stepping) %DebugPrepareStepInIfStepping(f);
254     var new_receiver = needs_wrapper ? ToObject(receiver) : receiver;
255     %_CallFunction(new_receiver, value_array[1], value_array[0], this, f);
256   }
257 }
258
259
260 // -------------------------------------------------------------------
261
262 function SetUpMap() {
263   %CheckIsBootstrapping();
264
265   %SetCode($Map, MapConstructor);
266   %FunctionSetPrototype($Map, new $Object());
267   %AddNamedProperty($Map.prototype, "constructor", $Map, DONT_ENUM);
268   %AddNamedProperty(
269       $Map.prototype, symbolToStringTag, "Map", DONT_ENUM | READ_ONLY);
270
271   %FunctionSetLength(MapForEach, 1);
272
273   // Set up the non-enumerable functions on the Map prototype object.
274   InstallGetter($Map.prototype, "size", MapGetSizeJS);
275   InstallFunctions($Map.prototype, DONT_ENUM, $Array(
276     "get", MapGetJS,
277     "set", MapSetJS,
278     "has", MapHasJS,
279     "delete", MapDeleteJS,
280     "clear", MapClearJS,
281     "forEach", MapForEach
282   ));
283 }
284
285 SetUpMap();