Revision: 21615
Author:   [email protected]
Date:     Tue Jun  3 00:34:01 2014 UTC
Log:      ES6: Add support for values/keys/entries for Map and Set

This allows code like this:

  var map = new Map();
  map.set(1, 'One');
  ...
  var iter = map.values();
  var res;
  while (!(res = iter.next()).done) {
    print(res.value);
  }

BUG=v8:1793
LOG=Y
[email protected]

Review URL: https://codereview.chromium.org/259883002

Patch from Erik Arvidsson <[email protected]>.
http://code.google.com/p/v8/source/detail?r=21615

Added:
 /branches/bleeding_edge/src/collection-iterator.js
 /branches/bleeding_edge/test/mjsunit/harmony/collection-iterator.js
 /branches/bleeding_edge/test/mjsunit/runtime-gen/mapiteratorinitialize.js
 /branches/bleeding_edge/test/mjsunit/runtime-gen/setiteratorinitialize.js
Deleted:
 /branches/bleeding_edge/test/mjsunit/runtime-gen/mapcreateiterator.js
 /branches/bleeding_edge/test/mjsunit/runtime-gen/setcreateiterator.js
Modified:
 /branches/bleeding_edge/src/bootstrapper.cc
 /branches/bleeding_edge/src/collection.js
 /branches/bleeding_edge/src/flag-definitions.h
 /branches/bleeding_edge/src/macros.py
 /branches/bleeding_edge/src/objects-debug.cc
 /branches/bleeding_edge/src/objects-inl.h
 /branches/bleeding_edge/src/objects.cc
 /branches/bleeding_edge/src/objects.h
 /branches/bleeding_edge/src/runtime.cc
 /branches/bleeding_edge/src/runtime.h
 /branches/bleeding_edge/test/cctest/test-api.cc
 /branches/bleeding_edge/test/cctest/test-ordered-hash-table.cc
 /branches/bleeding_edge/test/mjsunit/regress/regress-3281.js
 /branches/bleeding_edge/test/mjsunit/runtime-gen/mapiteratornext.js
 /branches/bleeding_edge/test/mjsunit/runtime-gen/setiteratornext.js
 /branches/bleeding_edge/tools/generate-runtime-tests.py
 /branches/bleeding_edge/tools/gyp/v8.gyp

