Revision: 15960
Author: [email protected]
Date: Tue Jul 30 09:33:08 2013
Log: Add new Harmony methods to String.prototype object.
String.prototype.repeat
String.prototype.startsWith
String.prototype.endsWith
String.prototype.contains
http://people.mozilla.org/~jorendorff/es6-draft.html
BUG=v8:2796,v8:2797,v8:2798,v8:2799
TEST=mjsunit/string-repeat,mjsunit/string-startswith,mjsunit/string-endswith,mjsunit/string-contains
[email protected]
Review URL: https://codereview.chromium.org/21014007
Patch from Ioseb Dzmanashvili <[email protected]>.
http://code.google.com/p/v8/source/detail?r=15960
Added:
/branches/bleeding_edge/src/harmony-string.js
/branches/bleeding_edge/test/mjsunit/harmony/string-contains.js
/branches/bleeding_edge/test/mjsunit/harmony/string-endswith.js
/branches/bleeding_edge/test/mjsunit/harmony/string-repeat.js
/branches/bleeding_edge/test/mjsunit/harmony/string-startswith.js
Modified:
/branches/bleeding_edge/src/bootstrapper.cc
/branches/bleeding_edge/src/flag-definitions.h
/branches/bleeding_edge/src/messages.js
/branches/bleeding_edge/tools/gyp/v8.gyp
=======================================
--- /dev/null
+++ /branches/bleeding_edge/src/harmony-string.js Tue Jul 30 09:33:08 2013
@@ -0,0 +1,154 @@
+// 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 $String = global.String;
+// var $Array = global.Array;
+
+// -------------------------------------------------------------------
+
+// ES6 draft 07-15-13, section 15.5.3.21
+function StringRepeat(count) {
+ if (IS_NULL_OR_UNDEFINED(this) && !IS_UNDETECTABLE(this)) {
+ throw MakeTypeError("called_on_null_or_undefined",
+ ["String.prototype.repeat"]);
+ }
+
+ var s = TO_STRING_INLINE(this);
+ var n = ToInteger(count);
+ if (n < 0 || !NUMBER_IS_FINITE(n)) {
+ throw MakeRangeError("invalid_count_value", []);
+ }
+
+ var elements = new InternalArray(n);
+ for (var i = 0; i < n; i++) {
+ elements[i] = s;
+ }
+
+ return %StringBuilderConcat(elements, n, "");
+}
+
+
+// ES6 draft 07-15-13, section 15.5.3.22
+function StringStartsWith(searchString /* position */) { // length == 1
+ if (IS_NULL_OR_UNDEFINED(this) && !IS_UNDETECTABLE(this)) {
+ throw MakeTypeError("called_on_null_or_undefined",
+ ["String.prototype.startsWith"]);
+ }
+
+ var s = TO_STRING_INLINE(this);
+ var ss = TO_STRING_INLINE(searchString);
+ var pos = 0;
+ if (%_ArgumentsLength() > 1) {
+ pos = %_Arguments(1); // position
+ pos = ToInteger(pos);
+ }
+
+ var s_len = s.length;
+ var start = MathMin(MathMax(pos, 0), s_len);
+ var ss_len = ss.length;
+ if (ss_len + start > s_len) {
+ return false;
+ }
+
+ return %StringIndexOf(s, ss, start) === start;
+}
+
+
+// ES6 draft 07-15-13, section 15.5.3.23
+function StringEndsWith(searchString /* position */) { // length == 1
+ if (IS_NULL_OR_UNDEFINED(this) && !IS_UNDETECTABLE(this)) {
+ throw MakeTypeError("called_on_null_or_undefined",
+ ["String.prototype.endsWith"]);
+ }
+
+ var s = TO_STRING_INLINE(this);
+ var ss = TO_STRING_INLINE(searchString);
+ var s_len = s.length;
+ var pos = s_len;
+ if (%_ArgumentsLength() > 1) {
+ var arg = %_Arguments(1); // position
+ if (!IS_UNDEFINED(arg)) {
+ pos = ToInteger(arg);
+ }
+ }
+
+ var end = MathMin(MathMax(pos, 0), s_len);
+ var ss_len = ss.length;
+ var start = end - ss_len;
+ if (start < 0) {
+ return false;
+ }
+
+ return %StringLastIndexOf(s, ss, start) === start;
+}
+
+
+// ES6 draft 07-15-13, section 15.5.3.24
+function StringContains(searchString /* position */) { // length == 1
+ if (IS_NULL_OR_UNDEFINED(this) && !IS_UNDETECTABLE(this)) {
+ throw MakeTypeError("called_on_null_or_undefined",
+ ["String.prototype.contains"]);
+ }
+
+ var s = TO_STRING_INLINE(this);
+ var ss = TO_STRING_INLINE(searchString);
+ var pos = 0;
+ if (%_ArgumentsLength() > 1) {
+ pos = %_Arguments(1); // position
+ pos = ToInteger(pos);
+ }
+
+ var s_len = s.length;
+ var start = MathMin(MathMax(pos, 0), s_len);
+ var ss_len = ss.length;
+ if (ss_len + start > s_len) {
+ return false;
+ }
+
+ return %StringIndexOf(s, ss, start) !== -1;
+}
+
+
+// -------------------------------------------------------------------
+
+function ExtendStringPrototype() {
+ %CheckIsBootstrapping();
+
+ // Set up the non-enumerable functions on the String prototype object.
+ InstallFunctions($String.prototype, DONT_ENUM, $Array(
+ "repeat", StringRepeat,
+ "startsWith", StringStartsWith,
+ "endsWith", StringEndsWith,
+ "contains", StringContains
+ ));
+}
+
+ExtendStringPrototype();
=======================================
--- /dev/null
+++ /branches/bleeding_edge/test/mjsunit/harmony/string-contains.js Tue Jul
30 09:33:08 2013
@@ -0,0 +1,151 @@
+// 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-strings
+
+assertEquals(1, String.prototype.contains.length);
+
+var reString = "asdf[a-z]+(asdf)?";
+assertTrue(reString.contains("[a-z]+"));
+assertTrue(reString.contains("(asdf)?"));
+
+// Random greek letters
+var twoByteString = "\u039a\u0391\u03a3\u03a3\u0395";
+
+// Test single char pattern
+assertTrue(twoByteString.contains("\u039a"), "Lamda");
+assertTrue(twoByteString.contains("\u0391"), "Alpha");
+assertTrue(twoByteString.contains("\u03a3"), "First Sigma");
+assertTrue(twoByteString.contains("\u03a3",3), "Second Sigma");
+assertTrue(twoByteString.contains("\u0395"), "Epsilon");
+assertFalse(twoByteString.contains("\u0392"), "Not beta");
+
+// Test multi-char pattern
+assertTrue(twoByteString.contains("\u039a\u0391"), "lambda Alpha");
+assertTrue(twoByteString.contains("\u0391\u03a3"), "Alpha Sigma");
+assertTrue(twoByteString.contains("\u03a3\u03a3"), "Sigma Sigma");
+assertTrue(twoByteString.contains("\u03a3\u0395"), "Sigma Epsilon");
+
+assertFalse(twoByteString.contains("\u0391\u03a3\u0395"),
+ "Not Alpha Sigma Epsilon");
+
+//single char pattern
+assertTrue(twoByteString.contains("\u0395"));
+
+assertThrows("String.prototype.contains.call(null, 'test')", TypeError);
+assertThrows("String.prototype.contains.call(null, null)", TypeError);
+assertThrows("String.prototype.contains.call(undefined, undefined)",
TypeError);
+
+assertThrows("String.prototype.contains.apply(null, ['test'])", TypeError);
+assertThrows("String.prototype.contains.apply(null, [null])", TypeError);
+assertThrows("String.prototype.contains.apply(undefined, [undefined])",
TypeError);
+
+var TEST_INPUT = [{
+ msg: "Empty string", val: ""
+}, {
+ msg: "Number 1234.34", val: 1234.34
+}, {
+ msg: "Integer number 0", val: 0
+}, {
+ msg: "Negative number -1", val: -1
+}, {
+ msg: "Boolean true", val: true
+}, {
+ msg: "Boolean false", val: false
+}, {
+ msg: "Regular expression /\d+/", val: /\d+/
+}, {
+ msg: "Empty array []", val: []
+}, {
+ msg: "Empty object {}", val: {}
+}, {
+ msg: "Array of size 3", val: new Array(3)
+}];
+
+var i = 0;
+var l = TEST_INPUT.length;
+
+for (; i < l; i++) {
+ var e = TEST_INPUT[i];
+ var v = e.val;
+ var s = String(v);
+ assertTrue(s.contains(v), e.msg);
+ assertTrue(String.prototype.contains.call(v, v), e.msg);
+ assertTrue(String.prototype.contains.apply(v, [v]), e.msg);
+}
+
+// Test cases found in FF
+assertTrue("abc".contains("a"));
+assertTrue("abc".contains("b"));
+assertTrue("abc".contains("abc"));
+assertTrue("abc".contains("bc"));
+assertFalse("abc".contains("d"));
+assertFalse("abc".contains("abcd"));
+assertFalse("abc".contains("ac"));
+assertTrue("abc".contains("abc", 0));
+assertTrue("abc".contains("bc", 0));
+assertFalse("abc".contains("de", 0));
+assertTrue("abc".contains("bc", 1));
+assertTrue("abc".contains("c", 1));
+assertFalse("abc".contains("a", 1));
+assertFalse("abc".contains("abc", 1));
+assertTrue("abc".contains("c", 2));
+assertFalse("abc".contains("d", 2));
+assertFalse("abc".contains("dcd", 2));
+assertFalse("abc".contains("a", 42));
+assertFalse("abc".contains("a", Infinity));
+assertTrue("abc".contains("ab", -43));
+assertFalse("abc".contains("cd", -42));
+assertTrue("abc".contains("ab", -Infinity));
+assertFalse("abc".contains("cd", -Infinity));
+assertTrue("abc".contains("ab", NaN));
+assertFalse("abc".contains("cd", NaN));
+assertFalse("xyzzy".contains("zy\0", 2));
+
+var dots = Array(10000).join('.');
+assertFalse(dots.contains("\x01", 10000));
+assertFalse(dots.contains("\0", 10000));
+
+var myobj = {
+ toString: function () {
+ return "abc";
+ },
+ contains: String.prototype.contains
+};
+assertTrue(myobj.contains("abc"));
+assertFalse(myobj.contains("cd"));
+
+var gotStr = false;
+var gotPos = false;
+myobj = {
+ toString: function () {
+ assertFalse(gotPos);
+ gotStr = true;
+ return "xyz";
+ },
+ contains: String.prototype.contains
+};
=======================================
--- /dev/null
+++ /branches/bleeding_edge/test/mjsunit/harmony/string-endswith.js Tue Jul
30 09:33:08 2013
@@ -0,0 +1,136 @@
+// 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-strings
+
+assertEquals(1, String.prototype.endsWith.length);
+
+var testString = "Hello World";
+assertTrue(testString.endsWith(""));
+assertTrue(testString.endsWith("World"));
+assertFalse(testString.endsWith("world"));
+assertFalse(testString.endsWith("Hello World!"));
+assertFalse(testString.endsWith(null));
+assertFalse(testString.endsWith(undefined));
+
+assertTrue("null".endsWith(null));
+assertTrue("undefined".endsWith(undefined));
+
+var georgianUnicodeString
= "\u10D0\u10D1\u10D2\u10D3\u10D4\u10D5\u10D6\u10D7";
+assertTrue(georgianUnicodeString.endsWith(georgianUnicodeString));
+assertTrue(georgianUnicodeString.endsWith("\u10D4\u10D5\u10D6\u10D7"));
+assertFalse(georgianUnicodeString.endsWith("\u10D0"));
+
+assertThrows("String.prototype.endsWith.call(null, 'test')", TypeError);
+assertThrows("String.prototype.endsWith.call(null, null)", TypeError);
+assertThrows("String.prototype.endsWith.call(undefined, undefined)",
TypeError);
+
+assertThrows("String.prototype.endsWith.apply(null, ['test'])", TypeError);
+assertThrows("String.prototype.endsWith.apply(null, [null])", TypeError);
+assertThrows("String.prototype.endsWith.apply(undefined, [undefined])",
TypeError);
+
+var TEST_INPUT = [{
+ msg: "Empty string", val: ""
+}, {
+ msg: "Number 1234.34", val: 1234.34
+}, {
+ msg: "Integer number 0", val: 0
+}, {
+ msg: "Negative number -1", val: -1
+}, {
+ msg: "Boolean true", val: true
+}, {
+ msg: "Boolean false", val: false
+}, {
+ msg: "Regular expression /\d+/", val: /\d+/
+}, {
+ msg: "Empty array []", val: []
+}, {
+ msg: "Empty object {}", val: {}
+}, {
+ msg: "Array of size 3", val: new Array(3)
+}];
+
+function testNonStringValues() {
+ var i = 0;
+ var l = TEST_INPUT.length;
+
+ for (; i < l; i++) {
+ var e = TEST_INPUT[i];
+ var v = e.val;
+ var s = String(v);
+ assertTrue(s.endsWith(v), e.msg);
+ assertTrue(String.prototype.endsWith.call(v, v), e.msg);
+ assertTrue(String.prototype.endsWith.apply(v, [v]), e.msg);
+ }
+}
+testNonStringValues();
+
+var CustomType = function(value) {
+ this.endsWith = String.prototype.endsWith;
+ this.toString = function() {
+ return String(value);
+ }
+};
+
+function testCutomType() {
+ var i = 0;
+ var l = TEST_INPUT.length;
+
+ for (; i < l; i++) {
+ var e = TEST_INPUT[i];
+ var v = e.val;
+ var o = new CustomType(v);
+ assertTrue(o.endsWith(v), e.msg);
+ }
+}
+testCutomType();
+
+
+// Test cases found in FF
+assertTrue("abc".endsWith("abc"));
+assertTrue("abcd".endsWith("bcd"));
+assertTrue("abc".endsWith("c"));
+assertFalse("abc".endsWith("abcd"));
+assertFalse("abc".endsWith("bbc"));
+assertFalse("abc".endsWith("b"));
+assertTrue("abc".endsWith("abc", 3));
+assertTrue("abc".endsWith("bc", 3));
+assertFalse("abc".endsWith("a", 3));
+assertTrue("abc".endsWith("bc", 3));
+assertTrue("abc".endsWith("a", 1));
+assertFalse("abc".endsWith("abc", 1));
+assertTrue("abc".endsWith("b", 2));
+assertFalse("abc".endsWith("d", 2));
+assertFalse("abc".endsWith("dcd", 2));
+assertFalse("abc".endsWith("a", 42));
+assertTrue("abc".endsWith("bc", Infinity));
+assertFalse("abc".endsWith("a", Infinity));
+assertTrue("abc".endsWith("bc", undefined));
+assertFalse("abc".endsWith("bc", -43));
+assertFalse("abc".endsWith("bc", -Infinity));
+assertFalse("abc".endsWith("bc", NaN));
=======================================
--- /dev/null
+++ /branches/bleeding_edge/test/mjsunit/harmony/string-repeat.js Tue Jul
30 09:33:08 2013
@@ -0,0 +1,74 @@
+// 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-strings
+
+assertEquals("000", String.prototype.repeat.call(0, 3));
+assertEquals("-1-1-1", String.prototype.repeat.call(-1, 3));
+assertEquals("2.12.12.1", String.prototype.repeat.call(2.1, 3));
+assertEquals("", String.prototype.repeat.call([], 3));
+assertEquals("1,2,3", String.prototype.repeat.call([1, 2, 3], 1));
+assertEquals("true", String.prototype.repeat.call(true, 1));
+assertEquals("false", String.prototype.repeat.call(false, 1));
+assertEquals("[object Object]", String.prototype.repeat.call({}, 1));
+
+assertEquals("000", String.prototype.repeat.apply(0, [3]));
+assertEquals("-1-1-1", String.prototype.repeat.apply(-1, [3]));
+assertEquals("2.12.12.1", String.prototype.repeat.apply(2.1, [3]));
+assertEquals("", String.prototype.repeat.apply([], [3]));
+assertEquals("1,2,3", String.prototype.repeat.apply([1, 2, 3], [1]));
+assertEquals("true", String.prototype.repeat.apply(true, [1]));
+assertEquals("false", String.prototype.repeat.apply(false, [1]));
+assertEquals("[object Object]", String.prototype.repeat.apply({}, [1]));
+
+assertEquals("\u10D8\u10D8\u10D8", "\u10D8".repeat(3));
+
+assertThrows('String.prototype.repeat.call(null, 1)', TypeError);
+assertThrows('String.prototype.repeat.call(undefined, 1)', TypeError);
+assertThrows('String.prototype.repeat.apply(null, [1])', TypeError);
+assertThrows('String.prototype.repeat.apply(undefined, [1])', TypeError);
+
+// Test cases found in FF
+assertEquals("abc", "abc".repeat(1));
+assertEquals("abcabc", "abc".repeat(2));
+assertEquals("abcabcabc", "abc".repeat(3));
+assertEquals("aaaaaaaaaa", "a".repeat(10));
+assertEquals("", "".repeat(5));
+assertEquals("", "abc".repeat(0));
+assertEquals("abcabc", "abc".repeat(2.0));
+
+assertThrows('"a".repeat(-1)', RangeError);
+assertThrows('"a".repeat(Number.POSITIVE_INFINITY)', RangeError);
+
+var myobj = {
+ toString: function() {
+ return "abc";
+ },
+ repeat : String.prototype.repeat
+};
+assertEquals("abc", myobj.repeat(1));
+assertEquals("abcabc", myobj.repeat(2));
=======================================
--- /dev/null
+++ /branches/bleeding_edge/test/mjsunit/harmony/string-startswith.js Tue
Jul 30 09:33:08 2013
@@ -0,0 +1,135 @@
+// 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-strings
+
+assertEquals(1, String.prototype.startsWith.length);
+
+var testString = "Hello World";
+assertTrue(testString.startsWith(""));
+assertTrue(testString.startsWith("Hello"));
+assertFalse(testString.startsWith("hello"));
+assertFalse(testString.startsWith("Hello World!"));
+assertFalse(testString.startsWith(null));
+assertFalse(testString.startsWith(undefined));
+
+assertTrue("null".startsWith(null));
+assertTrue("undefined".startsWith(undefined));
+
+var georgianUnicodeString
= "\u10D0\u10D1\u10D2\u10D3\u10D4\u10D5\u10D6\u10D7";
+assertTrue(georgianUnicodeString.startsWith(georgianUnicodeString));
+assertTrue(georgianUnicodeString.startsWith("\u10D0\u10D1\u10D2"));
+assertFalse(georgianUnicodeString.startsWith("\u10D8"));
+
+assertThrows("String.prototype.startsWith.call(null, 'test')", TypeError);
+assertThrows("String.prototype.startsWith.call(null, null)", TypeError);
+assertThrows("String.prototype.startsWith.call(undefined, undefined)",
TypeError);
+
+assertThrows("String.prototype.startsWith.apply(null, ['test'])",
TypeError);
+assertThrows("String.prototype.startsWith.apply(null, [null])", TypeError);
+assertThrows("String.prototype.startsWith.apply(undefined, [undefined])",
TypeError);
+
+var TEST_INPUT = [{
+ msg: "Empty string", val: ""
+}, {
+ msg: "Number 1234.34", val: 1234.34
+}, {
+ msg: "Integer number 0", val: 0
+}, {
+ msg: "Negative number -1", val: -1
+}, {
+ msg: "Boolean true", val: true
+}, {
+ msg: "Boolean false", val: false
+}, {
+ msg: "Regular expression /\d+/", val: /\d+/
+}, {
+ msg: "Empty array []", val: []
+}, {
+ msg: "Empty object {}", val: {}
+}, {
+ msg: "Array of size 3", val: new Array(3)
+}];
+
+function testNonStringValues() {
+ var i = 0;
+ var l = TEST_INPUT.length;
+
+ for (; i < l; i++) {
+ var e = TEST_INPUT[i];
+ var v = e.val;
+ var s = String(v);
+ assertTrue(s.startsWith(v), e.msg);
+ assertTrue(String.prototype.startsWith.call(v, v), e.msg);
+ assertTrue(String.prototype.startsWith.apply(v, [v]), e.msg);
+ }
+}
+testNonStringValues();
+
+var CustomType = function(value) {
+ this.startsWith = String.prototype.startsWith;
+ this.toString = function() {
+ return String(value);
+ }
+};
+
+function testCutomType() {
+ var i = 0;
+ var l = TEST_INPUT.length;
+
+ for (; i < l; i++) {
+ var e = TEST_INPUT[i];
+ var v = e.val;
+ var o = new CustomType(v);
+ assertTrue(o.startsWith(v), e.msg);
+ }
+}
+testCutomType();
+
+// Test cases found in FF
+assertTrue("abc".startsWith("abc"));
+assertTrue("abcd".startsWith("abc"));
+assertTrue("abc".startsWith("a"));
+assertFalse("abc".startsWith("abcd"));
+assertFalse("abc".startsWith("bcde"));
+assertFalse("abc".startsWith("b"));
+assertTrue("abc".startsWith("abc", 0));
+assertFalse("abc".startsWith("bc", 0));
+assertTrue("abc".startsWith("bc", 1));
+assertFalse("abc".startsWith("c", 1));
+assertFalse("abc".startsWith("abc", 1));
+assertTrue("abc".startsWith("c", 2));
+assertFalse("abc".startsWith("d", 2));
+assertFalse("abc".startsWith("dcd", 2));
+assertFalse("abc".startsWith("a", 42));
+assertFalse("abc".startsWith("a", Infinity));
+assertTrue("abc".startsWith("a", NaN));
+assertFalse("abc".startsWith("b", NaN));
+assertTrue("abc".startsWith("ab", -43));
+assertTrue("abc".startsWith("ab", -Infinity));
+assertFalse("abc".startsWith("bc", -42));
+assertFalse("abc".startsWith("bc", -Infinity));
=======================================
--- /branches/bleeding_edge/src/bootstrapper.cc Wed Jul 24 05:34:50 2013
+++ /branches/bleeding_edge/src/bootstrapper.cc Tue Jul 30 09:33:08 2013
@@ -2079,6 +2079,11 @@
"native array-iterator.js") == 0) {
if (!CompileExperimentalBuiltin(isolate(), i)) return false;
}
+ if (FLAG_harmony_strings &&
+ strcmp(ExperimentalNatives::GetScriptName(i).start(),
+ "native harmony-string.js") == 0) {
+ if (!CompileExperimentalBuiltin(isolate(), i)) return false;
+ }
}
InstallExperimentalNativeFunctions();
=======================================
--- /branches/bleeding_edge/src/flag-definitions.h Mon Jul 29 02:12:16 2013
+++ /branches/bleeding_edge/src/flag-definitions.h Tue Jul 30 09:33:08 2013
@@ -173,6 +173,7 @@
DEFINE_bool(harmony_iteration, false, "enable harmony iteration (for-of)")
DEFINE_bool(harmony_numeric_literals, false,
"enable harmony numeric literals (0o77, 0b11)")
+DEFINE_bool(harmony_strings, false, "enable harmony string")
DEFINE_bool(harmony, false, "enable all harmony features (except typeof)")
DEFINE_implication(harmony, harmony_scoping)
DEFINE_implication(harmony, harmony_modules)
@@ -183,6 +184,7 @@
DEFINE_implication(harmony, harmony_generators)
DEFINE_implication(harmony, harmony_iteration)
DEFINE_implication(harmony, harmony_numeric_literals)
+DEFINE_implication(harmony, harmony_strings)
DEFINE_implication(harmony_modules, harmony_scoping)
DEFINE_implication(harmony_observation, harmony_collections)
// TODO[dslomov] add harmony => harmony_typed_arrays
=======================================
--- /branches/bleeding_edge/src/messages.js Fri Jul 26 04:28:08 2013
+++ /branches/bleeding_edge/src/messages.js Tue Jul 30 09:33:08 2013
@@ -126,6 +126,7 @@
stack_overflow: ["Maximum call stack size exceeded"],
invalid_time_value: ["Invalid time value"],
+ invalid_count_value: ["Invalid count value"],
// SyntaxError
paren_in_arg_string: ["Function arg string contains
parenthesis"],
not_isvar: ["builtin %IS_VAR: not a variable"],
=======================================
--- /branches/bleeding_edge/tools/gyp/v8.gyp Tue Jul 30 03:25:20 2013
+++ /branches/bleeding_edge/tools/gyp/v8.gyp Tue Jul 30 09:33:08 2013
@@ -906,7 +906,8 @@
'../../src/arraybuffer.js',
'../../src/typedarray.js',
'../../src/generator.js',
- '../../src/array-iterator.js'
+ '../../src/array-iterator.js',
+ '../../src/harmony-string.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.