Bug 895774 - Fix ScriptFrameIter::computeThis with multiple compartments and contexts; r=jandem
authorNick Fitzgerald <fitzgen@gmail.com>
Wed, 31 Jul 2013 10:59:23 -0700
changeset 148160 6938e78dbe4f01583644cfb2c7340e7b9cae1094
parent 148159 9b4975efc31f58c991816f95f26e42a762a84e0f
child 148161 05a97e13092cd0bde0d2491f5c0126ddc0c3661c
push id2697
push userbbajaj@mozilla.com
push dateMon, 05 Aug 2013 18:49:53 +0000
treeherdermozilla-beta@dfec938c7b63 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjandem
bugs895774
milestone24.0a2
Bug 895774 - Fix ScriptFrameIter::computeThis with multiple compartments and contexts; r=jandem
js/src/jit-test/tests/basic/testBug895774.js
js/src/jsdbgapi.cpp
js/src/vm/Debugger.cpp
js/src/vm/Stack.cpp
js/src/vm/Stack.h
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/basic/testBug895774.js
@@ -0,0 +1,14 @@
+var g1 = newGlobal();
+var g2 = newGlobal();
+g1.eval("function f1() { debugger; evaluate('debugger', {newContext:true}) }");
+g2.eval("function f2() { f1(); assertEq(Number(this), 42) }");
+g2.f1 = g1.f1;
+
+var dbg = new Debugger(g1,g2);
+dbg.onDebuggerStatement = function(frame) {
+    var target = frame.older;
+    dbg.onDebuggerStatement = function(frame) {
+        assertEq(Number(target.this.unsafeDereference()), 42);
+    }
+}
+g2.f2.call(42);
--- a/js/src/jsdbgapi.cpp
+++ b/js/src/jsdbgapi.cpp
@@ -1058,17 +1058,17 @@ FormatFrame(JSContext *cx, const NonBuil
         JSAbstractFramePtr frame(Jsvalify(iter.abstractFramePtr()));
         callObj = frame.callObject(cx);
         if (callObj)
             callProps.fetch(callObj);
     }
 
     RootedValue thisVal(cx);
     AutoPropertyDescArray thisProps(cx);
-    if (iter.computeThis()) {
+    if (iter.computeThis(cx)) {
         thisVal = iter.thisv();
         if (showThisProps && !thisVal.isPrimitive())
             thisProps.fetch(&thisVal.toObject());
     }
 
     // print the frame number and function name
     if (funname) {
         JSAutoByteString funbytes;
--- a/js/src/vm/Debugger.cpp
+++ b/js/src/vm/Debugger.cpp
@@ -3811,17 +3811,17 @@ DebuggerFrame_getConstructing(JSContext 
 
 static JSBool
 DebuggerFrame_getThis(JSContext *cx, unsigned argc, Value *vp)
 {
     THIS_FRAME(cx, argc, vp, "get this", args, thisobj, iter);
     RootedValue thisv(cx);
     {
         AutoCompartment ac(cx, iter.scopeChain());
-        if (!iter.computeThis())
+        if (!iter.computeThis(cx))
             return false;
         thisv = iter.thisv();
     }
     if (!Debugger::fromChildJSObject(thisobj)->wrapDebuggeeValue(cx, &thisv))
         return false;
     args.rval().set(thisv);
     return true;
 }
@@ -4184,17 +4184,17 @@ DebuggerGenericEval(JSContext *cx, const
         ac.construct(cx, iter->scopeChain());
     else
         ac.construct(cx, scope);
 
     RootedValue thisv(cx);
     Rooted<Env *> env(cx);
     if (iter) {
         /* ExecuteInEnv requires 'fp' to have a computed 'this" value. */
-        if (!iter->computeThis())
+        if (!iter->computeThis(cx))
             return false;
         thisv = iter->thisv();
         env = GetDebugScopeForFrame(cx, iter->abstractFramePtr());
         if (!env)
             return false;
     } else {
         thisv = ObjectValue(*scope);
         env = scope;
--- a/js/src/vm/Stack.cpp
+++ b/js/src/vm/Stack.cpp
@@ -1123,22 +1123,22 @@ ScriptFrameIter::argsObj() const
       case SCRIPTED:
         return interpFrame()->argsObj();
     }
     JS_NOT_REACHED("Unexpected state");
     return interpFrame()->argsObj();
 }
 
 bool
-ScriptFrameIter::computeThis() const
+ScriptFrameIter::computeThis(JSContext *cx) const
 {
     JS_ASSERT(!done());
     if (!isIon()) {
-        JS_ASSERT(data_.cx_);
-        return ComputeThis(data_.cx_, abstractFramePtr());
+        assertSameCompartment(cx, scopeChain());
+        return ComputeThis(cx, abstractFramePtr());
     }
     return true;
 }
 
 Value
 ScriptFrameIter::thisv() const
 {
     switch (data_.state_) {
--- a/js/src/vm/Stack.h
+++ b/js/src/vm/Stack.h
@@ -1512,17 +1512,17 @@ class ScriptFrameIter
 
     JSObject   *scopeChain() const;
     CallObject &callObj() const;
 
     bool        hasArgsObj() const;
     ArgumentsObject &argsObj() const;
 
     // Ensure that thisv is correct, see ComputeThis.
-    bool        computeThis() const;
+    bool        computeThis(JSContext *cx) const;
     Value       thisv() const;
 
     Value       returnValue() const;
     void        setReturnValue(const Value &v);
 
     JSFunction *maybeCallee() const {
         return isFunctionFrame() ? callee() : NULL;
     }