Bug 580051 - Catch ints-as-doubles in JSOP_TABLESWITCH (r=jorendorff)
authorLuke Wagner <lw@mozilla.com>
Tue, 20 Jul 2010 19:32:11 -0700
changeset 48518 73922e37b73313237a6e1235ec2bf64d4c309601
parent 48517 faf55b60e857e7672e41f043c7a7a5bfebcdda88
child 48519 605610554494be3984ba3546b1ee36571c296107
push id14748
push userrsayre@mozilla.com
push dateSun, 01 Aug 2010 00:33:23 +0000
treeherdermozilla-central@f0df797bb2a9 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjorendorff
bugs580051
milestone2.0b2pre
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 580051 - Catch ints-as-doubles in JSOP_TABLESWITCH (r=jorendorff)
js/src/jsinterp.cpp
js/src/trace-test/tests/basic/testDoubleZeroInSwitch1.js
js/src/trace-test/tests/basic/testDoubleZeroInSwitch2.js
--- a/js/src/jsinterp.cpp
+++ b/js/src/jsinterp.cpp
@@ -4956,21 +4956,21 @@ BEGIN_CASE(JSOP_TABLESWITCH)
      * ECMAv2+ forbids conversion of discriminant, so we will skip to the
      * default case if the discriminant isn't already an int jsval.  (This
      * opcode is emitted only for dense jsint-domain switches.)
      */
     const Value &rref = *--regs.sp;
     int32_t i;
     if (rref.isInt32()) {
         i = rref.toInt32();
-    } else if (rref.isDouble() && rref.toDouble() == 0) {
-        /* Treat -0 (double) as 0. */
-        i = 0;
     } else {
-        DO_NEXT_OP(len);
+        double d;
+        /* Don't use JSDOUBLE_IS_INT32; treat -0 (double) as 0. */
+        if (!rref.isDouble() || (d = rref.toDouble()) != (i = int32_t(rref.toDouble())))
+            DO_NEXT_OP(len);
     }
 
     pc2 += JUMP_OFFSET_LEN;
     jsint low = GET_JUMP_OFFSET(pc2);
     pc2 += JUMP_OFFSET_LEN;
     jsint high = GET_JUMP_OFFSET(pc2);
 
     i -= low;
new file mode 100644
--- /dev/null
+++ b/js/src/trace-test/tests/basic/testDoubleZeroInSwitch1.js
@@ -0,0 +1,7 @@
+var a = Math.sin(Math.PI/2);  // spec does not specify precise answer here...
+if (a === 1) {    // ...but if a === 1 here...
+    switch (a) {
+      case 1: break;  // ...then it must also match here
+      default: throw "FAIL";
+    }
+}
new file mode 100644
--- /dev/null
+++ b/js/src/trace-test/tests/basic/testDoubleZeroInSwitch2.js
@@ -0,0 +1,9 @@
+var arr = Float32Array(1);
+arr[0] = 15;
+var a = arr[0];
+assertEq(a, 15);
+switch (a) {
+  case 15: break;
+  default: throw "FAIL";
+}
+