Bug 613692. Make sure to update what our current value is when doing type conversions inside incHelper. r=dvander
authorBoris Zbarsky <bzbarsky@mit.edu>
Tue, 23 Nov 2010 14:08:26 -0500
changeset 58282 fe0e393e35303dfcf2923a647e9fcaad7de2b96a
parent 58078 870bb8ee43e62221b89d2dc8d9aa9ccd41cbc3a3
child 58283 9e628f0c5b100f5f9083e2189df4adcbd4e8a363
push id1
push usershaver@mozilla.com
push dateTue, 04 Jan 2011 17:58:04 +0000
reviewersdvander
bugs613692
milestone2.0b8pre
Bug 613692. Make sure to update what our current value is when doing type conversions inside incHelper. r=dvander
js/src/jit-test/tests/basic/testUndefinedIncrement.js
js/src/jstracer.cpp
js/src/jstracer.h
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/basic/testUndefinedIncrement.js
@@ -0,0 +1,15 @@
+function f() {
+    for (var i = 0; i < 2*RUNLOOP; ++i) {
+	var n = undefined;
+	if (n++) { }
+    }
+}
+
+f();
+
+checkStats({
+    recorderStarted: 1,
+    recorderAborted: 0,
+    traceCompleted: 1,
+    traceTriggered: 1
+});
--- a/js/src/jstracer.cpp
+++ b/js/src/jstracer.cpp
@@ -8676,26 +8676,30 @@ TraceRecorder::inc(const Value &v, LIns*
     v_ins = v_after;
     return RECORD_CONTINUE;
 }
 
 /*
  * Do an increment operation without storing anything to the stack.
  */
 JS_REQUIRES_STACK RecordingStatus
-TraceRecorder::incHelper(const Value &v, LIns* v_ins, LIns*& v_after, jsint incr)
+TraceRecorder::incHelper(const Value &v, LIns*& v_ins, LIns*& v_after, jsint incr)
 {
     // FIXME: Bug 606071 on making this work for objects.
     if (!v.isPrimitive())
         RETURN_STOP("can inc primitives only");
 
+    // We need to modify |v_ins| the same way relational() modifies
+    // its RHS and LHS.
     if (v.isUndefined()) {
         v_after = w.immd(js_NaN);
+        v_ins = w.immd(js_NaN);
     } else if (v.isNull()) {
         v_after = w.immd(incr);
+        v_ins = w.immd(0.0);
     } else {
         if (v.isBoolean()) {
             v_ins = w.i2d(v_ins);
         } else if (v.isString()) {
             LIns* args[] = { v_ins, cx_ins };
             v_ins = w.call(&js_StringToNumber_ci, args);
         } else {
             JS_ASSERT(v.isNumber());
--- a/js/src/jstracer.h
+++ b/js/src/jstracer.h
@@ -1289,17 +1289,17 @@ class TraceRecorder
     JS_REQUIRES_STACK AbortableRecordingStatus ifop();
     JS_REQUIRES_STACK RecordingStatus switchop();
 #ifdef NANOJIT_IA32
     JS_REQUIRES_STACK AbortableRecordingStatus tableswitch();
 #endif
     JS_REQUIRES_STACK RecordingStatus inc(Value& v, jsint incr, bool pre = true);
     JS_REQUIRES_STACK RecordingStatus inc(const Value &v, nanojit::LIns*& v_ins, jsint incr,
                                             bool pre = true);
-    JS_REQUIRES_STACK RecordingStatus incHelper(const Value &v, nanojit::LIns* v_ins,
+    JS_REQUIRES_STACK RecordingStatus incHelper(const Value &v, nanojit::LIns*& v_ins,
                                                   nanojit::LIns*& v_after, jsint incr);
     JS_REQUIRES_STACK AbortableRecordingStatus incProp(jsint incr, bool pre = true);
     JS_REQUIRES_STACK RecordingStatus incElem(jsint incr, bool pre = true);
     JS_REQUIRES_STACK AbortableRecordingStatus incName(jsint incr, bool pre = true);
 
     JS_REQUIRES_STACK void strictEquality(bool equal, bool cmpCase);
     JS_REQUIRES_STACK AbortableRecordingStatus equality(bool negate, bool tryBranchAfterCond);
     JS_REQUIRES_STACK AbortableRecordingStatus equalityHelper(Value& l, Value& r,