Detect global object wrapping at recording time and on trace (495699, r=mrbkap).
authorAndreas Gal <gal@mozilla.com>
Mon, 01 Jun 2009 18:52:08 -0700
changeset 25864 e292a34f8844dbd0f01efe63adc755e9d2e462fb
parent 25863 71c7ae28fa74623de4bc6607b701674e289793e3
child 25865 50085f9b548eb0b69cb9549ed84103206ca7eca5
push id1645
push userrsayre@mozilla.com
push dateThu, 04 Jun 2009 16:54:53 +0000
reviewersmrbkap
bugs495699
milestone1.9.1pre
Detect global object wrapping at recording time and on trace (495699, r=mrbkap).
js/src/jstracer.cpp
--- a/js/src/jstracer.cpp
+++ b/js/src/jstracer.cpp
@@ -6665,28 +6665,36 @@ TraceRecorder::getThis(LIns*& this_ins)
         if (thisObj != globalObj)
             ABORT_TRACE("global object was wrapped while recording");
         this_ins = INS_CONSTPTR(thisObj);
         set(&thisv, this_ins);
         return JSRS_CONTINUE;
     }
     this_ins = get(&thisv);
 
-    /*
-     * mrbkap says its not necessary to ever call the thisObject hook if obj is not the global
-     * object, because the only implicit way to obtain a reference to an object that must be
-     * wrapped is via the global object. All other sources (API, explicit references) already
-     * are wrapped as we obtain them through XPConnect. The only exception are With objects,
-     * which have to call the getThis object hook. We don't trace those cases.
-     */
-    JS_ASSERT(original == thisv);
-
     if (guardClass(JSVAL_TO_OBJECT(thisv), this_ins, &js_WithClass, snapshot(MISMATCH_EXIT)))
         ABORT_TRACE("can't trace getThis on With object");
 
+    /*
+     * The only unwrapped object that needs to be wrapped that we can get here is the
+     * global object obtained throught the scope chain.
+     */
+    JS_ASSERT(JSVAL_IS_OBJECT(thisv));
+    JSObject* obj = js_GetWrappedObject(cx, JSVAL_TO_OBJECT(thisv));
+    OBJ_TO_INNER_OBJECT(cx, obj);
+    if (!obj)
+        return JSRS_ERROR;
+
+    JS_ASSERT(original == thisv || original == OBJECT_TO_JSVAL(obj));
+    this_ins = lir->ins_choose(lir->ins2(LIR_eq,
+                                         this_ins,
+                                         INS_CONSTPTR(obj)),
+                               INS_CONSTPTR(JSVAL_TO_OBJECT(thisv)),
+                               this_ins);
+
     return JSRS_CONTINUE;
 }
 
 
 LIns*
 TraceRecorder::getStringLength(LIns* str_ins)
 {
     LIns* len_ins = lir->insLoad(LIR_ldp, str_ins, (int)offsetof(JSString, length));