Revert "Revert "Upgrade to 5.0.71.48"" DO NOT MERGE
This reverts commit f2e3994fa5148cc3d9946666f0b0596290192b0e,
and updates the x64 makefile properly so it doesn't break that
build.
FPIIM-449
Change-Id: Ib83e35bfbae6af627451c926a9650ec57c045605
(cherry picked from commit 109988c7ccb6f3fd1a58574fa3dfb88beaef6632)
diff --git a/src/js/string.js b/src/js/string.js
index b220038..a401978 100644
--- a/src/js/string.js
+++ b/src/js/string.js
@@ -17,12 +17,11 @@
var InternalPackedArray = utils.InternalPackedArray;
var MakeRangeError;
var MakeTypeError;
-var MathMax;
-var MathMin;
+var MaxSimple;
+var MinSimple;
var matchSymbol = utils.ImportNow("match_symbol");
-var RegExpExec;
var RegExpExecNoTests;
-var RegExpLastMatchInfo;
+var replaceSymbol = utils.ImportNow("replace_symbol");
var searchSymbol = utils.ImportNow("search_symbol");
var splitSymbol = utils.ImportNow("split_symbol");
@@ -31,11 +30,9 @@
ArrayJoin = from.ArrayJoin;
MakeRangeError = from.MakeRangeError;
MakeTypeError = from.MakeTypeError;
- MathMax = from.MathMax;
- MathMin = from.MathMin;
- RegExpExec = from.RegExpExec;
+ MaxSimple = from.MaxSimple;
+ MinSimple = from.MinSimple;
RegExpExecNoTests = from.RegExpExecNoTests;
- RegExpLastMatchInfo = from.RegExpLastMatchInfo;
});
//-------------------------------------------------------------------
@@ -84,41 +81,34 @@
// ECMA-262, section 15.5.4.6
function StringConcat(other /* and more */) { // length == 1
+ "use strict";
CHECK_OBJECT_COERCIBLE(this, "String.prototype.concat");
- var len = %_ArgumentsLength();
- var this_as_string = TO_STRING(this);
- if (len === 1) {
- return this_as_string + TO_STRING(other);
+ var s = TO_STRING(this);
+ var len = arguments.length;
+ for (var i = 0; i < len; ++i) {
+ s = s + TO_STRING(arguments[i]);
}
- var parts = new InternalArray(len + 1);
- parts[0] = this_as_string;
- for (var i = 0; i < len; i++) {
- var part = %_Arguments(i);
- parts[i + 1] = TO_STRING(part);
- }
- return %StringBuilderConcat(parts, len + 1, "");
+ return s;
}
// ECMA-262 section 15.5.4.7
-function StringIndexOfJS(pattern /* position */) { // length == 1
+function StringIndexOf(pattern, position) { // length == 1
CHECK_OBJECT_COERCIBLE(this, "String.prototype.indexOf");
var subject = TO_STRING(this);
pattern = TO_STRING(pattern);
- var index = 0;
- if (%_ArgumentsLength() > 1) {
- index = %_Arguments(1); // position
- index = TO_INTEGER(index);
- if (index < 0) index = 0;
- if (index > subject.length) index = subject.length;
- }
+ var index = TO_INTEGER(position);
+ if (index < 0) index = 0;
+ if (index > subject.length) index = subject.length;
return %StringIndexOf(subject, pattern, index);
}
+%FunctionSetLength(StringIndexOf, 1);
+
// ECMA-262 section 15.5.4.8
-function StringLastIndexOfJS(pat /* position */) { // length == 1
+function StringLastIndexOf(pat, pos) { // length == 1
CHECK_OBJECT_COERCIBLE(this, "String.prototype.lastIndexOf");
var sub = TO_STRING(this);
@@ -126,16 +116,14 @@
var pat = TO_STRING(pat);
var patLength = pat.length;
var index = subLength - patLength;
- if (%_ArgumentsLength() > 1) {
- var position = TO_NUMBER(%_Arguments(1));
- if (!NUMBER_IS_NAN(position)) {
- position = TO_INTEGER(position);
- if (position < 0) {
- position = 0;
- }
- if (position + patLength < subLength) {
- index = position;
- }
+ var position = TO_NUMBER(pos);
+ if (!NUMBER_IS_NAN(position)) {
+ position = TO_INTEGER(position);
+ if (position < 0) {
+ position = 0;
+ }
+ if (position + patLength < subLength) {
+ index = position;
}
}
if (index < 0) {
@@ -144,6 +132,8 @@
return %StringLastIndexOf(sub, pat, index);
}
+%FunctionSetLength(StringLastIndexOf, 1);
+
// ECMA-262 section 15.5.4.9
//
@@ -180,11 +170,10 @@
// For now we do nothing, as proper normalization requires big tables.
// If Intl is enabled, then i18n.js will override it and provide the the
// proper functionality.
-function StringNormalizeJS() {
+function StringNormalize(formArg) { // length == 0
CHECK_OBJECT_COERCIBLE(this, "String.prototype.normalize");
var s = TO_STRING(this);
- var formArg = %_Arguments(0);
var form = IS_UNDEFINED(formArg) ? 'NFC' : TO_STRING(formArg);
var NORMALIZATION_FORMS = ['NFC', 'NFD', 'NFKC', 'NFKD'];
@@ -197,6 +186,8 @@
return s;
}
+%FunctionSetLength(StringNormalize, 0);
+
// This has the same size as the RegExpLastMatchInfo array, and can be used
// for functions that expect that structure to be returned. It is used when
@@ -206,14 +197,12 @@
var reusableMatchInfo = [2, "", "", -1, -1];
-// ECMA-262, section 15.5.4.11
+// ES6, section 21.1.3.14
function StringReplace(search, replace) {
CHECK_OBJECT_COERCIBLE(this, "String.prototype.replace");
- var subject = TO_STRING(this);
-
// Decision tree for dispatch
- // .. regexp search
+ // .. regexp search (in src/js/regexp.js, RegExpReplace)
// .... string replace
// ...... non-global search
// ........ empty string replace
@@ -229,40 +218,15 @@
// ...... function replace
// ...... string replace (with $-expansion)
- if (IS_REGEXP(search)) {
- if (!IS_CALLABLE(replace)) {
- replace = TO_STRING(replace);
-
- if (!REGEXP_GLOBAL(search)) {
- // Non-global regexp search, string replace.
- var match = RegExpExec(search, subject, 0);
- if (match == null) {
- search.lastIndex = 0
- return subject;
- }
- if (replace.length == 0) {
- return %_SubString(subject, 0, match[CAPTURE0]) +
- %_SubString(subject, match[CAPTURE1], subject.length)
- }
- return ExpandReplacement(replace, subject, RegExpLastMatchInfo,
- %_SubString(subject, 0, match[CAPTURE0])) +
- %_SubString(subject, match[CAPTURE1], subject.length);
- }
-
- // Global regexp search, string replace.
- search.lastIndex = 0;
- return %StringReplaceGlobalRegExpWithString(
- subject, search, replace, RegExpLastMatchInfo);
+ if (!IS_NULL_OR_UNDEFINED(search)) {
+ var replacer = search[replaceSymbol];
+ if (!IS_UNDEFINED(replacer)) {
+ return %_Call(replacer, search, this, replace);
}
-
- if (REGEXP_GLOBAL(search)) {
- // Global regexp search, function replace.
- return StringReplaceGlobalRegExpWithFunction(subject, search, replace);
- }
- // Non-global regexp search, function replace.
- return StringReplaceNonGlobalRegExpWithFunction(subject, search, replace);
}
+ var subject = TO_STRING(this);
+
search = TO_STRING(search);
if (search.length == 1 &&
@@ -379,130 +343,6 @@
}
-// Compute the string of a given regular expression capture.
-function CaptureString(string, lastCaptureInfo, index) {
- // Scale the index.
- var scaled = index << 1;
- // Compute start and end.
- var start = lastCaptureInfo[CAPTURE(scaled)];
- // If start isn't valid, return undefined.
- if (start < 0) return;
- var end = lastCaptureInfo[CAPTURE(scaled + 1)];
- return %_SubString(string, start, end);
-}
-
-
-// TODO(lrn): This array will survive indefinitely if replace is never
-// called again. However, it will be empty, since the contents are cleared
-// in the finally block.
-var reusableReplaceArray = new InternalArray(4);
-
-// Helper function for replacing regular expressions with the result of a
-// function application in String.prototype.replace.
-function StringReplaceGlobalRegExpWithFunction(subject, regexp, replace) {
- var resultArray = reusableReplaceArray;
- if (resultArray) {
- reusableReplaceArray = null;
- } else {
- // Inside a nested replace (replace called from the replacement function
- // of another replace) or we have failed to set the reusable array
- // back due to an exception in a replacement function. Create a new
- // array to use in the future, or until the original is written back.
- resultArray = new InternalArray(16);
- }
- var res = %RegExpExecMultiple(regexp,
- subject,
- RegExpLastMatchInfo,
- resultArray);
- regexp.lastIndex = 0;
- if (IS_NULL(res)) {
- // No matches at all.
- reusableReplaceArray = resultArray;
- return subject;
- }
- var len = res.length;
- if (NUMBER_OF_CAPTURES(RegExpLastMatchInfo) == 2) {
- // If the number of captures is two then there are no explicit captures in
- // the regexp, just the implicit capture that captures the whole match. In
- // this case we can simplify quite a bit and end up with something faster.
- // The builder will consist of some integers that indicate slices of the
- // input string and some replacements that were returned from the replace
- // function.
- var match_start = 0;
- for (var i = 0; i < len; i++) {
- var elem = res[i];
- if (%_IsSmi(elem)) {
- // Integers represent slices of the original string.
- if (elem > 0) {
- match_start = (elem >> 11) + (elem & 0x7ff);
- } else {
- match_start = res[++i] - elem;
- }
- } else {
- var func_result = replace(elem, match_start, subject);
- // Overwrite the i'th element in the results with the string we got
- // back from the callback function.
- res[i] = TO_STRING(func_result);
- match_start += elem.length;
- }
- }
- } else {
- for (var i = 0; i < len; i++) {
- var elem = res[i];
- if (!%_IsSmi(elem)) {
- // elem must be an Array.
- // Use the apply argument as backing for global RegExp properties.
- var func_result = %Apply(replace, UNDEFINED, elem, 0, elem.length);
- // Overwrite the i'th element in the results with the string we got
- // back from the callback function.
- res[i] = TO_STRING(func_result);
- }
- }
- }
- var result = %StringBuilderConcat(res, len, subject);
- resultArray.length = 0;
- reusableReplaceArray = resultArray;
- return result;
-}
-
-
-function StringReplaceNonGlobalRegExpWithFunction(subject, regexp, replace) {
- var matchInfo = RegExpExec(regexp, subject, 0);
- if (IS_NULL(matchInfo)) {
- regexp.lastIndex = 0;
- return subject;
- }
- var index = matchInfo[CAPTURE0];
- var result = %_SubString(subject, 0, index);
- var endOfMatch = matchInfo[CAPTURE1];
- // Compute the parameter list consisting of the match, captures, index,
- // and subject for the replace function invocation.
- // The number of captures plus one for the match.
- var m = NUMBER_OF_CAPTURES(matchInfo) >> 1;
- var replacement;
- if (m == 1) {
- // No captures, only the match, which is always valid.
- var s = %_SubString(subject, index, endOfMatch);
- // Don't call directly to avoid exposing the built-in global object.
- replacement = replace(s, index, subject);
- } else {
- var parameters = new InternalArray(m + 2);
- for (var j = 0; j < m; j++) {
- parameters[j] = CaptureString(subject, matchInfo, j);
- }
- parameters[j] = index;
- parameters[j + 1] = subject;
-
- replacement = %Apply(replace, UNDEFINED, parameters, 0, j + 2);
- }
-
- result += replacement; // The add method converts to string if necessary.
- // Can't use matchInfo any more from here, since the function could
- // overwrite it.
- return result + %_SubString(subject, endOfMatch, subject.length);
-}
-
-
// ES6 21.1.3.15.
function StringSearch(pattern) {
CHECK_OBJECT_COERCIBLE(this, "String.prototype.search");
@@ -719,28 +559,14 @@
// ECMA-262, section 15.5.3.2
-function StringFromCharCode(code) {
- var n = %_ArgumentsLength();
- if (n == 1) return %_StringCharFromCode(code & 0xffff);
-
- var one_byte = %NewString(n, NEW_ONE_BYTE_STRING);
- var i;
- for (i = 0; i < n; i++) {
- code = %_Arguments(i) & 0xffff;
- if (code > 0xff) break;
- %_OneByteSeqStringSetChar(i, code, one_byte);
+function StringFromCharCode(_) { // length == 1
+ "use strict";
+ var s = "";
+ var n = arguments.length;
+ for (var i = 0; i < n; ++i) {
+ s += %_StringCharFromCode(arguments[i] & 0xffff);
}
- if (i == n) return one_byte;
- one_byte = %TruncateString(one_byte, i);
-
- var two_byte = %NewString(n - i, NEW_TWO_BYTE_STRING);
- %_TwoByteSeqStringSetChar(0, code, two_byte);
- i++;
- for (var j = 1; i < n; i++, j++) {
- code = %_Arguments(i) & 0xffff;
- %_TwoByteSeqStringSetChar(j, code, two_byte);
- }
- return one_byte + two_byte;
+ return s;
}
@@ -870,7 +696,7 @@
// ES6 draft 04-05-14, section 21.1.3.18
-function StringStartsWith(searchString /* position */) { // length == 1
+function StringStartsWith(searchString, position) { // length == 1
CHECK_OBJECT_COERCIBLE(this, "String.prototype.startsWith");
var s = TO_STRING(this);
@@ -880,16 +706,10 @@
}
var ss = TO_STRING(searchString);
- var pos = 0;
- if (%_ArgumentsLength() > 1) {
- var arg = %_Arguments(1); // position
- if (!IS_UNDEFINED(arg)) {
- pos = TO_INTEGER(arg);
- }
- }
+ var pos = TO_INTEGER(position);
var s_len = s.length;
- var start = MathMin(MathMax(pos, 0), s_len);
+ var start = MinSimple(MaxSimple(pos, 0), s_len);
var ss_len = ss.length;
if (ss_len + start > s_len) {
return false;
@@ -898,9 +718,11 @@
return %_SubString(s, start, start + ss_len) === ss;
}
+%FunctionSetLength(StringStartsWith, 1);
+
// ES6 draft 04-05-14, section 21.1.3.7
-function StringEndsWith(searchString /* position */) { // length == 1
+function StringEndsWith(searchString, position) { // length == 1
CHECK_OBJECT_COERCIBLE(this, "String.prototype.endsWith");
var s = TO_STRING(this);
@@ -911,15 +733,9 @@
var ss = TO_STRING(searchString);
var s_len = s.length;
- var pos = s_len;
- if (%_ArgumentsLength() > 1) {
- var arg = %_Arguments(1); // position
- if (!IS_UNDEFINED(arg)) {
- pos = TO_INTEGER(arg);
- }
- }
+ var pos = !IS_UNDEFINED(position) ? TO_INTEGER(position) : s_len
- var end = MathMin(MathMax(pos, 0), s_len);
+ var end = MinSimple(MaxSimple(pos, 0), s_len);
var ss_len = ss.length;
var start = end - ss_len;
if (start < 0) {
@@ -929,9 +745,11 @@
return %_SubString(s, start, start + ss_len) === ss;
}
+%FunctionSetLength(StringEndsWith, 1);
+
// ES6 draft 04-05-14, section 21.1.3.6
-function StringIncludes(searchString /* position */) { // length == 1
+function StringIncludes(searchString, position) { // length == 1
CHECK_OBJECT_COERCIBLE(this, "String.prototype.includes");
var string = TO_STRING(this);
@@ -941,11 +759,7 @@
}
searchString = TO_STRING(searchString);
- var pos = 0;
- if (%_ArgumentsLength() > 1) {
- pos = %_Arguments(1); // position
- pos = TO_INTEGER(pos);
- }
+ var pos = TO_INTEGER(position);
var stringLength = string.length;
if (pos < 0) pos = 0;
@@ -959,6 +773,8 @@
return %StringIndexOf(string, searchString, pos) !== -1;
}
+%FunctionSetLength(StringIncludes, 1);
+
// ES6 Draft 05-22-2014, section 21.1.3.3
function StringCodePointAt(pos) {
@@ -984,12 +800,13 @@
// ES6 Draft 05-22-2014, section 21.1.2.2
function StringFromCodePoint(_) { // length = 1
+ "use strict";
var code;
- var length = %_ArgumentsLength();
+ var length = arguments.length;
var index;
var result = "";
for (index = 0; index < length; index++) {
- code = %_Arguments(index);
+ code = arguments[index];
if (!%_IsSmi(code)) {
code = TO_NUMBER(code);
}
@@ -1013,8 +830,8 @@
// ES6 Draft 03-17-2015, section 21.1.2.4
function StringRaw(callSite) {
- // TODO(caitp): Use rest parameters when implemented
- var numberOfSubstitutions = %_ArgumentsLength();
+ "use strict";
+ var numberOfSubstitutions = arguments.length;
var cooked = TO_OBJECT(callSite);
var raw = TO_OBJECT(cooked.raw);
var literalSegments = TO_LENGTH(raw.length);
@@ -1024,7 +841,7 @@
for (var i = 1; i < literalSegments; ++i) {
if (i < numberOfSubstitutions) {
- result += TO_STRING(%_Arguments(i));
+ result += TO_STRING(arguments[i]);
}
result += TO_STRING(raw[i]);
}
@@ -1058,11 +875,11 @@
"concat", StringConcat,
"endsWith", StringEndsWith,
"includes", StringIncludes,
- "indexOf", StringIndexOfJS,
- "lastIndexOf", StringLastIndexOfJS,
+ "indexOf", StringIndexOf,
+ "lastIndexOf", StringLastIndexOf,
"localeCompare", StringLocaleCompareJS,
"match", StringMatchJS,
- "normalize", StringNormalizeJS,
+ "normalize", StringNormalize,
"repeat", StringRepeat,
"replace", StringReplace,
"search", StringSearch,
@@ -1098,9 +915,10 @@
// Exports
utils.Export(function(to) {
+ to.ExpandReplacement = ExpandReplacement;
to.StringCharAt = StringCharAtJS;
- to.StringIndexOf = StringIndexOfJS;
- to.StringLastIndexOf = StringLastIndexOfJS;
+ to.StringIndexOf = StringIndexOf;
+ to.StringLastIndexOf = StringLastIndexOf;
to.StringMatch = StringMatchJS;
to.StringReplace = StringReplace;
to.StringSlice = StringSlice;