Chromium Code Reviews| Index: src/collection.js |
| diff --git a/src/collection.js b/src/collection.js |
| index 9054187a12d0372ef1e028569a197059579f26ba..a9b87c07434c9a8f7332a1c6cb496a52112b28f0 100644 |
| --- a/src/collection.js |
| +++ b/src/collection.js |
| @@ -113,8 +113,33 @@ function SetClear() { |
| throw MakeTypeError('incompatible_method_receiver', |
| ['Set.prototype.clear', this]); |
| } |
| - // Replace the internal table with a new empty table. |
| - %SetInitialize(this); |
| + %SetClear(this); |
| +} |
| + |
| + |
| +// Matches OrderedHashTableIterator::Kind enum values. |
| +var SET_ITERATOR_KIND_VALUES = 2; |
| + |
| + |
| +function SetForEach(f, receiver) { |
| + if (!IS_SET(this)) { |
| + throw MakeTypeError('incompatible_method_receiver', |
| + ['Set.prototype.forEach', this]); |
| + } |
| + |
| + if (typeof f !== 'function') { |
|
adamk
2014/04/14 19:15:42
I think you want IS_SPEC_FUNCTION(f) here, which i
arv (Not doing code reviews)
2014/04/14 19:51:49
IS_SPEC_FUNCTION is not correct any more. It tests
rossberg
2014/04/15 10:49:29
They are testing the same thing (whether the insta
|
| + throw MakeTypeError('called_non_callable', [f]); |
| + } |
| + |
| + var iterator = %SetCreateIterator(this, SET_ITERATOR_KIND_VALUES); |
| + var entry; |
| + try { |
| + while (!(entry = %SetIteratorNext(iterator)).done) { |
| + %_CallFunction(receiver, entry.value, entry.value, this, f); |
|
adamk
2014/04/14 19:15:42
Can you add a test that throws in its forEach func
arv (Not doing code reviews)
2014/04/14 19:51:49
Done.
|
| + } |
| + } finally { |
| + %SetIteratorClose(iterator); |
| + } |
| } |
| @@ -127,13 +152,16 @@ function SetUpSet() { |
| %FunctionSetPrototype($Set, new $Object()); |
| %SetProperty($Set.prototype, "constructor", $Set, DONT_ENUM); |
| + %FunctionSetLength(SetForEach, 1); |
| + |
| // Set up the non-enumerable functions on the Set prototype object. |
| InstallGetter($Set.prototype, "size", SetGetSize); |
| InstallFunctions($Set.prototype, DONT_ENUM, $Array( |
| "add", SetAdd, |
| "has", SetHas, |
| "delete", SetDelete, |
| - "clear", SetClear |
| + "clear", SetClear, |
| + "forEach", SetForEach |
| )); |
| } |
| @@ -202,8 +230,33 @@ function MapClear() { |
| throw MakeTypeError('incompatible_method_receiver', |
| ['Map.prototype.clear', this]); |
| } |
| - // Replace the internal table with a new empty table. |
| - %MapInitialize(this); |
| + %MapClear(this); |
| +} |
| + |
| + |
| +// Matches OrderedHashTableIterator::Kind enum values. |
| +var MAP_ITERATOR_KIND_ENTRIES = 3; |
| + |
| + |
| +function MapForEach(f, receiver) { |
| + if (!IS_MAP(this)) { |
| + throw MakeTypeError('incompatible_method_receiver', |
|
adamk
2014/04/14 19:15:42
Can you add tests for this and the other error cas
arv (Not doing code reviews)
2014/04/14 19:51:49
Done.
|
| + ['Map.prototype.forEach', this]); |
| + } |
| + |
| + if (typeof f !== 'function') { |
|
adamk
2014/04/14 19:15:42
IS_SPEC_FUNCTION
|
| + throw MakeTypeError('called_non_callable', [f]); |
| + } |
| + |
| + var iterator = %MapCreateIterator(this, MAP_ITERATOR_KIND_ENTRIES); |
| + var entry; |
| + try { |
| + while (!(entry = %MapIteratorNext(iterator)).done) { |
| + %_CallFunction(receiver, entry.value[1], entry.value[0], this, f); |
| + } |
| + } finally { |
| + %MapIteratorClose(iterator); |
| + } |
| } |
| @@ -216,6 +269,8 @@ function SetUpMap() { |
| %FunctionSetPrototype($Map, new $Object()); |
| %SetProperty($Map.prototype, "constructor", $Map, DONT_ENUM); |
| + %FunctionSetLength(MapForEach, 1); |
| + |
| // Set up the non-enumerable functions on the Map prototype object. |
| InstallGetter($Map.prototype, "size", MapGetSize); |
| InstallFunctions($Map.prototype, DONT_ENUM, $Array( |
| @@ -223,7 +278,8 @@ function SetUpMap() { |
| "set", MapSet, |
| "has", MapHas, |
| "delete", MapDelete, |
| - "clear", MapClear |
| + "clear", MapClear, |
| + "forEach", MapForEach |
| )); |
| } |