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
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.
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.
30 // This file relies on the fact that the following declaration has been made
32 // var $Array = global.Array;
34 var $Set = global.Set;
35 var $Map = global.Map;
36 var $WeakMap = global.WeakMap;
37 var $WeakSet = global.WeakSet;
39 // Global sentinel to be used instead of undefined keys, which are not
40 // supported internally but required for Harmony sets and maps.
41 var undefined_sentinel = {};
44 // Map and Set uses SameValueZero which means that +0 and -0 should be treated
46 function NormalizeKey(key) {
47 if (IS_UNDEFINED(key)) {
48 return undefined_sentinel;
59 // -------------------------------------------------------------------
62 function SetConstructor() {
63 if (%_IsConstructCall()) {
66 throw MakeTypeError('constructor_not_function', ['Set']);
71 function SetAdd(key) {
73 throw MakeTypeError('incompatible_method_receiver',
74 ['Set.prototype.add', this]);
76 return %SetAdd(this, NormalizeKey(key));
80 function SetHas(key) {
82 throw MakeTypeError('incompatible_method_receiver',
83 ['Set.prototype.has', this]);
85 return %SetHas(this, NormalizeKey(key));
89 function SetDelete(key) {
91 throw MakeTypeError('incompatible_method_receiver',
92 ['Set.prototype.delete', this]);
94 key = NormalizeKey(key);
95 if (%SetHas(this, key)) {
96 %SetDelete(this, key);
104 function SetGetSize() {
106 throw MakeTypeError('incompatible_method_receiver',
107 ['Set.prototype.size', this]);
109 return %SetGetSize(this);
113 function SetClear() {
115 throw MakeTypeError('incompatible_method_receiver',
116 ['Set.prototype.clear', this]);
118 // Replace the internal table with a new empty table.
119 %SetInitialize(this);
123 // -------------------------------------------------------------------
125 function SetUpSet() {
126 %CheckIsBootstrapping();
128 %SetCode($Set, SetConstructor);
129 %FunctionSetPrototype($Set, new $Object());
130 %SetProperty($Set.prototype, "constructor", $Set, DONT_ENUM);
132 // Set up the non-enumerable functions on the Set prototype object.
133 InstallGetter($Set.prototype, "size", SetGetSize);
134 InstallFunctions($Set.prototype, DONT_ENUM, $Array(
145 // -------------------------------------------------------------------
148 function MapConstructor() {
149 if (%_IsConstructCall()) {
150 %MapInitialize(this);
152 throw MakeTypeError('constructor_not_function', ['Map']);
157 function MapGet(key) {
159 throw MakeTypeError('incompatible_method_receiver',
160 ['Map.prototype.get', this]);
162 return %MapGet(this, NormalizeKey(key));
166 function MapSet(key, value) {
168 throw MakeTypeError('incompatible_method_receiver',
169 ['Map.prototype.set', this]);
171 return %MapSet(this, NormalizeKey(key), value);
175 function MapHas(key) {
177 throw MakeTypeError('incompatible_method_receiver',
178 ['Map.prototype.has', this]);
180 return %MapHas(this, NormalizeKey(key));
184 function MapDelete(key) {
186 throw MakeTypeError('incompatible_method_receiver',
187 ['Map.prototype.delete', this]);
189 return %MapDelete(this, NormalizeKey(key));
193 function MapGetSize() {
195 throw MakeTypeError('incompatible_method_receiver',
196 ['Map.prototype.size', this]);
198 return %MapGetSize(this);
202 function MapClear() {
204 throw MakeTypeError('incompatible_method_receiver',
205 ['Map.prototype.clear', this]);
207 // Replace the internal table with a new empty table.
208 %MapInitialize(this);
212 // -------------------------------------------------------------------
214 function SetUpMap() {
215 %CheckIsBootstrapping();
217 %SetCode($Map, MapConstructor);
218 %FunctionSetPrototype($Map, new $Object());
219 %SetProperty($Map.prototype, "constructor", $Map, DONT_ENUM);
221 // Set up the non-enumerable functions on the Map prototype object.
222 InstallGetter($Map.prototype, "size", MapGetSize);
223 InstallFunctions($Map.prototype, DONT_ENUM, $Array(
235 // -------------------------------------------------------------------
238 function WeakMapConstructor() {
239 if (%_IsConstructCall()) {
240 %WeakCollectionInitialize(this);
242 throw MakeTypeError('constructor_not_function', ['WeakMap']);
247 function WeakMapGet(key) {
248 if (!IS_WEAKMAP(this)) {
249 throw MakeTypeError('incompatible_method_receiver',
250 ['WeakMap.prototype.get', this]);
252 if (!(IS_SPEC_OBJECT(key) || IS_SYMBOL(key))) {
253 throw %MakeTypeError('invalid_weakmap_key', [this, key]);
255 return %WeakCollectionGet(this, key);
259 function WeakMapSet(key, value) {
260 if (!IS_WEAKMAP(this)) {
261 throw MakeTypeError('incompatible_method_receiver',
262 ['WeakMap.prototype.set', this]);
264 if (!(IS_SPEC_OBJECT(key) || IS_SYMBOL(key))) {
265 throw %MakeTypeError('invalid_weakmap_key', [this, key]);
267 return %WeakCollectionSet(this, key, value);
271 function WeakMapHas(key) {
272 if (!IS_WEAKMAP(this)) {
273 throw MakeTypeError('incompatible_method_receiver',
274 ['WeakMap.prototype.has', this]);
276 if (!(IS_SPEC_OBJECT(key) || IS_SYMBOL(key))) {
277 throw %MakeTypeError('invalid_weakmap_key', [this, key]);
279 return %WeakCollectionHas(this, key);
283 function WeakMapDelete(key) {
284 if (!IS_WEAKMAP(this)) {
285 throw MakeTypeError('incompatible_method_receiver',
286 ['WeakMap.prototype.delete', this]);
288 if (!(IS_SPEC_OBJECT(key) || IS_SYMBOL(key))) {
289 throw %MakeTypeError('invalid_weakmap_key', [this, key]);
291 return %WeakCollectionDelete(this, key);
295 function WeakMapClear() {
296 if (!IS_WEAKMAP(this)) {
297 throw MakeTypeError('incompatible_method_receiver',
298 ['WeakMap.prototype.clear', this]);
300 // Replace the internal table with a new empty table.
301 %WeakCollectionInitialize(this);
305 // -------------------------------------------------------------------
307 function SetUpWeakMap() {
308 %CheckIsBootstrapping();
310 %SetCode($WeakMap, WeakMapConstructor);
311 %FunctionSetPrototype($WeakMap, new $Object());
312 %SetProperty($WeakMap.prototype, "constructor", $WeakMap, DONT_ENUM);
314 // Set up the non-enumerable functions on the WeakMap prototype object.
315 InstallFunctions($WeakMap.prototype, DONT_ENUM, $Array(
319 "delete", WeakMapDelete,
320 "clear", WeakMapClear
327 // -------------------------------------------------------------------
330 function WeakSetConstructor() {
331 if (%_IsConstructCall()) {
332 %WeakCollectionInitialize(this);
334 throw MakeTypeError('constructor_not_function', ['WeakSet']);
339 function WeakSetAdd(value) {
340 if (!IS_WEAKSET(this)) {
341 throw MakeTypeError('incompatible_method_receiver',
342 ['WeakSet.prototype.add', this]);
344 if (!(IS_SPEC_OBJECT(value) || IS_SYMBOL(value))) {
345 throw %MakeTypeError('invalid_weakset_value', [this, value]);
347 return %WeakCollectionSet(this, value, true);
351 function WeakSetHas(value) {
352 if (!IS_WEAKSET(this)) {
353 throw MakeTypeError('incompatible_method_receiver',
354 ['WeakSet.prototype.has', this]);
356 if (!(IS_SPEC_OBJECT(value) || IS_SYMBOL(value))) {
357 throw %MakeTypeError('invalid_weakset_value', [this, value]);
359 return %WeakCollectionHas(this, value);
363 function WeakSetDelete(value) {
364 if (!IS_WEAKSET(this)) {
365 throw MakeTypeError('incompatible_method_receiver',
366 ['WeakSet.prototype.delete', this]);
368 if (!(IS_SPEC_OBJECT(value) || IS_SYMBOL(value))) {
369 throw %MakeTypeError('invalid_weakset_value', [this, value]);
371 return %WeakCollectionDelete(this, value);
375 function WeakSetClear() {
376 if (!IS_WEAKSET(this)) {
377 throw MakeTypeError('incompatible_method_receiver',
378 ['WeakSet.prototype.clear', this]);
380 // Replace the internal table with a new empty table.
381 %WeakCollectionInitialize(this);
385 // -------------------------------------------------------------------
387 function SetUpWeakSet() {
388 %CheckIsBootstrapping();
390 %SetCode($WeakSet, WeakSetConstructor);
391 %FunctionSetPrototype($WeakSet, new $Object());
392 %SetProperty($WeakSet.prototype, "constructor", $WeakSet, DONT_ENUM);
394 // Set up the non-enumerable functions on the WeakSet prototype object.
395 InstallFunctions($WeakSet.prototype, DONT_ENUM, $Array(
398 "delete", WeakSetDelete,
399 "clear", WeakSetClear