blob: 308b9edef7cb70b31161d187bb24f828c7778e66 [file] [log] [blame]
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001// 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(function(global, utils) {
6
7"use strict";
8
9%CheckIsBootstrapping();
10
11// -------------------------------------------------------------------
12// Imports
13
14var GetExistingHash;
15var GetHash;
16var GlobalObject = global.Object;
17var GlobalWeakMap = global.WeakMap;
18var GlobalWeakSet = global.WeakSet;
19var MakeTypeError;
20var toStringTagSymbol = utils.ImportNow("to_string_tag_symbol");
21
22utils.Import(function(from) {
23 GetExistingHash = from.GetExistingHash;
24 GetHash = from.GetHash;
25 MakeTypeError = from.MakeTypeError;
26});
27
28// -------------------------------------------------------------------
29// Harmony WeakMap
30
31function WeakMapConstructor(iterable) {
32 if (IS_UNDEFINED(new.target)) {
33 throw MakeTypeError(kConstructorNotFunction, "WeakMap");
34 }
35
36 %WeakCollectionInitialize(this);
37
38 if (!IS_NULL_OR_UNDEFINED(iterable)) {
39 var adder = this.set;
40 if (!IS_CALLABLE(adder)) {
41 throw MakeTypeError(kPropertyNotFunction, adder, 'set', this);
42 }
43 for (var nextItem of iterable) {
44 if (!IS_RECEIVER(nextItem)) {
45 throw MakeTypeError(kIteratorValueNotAnObject, nextItem);
46 }
47 %_Call(adder, this, nextItem[0], nextItem[1]);
48 }
49 }
50}
51
52
53function WeakMapGet(key) {
54 if (!IS_WEAKMAP(this)) {
55 throw MakeTypeError(kIncompatibleMethodReceiver,
56 'WeakMap.prototype.get', this);
57 }
58 if (!IS_RECEIVER(key)) return UNDEFINED;
59 var hash = GetExistingHash(key);
60 if (IS_UNDEFINED(hash)) return UNDEFINED;
61 return %WeakCollectionGet(this, key, hash);
62}
63
64
65function WeakMapSet(key, value) {
66 if (!IS_WEAKMAP(this)) {
67 throw MakeTypeError(kIncompatibleMethodReceiver,
68 'WeakMap.prototype.set', this);
69 }
70 if (!IS_RECEIVER(key)) throw MakeTypeError(kInvalidWeakMapKey);
71 return %WeakCollectionSet(this, key, value, GetHash(key));
72}
73
74
75function WeakMapHas(key) {
76 if (!IS_WEAKMAP(this)) {
77 throw MakeTypeError(kIncompatibleMethodReceiver,
78 'WeakMap.prototype.has', this);
79 }
80 if (!IS_RECEIVER(key)) return false;
81 var hash = GetExistingHash(key);
82 if (IS_UNDEFINED(hash)) return false;
83 return %WeakCollectionHas(this, key, hash);
84}
85
86
87function WeakMapDelete(key) {
88 if (!IS_WEAKMAP(this)) {
89 throw MakeTypeError(kIncompatibleMethodReceiver,
90 'WeakMap.prototype.delete', this);
91 }
92 if (!IS_RECEIVER(key)) return false;
93 var hash = GetExistingHash(key);
94 if (IS_UNDEFINED(hash)) return false;
95 return %WeakCollectionDelete(this, key, hash);
96}
97
98
99// -------------------------------------------------------------------
100
101%SetCode(GlobalWeakMap, WeakMapConstructor);
102%FunctionSetLength(GlobalWeakMap, 0);
103%FunctionSetPrototype(GlobalWeakMap, new GlobalObject());
104%AddNamedProperty(GlobalWeakMap.prototype, "constructor", GlobalWeakMap,
105 DONT_ENUM);
106%AddNamedProperty(GlobalWeakMap.prototype, toStringTagSymbol, "WeakMap",
107 DONT_ENUM | READ_ONLY);
108
109// Set up the non-enumerable functions on the WeakMap prototype object.
110utils.InstallFunctions(GlobalWeakMap.prototype, DONT_ENUM, [
111 "get", WeakMapGet,
112 "set", WeakMapSet,
113 "has", WeakMapHas,
114 "delete", WeakMapDelete
115]);
116
117// -------------------------------------------------------------------
118// Harmony WeakSet
119
120function WeakSetConstructor(iterable) {
121 if (IS_UNDEFINED(new.target)) {
122 throw MakeTypeError(kConstructorNotFunction, "WeakSet");
123 }
124
125 %WeakCollectionInitialize(this);
126
127 if (!IS_NULL_OR_UNDEFINED(iterable)) {
128 var adder = this.add;
129 if (!IS_CALLABLE(adder)) {
130 throw MakeTypeError(kPropertyNotFunction, adder, 'add', this);
131 }
132 for (var value of iterable) {
133 %_Call(adder, this, value);
134 }
135 }
136}
137
138
139function WeakSetAdd(value) {
140 if (!IS_WEAKSET(this)) {
141 throw MakeTypeError(kIncompatibleMethodReceiver,
142 'WeakSet.prototype.add', this);
143 }
144 if (!IS_RECEIVER(value)) throw MakeTypeError(kInvalidWeakSetValue);
145 return %WeakCollectionSet(this, value, true, GetHash(value));
146}
147
148
149function WeakSetHas(value) {
150 if (!IS_WEAKSET(this)) {
151 throw MakeTypeError(kIncompatibleMethodReceiver,
152 'WeakSet.prototype.has', this);
153 }
154 if (!IS_RECEIVER(value)) return false;
155 var hash = GetExistingHash(value);
156 if (IS_UNDEFINED(hash)) return false;
157 return %WeakCollectionHas(this, value, hash);
158}
159
160
161function WeakSetDelete(value) {
162 if (!IS_WEAKSET(this)) {
163 throw MakeTypeError(kIncompatibleMethodReceiver,
164 'WeakSet.prototype.delete', this);
165 }
166 if (!IS_RECEIVER(value)) return false;
167 var hash = GetExistingHash(value);
168 if (IS_UNDEFINED(hash)) return false;
169 return %WeakCollectionDelete(this, value, hash);
170}
171
172
173// -------------------------------------------------------------------
174
175%SetCode(GlobalWeakSet, WeakSetConstructor);
176%FunctionSetLength(GlobalWeakSet, 0);
177%FunctionSetPrototype(GlobalWeakSet, new GlobalObject());
178%AddNamedProperty(GlobalWeakSet.prototype, "constructor", GlobalWeakSet,
179 DONT_ENUM);
180%AddNamedProperty(GlobalWeakSet.prototype, toStringTagSymbol, "WeakSet",
181 DONT_ENUM | READ_ONLY);
182
183// Set up the non-enumerable functions on the WeakSet prototype object.
184utils.InstallFunctions(GlobalWeakSet.prototype, DONT_ENUM, [
185 "add", WeakSetAdd,
186 "has", WeakSetHas,
187 "delete", WeakSetDelete
188]);
189
190})