=======================================
--- /dev/null
+++ /branches/bleeding_edge/src/collection-iterator.js Tue Jun 3 00:34:01 2014 UTC
@@ -0,0 +1,162 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+'use strict';
+
+
+// This file relies on the fact that the following declaration has been made
+// in runtime.js:
+// var $Set = global.Set;
+// var $Map = global.Map;
+
+
+function SetIteratorConstructor(set, kind) {
+  %SetIteratorInitialize(this, set, kind);
+}
+
+
+function SetIteratorNextJS() {
+  if (!IS_SET_ITERATOR(this)) {
+    throw MakeTypeError('incompatible_method_receiver',
+                        ['Set Iterator.prototype.next', this]);
+  }
+  return %SetIteratorNext(this);
+}
+
+
+function SetIteratorSymbolIterator() {
+  return this;
+}
+
+
+function SetEntries() {
+  if (!IS_SET(this)) {
+    throw MakeTypeError('incompatible_method_receiver',
+                        ['Set.prototype.entries', this]);
+  }
+  return new SetIterator(this, ITERATOR_KIND_ENTRIES);
+}
+
+
+function SetValues() {
+  if (!IS_SET(this)) {
+    throw MakeTypeError('incompatible_method_receiver',
+                        ['Set.prototype.values', this]);
+  }
+  return new SetIterator(this, ITERATOR_KIND_VALUES);
+}
+
+
+function SetUpSetIterator() {
+  %CheckIsBootstrapping();
+
+  %SetCode(SetIterator, SetIteratorConstructor);
+  %FunctionSetPrototype(SetIterator, new $Object());
+  %FunctionSetInstanceClassName(SetIterator, 'Set Iterator');
+  InstallFunctions(SetIterator.prototype, DONT_ENUM, $Array(
+    'next', SetIteratorNextJS
+  ));
+
+  %FunctionSetName(SetIteratorSymbolIterator, '[Symbol.iterator]');
+  %SetProperty(SetIterator.prototype, InternalSymbol('Symbol.iterator'),
+      SetIteratorSymbolIterator, DONT_ENUM);
+}
+
+SetUpSetIterator();
+
+
+function ExtendSetPrototype() {
+  %CheckIsBootstrapping();
+
+  InstallFunctions($Set.prototype, DONT_ENUM, $Array(
+    'entries', SetEntries,
+    'values', SetValues
+  ));
+
+ %SetProperty($Set.prototype, InternalSymbol('Symbol.iterator'), SetValues,
+      DONT_ENUM);
+}
+
+ExtendSetPrototype();
+
+
+
+function MapIteratorConstructor(map, kind) {
+  %MapIteratorInitialize(this, map, kind);
+}
+
+
+function MapIteratorSymbolIterator() {
+  return this;
+}
+
+
+function MapIteratorNextJS() {
+  if (!IS_MAP_ITERATOR(this)) {
+    throw MakeTypeError('incompatible_method_receiver',
+                        ['Map Iterator.prototype.next', this]);
+  }
+  return %MapIteratorNext(this);
+}
+
+
+function MapEntries() {
+  if (!IS_MAP(this)) {
+    throw MakeTypeError('incompatible_method_receiver',
+                        ['Map.prototype.entries', this]);
+  }
+  return new MapIterator(this, ITERATOR_KIND_ENTRIES);
+}
+
+
+function MapKeys() {
+  if (!IS_MAP(this)) {
+    throw MakeTypeError('incompatible_method_receiver',
+                        ['Map.prototype.keys', this]);
+  }
+  return new MapIterator(this, ITERATOR_KIND_KEYS);
+}
+
+
+function MapValues() {
+  if (!IS_MAP(this)) {
+    throw MakeTypeError('incompatible_method_receiver',
+                        ['Map.prototype.values', this]);
+  }
+  return new MapIterator(this, ITERATOR_KIND_VALUES);
+}
+
+
+function SetUpMapIterator() {
+  %CheckIsBootstrapping();
+
+  %SetCode(MapIterator, MapIteratorConstructor);
+  %FunctionSetPrototype(MapIterator, new $Object());
+  %FunctionSetInstanceClassName(MapIterator, 'Map Iterator');
+  InstallFunctions(MapIterator.prototype, DONT_ENUM, $Array(
+    'next', MapIteratorNextJS
+  ));
+
+  %FunctionSetName(MapIteratorSymbolIterator, '[Symbol.iterator]');
+  %SetProperty(MapIterator.prototype, InternalSymbol('Symbol.iterator'),
+      MapIteratorSymbolIterator, DONT_ENUM);
+}
+
+SetUpMapIterator();
+
+
+function ExtendMapPrototype() {
+  %CheckIsBootstrapping();
+
+  InstallFunctions($Map.prototype, DONT_ENUM, $Array(
+    'entries', MapEntries,
+    'keys', MapKeys,
+    'values', MapValues
+  ));
+
+ %SetProperty($Map.prototype, InternalSymbol('Symbol.iterator'), MapEntries,
+      DONT_ENUM);
+}
+
+ExtendMapPrototype();
=======================================
--- /dev/null
+++ /branches/bleeding_edge/test/mjsunit/harmony/collection-iterator.js Tue Jun 3 00:34:01 2014 UTC
@@ -0,0 +1,195 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Flags: --harmony-collections --allow-natives-syntax
+
+
+(function TestSetIterator() {
+  var s = new Set;
+  var iter = s.values();
+  assertEquals('Set Iterator', %_ClassOf(iter));
+
+  var SetIteratorPrototype = iter.__proto__;
+  assertFalse(SetIteratorPrototype.hasOwnProperty('constructor'));
+  assertEquals(SetIteratorPrototype.__proto__, Object.prototype);
+
+  var propertyNames = Object.getOwnPropertyNames(SetIteratorPrototype);
+  assertArrayEquals(['next'], propertyNames);
+
+  assertEquals(new Set().values().__proto__, SetIteratorPrototype);
+  assertEquals(new Set().entries().__proto__, SetIteratorPrototype);
+})();
+
+
+(function TestSetIteratorValues() {
+  var s = new Set;
+  s.add(1);
+  s.add(2);
+  s.add(3);
+  var iter = s.values();
+
+  assertEquals({value: 1, done: false}, iter.next());
+  assertEquals({value: 2, done: false}, iter.next());
+  assertEquals({value: 3, done: false}, iter.next());
+  assertEquals({value: undefined, done: true}, iter.next());
+  assertEquals({value: undefined, done: true}, iter.next());
+})();
+
+
+(function TestSetIteratorEntries() {
+  var s = new Set;
+  s.add(1);
+  s.add(2);
+  s.add(3);
+  var iter = s.entries();
+
+  assertEquals({value: [1, 1], done: false}, iter.next());
+  assertEquals({value: [2, 2], done: false}, iter.next());
+  assertEquals({value: [3, 3], done: false}, iter.next());
+  assertEquals({value: undefined, done: true}, iter.next());
+  assertEquals({value: undefined, done: true}, iter.next());
+})();
+
+
+(function TestSetIteratorMutations() {
+  var s = new Set;
+  s.add(1);
+  var iter = s.values();
+  assertEquals({value: 1, done: false}, iter.next());
+  s.add(2);
+  s.add(3);
+  s.add(4);
+  s.add(5);
+  assertEquals({value: 2, done: false}, iter.next());
+  s.delete(3);
+  assertEquals({value: 4, done: false}, iter.next());
+  s.delete(5);
+  assertEquals({value: undefined, done: true}, iter.next());
+  s.add(4);
+  assertEquals({value: undefined, done: true}, iter.next());
+})();
+
+
+(function TestSetInvalidReceiver() {
+  assertThrows(function() {
+    Set.prototype.values.call({});
+  }, TypeError);
+  assertThrows(function() {
+    Set.prototype.entries.call({});
+  }, TypeError);
+})();
+
+
+(function TestSetIteratorInvalidReceiver() {
+  var iter = new Set().values();
+  assertThrows(function() {
+    iter.next.call({});
+  });
+})();
+
+
+(function TestSetIteratorSymbol() {
+  assertEquals(Set.prototype[Symbol.iterator], Set.prototype.values);
+  assertTrue(Set.prototype.hasOwnProperty(Symbol.iterator));
+  assertFalse(Set.prototype.propertyIsEnumerable(Symbol.iterator));
+
+  var iter = new Set().values();
+  assertEquals(iter, iter[Symbol.iterator]());
+  assertEquals(iter[Symbol.iterator].name, '[Symbol.iterator]');
+})();
+
+
+(function TestMapIterator() {
+  var m = new Map;
+  var iter = m.values();
+  assertEquals('Map Iterator', %_ClassOf(iter));
+
+  var MapIteratorPrototype = iter.__proto__;
+  assertFalse(MapIteratorPrototype.hasOwnProperty('constructor'));
+  assertEquals(MapIteratorPrototype.__proto__, Object.prototype);
+
+  var propertyNames = Object.getOwnPropertyNames(MapIteratorPrototype);
+  assertArrayEquals(['next'], propertyNames);
+
+  assertEquals(new Map().values().__proto__, MapIteratorPrototype);
+  assertEquals(new Map().keys().__proto__, MapIteratorPrototype);
+  assertEquals(new Map().entries().__proto__, MapIteratorPrototype);
+})();
+
+
+(function TestMapIteratorValues() {
+  var m = new Map;
+  m.set(1, 11);
+  m.set(2, 22);
+  m.set(3, 33);
+  var iter = m.values();
+
+  assertEquals({value: 11, done: false}, iter.next());
+  assertEquals({value: 22, done: false}, iter.next());
+  assertEquals({value: 33, done: false}, iter.next());
+  assertEquals({value: undefined, done: true}, iter.next());
+  assertEquals({value: undefined, done: true}, iter.next());
+})();
+
+
+(function TestMapIteratorKeys() {
+  var m = new Map;
+  m.set(1, 11);
+  m.set(2, 22);
+  m.set(3, 33);
+  var iter = m.keys();
+
+  assertEquals({value: 1, done: false}, iter.next());
+  assertEquals({value: 2, done: false}, iter.next());
+  assertEquals({value: 3, done: false}, iter.next());
+  assertEquals({value: undefined, done: true}, iter.next());
+  assertEquals({value: undefined, done: true}, iter.next());
+})();
+
+
+(function TestMapIteratorEntries() {
+  var m = new Map;
+  m.set(1, 11);
+  m.set(2, 22);
+  m.set(3, 33);
+  var iter = m.entries();
+
+  assertEquals({value: [1, 11], done: false}, iter.next());
+  assertEquals({value: [2, 22], done: false}, iter.next());
+  assertEquals({value: [3, 33], done: false}, iter.next());
+  assertEquals({value: undefined, done: true}, iter.next());
+  assertEquals({value: undefined, done: true}, iter.next());
+})();
+
+
+(function TestMapInvalidReceiver() {
+  assertThrows(function() {
+    Map.prototype.values.call({});
+  }, TypeError);
+  assertThrows(function() {
+    Map.prototype.keys.call({});
+  }, TypeError);
+  assertThrows(function() {
+    Map.prototype.entries.call({});
+  }, TypeError);
+})();
+
+
+(function TestMapIteratorInvalidReceiver() {
+  var iter = new Map().values();
+  assertThrows(function() {
+    iter.next.call({});
+  }, TypeError);
+})();
+
+
+(function TestMapIteratorSymbol() {
+  assertEquals(Map.prototype[Symbol.iterator], Map.prototype.entries);
+  assertTrue(Map.prototype.hasOwnProperty(Symbol.iterator));
+  assertFalse(Map.prototype.propertyIsEnumerable(Symbol.iterator));
+
+  var iter = new Map().values();
+  assertEquals(iter, iter[Symbol.iterator]());
+  assertEquals(iter[Symbol.iterator].name, '[Symbol.iterator]');
+})();
=======================================
--- /dev/null
+++ /branches/bleeding_edge/test/mjsunit/runtime-gen/mapiteratorinitialize.js Tue Jun 3 00:34:01 2014 UTC
@@ -0,0 +1,7 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony
+var _holder = new Map().entries();
+var _map = new Map();
+var _kind = 1;
+%MapIteratorInitialize(_holder, _map, _kind);
=======================================
--- /dev/null
+++ /branches/bleeding_edge/test/mjsunit/runtime-gen/setiteratorinitialize.js Tue Jun 3 00:34:01 2014 UTC
@@ -0,0 +1,7 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony
+var _holder = new Set().values();
+var _set = new Set();
+var arg2 = 2;
+%SetIteratorInitialize(_holder, _set, arg2);
=======================================
--- /branches/bleeding_edge/test/mjsunit/runtime-gen/mapcreateiterator.js Thu May 8 13:11:59 2014 UTC
+++ /dev/null
@@ -1,6 +0,0 @@
-// Copyright 2014 the V8 project authors. All rights reserved.
-// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
-// Flags: --allow-natives-syntax --harmony
-var _holder = new Map();
-var _kind = 1;
-%MapCreateIterator(_holder, _kind);
=======================================
--- /branches/bleeding_edge/test/mjsunit/runtime-gen/setcreateiterator.js Thu May 8 13:11:59 2014 UTC
+++ /dev/null
@@ -1,6 +0,0 @@
-// Copyright 2014 the V8 project authors. All rights reserved.
-// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
-// Flags: --allow-natives-syntax --harmony
-var _holder = new Set();
-var arg1 = 2;
-%SetCreateIterator(_holder, arg1);
=======================================
--- /branches/bleeding_edge/src/bootstrapper.cc Mon Jun  2 13:35:26 2014 UTC
+++ /branches/bleeding_edge/src/bootstrapper.cc Tue Jun  3 00:34:01 2014 UTC
@@ -1347,16 +1347,24 @@
     InstallFunction(global, "Set", JS_SET_TYPE, JSSet::kSize,
isolate()->initial_object_prototype(), Builtins::kIllegal);
     {   // -- S e t I t e r a t o r
-      Handle<Map> map = isolate()->factory()->NewMap(
-          JS_SET_ITERATOR_TYPE, JSSetIterator::kSize);
-      map->set_constructor(native_context()->closure());
-      native_context()->set_set_iterator_map(*map);
+      Handle<JSObject> builtins(native_context()->builtins());
+      Handle<JSFunction> set_iterator_function =
+          InstallFunction(builtins, "SetIterator", JS_SET_ITERATOR_TYPE,
+                          JSSetIterator::kSize,
+                          isolate()->initial_object_prototype(),
+                          Builtins::kIllegal);
+      native_context()->set_set_iterator_map(
+          set_iterator_function->initial_map());
     }
     {   // -- M a p I t e r a t o r
-      Handle<Map> map = isolate()->factory()->NewMap(
-          JS_MAP_ITERATOR_TYPE, JSMapIterator::kSize);
-      map->set_constructor(native_context()->closure());
-      native_context()->set_map_iterator_map(*map);
+      Handle<JSObject> builtins(native_context()->builtins());
+      Handle<JSFunction> map_iterator_function =
+          InstallFunction(builtins, "MapIterator", JS_MAP_ITERATOR_TYPE,
+                          JSMapIterator::kSize,
+                          isolate()->initial_object_prototype(),
+                          Builtins::kIllegal);
+      native_context()->set_map_iterator_map(
+          map_iterator_function->initial_map());
     }
   }

