Fix constant folding bug in Uint8Clamped arrays (bug 624483, r=vlad).
authorDavid Anderson <danderson@mozilla.com>
Mon, 31 Jan 2011 12:46:09 -0800
changeset 61703 7fcc58bfd920b9e2fc9439ea0c10962f8d23736e
parent 61702 62ba32799f6fc8863358334a9d1ae2e2aeb51957
child 61704 caca24ca36cd721eb9e4ed371fa40258d3e7a278
push idunknown
push userunknown
push dateunknown
reviewersvlad
bugs624483
milestone2.0b11pre
Fix constant folding bug in Uint8Clamped arrays (bug 624483, r=vlad).
js/src/jit-test/tests/jaeger/bug624483.js
js/src/methodjit/TypedArrayIC.h
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/jaeger/bug624483.js
@@ -0,0 +1,5 @@
+var arr = new Uint8ClampedArray(16);
+for (var i = 0; i < 16; i++) {
+    arr[i] = "Infinity";
+}
+assertEq(arr[14], 255);
--- a/js/src/methodjit/TypedArrayIC.h
+++ b/js/src/methodjit/TypedArrayIC.h
@@ -173,44 +173,40 @@ ConstantFoldForIntArray(JSContext *cx, j
         vr->knownType() == JSVAL_TYPE_NULL) {
         *vr = ValueRemat::FromConstant(Int32Value(0));
         return true;
     }
 
     if (!vr->isConstant())
         return true;
 
-    if (vr->knownType() == JSVAL_TYPE_INT32) {
-        if (tarray->type == js::TypedArray::TYPE_UINT8_CLAMPED)
-            *vr = ValueRemat::FromConstant(Int32Value(ClampIntForUint8Array(vr->value().toInt32())));
-        return true;
-    }
-
+    // Convert from string to double first (see bug 624483).
     Value v = vr->value();
-    if (v.isDouble()) {
-        int32 i32 = tarray->type == js::TypedArray::TYPE_UINT8_CLAMPED
-                    ? js_TypedArray_uint8_clamp_double(v.toDouble())
-                    : js_DoubleToECMAInt32(v.toDouble());
-        *vr = ValueRemat::FromConstant(Int32Value(i32));
-        return true;
+    if (v.isString()) {
+        double d;
+        if (!StringToNumberType<double>(cx, v.toString(), &d))
+            return false;
+        v.setNumber(d);
     }
 
     int32 i32 = 0;
-    if (v.isString()) {
-        if (!StringToNumberType<int32>(cx, v.toString(), &i32))
-            return false;
+    if (v.isDouble()) {
+        i32 = (tarray->type == js::TypedArray::TYPE_UINT8_CLAMPED)
+              ? js_TypedArray_uint8_clamp_double(v.toDouble())
+              : js_DoubleToECMAInt32(v.toDouble());
+    } else if (v.isInt32()) {
+        i32 = v.toInt32();
+        if (tarray->type == js::TypedArray::TYPE_UINT8_CLAMPED)
+            i32 = ClampIntForUint8Array(i32);
     } else if (v.isBoolean()) {
         i32 = v.toBoolean() ? 1 : 0;
     } else {
         JS_NOT_REACHED("unknown constant type");
     }
 
-    if (tarray->type == js::TypedArray::TYPE_UINT8_CLAMPED)
-        i32 = ClampIntForUint8Array(i32);
-
     *vr = ValueRemat::FromConstant(Int32Value(i32));
 
     return true;
 }
 
 template <typename S, typename T>
 static void
 StoreToIntArray(Assembler &masm, js::TypedArray *tarray, S src, T address)