Index: src/collection.js |
diff --git a/src/collection.js b/src/collection.js |
index 0d8dd77f7bd3be944ffcd25b51544d8ebe740c00..375fdf50190e04e25ef3d47f2bebd3682476481b 100644 |
--- a/src/collection.js |
+++ b/src/collection.js |
@@ -12,15 +12,64 @@ var $Set = global.Set; |
var $Map = global.Map; |
+// TODO(arv): Move these general functions to v8natives.js when Map and Set are |
+// no longer experimental. |
+ |
+ |
+// 7.4.1 CheckIterable ( obj ) |
+function ToIterable(obj) { |
+ if (!IS_SPEC_OBJECT(obj)) { |
+ return UNDEFINED; |
+ } |
+ return obj[symbolIterator]; |
+} |
+ |
+ |
+// 7.4.2 GetIterator ( obj, method ) |
+function GetIterator(obj, method) { |
+ if (IS_UNDEFINED(method)) { |
+ method = ToIterable(obj); |
+ } |
+ if (!IS_SPEC_FUNCTION(method)) { |
+ throw MakeTypeError('not_iterable', [obj]); |
+ } |
+ var iterator = %_CallFunction(obj, method); |
+ if (!IS_SPEC_OBJECT(iterator)) { |
+ throw MakeTypeError('not_an_iterator', [iterator]); |
+ } |
+ return iterator; |
+} |
+ |
+ |
// ------------------------------------------------------------------- |
// Harmony Set |
-function SetConstructor() { |
- if (%_IsConstructCall()) { |
- %SetInitialize(this); |
- } else { |
+function SetConstructor(iterable) { |
+ if (!%_IsConstructCall()) { |
throw MakeTypeError('constructor_not_function', ['Set']); |
} |
+ |
+ var iter, adder; |
+ |
+ if (!IS_NULL_OR_UNDEFINED(iterable)) { |
+ iter = GetIterator(iterable); |
+ adder = this.add; |
+ if (!IS_SPEC_FUNCTION(adder)) { |
+ throw MakeTypeError('property_not_function', ['add', this]); |
+ } |
+ } |
+ |
+ %SetInitialize(this); |
+ |
+ if (IS_UNDEFINED(iter)) return; |
+ |
+ var next, done; |
+ while (!(next = iter.next()).done) { |
+ if (!IS_SPEC_OBJECT(next)) { |
+ throw MakeTypeError('iterator_result_not_an_object', [next]); |
+ } |
+ %_CallFunction(this, next.value, adder); |
+ } |
} |
@@ -117,12 +166,36 @@ SetUpSet(); |
// ------------------------------------------------------------------- |
// Harmony Map |
-function MapConstructor() { |
- if (%_IsConstructCall()) { |
- %MapInitialize(this); |
- } else { |
+function MapConstructor(iterable) { |
+ if (!%_IsConstructCall()) { |
throw MakeTypeError('constructor_not_function', ['Map']); |
} |
+ |
+ var iter, adder; |
+ |
+ if (!IS_NULL_OR_UNDEFINED(iterable)) { |
+ iter = GetIterator(iterable); |
+ adder = this.set; |
+ if (!IS_SPEC_FUNCTION(adder)) { |
+ throw MakeTypeError('property_not_function', ['set', this]); |
+ } |
+ } |
+ |
+ %MapInitialize(this); |
+ |
+ if (IS_UNDEFINED(iter)) return; |
+ |
+ var next, done, nextItem; |
+ while (!(next = iter.next()).done) { |
+ if (!IS_SPEC_OBJECT(next)) { |
+ throw MakeTypeError('iterator_result_not_an_object', [next]); |
+ } |
+ nextItem = next.value; |
+ if (!IS_SPEC_OBJECT(nextItem)) { |
+ throw MakeTypeError('iterator_value_not_an_object', [nextItem]); |
+ } |
+ %_CallFunction(this, nextItem[0], nextItem[1], adder); |
+ } |
} |