@@ -2013,6 +2021,7 @@
     INSTALL_EXPERIMENTAL_NATIVE(i, symbols, "symbol.js")
     INSTALL_EXPERIMENTAL_NATIVE(i, proxies, "proxy.js")
     INSTALL_EXPERIMENTAL_NATIVE(i, collections, "collection.js")
+    INSTALL_EXPERIMENTAL_NATIVE(i, collections, "collection-iterator.js")
     INSTALL_EXPERIMENTAL_NATIVE(i, generators, "generator.js")
     INSTALL_EXPERIMENTAL_NATIVE(i, iteration, "array-iterator.js")
     INSTALL_EXPERIMENTAL_NATIVE(i, strings, "harmony-string.js")
=======================================
--- /branches/bleeding_edge/src/collection.js   Wed May 21 12:16:47 2014 UTC
+++ /branches/bleeding_edge/src/collection.js   Tue Jun  3 00:34:01 2014 UTC
@@ -79,7 +79,7 @@
     throw MakeTypeError('called_non_callable', [f]);
   }

-  var iterator = %SetCreateIterator(this, ITERATOR_KIND_VALUES);
+  var iterator = new SetIterator(this, ITERATOR_KIND_VALUES);
   var entry;
   var stepping = %_DebugCallbackSupportsStepping(f);
   while (!(entry = %SetIteratorNext(iterator)).done) {
@@ -190,7 +190,7 @@
     throw MakeTypeError('called_non_callable', [f]);
   }

