Bug 609502 - Fix edge cases in charCodeAt and Math.abs (r=nnethercote,gal, a=blocker)
authorPaul Biggar <pbiggar@mozilla.com>
Mon, 13 Dec 2010 16:22:59 -0800
changeset 59235 e5090c9f6be394214f2efbfa87496084c391a51d
parent 59234 aae231781a45859dd573778419333c3393c0e046
child 59236 421dafd0878e5ed3d5a92ac1d565261cd458be2b
push id1
push usershaver@mozilla.com
push dateTue, 04 Jan 2011 17:58:04 +0000
reviewersnnethercote, gal, blocker
bugs609502
milestone2.0b8pre
Bug 609502 - Fix edge cases in charCodeAt and Math.abs (r=nnethercote,gal, a=blocker)
js/src/jit-test/tests/basic/bug609502-1.js
js/src/jit-test/tests/basic/bug609502-2.js
js/src/jit-test/tests/basic/bug609502-3.js
js/src/jstracer.cpp
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/basic/bug609502-1.js
@@ -0,0 +1,9 @@
+for(var i = 0; i < RUNLOOP; i++) {
+      x = ''.charCodeAt(NaN);
+}
+
+for(var i = 0; i < RUNLOOP; i++) {
+      x = ''.charAt(NaN);
+}
+
+// Don't assert
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/basic/bug609502-2.js
@@ -0,0 +1,5 @@
+for (var i = 0; i < RUNLOOP; i++) {
+    Math.abs(-2147483648)
+}
+
+// Don't assert
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/basic/bug609502-3.js
@@ -0,0 +1,11 @@
+{
+      function a() {}
+}
+Math.floor(Math.d)
+  function c() {}
+  c()
+  for each(let b in [0, 0, 0, 0, 0, 0, 0, -2147483648]) {
+        print(Math.abs(b))
+  }
+
+// Don't assert
--- a/js/src/jstracer.cpp
+++ b/js/src/jstracer.cpp
@@ -11167,17 +11167,17 @@ TraceRecorder::callNative(uintN argc, JS
                     if (ceilReturningInt(vp[2].toNumber(), &result))
                         return callFloatReturningInt(argc, &ceilReturningInt_ci);
                 } else if (native == js_math_round) {
                     if (roundReturningInt(vp[2].toNumber(), &result))
                         return callFloatReturningInt(argc, &roundReturningInt_ci);
                 }
             } else if (native == js_math_abs) {
                 LIns* a = get(&vp[2]);
-                if (IsPromoteInt(a)) {
+                if (IsPromoteInt(a) && vp[2].toNumber() != INT_MIN) {
                     a = w.demote(a);
                     /* abs(INT_MIN) can't be done using integers;  exit if we see it. */
                     LIns* intMin_ins = w.name(w.immi(0x80000000), "INT_MIN");
                     LIns* isIntMin_ins = w.name(w.eqi(a, intMin_ins), "isIntMin");
                     guard(false, isIntMin_ins, MISMATCH_EXIT);
                     LIns* neg_ins = w.negi(a);
                     LIns* isNeg_ins = w.name(w.ltiN(a, 0), "isNeg");
                     LIns* abs_ins = w.name(w.cmovi(isNeg_ins, neg_ins, a), "abs");
@@ -11185,27 +11185,31 @@ TraceRecorder::callNative(uintN argc, JS
                     pendingSpecializedNative = IGNORE_NATIVE_CALL_COMPLETE_CALLBACK;
                     return RECORD_CONTINUE;
                 }
             }
             if (vp[1].isString()) {
                 JSString *str = vp[1].toString();
                 if (native == js_str_charAt) {
                     jsdouble i = vp[2].toNumber();
+                    if (JSDOUBLE_IS_NaN(i))
+                      i = 0;
                     if (i < 0 || i >= str->length())
                         RETURN_STOP("charAt out of bounds");
                     LIns* str_ins = get(&vp[1]);
                     LIns* idx_ins = get(&vp[2]);
                     LIns* char_ins;
                     CHECK_STATUS(getCharAt(str, str_ins, idx_ins, mode, &char_ins));
                     set(&vp[0], char_ins);
                     pendingSpecializedNative = IGNORE_NATIVE_CALL_COMPLETE_CALLBACK;
                     return RECORD_CONTINUE;
                 } else if (native == js_str_charCodeAt) {
                     jsdouble i = vp[2].toNumber();
+                    if (JSDOUBLE_IS_NaN(i))
+                      i = 0;
                     if (i < 0 || i >= str->length())
                         RETURN_STOP("charCodeAt out of bounds");
                     LIns* str_ins = get(&vp[1]);
                     LIns* idx_ins = get(&vp[2]);
                     LIns* charCode_ins;
                     CHECK_STATUS(getCharCodeAt(str, str_ins, idx_ins, &charCode_ins));
                     set(&vp[0], charCode_ins);
                     pendingSpecializedNative = IGNORE_NATIVE_CALL_COMPLETE_CALLBACK;