Revision: 15620
Author:   [email protected]
Date:     Thu Jul 11 04:20:54 2013
Log:      This adds the following array iterator methods:

Array.prototype.values
Array.prototype.keys
Array.prototype.entries

These all return an Array Iterator object which has a next
method.

http://people.mozilla.org/~jorendorff/es6-draft.html#sec-15.4.5

BUG=v8:2722
[email protected]

Review URL: https://codereview.chromium.org/16848004
http://code.google.com/p/v8/source/detail?r=15620

Added:
 /branches/bleeding_edge/src/array-iterator.js
 /branches/bleeding_edge/test/mjsunit/harmony/array-iterator.js
Modified:
 /branches/bleeding_edge/src/bootstrapper.cc
 /branches/bleeding_edge/tools/gyp/v8.gyp

=======================================
--- /dev/null
+++ /branches/bleeding_edge/src/array-iterator.js       Thu Jul 11 04:20:54 2013
@@ -0,0 +1,127 @@
+// Copyright 2013 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+//       notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+//       copyright notice, this list of conditions and the following
+//       disclaimer in the documentation and/or other materials provided
+//       with the distribution.
+//     * Neither the name of Google Inc. nor the names of its
+//       contributors may be used to endorse or promote products derived
+//       from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// 'AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+'use strict';
+
+// This file relies on the fact that the following declaration has been made
+// in runtime.js:
+// var $Array = global.Array;
+
+var ARRAY_ITERATOR_KIND_KEYS = 1;
+var ARRAY_ITERATOR_KIND_VALUES = 2;
+var ARRAY_ITERATOR_KIND_ENTRIES = 3;
+// The spec draft also has "sparse" but it is never used.
+
+var iteratorObjectSymbol = %CreateSymbol(void 0);
+var arrayIteratorNextIndexSymbol = %CreateSymbol(void 0);
+var arrayIterationKindSymbol = %CreateSymbol(void 0);
+
+function ArrayIterator() {}
+
+// 15.4.5.1 CreateArrayIterator Abstract Operation
+function CreateArrayIterator(array, kind) {
+  var object = ToObject(array);
+  var iterator = new ArrayIterator;
+  iterator[iteratorObjectSymbol] = object;
+  iterator[arrayIteratorNextIndexSymbol] = 0;
+  iterator[arrayIterationKindSymbol] = kind;
+  return iterator;
+}
+
+// 15.19.4.3.4 CreateItrResultObject
+function CreateIteratorResultObject(value, done) {
+  return {value: value, done: done};
+}
+
+// 15.4.5.2.2 ArrayIterator.prototype.next( )
+function ArrayIteratorNext() {
+  var iterator = ToObject(this);
+  var array = iterator[iteratorObjectSymbol];
+  if (!array) {
+    throw MakeTypeError('incompatible_method_receiver',
+                        ['Array Iterator.prototype.next']);
+  }
+
+  var index = iterator[arrayIteratorNextIndexSymbol];
+  var itemKind = iterator[arrayIterationKindSymbol];
+  var length = TO_UINT32(array.length);
+
+  // "sparse" is never used.
+
+  if (index >= length) {
+    iterator[arrayIteratorNextIndexSymbol] = 1 / 0; // Infinity
+    return CreateIteratorResultObject(void 0, true);
+  }
+
+  var elementKey = ToString(index);
+  iterator[arrayIteratorNextIndexSymbol] = index + 1;
+
+  if (itemKind == ARRAY_ITERATOR_KIND_VALUES)
+    return CreateIteratorResultObject(array[elementKey], false);
+
+  if (itemKind == ARRAY_ITERATOR_KIND_ENTRIES)
+ return CreateIteratorResultObject([elementKey, array[elementKey]], false);
+
+  return CreateIteratorResultObject(elementKey, false);
+}
+
+function ArrayEntries() {
+  return CreateArrayIterator(this, ARRAY_ITERATOR_KIND_ENTRIES);
+}
+
+function ArrayValues() {
+  return CreateArrayIterator(this, ARRAY_ITERATOR_KIND_VALUES);
+}
+
+function ArrayKeys() {
+  return CreateArrayIterator(this, ARRAY_ITERATOR_KIND_KEYS);
+}
+
+function SetUpArrayIterator() {
+  %CheckIsBootstrapping();
+
+  %FunctionSetInstanceClassName(ArrayIterator, 'Array Iterator');
+  %FunctionSetReadOnlyPrototype(ArrayIterator);
+
+  InstallFunctions(ArrayIterator.prototype, DONT_ENUM, $Array(
+    'next', ArrayIteratorNext
+  ));
+}
+
+SetUpArrayIterator();
+
+function ExtendArrayPrototype() {
+  %CheckIsBootstrapping();
+
+  InstallFunctions($Array.prototype, DONT_ENUM, $Array(
+    'entries', ArrayEntries,
+    'values', ArrayValues,
+    'keys', ArrayKeys
+  ));
+}
+
+ExtendArrayPrototype();
=======================================
--- /dev/null
+++ /branches/bleeding_edge/test/mjsunit/harmony/array-iterator.js Thu Jul 11 04:20:54 2013
@@ -0,0 +1,195 @@
+// Copyright 2013 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+//       notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+//       copyright notice, this list of conditions and the following
+//       disclaimer in the documentation and/or other materials provided
+//       with the distribution.
+//     * Neither the name of Google Inc. nor the names of its
+//       contributors may be used to endorse or promote products derived
+//       from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Flags: --harmony-iteration --allow-natives-syntax
+
+function TestArrayPrototype() {
+  assertTrue(Array.prototype.hasOwnProperty('entries'));
+  assertTrue(Array.prototype.hasOwnProperty('values'));
+  assertTrue(Array.prototype.hasOwnProperty('keys'));
+
+  assertFalse(Array.prototype.propertyIsEnumerable('entries'));
+  assertFalse(Array.prototype.propertyIsEnumerable('values'));
+  assertFalse(Array.prototype.propertyIsEnumerable('keys'));
+}
+TestArrayPrototype();
+
+function assertIteratorResult(value, done, result) {
+  assertEquals({ value: value, done: done}, result);
+}
+
+function TestValues() {
+  var array = ['a', 'b', 'c'];
+  var iterator = array.values();
+  assertIteratorResult('a', false, iterator.next());
+  assertIteratorResult('b', false, iterator.next());
+  assertIteratorResult('c', false, iterator.next());
+  assertIteratorResult(void 0, true, iterator.next());
+
+  array.push('d');
+  assertIteratorResult(void 0, true, iterator.next());
+}
+TestValues();
+
+function TestValuesMutate() {
+  var array = ['a', 'b', 'c'];
+  var iterator = array.values();
+  assertIteratorResult('a', false, iterator.next());
+  assertIteratorResult('b', false, iterator.next());
+  assertIteratorResult('c', false, iterator.next());
+  array.push('d');
+  assertIteratorResult('d', false, iterator.next());
+  assertIteratorResult(void 0, true, iterator.next());
+}
+TestValuesMutate();
+
+function TestKeys() {
+  var array = ['a', 'b', 'c'];
+  var iterator = array.keys();
+  assertIteratorResult('0', false, iterator.next());
+  assertIteratorResult('1', false, iterator.next());
+  assertIteratorResult('2', false, iterator.next());
+  assertIteratorResult(void 0, true, iterator.next());
+
+  array.push('d');
+  assertIteratorResult(void 0, true, iterator.next());
+}
+TestKeys();
+
+function TestKeysMutate() {
+  var array = ['a', 'b', 'c'];
+  var iterator = array.keys();
+  assertIteratorResult('0', false, iterator.next());
+  assertIteratorResult('1', false, iterator.next());
+  assertIteratorResult('2', false, iterator.next());
+  array.push('d');
+  assertIteratorResult('3', false, iterator.next());
+  assertIteratorResult(void 0, true, iterator.next());
+}
+TestKeysMutate();
+
+function TestEntries() {
+  var array = ['a', 'b', 'c'];
+  var iterator = array.entries();
+  assertIteratorResult(['0', 'a'], false, iterator.next());
+  assertIteratorResult(['1', 'b'], false, iterator.next());
+  assertIteratorResult(['2', 'c'], false, iterator.next());
+  assertIteratorResult(void 0, true, iterator.next());
+
+  array.push('d');
+  assertIteratorResult(void 0, true, iterator.next());
+}
+TestEntries();
+
+function TestEntriesMutate() {
+  var array = ['a', 'b', 'c'];
+  var iterator = array.entries();
+  assertIteratorResult(['0', 'a'], false, iterator.next());
+  assertIteratorResult(['1', 'b'], false, iterator.next());
+  assertIteratorResult(['2', 'c'], false, iterator.next());
+  array.push('d');
+  assertIteratorResult(['3', 'd'], false, iterator.next());
+  assertIteratorResult(void 0, true, iterator.next());
+}
+TestEntriesMutate();
+
+function TestArrayIteratorPrototype() {
+  var array = [];
+  var iterator = array.values();
+
+  var ArrayIterator = iterator.constructor;
+  assertEquals(ArrayIterator.prototype, array.values().__proto__);
+  assertEquals(ArrayIterator.prototype, array.keys().__proto__);
+  assertEquals(ArrayIterator.prototype, array.entries().__proto__);
+
+  assertEquals(Object.prototype, ArrayIterator.prototype.__proto__);
+
+  assertEquals('Array Iterator', %_ClassOf(array.values()));
+  assertEquals('Array Iterator', %_ClassOf(array.keys()));
+  assertEquals('Array Iterator', %_ClassOf(array.entries()));
+
+  var prototypeDescriptor =
+      Object.getOwnPropertyDescriptor(ArrayIterator, 'prototype');
+  assertFalse(prototypeDescriptor.configurable);
+  assertFalse(prototypeDescriptor.enumerable);
+  assertFalse(prototypeDescriptor.writable);
+}
+TestArrayIteratorPrototype();
+
+function TestForArrayValues() {
+  var buffer = [];
+  var array = [0, 'a', true, false, null, /* hole */, undefined, NaN];
+  var i = 0;
+  for (var value of array.values()) {
+    buffer[i++] = value;
+  }
+
+  assertEquals(8, buffer.length);
+
+  for (var i = 0; i < buffer.length - 1; i++) {
+    assertEquals(array[i], buffer[i]);
+  }
+  assertTrue(isNaN(buffer[buffer.length - 1]));
+}
+TestForArrayValues();
+
+function TestForArrayKeys() {
+  var buffer = [];
+  var array = [0, 'a', true, false, null, /* hole */, undefined, NaN];
+  var i = 0;
+  for (var key of array.keys()) {
+    buffer[i++] = key;
+  }
+
+  assertEquals(8, buffer.length);
+
+  for (var i = 0; i < buffer.length; i++) {
+    assertEquals(String(i), buffer[i]);
+  }
+}
+TestForArrayKeys();
+
+function TestForArrayEntries() {
+  var buffer = [];
+  var array = [0, 'a', true, false, null, /* hole */, undefined, NaN];
+  var i = 0;
+  for (var entry of array.entries()) {
+    buffer[i++] = entry;
+  }
+
+  assertEquals(8, buffer.length);
+
+  for (var i = 0; i < buffer.length - 1; i++) {
+    assertEquals(array[i], buffer[i][1]);
+  }
+  assertTrue(isNaN(buffer[buffer.length - 1][1]));
+
+  for (var i = 0; i < buffer.length; i++) {
+    assertEquals(String(i), buffer[i][0]);
+  }
+}
+TestForArrayEntries();
=======================================
--- /branches/bleeding_edge/src/bootstrapper.cc Fri Jul  5 03:12:36 2013
+++ /branches/bleeding_edge/src/bootstrapper.cc Thu Jul 11 04:20:54 2013
@@ -2072,6 +2072,11 @@
                "native generator.js") == 0) {
       if (!CompileExperimentalBuiltin(isolate(), i)) return false;
     }
+    if (FLAG_harmony_iteration &&
+        strcmp(ExperimentalNatives::GetScriptName(i).start(),
+               "native array-iterator.js") == 0) {
+      if (!CompileExperimentalBuiltin(isolate(), i)) return false;
+    }
   }

   InstallExperimentalNativeFunctions();
=======================================
--- /branches/bleeding_edge/tools/gyp/v8.gyp    Thu Jul 11 04:01:00 2013
+++ /branches/bleeding_edge/tools/gyp/v8.gyp    Thu Jul 11 04:20:54 2013
@@ -900,7 +900,8 @@
           '../../src/object-observe.js',
           '../../src/arraybuffer.js',
           '../../src/typedarray.js',
-          '../../src/generator.js'
+          '../../src/generator.js',
+          '../../src/array-iterator.js'
         ],
         'i18n_library_files': [
           '../../src/extensions/i18n/header.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/groups/opt_out.


Reply via email to