-  var iterator = %MapCreateIterator(this, ITERATOR_KIND_ENTRIES);
+  var iterator = new MapIterator(this, ITERATOR_KIND_ENTRIES);
   var entry;
   var stepping = %_DebugCallbackSupportsStepping(f);
   while (!(entry = %MapIteratorNext(iterator)).done) {
=======================================
--- /branches/bleeding_edge/src/flag-definitions.h Tue May 27 07:48:36 2014 UTC +++ /branches/bleeding_edge/src/flag-definitions.h Tue Jun 3 00:34:01 2014 UTC
@@ -178,6 +178,7 @@
 DEFINE_implication(harmony, harmony_strings)
 DEFINE_implication(harmony, harmony_arrays)
 DEFINE_implication(harmony_modules, harmony_scoping)
+DEFINE_implication(harmony_collections, harmony_symbols)

 DEFINE_implication(harmony, es_staging)
 DEFINE_implication(es_staging, harmony_maths)
=======================================
--- /branches/bleeding_edge/src/macros.py       Thu May 22 15:27:57 2014 UTC
+++ /branches/bleeding_edge/src/macros.py       Tue Jun  3 00:34:01 2014 UTC
@@ -126,6 +126,8 @@
 macro IS_ARRAYBUFFER(arg)       = (%_ClassOf(arg) === 'ArrayBuffer');
 macro IS_DATAVIEW(arg)          = (%_ClassOf(arg) === 'DataView');
 macro IS_GENERATOR(arg)         = (%_ClassOf(arg) === 'Generator');
+macro IS_SET_ITERATOR(arg)      = (%_ClassOf(arg) === 'Set Iterator');
+macro IS_MAP_ITERATOR(arg)      = (%_ClassOf(arg) === 'Map Iterator');
 macro IS_UNDETECTABLE(arg)      = (%_IsUndetectableObject(arg));
 macro FLOOR(arg)                = $floor(arg);

=======================================
--- /branches/bleeding_edge/src/objects-debug.cc Tue May 20 14:22:05 2014 UTC +++ /branches/bleeding_edge/src/objects-debug.cc Tue Jun 3 00:34:01 2014 UTC
@@ -701,8 +701,8 @@
   JSObjectVerify();
   VerifyHeapPointer(table());
   CHECK(table()->IsOrderedHashTable() || table()->IsUndefined());
-  CHECK(index()->IsSmi());
-  CHECK(kind()->IsSmi());
+  CHECK(index()->IsSmi() || index()->IsUndefined());
+  CHECK(kind()->IsSmi() || kind()->IsUndefined());
 }


