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']);
23 %_SetInitialize(this);
25 if (!IS_NULL_OR_UNDEFINED(iterable)) {
27 if (!IS_SPEC_FUNCTION(adder)) {
28 throw MakeTypeError('property_not_function', ['add', this]);
31 for (var value of iterable) {
32 %_CallFunction(this, value, adder);
38 function SetAddJS(key) {
40 throw MakeTypeError('incompatible_method_receiver',
41 ['Set.prototype.add', this]);
43 // Normalize -0 to +0 as required by the spec.
44 // Even though we use SameValueZero as the comparison for the keys we don't
45 // want to ever store -0 as the key since the key is directly exposed when
50 return %_SetAdd(this, key);
54 function SetHasJS(key) {
56 throw MakeTypeError('incompatible_method_receiver',
57 ['Set.prototype.has', this]);
59 return %_SetHas(this, key);
63 function SetDeleteJS(key) {
65 throw MakeTypeError('incompatible_method_receiver',
66 ['Set.prototype.delete', this]);
68 return %_SetDelete(this, key);
72 function SetGetSizeJS() {
74 throw MakeTypeError('incompatible_method_receiver',
75 ['Set.prototype.size', this]);
77 return %_SetGetSize(this);
81 function SetClearJS() {
83 throw MakeTypeError('incompatible_method_receiver',
84 ['Set.prototype.clear', this]);
90 function SetForEach(f, receiver) {
92 throw MakeTypeError('incompatible_method_receiver',
93 ['Set.prototype.forEach', this]);
96 if (!IS_SPEC_FUNCTION(f)) {
97 throw MakeTypeError('called_non_callable', [f]);
99 var needs_wrapper = false;
100 if (IS_NULL_OR_UNDEFINED(receiver)) {
101 receiver = %GetDefaultReceiver(f) || receiver;
103 needs_wrapper = SHOULD_CREATE_WRAPPER(f, receiver);
106 var iterator = new SetIterator(this, ITERATOR_KIND_VALUES);
108 var stepping = DEBUG_IS_ACTIVE && %DebugCallbackSupportsStepping(f);
109 var value_array = [UNDEFINED];
110 while (%SetIteratorNext(iterator, value_array)) {
111 if (stepping) %DebugPrepareStepInIfStepping(f);
112 key = value_array[0];
113 var new_receiver = needs_wrapper ? ToObject(receiver) : receiver;
114 %_CallFunction(new_receiver, key, key, this, f);
119 // -------------------------------------------------------------------
121 function SetUpSet() {
122 %CheckIsBootstrapping();
124 %SetCode($Set, SetConstructor);
125 %FunctionSetPrototype($Set, new $Object());
126 %AddNamedProperty($Set.prototype, "constructor", $Set, DONT_ENUM);
128 $Set.prototype, symbolToStringTag, "Set", DONT_ENUM | READ_ONLY);
130 %FunctionSetLength(SetForEach, 1);
132 // Set up the non-enumerable functions on the Set prototype object.
133 InstallGetter($Set.prototype, "size", SetGetSizeJS);
134 InstallFunctions($Set.prototype, DONT_ENUM, $Array(
137 "delete", SetDeleteJS,
139 "forEach", SetForEach
146 // -------------------------------------------------------------------
149 function MapConstructor(iterable) {
150 if (!%_IsConstructCall()) {
151 throw MakeTypeError('constructor_not_function', ['Map']);
154 %_MapInitialize(this);
156 if (!IS_NULL_OR_UNDEFINED(iterable)) {
157 var adder = this.set;
158 if (!IS_SPEC_FUNCTION(adder)) {
159 throw MakeTypeError('property_not_function', ['set', this]);
162 for (var nextItem of iterable) {
163 if (!IS_SPEC_OBJECT(nextItem)) {
164 throw MakeTypeError('iterator_value_not_an_object', [nextItem]);
166 %_CallFunction(this, nextItem[0], nextItem[1], adder);
172 function MapGetJS(key) {
174 throw MakeTypeError('incompatible_method_receiver',
175 ['Map.prototype.get', this]);
177 return %_MapGet(this, key);
181 function MapSetJS(key, value) {
183 throw MakeTypeError('incompatible_method_receiver',
184 ['Map.prototype.set', this]);
186 // Normalize -0 to +0 as required by the spec.
187 // Even though we use SameValueZero as the comparison for the keys we don't
188 // want to ever store -0 as the key since the key is directly exposed when
193 return %_MapSet(this, key, value);
197 function MapHasJS(key) {
199 throw MakeTypeError('incompatible_method_receiver',
200 ['Map.prototype.has', this]);
202 return %_MapHas(this, key);
206 function MapDeleteJS(key) {
208 throw MakeTypeError('incompatible_method_receiver',
209 ['Map.prototype.delete', this]);
211 return %_MapDelete(this, key);
215 function MapGetSizeJS() {
217 throw MakeTypeError('incompatible_method_receiver',
218 ['Map.prototype.size', this]);
220 return %_MapGetSize(this);
224 function MapClearJS() {
226 throw MakeTypeError('incompatible_method_receiver',
227 ['Map.prototype.clear', this]);
233 function MapForEach(f, receiver) {
235 throw MakeTypeError('incompatible_method_receiver',
236 ['Map.prototype.forEach', this]);
239 if (!IS_SPEC_FUNCTION(f)) {
240 throw MakeTypeError('called_non_callable', [f]);
242 var needs_wrapper = false;
243 if (IS_NULL_OR_UNDEFINED(receiver)) {
244 receiver = %GetDefaultReceiver(f) || receiver;
246 needs_wrapper = SHOULD_CREATE_WRAPPER(f, receiver);
249 var iterator = new MapIterator(this, ITERATOR_KIND_ENTRIES);
250 var stepping = DEBUG_IS_ACTIVE && %DebugCallbackSupportsStepping(f);
251 var value_array = [UNDEFINED, UNDEFINED];
252 while (%MapIteratorNext(iterator, value_array)) {
253 if (stepping) %DebugPrepareStepInIfStepping(f);
254 var new_receiver = needs_wrapper ? ToObject(receiver) : receiver;
255 %_CallFunction(new_receiver, value_array[1], value_array[0], this, f);
260 // -------------------------------------------------------------------
262 function SetUpMap() {
263 %CheckIsBootstrapping();
265 %SetCode($Map, MapConstructor);
266 %FunctionSetPrototype($Map, new $Object());
267 %AddNamedProperty($Map.prototype, "constructor", $Map, DONT_ENUM);
269 $Map.prototype, symbolToStringTag, "Map", DONT_ENUM | READ_ONLY);
271 %FunctionSetLength(MapForEach, 1);
273 // Set up the non-enumerable functions on the Map prototype object.
274 InstallGetter($Map.prototype, "size", MapGetSizeJS);
275 InstallFunctions($Map.prototype, DONT_ENUM, $Array(
279 "delete", MapDeleteJS,
281 "forEach", MapForEach