9054187a12d0372ef1e028569a197059579f26ba
[platform/framework/web/crosswalk.git] / src / v8 / src / collection.js
1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are
4 // met:
5 //
6 //     * Redistributions of source code must retain the above copyright
7 //       notice, this list of conditions and the following disclaimer.
8 //     * Redistributions in binary form must reproduce the above
9 //       copyright notice, this list of conditions and the following
10 //       disclaimer in the documentation and/or other materials provided
11 //       with the distribution.
12 //     * Neither the name of Google Inc. nor the names of its
13 //       contributors may be used to endorse or promote products derived
14 //       from this software without specific prior written permission.
15 //
16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
28 "use strict";
29
30 // This file relies on the fact that the following declaration has been made
31 // in runtime.js:
32 // var $Array = global.Array;
33
34 var $Set = global.Set;
35 var $Map = global.Map;
36
37 // Global sentinel to be used instead of undefined keys, which are not
38 // supported internally but required for Harmony sets and maps.
39 var undefined_sentinel = {};
40
41
42 // Map and Set uses SameValueZero which means that +0 and -0 should be treated
43 // as the same value.
44 function NormalizeKey(key) {
45   if (IS_UNDEFINED(key)) {
46     return undefined_sentinel;
47   }
48
49   if (key === 0) {
50     return 0;
51   }
52
53   return key;
54 }
55
56
57 // -------------------------------------------------------------------
58 // Harmony Set
59
60 function SetConstructor() {
61   if (%_IsConstructCall()) {
62     %SetInitialize(this);
63   } else {
64     throw MakeTypeError('constructor_not_function', ['Set']);
65   }
66 }
67
68
69 function SetAdd(key) {
70   if (!IS_SET(this)) {
71     throw MakeTypeError('incompatible_method_receiver',
72                         ['Set.prototype.add', this]);
73   }
74   return %SetAdd(this, NormalizeKey(key));
75 }
76
77
78 function SetHas(key) {
79   if (!IS_SET(this)) {
80     throw MakeTypeError('incompatible_method_receiver',
81                         ['Set.prototype.has', this]);
82   }
83   return %SetHas(this, NormalizeKey(key));
84 }
85
86
87 function SetDelete(key) {
88   if (!IS_SET(this)) {
89     throw MakeTypeError('incompatible_method_receiver',
90                         ['Set.prototype.delete', this]);
91   }
92   key = NormalizeKey(key);
93   if (%SetHas(this, key)) {
94     %SetDelete(this, key);
95     return true;
96   } else {
97     return false;
98   }
99 }
100
101
102 function SetGetSize() {
103   if (!IS_SET(this)) {
104     throw MakeTypeError('incompatible_method_receiver',
105                         ['Set.prototype.size', this]);
106   }
107   return %SetGetSize(this);
108 }
109
110
111 function SetClear() {
112   if (!IS_SET(this)) {
113     throw MakeTypeError('incompatible_method_receiver',
114                         ['Set.prototype.clear', this]);
115   }
116   // Replace the internal table with a new empty table.
117   %SetInitialize(this);
118 }
119
120
121 // -------------------------------------------------------------------
122
123 function SetUpSet() {
124   %CheckIsBootstrapping();
125
126   %SetCode($Set, SetConstructor);
127   %FunctionSetPrototype($Set, new $Object());
128   %SetProperty($Set.prototype, "constructor", $Set, DONT_ENUM);
129
130   // Set up the non-enumerable functions on the Set prototype object.
131   InstallGetter($Set.prototype, "size", SetGetSize);
132   InstallFunctions($Set.prototype, DONT_ENUM, $Array(
133     "add", SetAdd,
134     "has", SetHas,
135     "delete", SetDelete,
136     "clear", SetClear
137   ));
138 }
139
140 SetUpSet();
141
142
143 // -------------------------------------------------------------------
144 // Harmony Map
145
146 function MapConstructor() {
147   if (%_IsConstructCall()) {
148     %MapInitialize(this);
149   } else {
150     throw MakeTypeError('constructor_not_function', ['Map']);
151   }
152 }
153
154
155 function MapGet(key) {
156   if (!IS_MAP(this)) {
157     throw MakeTypeError('incompatible_method_receiver',
158                         ['Map.prototype.get', this]);
159   }
160   return %MapGet(this, NormalizeKey(key));
161 }
162
163
164 function MapSet(key, value) {
165   if (!IS_MAP(this)) {
166     throw MakeTypeError('incompatible_method_receiver',
167                         ['Map.prototype.set', this]);
168   }
169   return %MapSet(this, NormalizeKey(key), value);
170 }
171
172
173 function MapHas(key) {
174   if (!IS_MAP(this)) {
175     throw MakeTypeError('incompatible_method_receiver',
176                         ['Map.prototype.has', this]);
177   }
178   return %MapHas(this, NormalizeKey(key));
179 }
180
181
182 function MapDelete(key) {
183   if (!IS_MAP(this)) {
184     throw MakeTypeError('incompatible_method_receiver',
185                         ['Map.prototype.delete', this]);
186   }
187   return %MapDelete(this, NormalizeKey(key));
188 }
189
190
191 function MapGetSize() {
192   if (!IS_MAP(this)) {
193     throw MakeTypeError('incompatible_method_receiver',
194                         ['Map.prototype.size', this]);
195   }
196   return %MapGetSize(this);
197 }
198
199
200 function MapClear() {
201   if (!IS_MAP(this)) {
202     throw MakeTypeError('incompatible_method_receiver',
203                         ['Map.prototype.clear', this]);
204   }
205   // Replace the internal table with a new empty table.
206   %MapInitialize(this);
207 }
208
209
210 // -------------------------------------------------------------------
211
212 function SetUpMap() {
213   %CheckIsBootstrapping();
214
215   %SetCode($Map, MapConstructor);
216   %FunctionSetPrototype($Map, new $Object());
217   %SetProperty($Map.prototype, "constructor", $Map, DONT_ENUM);
218
219   // Set up the non-enumerable functions on the Map prototype object.
220   InstallGetter($Map.prototype, "size", MapGetSize);
221   InstallFunctions($Map.prototype, DONT_ENUM, $Array(
222     "get", MapGet,
223     "set", MapSet,
224     "has", MapHas,
225     "delete", MapDelete,
226     "clear", MapClear
227   ));
228 }
229
230 SetUpMap();