Bug 1297706 - Fix XDR decoding to use a nullptr sourceObject for nested lazy scripts. r=shu
authorJan de Mooij <jdemooij@mozilla.com>
Wed, 07 Sep 2016 09:11:06 +0200
changeset 312956 fa9899b5b63a7d097730e2df0bc82adcc0cd48c8
parent 312955 39135ac0e96152baa2220110df9bd766f0977646
child 312957 42dac4c946cbd89a269da27535fdce9c841dfa1c
push id30665
push usercbook@mozilla.com
push dateWed, 07 Sep 2016 15:20:43 +0000
treeherdermozilla-central@95acb9299faf [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersshu
bugs1297706
milestone51.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 1297706 - Fix XDR decoding to use a nullptr sourceObject for nested lazy scripts. r=shu
js/src/jsscript.cpp
js/src/jsscript.h
--- a/js/src/jsscript.cpp
+++ b/js/src/jsscript.cpp
@@ -937,30 +937,30 @@ js::XDRLazyScript(XDRState<mode>* xdr, H
             lazy.set(LazyScript::Create(cx, fun, nullptr, enclosingScope, enclosingScript,
                                         packedFields, begin, end, lineno, column));
             if (!lazy)
                 return false;
             fun->initLazyScript(lazy);
         }
     }
 
-    // Code free variables.
+    // Code closed-over bindings.
     if (!XDRLazyClosedOverBindings(xdr, lazy))
         return false;
 
     // Code inner functions.
     {
         RootedFunction func(cx);
         GCPtrFunction* innerFunctions = lazy->innerFunctions();
         size_t numInnerFunctions = lazy->numInnerFunctions();
         for (size_t i = 0; i < numInnerFunctions; i++) {
             if (mode == XDR_ENCODE)
                 func = innerFunctions[i];
 
-            if (!XDRInterpretedFunction(xdr, enclosingScope, enclosingScript, &func))
+            if (!XDRInterpretedFunction(xdr, nullptr, nullptr, &func))
                 return false;
 
             if (mode == XDR_DECODE)
                 innerFunctions[i] = func;
         }
     }
 
     return true;
@@ -3960,17 +3960,17 @@ LazyScript::Create(ExclusiveContext* cx,
 
     MOZ_ASSERT_IF(res, res->version() == version);
     return res;
 }
 
 /* static */ LazyScript*
 LazyScript::Create(ExclusiveContext* cx, HandleFunction fun,
                    HandleScript script, HandleScope enclosingScope,
-                   HandleScript sourceObjectScript,
+                   HandleScript enclosingScript,
                    uint64_t packedFields, uint32_t begin, uint32_t end,
                    uint32_t lineno, uint32_t column)
 {
     // Dummy atom which is not a valid property name.
     RootedAtom dummyAtom(cx, cx->names().comma);
 
     // Dummy function which is not a valid function as this is the one which is
     // holding this lazy script.
@@ -3986,20 +3986,25 @@ LazyScript::Create(ExclusiveContext* cx,
     JSAtom** closedOverBindings = res->closedOverBindings();
     for (i = 0, num = res->numClosedOverBindings(); i < num; i++)
         closedOverBindings[i] = dummyAtom;
 
     GCPtrFunction* functions = res->innerFunctions();
     for (i = 0, num = res->numInnerFunctions(); i < num; i++)
         functions[i].init(dummyFun);
 
-    // Set the enclosing scope of the lazy function, this would later be
-    // used to define the environment when the function would be used.
+    // Set the enclosing scope and source object of the lazy function. These
+    // values should only be non-null if we have a non-lazy enclosing script.
+    // AddLazyFunctionsForCompartment relies on the source object being null
+    // if we're nested inside another lazy function.
+    MOZ_ASSERT(!!enclosingScript == !!enclosingScope);
     MOZ_ASSERT(!res->sourceObject());
-    res->setEnclosingScopeAndSource(enclosingScope, &sourceObjectScript->scriptSourceUnwrap());
+    MOZ_ASSERT(!res->enclosingScope());
+    if (enclosingScript)
+        res->setEnclosingScopeAndSource(enclosingScope, &enclosingScript->scriptSourceUnwrap());
 
     MOZ_ASSERT(!res->hasScript());
     if (script)
         res->initScript(script);
 
     return res;
 }
 
--- a/js/src/jsscript.h
+++ b/js/src/jsscript.h
@@ -1900,21 +1900,21 @@ class LazyScript : public gc::TenuredCel
 
     // Create a LazyScript and initialize the closedOverBindings and the
     // innerFunctions with dummy values to be replaced in a later initialization
     // phase.
     //
     // The "script" argument to this function can be null.  If it's non-null,
     // then this LazyScript should be associated with the given JSScript.
     //
-    // The sourceObjectScript argument must be non-null and is the script that
-    // should be used to get the sourceObject_ of this lazyScript.
+    // The enclosingScript and enclosingScope arguments may be null if the
+    // enclosing function is also lazy.
     static LazyScript* Create(ExclusiveContext* cx, HandleFunction fun,
                               HandleScript script, HandleScope enclosingScope,
-                              HandleScript sourceObjectScript,
+                              HandleScript enclosingScript,
                               uint64_t packedData, uint32_t begin, uint32_t end,
                               uint32_t lineno, uint32_t column);
 
     void initRuntimeFields(uint64_t packedFields);
 
     inline JSFunction* functionDelazifying(JSContext* cx) const;
     JSFunction* functionNonDelazifying() const {
         return function_;