Bug 1287521 - Call ToUint32(limit) before ToString(separator) in String.prototype.split. r=till
authorTooru Fujisawa <arai_a@mac.com>
Wed, 20 Jul 2016 14:11:35 +0900
changeset 330852 4ddabcdd2919946d54a1b5b06aa1de3d58105723
parent 330851 4e952735e78954dffc362bc6b8e5b3b4f6147313
child 330853 49bef2408c15ae8e76ee485bd8c338573fa8a1c7
push id9858
push userjlund@mozilla.com
push dateMon, 01 Aug 2016 14:37:10 +0000
treeherdermozilla-aurora@203106ef6cb6 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerstill
bugs1287521
milestone50.0a1
Bug 1287521 - Call ToUint32(limit) before ToString(separator) in String.prototype.split. r=till
js/src/builtin/String.js
js/src/tests/ecma_5/String/split-01.js
js/src/tests/ecma_6/String/split-order.js
--- a/js/src/builtin/String.js
+++ b/js/src/builtin/String.js
@@ -290,35 +290,39 @@ function String_split(separator, limit) 
         // Step 2.b.
         if (splitter !== undefined)
             return callContentFunction(splitter, separator, this, limit);
     }
 
     // Step 3.
     var S = ToString(this);
 
-    // Step 9 (reordered).
-    var R = ToString(separator);
-
     // Step 6.
+    var R;
     if (limit !== undefined) {
         var lim = limit >>> 0;
 
+        // Step 9.
+        R = ToString(separator);
+
         // Step 10.
         if (lim === 0)
             return [];
 
         // Step 11.
         if (separator === undefined)
             return [S];
 
         // Steps 4, 8, 12-18.
         return StringSplitStringLimit(S, R, lim);
     }
 
+    // Step 9.
+    R = ToString(separator);
+
     // Step 11.
     if (separator === undefined)
         return [S];
 
     // Optimized path.
     // Steps 4, 8, 12-18.
     return StringSplitString(S, R);
 }
--- a/js/src/tests/ecma_5/String/split-01.js
+++ b/js/src/tests/ecma_5/String/split-01.js
@@ -20,17 +20,17 @@ function assertEqArr(a1, a2) {
     }
 }
 
 var order = "";
 var o1 = { toString: function() { order += "b"; return "-"; }};
 var o2 = { valueOf:  function() { order += "a"; return 1; }};
 var res = "xyz-xyz".split(o1, o2);
 
-assertEq(order, "ba");
+assertEq(order, "ab");
 assertEqArr(res, ["xyz"]);
 
 assertEqArr("".split(/.?/), []);
 assertEqArr("abc".split(/\b/), ["abc"]);
 
 assertEqArr("abc".split(/((()))./, 2), ["",""]);
 assertEqArr("abc".split(/((((()))))./, 9), ["","","","","","","","",""]);
 
new file mode 100644
--- /dev/null
+++ b/js/src/tests/ecma_6/String/split-order.js
@@ -0,0 +1,22 @@
+var BUGNUMBER = 1287521;
+var summary = 'String.prototype.split should call ToUint32(limit) before ToString(separator).';
+
+print(BUGNUMBER + ": " + summary);
+
+var log = [];
+"abba".split({
+  toString() {
+    log.push("separator-tostring");
+    return "b";
+  }
+}, {
+  valueOf() {
+    log.push("limit-valueOf");
+    return 0;
+  }
+});
+
+assertEq(log.join(","), "limit-valueOf,separator-tostring");
+
+if (typeof reportCompare === "function")
+  reportCompare(true, true);