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.