Bug 1171036 - Change GetLengthProperty slow path to use ToLengthClamped instead of ToUint32. r=Waldo.
☠☠ backed out by a74edde76e5d ☠ ☠
authorJason Orendorff <jorendorff@mozilla.com>
Wed, 03 Jun 2015 10:01:45 -0500
changeset 249292 9345403c76288e468409cc12411f8ce16ed1a630
parent 249291 822901f56c1fe2ed23d638cc90759ffe08a0e93c
child 249293 c215b9a30b7395a9db4c527992c23ab45f5021e9
push id28923
push userryanvm@gmail.com
push dateWed, 17 Jun 2015 18:57:11 +0000
treeherdermozilla-central@099d6cd6725e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersWaldo
bugs1171036
milestone41.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1171036 - Change GetLengthProperty slow path to use ToLengthClamped instead of ToUint32. r=Waldo.
js/src/jsarray.cpp
js/src/tests/ecma_5/Array/unshift-01.js
--- a/js/src/jsarray.cpp
+++ b/js/src/jsarray.cpp
@@ -78,22 +78,23 @@ js::GetLengthProperty(JSContext* cx, Han
             return true;
         }
     }
 
     RootedValue value(cx);
     if (!GetProperty(cx, obj, obj, cx->names().length, &value))
         return false;
 
-    if (value.isInt32()) {
-        *lengthp = uint32_t(value.toInt32()); // uint32_t cast does ToUint32
-        return true;
+    bool overflow;
+    if (!ToLengthClamped(cx, value, lengthp, &overflow)) {
+        if (!overflow)
+            return false;
+        *lengthp = UINT32_MAX;
     }
-
-    return ToUint32(cx, value, lengthp);
+    return true;
 }
 
 /*
  * Determine if the id represents an array index.
  *
  * An id is an array index according to ECMA by (15.4):
  *
  * "Array objects give special treatment to a certain class of property names.
--- a/js/src/tests/ecma_5/Array/unshift-01.js
+++ b/js/src/tests/ecma_5/Array/unshift-01.js
@@ -8,34 +8,38 @@ var BUGNUMBER = 614070;
 var summary = 'Array.prototype.unshift without args';
 
 print(BUGNUMBER + ": " + summary);
 
 /**************
  * BEGIN TEST *
  **************/
 
+// ES6 ToLength clamps length values to 2^53 - 1.
+// We currently clamp to 2^32 - 1 instead. See bug 924058.
+var MAX_LENGTH = 0xffffffff;
+
 var a = {};
-a.length = 4294967296;
-assertEq([].unshift.call(a), 0);
-assertEq(a.length, 0);
+a.length = MAX_LENGTH + 1;
+assertEq([].unshift.call(a), MAX_LENGTH);
+assertEq(a.length, MAX_LENGTH);
 
 function testGetSet(len, expected) {
     var newlen;
     var a = { get length() { return len; }, set length(v) { newlen = v; } };
     var res = [].unshift.call(a);
     assertEq(res, expected);
     assertEq(newlen, expected);
 }
 
 testGetSet(0, 0);
 testGetSet(10, 10);
 testGetSet("1", 1);
 testGetSet(null, 0);
-testGetSet(4294967297, 1);
-testGetSet(-5, 4294967291);
+testGetSet(MAX_LENGTH + 2, MAX_LENGTH);
+testGetSet(-5, 0);
 
 /******************************************************************************/
 
 if (typeof reportCompare === "function")
   reportCompare(true, true);
 
 print("All tests passed!");