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