Revision: 21994
Author: [email protected]
Date: Wed Jun 25 07:43:14 2014 UTC
Log: Add @@iterator support for strings
[email protected]
BUG=
Review URL: https://codereview.chromium.org/335423002
http://code.google.com/p/v8/source/detail?r=21994
Added:
/branches/bleeding_edge/src/string-iterator.js
/branches/bleeding_edge/test/mjsunit/harmony/string-iterator.js
Modified:
/branches/bleeding_edge/src/bootstrapper.cc
/branches/bleeding_edge/test/mjsunit/harmony/iteration-semantics.js
/branches/bleeding_edge/tools/generate-runtime-tests.py
/branches/bleeding_edge/tools/gyp/v8.gyp
=======================================
--- /dev/null
+++ /branches/bleeding_edge/src/string-iterator.js Wed Jun 25 07:43:14 2014
UTC
@@ -0,0 +1,106 @@
+// 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 $String = global.String;
+
+
+var stringIteratorIteratedStringSymbol =
+ GLOBAL_PRIVATE("StringIterator#iteratedString");
+var stringIteratorNextIndexSymbol = GLOBAL_PRIVATE("StringIterator#next");
+
+
+function StringIterator() {}
+
+
+// 21.1.5.1 CreateStringIterator Abstract Operation
+function CreateStringIterator(string) {
+ var s = TO_STRING_INLINE(string);
+ var iterator = new StringIterator;
+ SET_PRIVATE(iterator, stringIteratorIteratedStringSymbol, s);
+ SET_PRIVATE(iterator, stringIteratorNextIndexSymbol, 0);
+ return iterator;
+}
+
+
+// 21.1.5.2.2 %StringIteratorPrototype%[@@iterator]
+function StringIteratorIterator() {
+ return this;
+}
+
+
+// 21.1.5.2.1 %StringIteratorPrototype%.next( )
+function StringIteratorNext() {
+ var iterator = ToObject(this);
+
+ if (!HAS_PRIVATE(iterator, stringIteratorIteratedStringSymbol)) {
+ throw MakeTypeError('incompatible_method_receiver',
+ ['String Iterator.prototype.next']);
+ }
+
+ var s = GET_PRIVATE(iterator, stringIteratorIteratedStringSymbol);
+ if (IS_UNDEFINED(s)) {
+ return CreateIteratorResultObject(UNDEFINED, true);
+ }
+
+ var position = GET_PRIVATE(iterator, stringIteratorNextIndexSymbol);
+ var length = TO_UINT32(s.length);
+
+ if (position >= length) {
+ SET_PRIVATE(iterator, stringIteratorIteratedStringSymbol, UNDEFINED);
+ return CreateIteratorResultObject(UNDEFINED, true);
+ }
+
+ var first = %_StringCharCodeAt(s, position);
+ var resultString = %_StringCharFromCode(first);
+ position++;
+
+ if (first >= 0xD800 && first <= 0xDBFF && position < length) {
+ var second = %_StringCharCodeAt(s, position);
+ if (second >= 0xDC00 && second <= 0xDFFF) {
+ resultString += %_StringCharFromCode(second);
+ position++;
+ }
+ }
+
+ SET_PRIVATE(iterator, stringIteratorNextIndexSymbol, position);
+
+ return CreateIteratorResultObject(resultString, false);
+}
+
+
+function SetUpStringIterator() {
+ %CheckIsBootstrapping();
+
+ %FunctionSetPrototype(StringIterator, new $Object());
+ %FunctionSetInstanceClassName(StringIterator, 'String Iterator');
+
+ InstallFunctions(StringIterator.prototype, DONT_ENUM, $Array(
+ 'next', StringIteratorNext
+ ));
+ %FunctionSetName(StringIteratorIterator, '[Symbol.iterator]');
+ %SetProperty(StringIterator.prototype, symbolIterator,
StringIteratorIterator,
+ DONT_ENUM);
+}
+SetUpStringIterator();
+
+
+// 21.1.3.27 String.prototype [ @@iterator ]( )
+function StringPrototypeIterator() {
+ return CreateStringIterator(this);
+}
+
+
+function ExtendStringPrototypeWithIterator() {
+ %CheckIsBootstrapping();
+
+ %FunctionSetName(StringPrototypeIterator, '[Symbol.iterator]');
+ %SetProperty($String.prototype, symbolIterator, StringPrototypeIterator,
+ DONT_ENUM);
+}
+ExtendStringPrototypeWithIterator();
=======================================
--- /dev/null
+++ /branches/bleeding_edge/test/mjsunit/harmony/string-iterator.js Wed Jun
25 07:43:14 2014 UTC
@@ -0,0 +1,91 @@
+// 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-iteration
+
+
+function TestStringPrototypeIterator() {
+ assertTrue(String.prototype.hasOwnProperty(Symbol.iterator));
+ assertFalse("".hasOwnProperty(Symbol.iterator));
+ assertFalse("".propertyIsEnumerable(Symbol.iterator));
+}
+TestStringPrototypeIterator();
+
+
+function assertIteratorResult(value, done, result) {
+ assertEquals({value: value, done: done}, result);
+}
+
+
+function TestManualIteration() {
+ var string = "abc";
+ var iterator = string[Symbol.iterator]();
+ assertIteratorResult('a', false, iterator.next());
+ assertIteratorResult('b', false, iterator.next());
+ assertIteratorResult('c', false, iterator.next());
+ assertIteratorResult(void 0, true, iterator.next());
+ assertIteratorResult(void 0, true, iterator.next());
+}
+TestManualIteration();
+
+
+function TestSurrogatePairs() {
+ var lo = "\uD834";
+ var hi = "\uDF06";
+ var pair = lo + hi;
+ var string = "abc" + pair + "def" + lo + pair + hi + lo;
+ var iterator = string[Symbol.iterator]();
+ assertIteratorResult('a', false, iterator.next());
+ assertIteratorResult('b', false, iterator.next());
+ assertIteratorResult('c', false, iterator.next());
+ assertIteratorResult(pair, false, iterator.next());
+ assertIteratorResult('d', false, iterator.next());
+ assertIteratorResult('e', false, iterator.next());
+ assertIteratorResult('f', false, iterator.next());
+ assertIteratorResult(lo, false, iterator.next());
+ assertIteratorResult(pair, false, iterator.next());
+ assertIteratorResult(hi, false, iterator.next());
+ assertIteratorResult(lo, false, iterator.next());
+ assertIteratorResult(void 0, true, iterator.next());
+ assertIteratorResult(void 0, true, iterator.next());
+}
+TestSurrogatePairs();
+
+
+function TestStringIteratorPrototype() {
+ var iterator = ""[Symbol.iterator]();
+ var StringIteratorPrototype = iterator.__proto__;
+ assertFalse(StringIteratorPrototype.hasOwnProperty('constructor'));
+ assertEquals(StringIteratorPrototype.__proto__, Object.prototype);
+ assertArrayEquals(['next'],
+ Object.getOwnPropertyNames(StringIteratorPrototype));
+ assertEquals('[object String Iterator]', "" + iterator);
+}
+TestStringIteratorPrototype();
+
+
+function TestForOf() {
+ var lo = "\uD834";
+ var hi = "\uDF06";
+ var pair = lo + hi;
+ var string = "abc" + pair + "def" + lo + pair + hi + lo;
+ var expected = ['a', 'b', 'c', pair, 'd', 'e', 'f', lo, pair, hi, lo];
+
+ var i = 0;
+ for (var char of string) {
+ assertEquals(expected[i++], char);
+ }
+
+ assertEquals(expected.length, i);
+}
+TestForOf();
+
+
+function TestNonOwnSlots() {
+ var iterator = ""[Symbol.iterator]();
+ var object = {__proto__: iterator};
+
+ assertThrows(function() { object.next(); }, TypeError);
+}
+TestNonOwnSlots();
=======================================
--- /branches/bleeding_edge/src/bootstrapper.cc Tue Jun 24 14:53:48 2014 UTC
+++ /branches/bleeding_edge/src/bootstrapper.cc Wed Jun 25 07:43:14 2014 UTC
@@ -2052,6 +2052,7 @@
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, iteration, "string-iterator.js")
INSTALL_EXPERIMENTAL_NATIVE(i, strings, "harmony-string.js")
INSTALL_EXPERIMENTAL_NATIVE(i, arrays, "harmony-array.js")
INSTALL_EXPERIMENTAL_NATIVE(i, maths, "harmony-math.js")
=======================================
--- /branches/bleeding_edge/test/mjsunit/harmony/iteration-semantics.js Thu
Jun 12 17:31:54 2014 UTC
+++ /branches/bleeding_edge/test/mjsunit/harmony/iteration-semantics.js Wed
Jun 25 07:43:14 2014 UTC
@@ -219,7 +219,7 @@
// Other non-iterators do cause an error.
assertThrows('fold(sum, 0, unreachable({}))', TypeError);
-assertThrows('fold(sum, 0, unreachable("foo"))', TypeError);
+assertThrows('fold(sum, 0, unreachable(false))', TypeError);
assertThrows('fold(sum, 0, unreachable(37))', TypeError);
// "next" is looked up each time.
=======================================
--- /branches/bleeding_edge/tools/generate-runtime-tests.py Mon Jun 23
18:05:57 2014 UTC
+++ /branches/bleeding_edge/tools/generate-runtime-tests.py Wed Jun 25
07:43:14 2014 UTC
@@ -51,7 +51,7 @@
EXPECTED_FUZZABLE_COUNT = 326
EXPECTED_CCTEST_COUNT = 6
EXPECTED_UNKNOWN_COUNT = 4
-EXPECTED_BUILTINS_COUNT = 800
+EXPECTED_BUILTINS_COUNT = 807
# Don't call these at all.
=======================================
--- /branches/bleeding_edge/tools/gyp/v8.gyp Tue Jun 24 14:03:24 2014 UTC
+++ /branches/bleeding_edge/tools/gyp/v8.gyp Wed Jun 25 07:43:14 2014 UTC
@@ -1261,6 +1261,7 @@
'../../src/collection-iterator.js',
'../../src/generator.js',
'../../src/array-iterator.js',
+ '../../src/string-iterator.js',
'../../src/harmony-string.js',
'../../src/harmony-array.js',
'../../src/harmony-math.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.