@@ -711,8 +711,8 @@
   JSObjectVerify();
   VerifyHeapPointer(table());
   CHECK(table()->IsOrderedHashTable() || table()->IsUndefined());
-  CHECK(index()->IsSmi());
-  CHECK(kind()->IsSmi());
+  CHECK(index()->IsSmi() || index()->IsUndefined());
+  CHECK(kind()->IsSmi() || kind()->IsUndefined());
 }


=======================================
--- /branches/bleeding_edge/src/objects-inl.h   Mon Jun  2 11:02:06 2014 UTC
+++ /branches/bleeding_edge/src/objects-inl.h   Tue Jun  3 00:34:01 2014 UTC
@@ -6125,20 +6125,6 @@
   ASSERT(HasDictionaryElements());
   return SeededNumberDictionary::cast(elements());
 }
-
-
-Handle<JSSetIterator> JSSetIterator::Create(
-    Handle<OrderedHashSet> table,
-    int kind) {
- return CreateInternal(table->GetIsolate()->set_iterator_map(), table, kind);
-}
-
-
-Handle<JSMapIterator> JSMapIterator::Create(
-    Handle<OrderedHashMap> table,
-    int kind) {
- return CreateInternal(table->GetIsolate()->map_iterator_map(), table, kind);
-}


 bool Name::IsHashFieldComputed(uint32_t field) {
=======================================
--- /branches/bleeding_edge/src/objects.cc      Mon Jun  2 12:51:19 2014 UTC
+++ /branches/bleeding_edge/src/objects.cc      Tue Jun  3 00:34:01 2014 UTC
@@ -16478,22 +16478,6 @@
   set_table(*table);
   set_index(Smi::FromInt(index));
 }
-
-
-template<class Derived, class TableType>
-Handle<Derived> OrderedHashTableIterator<Derived, TableType>::CreateInternal(
-    Handle<Map> map,
-    Handle<TableType> table,
-    int kind) {
-  Isolate* isolate = table->GetIsolate();
-
-  Handle<Derived> new_iterator = Handle<Derived>::cast(
-      isolate->factory()->NewJSObjectFromMap(map));
-  new_iterator->set_table(*table);
-  new_iterator->set_index(Smi::FromInt(0));
-  new_iterator->set_kind(Smi::FromInt(kind));
-  return new_iterator;
-}


 template Handle<JSObject>
@@ -16503,10 +16487,6 @@
 template void
 OrderedHashTableIterator<JSSetIterator, OrderedHashSet>::Transition();

