OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 "use strict"; | 5 "use strict"; |
6 | 6 |
7 // This file relies on the fact that the following declaration has been made | 7 // This file relies on the fact that the following declaration has been made |
8 // in runtime.js: | 8 // in runtime.js: |
9 // var $Array = global.Array; | 9 // var $Array = global.Array; |
10 | 10 |
11 var $Set = global.Set; | 11 var $Set = global.Set; |
12 var $Map = global.Map; | 12 var $Map = global.Map; |
13 | 13 |
14 | 14 |
| 15 // TODO(arv): Move these general functions to v8natives.js when Map and Set are |
| 16 // no longer experimental. |
| 17 |
| 18 |
| 19 // 7.4.1 CheckIterable ( obj ) |
| 20 function ToIterable(obj) { |
| 21 if (!IS_SPEC_OBJECT(obj)) { |
| 22 return UNDEFINED; |
| 23 } |
| 24 return obj[symbolIterator]; |
| 25 } |
| 26 |
| 27 |
| 28 // 7.4.2 GetIterator ( obj, method ) |
| 29 function GetIterator(obj, method) { |
| 30 if (IS_UNDEFINED(method)) { |
| 31 method = ToIterable(obj); |
| 32 } |
| 33 if (!IS_SPEC_FUNCTION(method)) { |
| 34 throw MakeTypeError('not_iterable', [obj]); |
| 35 } |
| 36 var iterator = %_CallFunction(obj, method); |
| 37 if (!IS_SPEC_OBJECT(iterator)) { |
| 38 throw MakeTypeError('not_an_iterator', [iterator]); |
| 39 } |
| 40 return iterator; |
| 41 } |
| 42 |
| 43 |
15 // ------------------------------------------------------------------- | 44 // ------------------------------------------------------------------- |
16 // Harmony Set | 45 // Harmony Set |
17 | 46 |
18 function SetConstructor() { | 47 function SetConstructor(iterable) { |
19 if (%_IsConstructCall()) { | 48 if (!%_IsConstructCall()) { |
20 %SetInitialize(this); | |
21 } else { | |
22 throw MakeTypeError('constructor_not_function', ['Set']); | 49 throw MakeTypeError('constructor_not_function', ['Set']); |
23 } | 50 } |
| 51 |
| 52 var iter, adder; |
| 53 |
| 54 if (!IS_NULL_OR_UNDEFINED(iterable)) { |
| 55 iter = GetIterator(iterable); |
| 56 adder = this.add; |
| 57 if (!IS_SPEC_FUNCTION(adder)) { |
| 58 throw MakeTypeError('property_not_function', ['add', this]); |
| 59 } |
| 60 } |
| 61 |
| 62 %SetInitialize(this); |
| 63 |
| 64 if (IS_UNDEFINED(iter)) return; |
| 65 |
| 66 var next, done; |
| 67 while (!(next = iter.next()).done) { |
| 68 if (!IS_SPEC_OBJECT(next)) { |
| 69 throw MakeTypeError('iterator_result_not_an_object', [next]); |
| 70 } |
| 71 %_CallFunction(this, next.value, adder); |
| 72 } |
24 } | 73 } |
25 | 74 |
26 | 75 |
27 function SetAddJS(key) { | 76 function SetAddJS(key) { |
28 if (!IS_SET(this)) { | 77 if (!IS_SET(this)) { |
29 throw MakeTypeError('incompatible_method_receiver', | 78 throw MakeTypeError('incompatible_method_receiver', |
30 ['Set.prototype.add', this]); | 79 ['Set.prototype.add', this]); |
31 } | 80 } |
32 return %SetAdd(this, key); | 81 return %SetAdd(this, key); |
33 } | 82 } |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
110 "forEach", SetForEach | 159 "forEach", SetForEach |
111 )); | 160 )); |
112 } | 161 } |
113 | 162 |
114 SetUpSet(); | 163 SetUpSet(); |
115 | 164 |
116 | 165 |
117 // ------------------------------------------------------------------- | 166 // ------------------------------------------------------------------- |
118 // Harmony Map | 167 // Harmony Map |
119 | 168 |
120 function MapConstructor() { | 169 function MapConstructor(iterable) { |
121 if (%_IsConstructCall()) { | 170 if (!%_IsConstructCall()) { |
122 %MapInitialize(this); | |
123 } else { | |
124 throw MakeTypeError('constructor_not_function', ['Map']); | 171 throw MakeTypeError('constructor_not_function', ['Map']); |
125 } | 172 } |
| 173 |
| 174 var iter, adder; |
| 175 |
| 176 if (!IS_NULL_OR_UNDEFINED(iterable)) { |
| 177 iter = GetIterator(iterable); |
| 178 adder = this.set; |
| 179 if (!IS_SPEC_FUNCTION(adder)) { |
| 180 throw MakeTypeError('property_not_function', ['set', this]); |
| 181 } |
| 182 } |
| 183 |
| 184 %MapInitialize(this); |
| 185 |
| 186 if (IS_UNDEFINED(iter)) return; |
| 187 |
| 188 var next, done, nextItem; |
| 189 while (!(next = iter.next()).done) { |
| 190 if (!IS_SPEC_OBJECT(next)) { |
| 191 throw MakeTypeError('iterator_result_not_an_object', [next]); |
| 192 } |
| 193 nextItem = next.value; |
| 194 if (!IS_SPEC_OBJECT(nextItem)) { |
| 195 throw MakeTypeError('iterator_value_not_an_object', [nextItem]); |
| 196 } |
| 197 %_CallFunction(this, nextItem[0], nextItem[1], adder); |
| 198 } |
126 } | 199 } |
127 | 200 |
128 | 201 |
129 function MapGetJS(key) { | 202 function MapGetJS(key) { |
130 if (!IS_MAP(this)) { | 203 if (!IS_MAP(this)) { |
131 throw MakeTypeError('incompatible_method_receiver', | 204 throw MakeTypeError('incompatible_method_receiver', |
132 ['Map.prototype.get', this]); | 205 ['Map.prototype.get', this]); |
133 } | 206 } |
134 return %MapGet(this, key); | 207 return %MapGet(this, key); |
135 } | 208 } |
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
217 "get", MapGetJS, | 290 "get", MapGetJS, |
218 "set", MapSetJS, | 291 "set", MapSetJS, |
219 "has", MapHasJS, | 292 "has", MapHasJS, |
220 "delete", MapDeleteJS, | 293 "delete", MapDeleteJS, |
221 "clear", MapClearJS, | 294 "clear", MapClearJS, |
222 "forEach", MapForEach | 295 "forEach", MapForEach |
223 )); | 296 )); |
224 } | 297 } |
225 | 298 |
226 SetUpMap(); | 299 SetUpMap(); |
OLD | NEW |