Bug 1145491 part 6. Fix script cloning to propagate the polluted-global-scope state to the lambda templates in the script. r=luke
☠☠ backed out by 3b7a4d9da546 ☠ ☠
authorBoris Zbarsky <bzbarsky@mit.edu>
Fri, 20 Mar 2015 21:34:18 -0400
changeset 263680 7be39afdf528795236b3d2bd82ff796947e195a7
parent 263679 8066b21e74a00e4613ddbf27d70777c95dd27c69
child 263681 8d14c6661f003cbe0aabf38268bddf2b20abba04
push id4718
push userraliiev@mozilla.com
push dateMon, 11 May 2015 18:39:53 +0000
treeherdermozilla-beta@c20c4ef55f08 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersluke
bugs1145491
milestone39.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1145491 part 6. Fix script cloning to propagate the polluted-global-scope state to the lambda templates in the script. r=luke
js/src/jit-test/tests/basic/weird-scopechains.js
js/src/jsfun.cpp
js/src/jsfun.h
js/src/jsscript.cpp
--- a/js/src/jit-test/tests/basic/weird-scopechains.js
+++ b/js/src/jit-test/tests/basic/weird-scopechains.js
@@ -6,16 +6,25 @@ function assertWithMessage(got, expected
     assertEq(message + ": " + got, message + ": " + expected);
 }
 
 // Create our test func via "evaluate" so it won't be compileAndGo and
 // we can clone it.
 evaluate(`function testFunc() {
     assertWithMessage(checkNameLookup(), "local", "nameLookup");
     assertWithMessage(checkThisBinding(), "local", "thisBinding");
+
+    // Important: lambda needs to close over "reason", so it won't just get the
+    // scope of testFunc as its scope.  Instead it'll get the Call object
+    // "reason" lives in.
+    var reason = " in lambda in Call";
+    (function() {
+	assertWithMessage(checkNameLookup(), "local", "nameLookup" + reason);
+	assertWithMessage(checkThisBinding(), "local", "thisBinding" + reason);
+    })();
 }`, { compileAndGo: false });
 
 var obj = {
     checkNameLookup: function() {
 	return "local";
     },
 
     checkThisBinding: function() {
--- a/js/src/jsfun.cpp
+++ b/js/src/jsfun.cpp
@@ -638,17 +638,18 @@ js::XDRInterpretedFunction(XDRState<mode
 
 template bool
 js::XDRInterpretedFunction(XDRState<XDR_ENCODE> *, HandleObject, HandleScript, MutableHandleFunction);
 
 template bool
 js::XDRInterpretedFunction(XDRState<XDR_DECODE> *, HandleObject, HandleScript, MutableHandleFunction);
 
 JSObject *
-js::CloneFunctionAndScript(JSContext *cx, HandleObject enclosingScope, HandleFunction srcFun)
+js::CloneFunctionAndScript(JSContext *cx, HandleObject enclosingScope, HandleFunction srcFun,
+                           PollutedGlobalScopeOption polluted)
 {
     /* NB: Keep this in sync with XDRInterpretedFunction. */
     RootedObject cloneProto(cx);
     if (srcFun->isStarGenerator()) {
         cloneProto = GlobalObject::getOrCreateStarGeneratorFunctionPrototype(cx, cx->global());
         if (!cloneProto)
             return nullptr;
     }
@@ -660,17 +661,17 @@ js::CloneFunctionAndScript(JSContext *cx
                                                   JSFunction::INTERPRETED, NullPtr(), NullPtr(),
                                                   cloneProto, allocKind, TenuredObject));
     if (!clone)
         return nullptr;
 
     RootedScript srcScript(cx, srcFun->getOrCreateScript(cx));
     if (!srcScript)
         return nullptr;
-    RootedScript clonedScript(cx, CloneScript(cx, enclosingScope, clone, srcScript));
+    RootedScript clonedScript(cx, CloneScript(cx, enclosingScope, clone, srcScript, polluted));
     if (!clonedScript)
         return nullptr;
 
     clone->setArgCount(srcFun->nargs());
     clone->setFlags(srcFun->flags());
     clone->initAtom(srcFun->displayAtom());
     clone->initScript(clonedScript);
     clonedScript->setFunction(clone);
--- a/js/src/jsfun.h
+++ b/js/src/jsfun.h
@@ -649,17 +649,18 @@ namespace js {
 JSString *FunctionToString(JSContext *cx, HandleFunction fun, bool bodyOnly, bool lambdaParen);
 
 template<XDRMode mode>
 bool
 XDRInterpretedFunction(XDRState<mode> *xdr, HandleObject enclosingScope,
                        HandleScript enclosingScript, MutableHandleFunction objp);
 
 extern JSObject *
-CloneFunctionAndScript(JSContext *cx, HandleObject enclosingScope, HandleFunction fun);
+CloneFunctionAndScript(JSContext *cx, HandleObject enclosingScope, HandleFunction fun,
+                       PollutedGlobalScopeOption polluted);
 
 /*
  * Report an error that call.thisv is not compatible with the specified class,
  * assuming that the method (clasp->name).prototype.<name of callee function>
  * is what was called.
  */
 extern void
 ReportIncompatibleMethod(JSContext *cx, CallReceiver call, const Class *clasp);
--- a/js/src/jsscript.cpp
+++ b/js/src/jsscript.cpp
@@ -3026,17 +3026,17 @@ js::CloneScript(JSContext *cx, HandleObj
                     RootedObject enclosingScope(cx);
                     if (ssi.done() || ssi.type() == StaticScopeIter<CanGC>::Function)
                         enclosingScope = fun;
                     else if (ssi.type() == StaticScopeIter<CanGC>::Block)
                         enclosingScope = objects[FindScopeObjectIndex(src, ssi.block())];
                     else
                         enclosingScope = objects[FindScopeObjectIndex(src, ssi.staticWith())];
 
-                    clone = CloneFunctionAndScript(cx, enclosingScope, innerFun);
+                    clone = CloneFunctionAndScript(cx, enclosingScope, innerFun, polluted);
                 }
             } else {
                 /*
                  * Clone object literals emitted for the JSOP_NEWOBJECT opcode. We only emit that
                  * instead of the less-optimized JSOP_NEWINIT for self-hosted code or code compiled
                  * with JSOPTION_COMPILE_N_GO set. As we don't clone the latter type of code, this
                  * case should only ever be hit when cloning objects from self-hosted code.
                  */