-template Handle<JSSetIterator>
-OrderedHashTableIterator<JSSetIterator, OrderedHashSet>::CreateInternal(
-    Handle<Map> map, Handle<OrderedHashSet> table, int kind);
-

 template Handle<JSObject>
 OrderedHashTableIterator<JSMapIterator, OrderedHashMap>::Next(
@@ -16515,10 +16495,6 @@
 template void
 OrderedHashTableIterator<JSMapIterator, OrderedHashMap>::Transition();

-template Handle<JSMapIterator>
-OrderedHashTableIterator<JSMapIterator, OrderedHashMap>::CreateInternal(
-    Handle<Map> map, Handle<OrderedHashMap> table, int kind);
-

 Handle<Object> JSSetIterator::ValueForKind(
     Handle<JSSetIterator> iterator, int entry_index) {
=======================================
--- /branches/bleeding_edge/src/objects.h       Mon Jun  2 12:51:19 2014 UTC
+++ /branches/bleeding_edge/src/objects.h       Tue Jun  3 00:34:01 2014 UTC
@@ -9985,10 +9985,6 @@
   // end.
   static Handle<JSObject> Next(Handle<Derived> iterator);

- protected:
-  static Handle<Derived> CreateInternal(
-      Handle<Map> map, Handle<TableType> table, int kind);
-
  private:
// Transitions the iterator to the non obsolote backing store. This is a NOP
   // if the [table] is not obsolete.
@@ -10001,11 +9997,6 @@
 class JSSetIterator: public OrderedHashTableIterator<JSSetIterator,
                                                      OrderedHashSet> {
  public:
-  // Creates a new iterator associated with [table].
- // [kind] needs to be one of the OrderedHashTableIterator Kind enum values.
-  static inline Handle<JSSetIterator> Create(
-      Handle<OrderedHashSet> table, int kind);
-
   // Dispatched behavior.
   DECLARE_PRINTER(JSSetIterator)
   DECLARE_VERIFIER(JSSetIterator)
@@ -10025,11 +10016,6 @@
 class JSMapIterator: public OrderedHashTableIterator<JSMapIterator,
                                                      OrderedHashMap> {
  public:
-  // Creates a new iterator associated with [table].
- // [kind] needs to be one of the OrderedHashTableIterator Kind enum values.
-  static inline Handle<JSMapIterator> Create(
-      Handle<OrderedHashMap> table, int kind);
-
   // Dispatched behavior.
   DECLARE_PRINTER(JSMapIterator)
   DECLARE_VERIFIER(JSMapIterator)
=======================================
--- /branches/bleeding_edge/src/runtime.cc      Mon Jun  2 12:51:19 2014 UTC
+++ /branches/bleeding_edge/src/runtime.cc      Tue Jun  3 00:34:01 2014 UTC
@@ -1584,15 +1584,19 @@
 }


-RUNTIME_FUNCTION(Runtime_SetCreateIterator) {
+RUNTIME_FUNCTION(Runtime_SetIteratorInitialize) {
   HandleScope scope(isolate);
-  ASSERT(args.length() == 2);
-  CONVERT_ARG_HANDLE_CHECKED(JSSet, holder, 0);
-  CONVERT_SMI_ARG_CHECKED(kind, 1)
+  ASSERT(args.length() == 3);
+  CONVERT_ARG_HANDLE_CHECKED(JSSetIterator, holder, 0);
+  CONVERT_ARG_HANDLE_CHECKED(JSSet, set, 1);
+  CONVERT_SMI_ARG_CHECKED(kind, 2)
   RUNTIME_ASSERT(kind == JSSetIterator::kKindValues ||
                  kind == JSSetIterator::kKindEntries);
-  Handle<OrderedHashSet> table(OrderedHashSet::cast(holder->table()));
-  return *JSSetIterator::Create(table, kind);
+  Handle<OrderedHashSet> table(OrderedHashSet::cast(set->table()));
+  holder->set_table(*table);
+  holder->set_index(Smi::FromInt(0));
+  holder->set_kind(Smi::FromInt(kind));
+  return isolate->heap()->undefined_value();
 }


@@ -1683,16 +1687,20 @@
 }


-RUNTIME_FUNCTION(Runtime_MapCreateIterator) {
+RUNTIME_FUNCTION(Runtime_MapIteratorInitialize) {
   HandleScope scope(isolate);
-  ASSERT(args.length() == 2);
-  CONVERT_ARG_HANDLE_CHECKED(JSMap, holder, 0);
-  CONVERT_SMI_ARG_CHECKED(kind, 1)
+  ASSERT(args.length() == 3);
+  CONVERT_ARG_HANDLE_CHECKED(JSMapIterator, holder, 0);
+  CONVERT_ARG_HANDLE_CHECKED(JSMap, map, 1);
+  CONVERT_SMI_ARG_CHECKED(kind, 2)
   RUNTIME_ASSERT(kind == JSMapIterator::kKindKeys
       || kind == JSMapIterator::kKindValues
       || kind == JSMapIterator::kKindEntries);
-  Handle<OrderedHashMap> table(OrderedHashMap::cast(holder->table()));
-  return *JSMapIterator::Create(table, kind);
+  Handle<OrderedHashMap> table(OrderedHashMap::cast(map->table()));
+  holder->set_table(*table);
+  holder->set_index(Smi::FromInt(0));
+  holder->set_kind(Smi::FromInt(kind));
+  return isolate->heap()->undefined_value();
 }


=======================================
--- /branches/bleeding_edge/src/runtime.h       Fri May 30 17:07:38 2014 UTC
+++ /branches/bleeding_edge/src/runtime.h       Tue Jun  3 00:34:01 2014 UTC
@@ -272,8 +272,8 @@
   F(SetDelete, 2, 1) \
   F(SetClear, 1, 1) \
   F(SetGetSize, 1, 1) \
-  F(SetCreateIterator, 2, 1) \
   \
+  F(SetIteratorInitialize, 3, 1) \
   F(SetIteratorNext, 1, 1) \
   \
   /* Harmony maps */ \
@@ -284,8 +284,8 @@
   F(MapClear, 1, 1) \
   F(MapSet, 3, 1) \
   F(MapGetSize, 1, 1) \
-  F(MapCreateIterator, 2, 1) \
   \
+  F(MapIteratorInitialize, 3, 1) \
   F(MapIteratorNext, 1, 1) \
   \
   /* Harmony weak maps and sets */ \
=======================================
--- /branches/bleeding_edge/test/cctest/test-api.cc Wed May 28 18:40:04 2014 UTC +++ /branches/bleeding_edge/test/cctest/test-api.cc Tue Jun 3 00:34:01 2014 UTC
@@ -21466,6 +21466,7 @@

 THREADED_TEST(Regress2535) {
   i::FLAG_harmony_collections = true;
+  i::FLAG_harmony_symbols = true;
   LocalContext context;
   v8::HandleScope scope(context->GetIsolate());
   Local<Value> set_value = CompileRun("new Set();");
=======================================
--- /branches/bleeding_edge/test/cctest/test-ordered-hash-table.cc Wed May 21 12:16:47 2014 UTC +++ /branches/bleeding_edge/test/cctest/test-ordered-hash-table.cc Tue Jun 3 00:34:01 2014 UTC
@@ -35,21 +35,6 @@
 namespace {

 using namespace v8::internal;
-
-
-void CheckIterResultObject(Isolate* isolate,
-                           Handle<JSObject> result,
-                           Handle<Object> value,
-                           bool done) {
-  Handle<Object> value_object =
-      Object::GetProperty(isolate, result, "value").ToHandleChecked();
-  Handle<Object> done_object =
-      Object::GetProperty(isolate, result, "done").ToHandleChecked();
-
-  CHECK_EQ(*value_object, *value);
-  CHECK(done_object->IsBoolean());
-  CHECK_EQ(done_object->BooleanValue(), done);
-}


 TEST(Set) {
@@ -64,11 +49,6 @@
   CHECK_EQ(0, ordered_set->NumberOfElements());
   CHECK_EQ(0, ordered_set->NumberOfDeletedElements());

-  Handle<JSSetIterator> value_iterator =
-      JSSetIterator::Create(ordered_set, JSSetIterator::kKindValues);
-  Handle<JSSetIterator> value_iterator_2 =
-      JSSetIterator::Create(ordered_set, JSSetIterator::kKindValues);
-
   Handle<Map> map = factory->NewMap(JS_OBJECT_TYPE, JSObject::kHeaderSize);
   Handle<JSObject> obj = factory->NewJSObjectFromMap(map);
   CHECK(!ordered_set->Contains(obj));
@@ -97,18 +77,6 @@
   CHECK(ordered_set->Contains(obj2));
   CHECK(ordered_set->Contains(obj3));

-  // Test iteration
-  CheckIterResultObject(
-      isolate, JSSetIterator::Next(value_iterator), obj1, false);
-  CheckIterResultObject(
-      isolate, JSSetIterator::Next(value_iterator), obj2, false);
-  CheckIterResultObject(
-      isolate, JSSetIterator::Next(value_iterator), obj3, false);
-  CheckIterResultObject(isolate,
-                        JSSetIterator::Next(value_iterator),
-                        factory->undefined_value(),
-                        true);
-
   // Test growth
   ordered_set = OrderedHashSet::Add(ordered_set, obj);
   Handle<JSObject> obj4 = factory->NewJSObjectFromMap(map);
@@ -122,22 +90,6 @@
   CHECK_EQ(0, ordered_set->NumberOfDeletedElements());
   CHECK_EQ(4, ordered_set->NumberOfBuckets());

-  // Test iteration after growth
-  CheckIterResultObject(
-      isolate, JSSetIterator::Next(value_iterator_2), obj1, false);
-  CheckIterResultObject(
-      isolate, JSSetIterator::Next(value_iterator_2), obj2, false);
-  CheckIterResultObject(
-      isolate, JSSetIterator::Next(value_iterator_2), obj3, false);
-  CheckIterResultObject(
-      isolate, JSSetIterator::Next(value_iterator_2), obj, false);
-  CheckIterResultObject(
-      isolate, JSSetIterator::Next(value_iterator_2), obj4, false);
-  CheckIterResultObject(isolate,
-                        JSSetIterator::Next(value_iterator_2),
-                        factory->undefined_value(),
-                        true);
-
   // Test shrinking
   ordered_set = OrderedHashSet::Remove(ordered_set, obj, &was_present);
   CHECK(was_present);
@@ -164,11 +116,6 @@
   CHECK_EQ(0, ordered_map->NumberOfElements());
   CHECK_EQ(0, ordered_map->NumberOfDeletedElements());

-  Handle<JSMapIterator> value_iterator =
-      JSMapIterator::Create(ordered_map, JSMapIterator::kKindValues);
-  Handle<JSMapIterator> key_iterator =
-      JSMapIterator::Create(ordered_map, JSMapIterator::kKindKeys);
-
   Handle<Map> map = factory->NewMap(JS_OBJECT_TYPE, JSObject::kHeaderSize);
   Handle<JSObject> obj = factory->NewJSObjectFromMap(map);
   Handle<JSObject> val = factory->NewJSObjectFromMap(map);
@@ -196,18 +143,6 @@
   CHECK(ordered_map->Lookup(obj2)->SameValue(*val2));
   CHECK(ordered_map->Lookup(obj3)->SameValue(*val3));

-  // Test iteration
-  CheckIterResultObject(
-      isolate, JSMapIterator::Next(value_iterator), val1, false);
-  CheckIterResultObject(
-      isolate, JSMapIterator::Next(value_iterator), val2, false);
-  CheckIterResultObject(
-      isolate, JSMapIterator::Next(value_iterator), val3, false);
-  CheckIterResultObject(isolate,
-                        JSMapIterator::Next(value_iterator),
-                        factory->undefined_value(),
-                        true);
-
   // Test growth
   ordered_map = OrderedHashMap::Put(ordered_map, obj, val);
   Handle<JSObject> obj4 = factory->NewJSObjectFromMap(map);
@@ -221,22 +156,6 @@
   CHECK_EQ(5, ordered_map->NumberOfElements());
   CHECK_EQ(4, ordered_map->NumberOfBuckets());

-  // Test iteration after growth
-  CheckIterResultObject(
-      isolate, JSMapIterator::Next(key_iterator), obj1, false);
-  CheckIterResultObject(
-      isolate, JSMapIterator::Next(key_iterator), obj2, false);
-  CheckIterResultObject(
-      isolate, JSMapIterator::Next(key_iterator), obj3, false);
-  CheckIterResultObject(
-      isolate, JSMapIterator::Next(key_iterator), obj, false);
-  CheckIterResultObject(
-      isolate, JSMapIterator::Next(key_iterator), obj4, false);
-  CheckIterResultObject(isolate,
-                        JSMapIterator::Next(key_iterator),
-                        factory->undefined_value(),
-                        true);
-
   // Test shrinking
   ordered_map = OrderedHashMap::Put(
       ordered_map, obj, factory->the_hole_value());
=======================================
--- /branches/bleeding_edge/test/mjsunit/regress/regress-3281.js Tue Apr 22 18:14:46 2014 UTC +++ /branches/bleeding_edge/test/mjsunit/regress/regress-3281.js Tue Jun 3 00:34:01 2014 UTC
@@ -2,12 +2,11 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.

-// Flags: --allow-natives-syntax --harmony-collections
-
+// Flags: --harmony-collections --expose-natives-as=builtins
 // Should not crash or raise an exception.

 var s = new Set();
-var setIterator = %SetCreateIterator(s, 2);
+var setIterator = new builtins.SetIterator(s, 2);

 var m = new Map();
-var mapIterator = %MapCreateIterator(m, 2);
+var mapIterator = new builtins.MapIterator(m, 2);
=======================================
--- /branches/bleeding_edge/test/mjsunit/runtime-gen/mapiteratornext.js Thu May 8 13:11:59 2014 UTC +++ /branches/bleeding_edge/test/mjsunit/runtime-gen/mapiteratornext.js Tue Jun 3 00:34:01 2014 UTC
@@ -1,5 +1,5 @@
 // Copyright 2014 the V8 project authors. All rights reserved.
 // AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
 // Flags: --allow-natives-syntax --harmony
-var _holder = %MapCreateIterator(new Map(), 3);
+var _holder = new Map().entries();
 %MapIteratorNext(_holder);
=======================================
--- /branches/bleeding_edge/test/mjsunit/runtime-gen/setiteratornext.js Thu May 8 13:11:59 2014 UTC +++ /branches/bleeding_edge/test/mjsunit/runtime-gen/setiteratornext.js Tue Jun 3 00:34:01 2014 UTC
@@ -1,5 +1,5 @@
 // Copyright 2014 the V8 project authors. All rights reserved.
 // AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
 // Flags: --allow-natives-syntax --harmony
-var _holder = %SetCreateIterator(new Set(), 2);
+var _holder = new Set().values();
 %SetIteratorNext(_holder);
=======================================
--- /branches/bleeding_edge/tools/generate-runtime-tests.py Fri May 30 17:07:38 2014 UTC +++ /branches/bleeding_edge/tools/generate-runtime-tests.py Tue Jun 3 00:34:01 2014 UTC
@@ -51,7 +51,7 @@
 EXPECTED_FUZZABLE_COUNT = 325
 EXPECTED_CCTEST_COUNT = 6
 EXPECTED_UNKNOWN_COUNT = 5
-EXPECTED_BUILTINS_COUNT = 782
+EXPECTED_BUILTINS_COUNT = 797


 # Don't call these at all.
@@ -159,7 +159,7 @@
   "RegExpExecMultiple": [None, None, "['a']", "['a']", None],
   "SetAccessorProperty": [None, None, "undefined", "undefined", None, None,
                           None],
-  "SetCreateIterator": [None, "2", None],
+  "SetIteratorInitialize": [None, None, "2", None],
   "SetDebugEventListener": ["undefined", None, None],
   "SetFunctionBreakPoint": [None, 200, None, None],
   "StringBuilderConcat": ["[1, 2, 3]", 3, None, None],
@@ -523,8 +523,8 @@
   def _JSMapIterator(self, name, recursion_budget):
     map_name = name + "_map"
     result = self._JSMap(map_name, recursion_budget)
-    iterator_type = random.randint(1, 3)
-    return (result + self._Variable(name, "%%MapCreateIterator(%s, %d)" %
+    iterator_type = random.choice(['keys', 'values', 'entries'])
+    return (result + self._Variable(name, "%s.%s()" %
                                           (map_name, iterator_type)))

   def _JSProxy(self, name, recursion_budget):
@@ -552,8 +552,8 @@
   def _JSSetIterator(self, name, recursion_budget):
     set_name = name + "_set"
     result = self._JSSet(set_name, recursion_budget)
-    iterator_type = random.randint(2, 3)
-    return (result + self._Variable(name, "%%SetCreateIterator(%s, %d)" %
+    iterator_type = random.choice(['values', 'entries'])
+    return (result + self._Variable(name, "%s.%s()" %
                                           (set_name, iterator_type)))

   def _JSTypedArray(self, name, recursion_budget):
@@ -666,13 +666,13 @@
                         _JSFunctionProxy],
"JSGeneratorObject": ["(function*(){ yield 1; })()", _JSGeneratorObject],
     "JSMap": ["new Map()", _JSMap],
-    "JSMapIterator": ["%MapCreateIterator(new Map(), 3)", _JSMapIterator],
+    "JSMapIterator": ["new Map().entries()", _JSMapIterator],
     "JSObject": ["new Object()", _JSObject],
     "JSProxy": ["Proxy.create({})", _JSProxy],
     "JSReceiver": ["new Object()", _JSReceiver],
     "JSRegExp": ["/ab/g", _JSRegExp],
     "JSSet": ["new Set()", _JSSet],
-    "JSSetIterator": ["%SetCreateIterator(new Set(), 2)", _JSSetIterator],
+    "JSSetIterator": ["new Set().values()", _JSSetIterator],
     "JSTypedArray": ["new Int32Array(2)", _JSTypedArray],
     "JSValue": ["new String('foo')", _JSValue],
     "JSWeakCollection": ["new WeakMap()", _JSWeakCollection],
=======================================
--- /branches/bleeding_edge/tools/gyp/v8.gyp    Thu May 29 04:13:50 2014 UTC
+++ /branches/bleeding_edge/tools/gyp/v8.gyp    Tue Jun  3 00:34:01 2014 UTC
@@ -1129,6 +1129,7 @@
           '../../src/symbol.js',
           '../../src/proxy.js',
           '../../src/collection.js',
+          '../../src/collection-iterator.js',
           '../../src/generator.js',
           '../../src/array-iterator.js',
           '../../src/harmony-string.js',

--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
--- You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.

Reply via email to