Bug 592992 - hoist outerizing from js::Invoke to js::ExternalInvoke (r=mrbkap)
authorLuke Wagner <lw@mozilla.com>
Wed, 10 Nov 2010 11:43:22 -0800
changeset 57761 6ecdb8a8a4955a999a530bf50b1f996a7b372bea
parent 57760 73886af75b65e41e1d9aa89e90255ff3cac8c777
child 57762 8c59a5bf187ba33ddf01f756e1acf5a438fd6434
push id1
push usershaver@mozilla.com
push dateTue, 04 Jan 2011 17:58:04 +0000
reviewersmrbkap
bugs592992
milestone2.0b8pre
Bug 592992 - hoist outerizing from js::Invoke to js::ExternalInvoke (r=mrbkap)
js/src/jsinterp.cpp
--- a/js/src/jsinterp.cpp
+++ b/js/src/jsinterp.cpp
@@ -724,39 +724,16 @@ Invoke(JSContext *cx, const CallArgs &ar
 
     /* Officially push fp. frame's destructor pops. */
     cx->stack().pushInvokeFrame(cx, args, &frame);
 
     /* Now that the new frame is rooted, maybe create a call object. */
     if (fun->isHeavyweight() && !js_GetCallObject(cx, fp))
         return false;
 
-    /*
-     * FIXME bug 592992: hoist to ExternalInvoke
-     *
-     * Compute |this|. Currently, this must happen after the frame is pushed
-     * and fp->scopeChain is correct because the thisObject hook may call
-     * GetScopeChain.
-     */
-    if (!(flags & JSINVOKE_CONSTRUCT)) {
-        Value &thisv = fp->functionThis();
-        if (thisv.isObject()) {
-            /*
-             * We must call the thisObject hook in case we are not called from the
-             * interpreter, where a prior bytecode has computed an appropriate
-             * |this| already.
-             */
-            JSObject *thisp = thisv.toObject().thisObject(cx);
-            if (!thisp)
-                 return false;
-            JS_ASSERT(IsSaneThisObject(*thisp));
-            thisv.setObject(*thisp);
-        }
-    }
-
     /* Run function until JSOP_STOP, JSOP_RETURN or error. */
     JSBool ok;
     {
         AutoPreserveEnumerators preserve(cx);
         ok = RunScript(cx, script, fp);
     }
 
     args.rval() = fp->returnValue();
@@ -800,25 +777,16 @@ InvokeSessionGuard::start(JSContext *cx,
         /* Push the stack frame once for the session. */
         uint32 flags = 0;
         if (!stack.getInvokeFrame(cx, args_, fun, script_, &flags, &frame_))
             return false;
         JSStackFrame *fp = frame_.fp();
         fp->initCallFrame(cx, calleev.toObject(), fun, argc, flags);
         stack.pushInvokeFrame(cx, args_, &frame_);
 
-        // FIXME bug 592992: hoist thisObject hook to ExternalInvoke
-        if (thisv.isObject()) {
-            JSObject *thisp = thisv.toObject().thisObject(cx);
-            if (!thisp)
-                return false;
-            JS_ASSERT(IsSaneThisObject(*thisp));
-            savedThis_.setObject(*thisp);
-        }
-
 #ifdef JS_METHODJIT
         /* Hoist dynamic checks from RunScript. */
         mjit::CompileStatus status = mjit::CanMethodJIT(cx, script_, fp);
         if (status == mjit::Compile_Error)
             return false;
         if (status != mjit::Compile_Okay)
             break;
         code_ = script_->getJIT(fp->isConstructing())->invokeEntry;
@@ -864,16 +832,29 @@ ExternalInvoke(JSContext *cx, const Valu
     InvokeArgsGuard args;
     if (!cx->stack().pushInvokeArgs(cx, argc, &args))
         return false;
 
     args.callee() = fval;
     args.thisv() = thisv;
     memcpy(args.argv(), argv, argc * sizeof(Value));
 
+    if (args.thisv().isObject()) {
+        /*
+         * We must call the thisObject hook in case we are not called from the
+         * interpreter, where a prior bytecode has computed an appropriate
+         * |this| already.
+         */
+        JSObject *thisp = args.thisv().toObject().thisObject(cx);
+        if (!thisp)
+             return false;
+        JS_ASSERT(IsSaneThisObject(*thisp));
+        args.thisv().setObject(*thisp);
+    }
+
     if (!Invoke(cx, args, 0))
         return false;
 
     *rval = args.rval();
     return true;
 }
 
 bool