OLD | NEW |
| (Empty) |
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 $WeakMap = global.WeakMap; | |
12 var $WeakSet = global.WeakSet; | |
13 | |
14 | |
15 // ------------------------------------------------------------------- | |
16 // Harmony WeakMap | |
17 | |
18 function WeakMapConstructor(iterable) { | |
19 if (!%_IsConstructCall()) { | |
20 throw MakeTypeError('constructor_not_function', ['WeakMap']); | |
21 } | |
22 | |
23 var iter, adder; | |
24 | |
25 if (!IS_NULL_OR_UNDEFINED(iterable)) { | |
26 iter = GetIterator(ToObject(iterable)); | |
27 adder = this.set; | |
28 if (!IS_SPEC_FUNCTION(adder)) { | |
29 throw MakeTypeError('property_not_function', ['set', this]); | |
30 } | |
31 } | |
32 | |
33 %WeakCollectionInitialize(this); | |
34 | |
35 if (IS_UNDEFINED(iter)) return; | |
36 | |
37 var next, done, nextItem; | |
38 while (!(next = iter.next()).done) { | |
39 if (!IS_SPEC_OBJECT(next)) { | |
40 throw MakeTypeError('iterator_result_not_an_object', [next]); | |
41 } | |
42 nextItem = next.value; | |
43 if (!IS_SPEC_OBJECT(nextItem)) { | |
44 throw MakeTypeError('iterator_value_not_an_object', [nextItem]); | |
45 } | |
46 %_CallFunction(this, nextItem[0], nextItem[1], adder); | |
47 } | |
48 } | |
49 | |
50 | |
51 function WeakMapGet(key) { | |
52 if (!IS_WEAKMAP(this)) { | |
53 throw MakeTypeError('incompatible_method_receiver', | |
54 ['WeakMap.prototype.get', this]); | |
55 } | |
56 if (!(IS_SPEC_OBJECT(key) || IS_SYMBOL(key))) { | |
57 throw %MakeTypeError('invalid_weakmap_key', [this, key]); | |
58 } | |
59 return %WeakCollectionGet(this, key); | |
60 } | |
61 | |
62 | |
63 function WeakMapSet(key, value) { | |
64 if (!IS_WEAKMAP(this)) { | |
65 throw MakeTypeError('incompatible_method_receiver', | |
66 ['WeakMap.prototype.set', this]); | |
67 } | |
68 if (!(IS_SPEC_OBJECT(key) || IS_SYMBOL(key))) { | |
69 throw %MakeTypeError('invalid_weakmap_key', [this, key]); | |
70 } | |
71 return %WeakCollectionSet(this, key, value); | |
72 } | |
73 | |
74 | |
75 function WeakMapHas(key) { | |
76 if (!IS_WEAKMAP(this)) { | |
77 throw MakeTypeError('incompatible_method_receiver', | |
78 ['WeakMap.prototype.has', this]); | |
79 } | |
80 if (!(IS_SPEC_OBJECT(key) || IS_SYMBOL(key))) { | |
81 throw %MakeTypeError('invalid_weakmap_key', [this, key]); | |
82 } | |
83 return %WeakCollectionHas(this, key); | |
84 } | |
85 | |
86 | |
87 function WeakMapDelete(key) { | |
88 if (!IS_WEAKMAP(this)) { | |
89 throw MakeTypeError('incompatible_method_receiver', | |
90 ['WeakMap.prototype.delete', this]); | |
91 } | |
92 if (!(IS_SPEC_OBJECT(key) || IS_SYMBOL(key))) { | |
93 throw %MakeTypeError('invalid_weakmap_key', [this, key]); | |
94 } | |
95 return %WeakCollectionDelete(this, key); | |
96 } | |
97 | |
98 | |
99 function WeakMapClear() { | |
100 if (!IS_WEAKMAP(this)) { | |
101 throw MakeTypeError('incompatible_method_receiver', | |
102 ['WeakMap.prototype.clear', this]); | |
103 } | |
104 // Replace the internal table with a new empty table. | |
105 %WeakCollectionInitialize(this); | |
106 } | |
107 | |
108 | |
109 // ------------------------------------------------------------------- | |
110 | |
111 function SetUpWeakMap() { | |
112 %CheckIsBootstrapping(); | |
113 | |
114 %SetCode($WeakMap, WeakMapConstructor); | |
115 %FunctionSetPrototype($WeakMap, new $Object()); | |
116 %AddNamedProperty($WeakMap.prototype, "constructor", $WeakMap, DONT_ENUM); | |
117 | |
118 // Set up the non-enumerable functions on the WeakMap prototype object. | |
119 InstallFunctions($WeakMap.prototype, DONT_ENUM, $Array( | |
120 "get", WeakMapGet, | |
121 "set", WeakMapSet, | |
122 "has", WeakMapHas, | |
123 "delete", WeakMapDelete, | |
124 "clear", WeakMapClear | |
125 )); | |
126 } | |
127 | |
128 SetUpWeakMap(); | |
129 | |
130 | |
131 // ------------------------------------------------------------------- | |
132 // Harmony WeakSet | |
133 | |
134 function WeakSetConstructor(iterable) { | |
135 if (!%_IsConstructCall()) { | |
136 throw MakeTypeError('constructor_not_function', ['WeakSet']); | |
137 } | |
138 | |
139 var iter, adder; | |
140 | |
141 if (!IS_NULL_OR_UNDEFINED(iterable)) { | |
142 iter = GetIterator(ToObject(iterable)); | |
143 adder = this.add; | |
144 if (!IS_SPEC_FUNCTION(adder)) { | |
145 throw MakeTypeError('property_not_function', ['add', this]); | |
146 } | |
147 } | |
148 | |
149 %WeakCollectionInitialize(this); | |
150 | |
151 if (IS_UNDEFINED(iter)) return; | |
152 | |
153 var next, done; | |
154 while (!(next = iter.next()).done) { | |
155 if (!IS_SPEC_OBJECT(next)) { | |
156 throw MakeTypeError('iterator_result_not_an_object', [next]); | |
157 } | |
158 %_CallFunction(this, next.value, adder); | |
159 } | |
160 } | |
161 | |
162 | |
163 function WeakSetAdd(value) { | |
164 if (!IS_WEAKSET(this)) { | |
165 throw MakeTypeError('incompatible_method_receiver', | |
166 ['WeakSet.prototype.add', this]); | |
167 } | |
168 if (!(IS_SPEC_OBJECT(value) || IS_SYMBOL(value))) { | |
169 throw %MakeTypeError('invalid_weakset_value', [this, value]); | |
170 } | |
171 return %WeakCollectionSet(this, value, true); | |
172 } | |
173 | |
174 | |
175 function WeakSetHas(value) { | |
176 if (!IS_WEAKSET(this)) { | |
177 throw MakeTypeError('incompatible_method_receiver', | |
178 ['WeakSet.prototype.has', this]); | |
179 } | |
180 if (!(IS_SPEC_OBJECT(value) || IS_SYMBOL(value))) { | |
181 throw %MakeTypeError('invalid_weakset_value', [this, value]); | |
182 } | |
183 return %WeakCollectionHas(this, value); | |
184 } | |
185 | |
186 | |
187 function WeakSetDelete(value) { | |
188 if (!IS_WEAKSET(this)) { | |
189 throw MakeTypeError('incompatible_method_receiver', | |
190 ['WeakSet.prototype.delete', this]); | |
191 } | |
192 if (!(IS_SPEC_OBJECT(value) || IS_SYMBOL(value))) { | |
193 throw %MakeTypeError('invalid_weakset_value', [this, value]); | |
194 } | |
195 return %WeakCollectionDelete(this, value); | |
196 } | |
197 | |
198 | |
199 function WeakSetClear() { | |
200 if (!IS_WEAKSET(this)) { | |
201 throw MakeTypeError('incompatible_method_receiver', | |
202 ['WeakSet.prototype.clear', this]); | |
203 } | |
204 // Replace the internal table with a new empty table. | |
205 %WeakCollectionInitialize(this); | |
206 } | |
207 | |
208 | |
209 // ------------------------------------------------------------------- | |
210 | |
211 function SetUpWeakSet() { | |
212 %CheckIsBootstrapping(); | |
213 | |
214 %SetCode($WeakSet, WeakSetConstructor); | |
215 %FunctionSetPrototype($WeakSet, new $Object()); | |
216 %AddNamedProperty($WeakSet.prototype, "constructor", $WeakSet, DONT_ENUM); | |
217 | |
218 // Set up the non-enumerable functions on the WeakSet prototype object. | |
219 InstallFunctions($WeakSet.prototype, DONT_ENUM, $Array( | |
220 "add", WeakSetAdd, | |
221 "has", WeakSetHas, | |
222 "delete", WeakSetDelete, | |
223 "clear", WeakSetClear | |
224 )); | |
225 } | |
226 | |
227 SetUpWeakSet(); | |
OLD | NEW |