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.
7 // This file relies on the fact that the following declaration has been made
9 // var $Array = global.Array;
11 var $Set = global.Set;
12 var $Map = global.Map;
15 // -------------------------------------------------------------------
18 function SetConstructor(iterable) {
19 if (!%_IsConstructCall()) {
20 throw MakeTypeError('constructor_not_function', ['Set']);
25 if (!IS_NULL_OR_UNDEFINED(iterable)) {
26 iter = GetIterator(ToObject(iterable));
28 if (!IS_SPEC_FUNCTION(adder)) {
29 throw MakeTypeError('property_not_function', ['add', this]);
33 %_SetInitialize(this);
35 if (IS_UNDEFINED(iter)) return;
38 while (!(next = iter.next()).done) {
39 if (!IS_SPEC_OBJECT(next)) {
40 throw MakeTypeError('iterator_result_not_an_object', [next]);
42 %_CallFunction(this, next.value, adder);
47 function SetAddJS(key) {
49 throw MakeTypeError('incompatible_method_receiver',
50 ['Set.prototype.add', this]);
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
59 return %_SetAdd(this, key);
63 function SetHasJS(key) {
65 throw MakeTypeError('incompatible_method_receiver',
66 ['Set.prototype.has', this]);
68 return %_SetHas(this, key);
72 function SetDeleteJS(key) {
74 throw MakeTypeError('incompatible_method_receiver',
75 ['Set.prototype.delete', this]);
77 return %_SetDelete(this, key);
81 function SetGetSizeJS() {
83 throw MakeTypeError('incompatible_method_receiver',
84 ['Set.prototype.size', this]);
86 return %_SetGetSize(this);
90 function SetClearJS() {
92 throw MakeTypeError('incompatible_method_receiver',
93 ['Set.prototype.clear', this]);
99 function SetForEach(f, receiver) {
101 throw MakeTypeError('incompatible_method_receiver',
102 ['Set.prototype.forEach', this]);
105 if (!IS_SPEC_FUNCTION(f)) {
106 throw MakeTypeError('called_non_callable', [f]);
108 var needs_wrapper = false;
109 if (IS_NULL_OR_UNDEFINED(receiver)) {
110 receiver = %GetDefaultReceiver(f) || receiver;
112 needs_wrapper = SHOULD_CREATE_WRAPPER(f, receiver);
115 var iterator = new SetIterator(this, ITERATOR_KIND_VALUES);
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);
128 // -------------------------------------------------------------------
130 function SetUpSet() {
131 %CheckIsBootstrapping();
133 %SetCode($Set, SetConstructor);
134 %FunctionSetPrototype($Set, new $Object());
135 %AddNamedProperty($Set.prototype, "constructor", $Set, DONT_ENUM);
137 $Set.prototype, symbolToStringTag, "Set", DONT_ENUM | READ_ONLY);
139 %FunctionSetLength(SetForEach, 1);
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(
146 "delete", SetDeleteJS,
148 "forEach", SetForEach
155 // -------------------------------------------------------------------
158 function MapConstructor(iterable) {
159 if (!%_IsConstructCall()) {
160 throw MakeTypeError('constructor_not_function', ['Map']);
165 if (!IS_NULL_OR_UNDEFINED(iterable)) {
166 iter = GetIterator(ToObject(iterable));
168 if (!IS_SPEC_FUNCTION(adder)) {
169 throw MakeTypeError('property_not_function', ['set', this]);
173 %_MapInitialize(this);
175 if (IS_UNDEFINED(iter)) return;
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]);
182 nextItem = next.value;
183 if (!IS_SPEC_OBJECT(nextItem)) {
184 throw MakeTypeError('iterator_value_not_an_object', [nextItem]);
186 %_CallFunction(this, nextItem[0], nextItem[1], adder);
191 function MapGetJS(key) {
193 throw MakeTypeError('incompatible_method_receiver',
194 ['Map.prototype.get', this]);
196 return %_MapGet(this, key);
200 function MapSetJS(key, value) {
202 throw MakeTypeError('incompatible_method_receiver',
203 ['Map.prototype.set', this]);
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
212 return %_MapSet(this, key, value);
216 function MapHasJS(key) {
218 throw MakeTypeError('incompatible_method_receiver',
219 ['Map.prototype.has', this]);
221 return %_MapHas(this, key);
225 function MapDeleteJS(key) {
227 throw MakeTypeError('incompatible_method_receiver',
228 ['Map.prototype.delete', this]);
230 return %_MapDelete(this, key);
234 function MapGetSizeJS() {
236 throw MakeTypeError('incompatible_method_receiver',
237 ['Map.prototype.size', this]);
239 return %_MapGetSize(this);
243 function MapClearJS() {
245 throw MakeTypeError('incompatible_method_receiver',
246 ['Map.prototype.clear', this]);
252 function MapForEach(f, receiver) {
254 throw MakeTypeError('incompatible_method_receiver',
255 ['Map.prototype.forEach', this]);
258 if (!IS_SPEC_FUNCTION(f)) {
259 throw MakeTypeError('called_non_callable', [f]);
261 var needs_wrapper = false;
262 if (IS_NULL_OR_UNDEFINED(receiver)) {
263 receiver = %GetDefaultReceiver(f) || receiver;
265 needs_wrapper = SHOULD_CREATE_WRAPPER(f, receiver);
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);
279 // -------------------------------------------------------------------
281 function SetUpMap() {
282 %CheckIsBootstrapping();
284 %SetCode($Map, MapConstructor);
285 %FunctionSetPrototype($Map, new $Object());
286 %AddNamedProperty($Map.prototype, "constructor", $Map, DONT_ENUM);
288 $Map.prototype, symbolToStringTag, "Map", DONT_ENUM | READ_ONLY);
290 %FunctionSetLength(MapForEach, 1);
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(
298 "delete", MapDeleteJS,
300 "forEach", MapForEach