Fix overeager property cache fills, leading to wrong answers after certain JOF_INCDEC ops. Bug 614782, r=dmandelin.
authorJason Orendorff <jorendorff@mozilla.com>
Mon, 06 Dec 2010 15:34:30 -0600
changeset 58745 68de0c5b62557117a2abe16d752306958a3d0a9f
parent 58725 0d6d19884ccd0ba5214856f41d026c70f843143f
child 58746 0641328503d89713b0744e06f92c14ff882b910f
push id1
push usershaver@mozilla.com
push dateTue, 04 Jan 2011 17:58:04 +0000
reviewersdmandelin
bugs614782
milestone2.0b8pre
Fix overeager property cache fills, leading to wrong answers after certain JOF_INCDEC ops. Bug 614782, r=dmandelin.
js/src/jit-test/tests/basic/testIncDecReadOnly.js
js/src/jspropertycache.cpp
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/basic/testIncDecReadOnly.js
@@ -0,0 +1,22 @@
+var r;
+Object.defineProperty(this, "x", {value: 0, writable: false});
+
+for (var a = 0; a < 10; ++a)
+    r = ++x;
+assertEq(x, 0);
+assertEq(r, 1);
+
+for (var a = 0; a < 10; ++a)
+    r = --x;
+assertEq(x, 0);
+assertEq(r, -1);
+
+for (var a = 0; a < 10; ++a)
+    r = x++;
+assertEq(x, 0);
+assertEq(r, 0);
+
+for (var a = 0; a < 10; ++a)
+    r = x--;
+assertEq(x, 0);
+assertEq(r, 0);
--- a/js/src/jspropertycache.cpp
+++ b/js/src/jspropertycache.cpp
@@ -197,17 +197,17 @@ PropertyCache::fill(JSContext *cx, JSObj
             }
         }
 
         /*
          * If getting a value via a stub getter, or doing an INCDEC op
          * with stub getters and setters, we can cache the slot.
          */
         if (!(cs->format & (JOF_SET | JOF_FOR)) &&
-            (!(cs->format & JOF_INCDEC) || shape->hasDefaultSetter()) &&
+            (!(cs->format & JOF_INCDEC) || (shape->hasDefaultSetter() && shape->writable())) &&
             shape->hasDefaultGetter() &&
             pobj->containsSlot(shape->slot)) {
             /* Great, let's cache shape's slot and use it on cache hit. */
             vword.setSlot(shape->slot);
         } else {
             /* Best we can do is to cache shape (still a nice speedup). */
             vword.setShape(shape);
             if (adding &&