Bug 901106 - Pass nsXULPrototypeDocuments directly through serialization and use AutoSafeJSContext at the serialization point. r=smaug
authorBobby Holley <bobbyholley@gmail.com>
Mon, 19 Aug 2013 16:24:27 -0700
changeset 143154 d3b0012435d2955c43c4e22990d50e48505e5d8c
parent 143153 a7f5e4533a8cc70227a16b3a6a64308663a4ba29
child 143155 dfeae8aacc8b42078eaff1cd67e0601fdc406e06
push id1
push userroot
push dateMon, 20 Oct 2014 17:29:22 +0000
reviewerssmaug
bugs901106
milestone26.0a1
Bug 901106 - Pass nsXULPrototypeDocuments directly through serialization and use AutoSafeJSContext at the serialization point. r=smaug
content/xul/content/src/nsXULElement.cpp
content/xul/content/src/nsXULElement.h
content/xul/document/src/XULDocument.cpp
content/xul/document/src/nsXULContentSink.cpp
content/xul/document/src/nsXULPrototypeDocument.cpp
--- a/content/xul/content/src/nsXULElement.cpp
+++ b/content/xul/content/src/nsXULElement.cpp
@@ -42,17 +42,16 @@
 #include "nsIObjectOutputStream.h"
 #include "nsIPresShell.h"
 #include "nsIPrincipal.h"
 #include "nsIRDFCompositeDataSource.h"
 #include "nsIRDFNode.h"
 #include "nsIRDFService.h"
 #include "nsIScriptContext.h"
 #include "nsIScriptRuntime.h"
-#include "nsIScriptGlobalObject.h"
 #include "nsIScriptSecurityManager.h"
 #include "nsIServiceManager.h"
 #include "mozilla/css/StyleRule.h"
 #include "nsIStyleSheet.h"
 #include "nsIURL.h"
 #include "nsViewManager.h"
 #include "nsIWidget.h"
 #include "nsIXULDocument.h"
@@ -1986,17 +1985,17 @@ nsXULPrototypeAttribute::~nsXULPrototype
 
 //----------------------------------------------------------------------
 //
 // nsXULPrototypeElement
 //
 
 nsresult
 nsXULPrototypeElement::Serialize(nsIObjectOutputStream* aStream,
-                                 nsIScriptGlobalObject* aGlobal,
+                                 nsXULPrototypeDocument* aProtoDoc,
                                  const nsCOMArray<nsINodeInfo> *aNodeInfos)
 {
     nsresult rv;
 
     // Write basic prototype data
     rv = aStream->Write32(mType);
 
     // Write Node Info
@@ -2048,34 +2047,34 @@ nsXULPrototypeElement::Serialize(nsIObje
       rv = tmp;
     }
     for (i = 0; i < mChildren.Length(); i++) {
         nsXULPrototypeNode* child = mChildren[i].get();
         switch (child->mType) {
         case eType_Element:
         case eType_Text:
         case eType_PI:
-            tmp = child->Serialize(aStream, aGlobal, aNodeInfos);
+            tmp = child->Serialize(aStream, aProtoDoc, aNodeInfos);
             if (NS_FAILED(tmp)) {
               rv = tmp;
             }
             break;
         case eType_Script:
             tmp = aStream->Write32(child->mType);
             if (NS_FAILED(tmp)) {
               rv = tmp;
             }
             nsXULPrototypeScript* script = static_cast<nsXULPrototypeScript*>(child);
 
             tmp = aStream->Write8(script->mOutOfLine);
             if (NS_FAILED(tmp)) {
               rv = tmp;
             }
             if (! script->mOutOfLine) {
-                tmp = script->Serialize(aStream, aGlobal, aNodeInfos);
+                tmp = script->Serialize(aStream, aProtoDoc, aNodeInfos);
                 if (NS_FAILED(tmp)) {
                   rv = tmp;
                 }
             } else {
                 tmp = aStream->WriteCompoundObject(script->mSrcURI,
                                                    NS_GET_IID(nsIURI),
                                                    true);
                 if (NS_FAILED(tmp)) {
@@ -2083,32 +2082,32 @@ nsXULPrototypeElement::Serialize(nsIObje
                 }
 
                 if (script->GetScriptObject()) {
                     // This may return NS_OK without muxing script->mSrcURI's
                     // data into the cache file, in the case where that
                     // muxed document is already there (written by a prior
                     // session, or by an earlier cache episode during this
                     // session).
-                    tmp = script->SerializeOutOfLine(aStream, aGlobal);
+                    tmp = script->SerializeOutOfLine(aStream, aProtoDoc);
                     if (NS_FAILED(tmp)) {
                       rv = tmp;
                     }
                 }
             }
             break;
         }
     }
 
     return rv;
 }
 
 nsresult
 nsXULPrototypeElement::Deserialize(nsIObjectInputStream* aStream,
-                                   nsIScriptGlobalObject* aGlobal,
+                                   nsXULPrototypeDocument* aProtoDoc,
                                    nsIURI* aDocumentURI,
                                    const nsCOMArray<nsINodeInfo> *aNodeInfos)
 {
     NS_PRECONDITION(aNodeInfos, "missing nodeinfo array");
 
     // Read Node Info
     uint32_t number;
     nsresult rv = aStream->Read32(&number);
@@ -2172,41 +2171,41 @@ nsXULPrototypeElement::Deserialize(nsIOb
 
             switch (childType) {
             case eType_Element:
                 child = new nsXULPrototypeElement();
                 if (! child)
                     return NS_ERROR_OUT_OF_MEMORY;
                 child->mType = childType;
 
-                tmp = child->Deserialize(aStream, aGlobal, aDocumentURI,
+                tmp = child->Deserialize(aStream, aProtoDoc, aDocumentURI,
                                          aNodeInfos);
                 if (NS_FAILED(tmp)) {
                   rv = tmp;
                 }
                 break;
             case eType_Text:
                 child = new nsXULPrototypeText();
                 if (! child)
                     return NS_ERROR_OUT_OF_MEMORY;
                 child->mType = childType;
 
-                tmp = child->Deserialize(aStream, aGlobal, aDocumentURI,
+                tmp = child->Deserialize(aStream, aProtoDoc, aDocumentURI,
                                          aNodeInfos);
                 if (NS_FAILED(tmp)) {
                   rv = tmp;
                 }
                 break;
             case eType_PI:
                 child = new nsXULPrototypePI();
                 if (! child)
                     return NS_ERROR_OUT_OF_MEMORY;
                 child->mType = childType;
 
-                tmp = child->Deserialize(aStream, aGlobal, aDocumentURI,
+                tmp = child->Deserialize(aStream, aProtoDoc, aDocumentURI,
                                          aNodeInfos);
                 if (NS_FAILED(tmp)) {
                   rv = tmp;
                 }
                 break;
             case eType_Script: {
                 // language version/options obtained during deserialization.
                 nsXULPrototypeScript* script = new nsXULPrototypeScript(0, 0);
@@ -2215,28 +2214,28 @@ nsXULPrototypeElement::Deserialize(nsIOb
                 child = script;
                 child->mType = childType;
 
                 tmp = aStream->ReadBoolean(&script->mOutOfLine);
                 if (NS_FAILED(tmp)) {
                   rv = tmp;
                 }
                 if (! script->mOutOfLine) {
-                    tmp = script->Deserialize(aStream, aGlobal, aDocumentURI,
+                    tmp = script->Deserialize(aStream, aProtoDoc, aDocumentURI,
                                               aNodeInfos);
                     if (NS_FAILED(tmp)) {
                       rv = tmp;
                     }
                 } else {
                     tmp = aStream->ReadObject(true, getter_AddRefs(script->mSrcURI));
                     if (NS_FAILED(tmp)) {
                       rv = tmp;
                     }
 
-                    tmp = script->DeserializeOutOfLine(aStream, aGlobal);
+                    tmp = script->DeserializeOutOfLine(aStream, aProtoDoc);
                     if (NS_FAILED(tmp)) {
                       rv = tmp;
                     }
                 }
                 // If we failed to deserialize, consider deleting 'script'?
                 break;
             }
             default:
@@ -2366,21 +2365,24 @@ nsXULPrototypeScript::nsXULPrototypeScri
 
 nsXULPrototypeScript::~nsXULPrototypeScript()
 {
     UnlinkJSObjects();
 }
 
 nsresult
 nsXULPrototypeScript::Serialize(nsIObjectOutputStream* aStream,
-                                nsIScriptGlobalObject* aGlobal,
+                                nsXULPrototypeDocument* aProtoDoc,
                                 const nsCOMArray<nsINodeInfo> *aNodeInfos)
 {
-    nsIScriptContext *context = aGlobal->GetScriptContext();
-    AutoPushJSContext cx(context->GetNativeContext());
+    AutoSafeJSContext cx;
+    JS::Rooted<JSObject*> global(cx, aProtoDoc->GetCompilationGlobal());
+    NS_ENSURE_TRUE(global, NS_ERROR_UNEXPECTED);
+    JSAutoCompartment ac(cx, global);
+
     NS_ASSERTION(!mSrcLoading || mSrcLoadWaiters != nullptr ||
                  !mScriptObject,
                  "script source still loading when serializing?!");
     if (!mScriptObject)
         return NS_ERROR_FAILURE;
 
     // Write basic prototype data
     nsresult rv;
@@ -2397,17 +2399,17 @@ nsXULPrototypeScript::Serialize(nsIObjec
     MOZ_ASSERT(!strcmp(JS_GetClass(JS::CurrentGlobalOrNull(cx))->name,
                        "nsXULPrototypeScript compilation scope"));
     return nsContentUtils::XPConnect()->WriteScript(aStream, cx,
                                                     xpc_UnmarkGrayScript(script));
 }
 
 nsresult
 nsXULPrototypeScript::SerializeOutOfLine(nsIObjectOutputStream* aStream,
-                                         nsIScriptGlobalObject* aGlobal)
+                                         nsXULPrototypeDocument* aProtoDoc)
 {
     nsresult rv = NS_ERROR_NOT_IMPLEMENTED;
 
     bool isChrome = false;
     if (NS_FAILED(mSrcURI->SchemeIs("chrome", &isChrome)) || !isChrome)
        // Don't cache scripts that don't come from chrome uris.
        return rv;
 
@@ -2427,64 +2429,64 @@ nsXULPrototypeScript::SerializeOutOfLine
      */
     if (exists)
         return NS_OK;
 
     nsCOMPtr<nsIObjectOutputStream> oos;
     rv = cache->GetOutputStream(mSrcURI, getter_AddRefs(oos));
     NS_ENSURE_SUCCESS(rv, rv);
     
-    nsresult tmp = Serialize(oos, aGlobal, nullptr);
+    nsresult tmp = Serialize(oos, aProtoDoc, nullptr);
     if (NS_FAILED(tmp)) {
       rv = tmp;
     }
     tmp = cache->FinishOutputStream(mSrcURI);
     if (NS_FAILED(tmp)) {
       rv = tmp;
     }
 
     if (NS_FAILED(rv))
         cache->AbortCaching();
     return rv;
 }
 
 
 nsresult
 nsXULPrototypeScript::Deserialize(nsIObjectInputStream* aStream,
-                                  nsIScriptGlobalObject* aGlobal,
+                                  nsXULPrototypeDocument* aProtoDoc,
                                   nsIURI* aDocumentURI,
                                   const nsCOMArray<nsINodeInfo> *aNodeInfos)
 {
     NS_ASSERTION(!mSrcLoading || mSrcLoadWaiters != nullptr ||
                  !mScriptObject,
                  "prototype script not well-initialized when deserializing?!");
 
     // Read basic prototype data
     aStream->Read32(&mLineNo);
     aStream->Read32(&mLangVersion);
 
-    nsIScriptContext *context = aGlobal->GetScriptContext();
-    AutoPushJSContext cx(context->GetNativeContext());
-    NS_ASSERTION(context != nullptr, "Have no context for deserialization");
-    NS_ENSURE_TRUE(context, NS_ERROR_UNEXPECTED);
-    JSAutoRequest ar(cx);
+    AutoSafeJSContext cx;
+    JS::Rooted<JSObject*> global(cx, aProtoDoc->GetCompilationGlobal());
+    NS_ENSURE_TRUE(global, NS_ERROR_UNEXPECTED);
+    JSAutoCompartment ac(cx, global);
+
     JS::Rooted<JSScript*> newScriptObject(cx);
     MOZ_ASSERT(!strcmp(JS_GetClass(JS::CurrentGlobalOrNull(cx))->name,
                        "nsXULPrototypeScript compilation scope"));
     nsresult rv = nsContentUtils::XPConnect()->ReadScript(aStream, cx,
                                                           newScriptObject.address());
     NS_ENSURE_SUCCESS(rv, rv);
     Set(newScriptObject);
     return NS_OK;
 }
 
 
 nsresult
 nsXULPrototypeScript::DeserializeOutOfLine(nsIObjectInputStream* aInput,
-                                           nsIScriptGlobalObject* aGlobal)
+                                           nsXULPrototypeDocument* aProtoDoc)
 {
     // Keep track of failure via rv, so we can
     // AbortCaching if things look bad.
     nsresult rv = NS_OK;
     nsXULPrototypeCache* cache = nsXULPrototypeCache::GetInstance();
   
     nsCOMPtr<nsIObjectInputStream> objectInput = aInput;
     if (cache) {
@@ -2518,17 +2520,17 @@ nsXULPrototypeScript::DeserializeOutOfLi
  
             // We do reflect errors into rv, but our caller may want to
             // ignore our return value, because mScriptObject will be null
             // after any error, and that suffices to cause the script to
             // be reloaded (from the src= URI, if any) and recompiled.
             // We're better off slow-loading than bailing out due to a
             // error.
             if (NS_SUCCEEDED(rv))
-                rv = Deserialize(objectInput, aGlobal, nullptr, nullptr);
+                rv = Deserialize(objectInput, aProtoDoc, nullptr, nullptr);
 
             if (NS_SUCCEEDED(rv)) {
                 if (useXULCache && mSrcURI) {
                     bool isChrome = false;
                     mSrcURI->SchemeIs("chrome", &isChrome);
                     if (isChrome)
                         cache->PutScript(mSrcURI, GetScriptObject());
                 }
@@ -2673,17 +2675,17 @@ nsXULPrototypeScript::Set(JSScript* aObj
 
 //----------------------------------------------------------------------
 //
 // nsXULPrototypeText
 //
 
 nsresult
 nsXULPrototypeText::Serialize(nsIObjectOutputStream* aStream,
-                              nsIScriptGlobalObject* aGlobal,
+                              nsXULPrototypeDocument* aProtoDoc,
                               const nsCOMArray<nsINodeInfo> *aNodeInfos)
 {
     nsresult rv;
 
     // Write basic prototype data
     rv = aStream->Write32(mType);
 
     nsresult tmp = aStream->WriteWStringZ(mValue.get());
@@ -2691,17 +2693,17 @@ nsXULPrototypeText::Serialize(nsIObjectO
       rv = tmp;
     }
 
     return rv;
 }
 
 nsresult
 nsXULPrototypeText::Deserialize(nsIObjectInputStream* aStream,
-                                nsIScriptGlobalObject* aGlobal,
+                                nsXULPrototypeDocument* aProtoDoc,
                                 nsIURI* aDocumentURI,
                                 const nsCOMArray<nsINodeInfo> *aNodeInfos)
 {
     nsresult rv;
 
     rv = aStream->ReadString(mValue);
 
     return rv;
@@ -2709,17 +2711,17 @@ nsXULPrototypeText::Deserialize(nsIObjec
 
 //----------------------------------------------------------------------
 //
 // nsXULPrototypePI
 //
 
 nsresult
 nsXULPrototypePI::Serialize(nsIObjectOutputStream* aStream,
-                            nsIScriptGlobalObject* aGlobal,
+                            nsXULPrototypeDocument* aProtoDoc,
                             const nsCOMArray<nsINodeInfo> *aNodeInfos)
 {
     nsresult rv;
 
     // Write basic prototype data
     rv = aStream->Write32(mType);
 
     nsresult tmp = aStream->WriteWStringZ(mTarget.get());
@@ -2731,17 +2733,17 @@ nsXULPrototypePI::Serialize(nsIObjectOut
       rv = tmp;
     }
 
     return rv;
 }
 
 nsresult
 nsXULPrototypePI::Deserialize(nsIObjectInputStream* aStream,
-                              nsIScriptGlobalObject* aGlobal,
+                              nsXULPrototypeDocument* aProtoDoc,
                               nsIURI* aDocumentURI,
                               const nsCOMArray<nsINodeInfo> *aNodeInfos)
 {
     nsresult rv;
 
     rv = aStream->ReadString(mTarget);
     nsresult tmp = aStream->ReadString(mData);
     if (NS_FAILED(tmp)) {
--- a/content/xul/content/src/nsXULElement.h
+++ b/content/xul/content/src/nsXULElement.h
@@ -39,17 +39,16 @@
 
 class nsIDocument;
 class nsString;
 class nsIDocShell;
 class nsXULPrototypeDocument;
 
 class nsIObjectInputStream;
 class nsIObjectOutputStream;
-class nsIScriptGlobalObject;
 class nsXULPrototypeNode;
 typedef nsTArray<nsRefPtr<nsXULPrototypeNode> > nsPrototypeArray;
 
 namespace mozilla {
 namespace css {
 class StyleRule;
 }
 }
@@ -106,20 +105,20 @@ class nsXULPrototypeNode
 {
 public:
     enum Type { eType_Element, eType_Script, eType_Text, eType_PI };
 
     Type                     mType;
 
     virtual ~nsXULPrototypeNode() {}
     virtual nsresult Serialize(nsIObjectOutputStream* aStream,
-                               nsIScriptGlobalObject* aGlobal,
+                               nsXULPrototypeDocument* aProtoDoc,
                                const nsCOMArray<nsINodeInfo> *aNodeInfos) = 0;
     virtual nsresult Deserialize(nsIObjectInputStream* aStream,
-                                 nsIScriptGlobalObject* aGlobal,
+                                 nsXULPrototypeDocument* aProtoDoc,
                                  nsIURI* aDocumentURI,
                                  const nsCOMArray<nsINodeInfo> *aNodeInfos) = 0;
 
 #ifdef NS_BUILD_REFCNT_LOGGING
     virtual const char* ClassName() = 0;
     virtual uint32_t ClassSize() = 0;
 #endif
 
@@ -170,20 +169,20 @@ public:
             if (mChildren[i].get())
                 mChildren[i]->ReleaseSubtree();
         }
         mChildren.Clear();
         nsXULPrototypeNode::ReleaseSubtree();
     }
 
     virtual nsresult Serialize(nsIObjectOutputStream* aStream,
-                               nsIScriptGlobalObject* aGlobal,
+                               nsXULPrototypeDocument* aProtoDoc,
                                const nsCOMArray<nsINodeInfo> *aNodeInfos) MOZ_OVERRIDE;
     virtual nsresult Deserialize(nsIObjectInputStream* aStream,
-                                 nsIScriptGlobalObject* aGlobal,
+                                 nsXULPrototypeDocument* aProtoDoc,
                                  nsIURI* aDocumentURI,
                                  const nsCOMArray<nsINodeInfo> *aNodeInfos) MOZ_OVERRIDE;
 
     nsresult SetAttrAt(uint32_t aPos, const nsAString& aValue, nsIURI* aDocumentURI);
 
     void Unlink();
 
     // Trace all scripts held by this element and its children.
@@ -213,26 +212,26 @@ public:
     virtual ~nsXULPrototypeScript();
 
 #ifdef NS_BUILD_REFCNT_LOGGING
     virtual const char* ClassName() MOZ_OVERRIDE { return "nsXULPrototypeScript"; }
     virtual uint32_t ClassSize() MOZ_OVERRIDE { return sizeof(*this); }
 #endif
 
     virtual nsresult Serialize(nsIObjectOutputStream* aStream,
-                               nsIScriptGlobalObject* aGlobal,
+                               nsXULPrototypeDocument* aProtoDoc,
                                const nsCOMArray<nsINodeInfo> *aNodeInfos) MOZ_OVERRIDE;
     nsresult SerializeOutOfLine(nsIObjectOutputStream* aStream,
-                                nsIScriptGlobalObject* aGlobal);
+                                nsXULPrototypeDocument* aProtoDoc);
     virtual nsresult Deserialize(nsIObjectInputStream* aStream,
-                                 nsIScriptGlobalObject* aGlobal,
+                                 nsXULPrototypeDocument* aProtoDoc,
                                  nsIURI* aDocumentURI,
                                  const nsCOMArray<nsINodeInfo> *aNodeInfos) MOZ_OVERRIDE;
     nsresult DeserializeOutOfLine(nsIObjectInputStream* aInput,
-                                  nsIScriptGlobalObject* aGlobal);
+                                  nsXULPrototypeDocument* aProtoDoc);
 
     nsresult Compile(const PRUnichar* aText, int32_t aTextLength,
                      nsIURI* aURI, uint32_t aLineNo,
                      nsIDocument* aDocument,
                      nsXULPrototypeDocument* aProtoDoc,
                      nsIOffThreadScriptReceiver *aOffThreadReceiver = nullptr);
 
     void UnlinkJSObjects();
@@ -288,20 +287,20 @@ public:
     }
 
 #ifdef NS_BUILD_REFCNT_LOGGING
     virtual const char* ClassName() MOZ_OVERRIDE { return "nsXULPrototypeText"; }
     virtual uint32_t ClassSize() MOZ_OVERRIDE { return sizeof(*this); }
 #endif
 
     virtual nsresult Serialize(nsIObjectOutputStream* aStream,
-                               nsIScriptGlobalObject* aGlobal,
+                               nsXULPrototypeDocument* aProtoDoc,
                                const nsCOMArray<nsINodeInfo> *aNodeInfos) MOZ_OVERRIDE;
     virtual nsresult Deserialize(nsIObjectInputStream* aStream,
-                                 nsIScriptGlobalObject* aGlobal,
+                                 nsXULPrototypeDocument* aProtoDoc,
                                  nsIURI* aDocumentURI,
                                  const nsCOMArray<nsINodeInfo> *aNodeInfos) MOZ_OVERRIDE;
 
     nsString                 mValue;
 };
 
 class nsXULPrototypePI : public nsXULPrototypeNode
 {
@@ -316,20 +315,20 @@ public:
     }
 
 #ifdef NS_BUILD_REFCNT_LOGGING
     virtual const char* ClassName() MOZ_OVERRIDE { return "nsXULPrototypePI"; }
     virtual uint32_t ClassSize() MOZ_OVERRIDE { return sizeof(*this); }
 #endif
 
     virtual nsresult Serialize(nsIObjectOutputStream* aStream,
-                               nsIScriptGlobalObject* aGlobal,
+                               nsXULPrototypeDocument* aProtoDoc,
                                const nsCOMArray<nsINodeInfo> *aNodeInfos) MOZ_OVERRIDE;
     virtual nsresult Deserialize(nsIObjectInputStream* aStream,
-                                 nsIScriptGlobalObject* aGlobal,
+                                 nsXULPrototypeDocument* aProtoDoc,
                                  nsIURI* aDocumentURI,
                                  const nsCOMArray<nsINodeInfo> *aNodeInfos) MOZ_OVERRIDE;
 
     nsString                 mTarget;
     nsString                 mData;
 };
 
 ////////////////////////////////////////////////////////////////////////
--- a/content/xul/document/src/XULDocument.cpp
+++ b/content/xul/document/src/XULDocument.cpp
@@ -3610,30 +3610,18 @@ XULDocument::OnScriptCompileComplete(JSS
             // written, at the bottom of ResumeWalk.  That way, master
             // out-of-line scripts are serialized in the same order that
             // they'll be read, in the FastLoad file, which reduces the
             // number of seeks that dump the underlying stream's buffer.
             //
             // Ignore the return value, as we don't need to propagate
             // a failure to write to the FastLoad file, because this
             // method aborts that whole process on error.
-            nsIScriptGlobalObject* global =
-                mCurrentPrototype->GetScriptGlobalObject();
-
-            NS_ASSERTION(global != nullptr, "master prototype w/o global?!");
-            if (global) {
-                nsIScriptContext *scriptContext =
-                    global->GetScriptContext();
-                NS_ASSERTION(scriptContext != nullptr,
-                             "Failed to get script context for language");
-                if (scriptContext)
-                    scriptProto->SerializeOutOfLine(nullptr, global);
-            }
+            scriptProto->SerializeOutOfLine(nullptr, mCurrentPrototype);
         }
-
         // ignore any evaluation errors
     }
 
     rv = ResumeWalk();
 
     // Load a pointer to the prototype-script's list of XULDocuments who
     // raced to load the same script
     XULDocument** docp = &scriptProto->mSrcLoadWaiters;
--- a/content/xul/document/src/nsXULContentSink.cpp
+++ b/content/xul/document/src/nsXULContentSink.cpp
@@ -980,17 +980,17 @@ XULContentSinkImpl::OpenScript(const PRU
           if (NS_FAILED(rv)) {
               return rv;
           }
 
           // Attempt to deserialize an out-of-line script from the FastLoad
           // file right away.  Otherwise we'll end up reloading the script and
           // corrupting the FastLoad file trying to serialize it, in the case
           // where it's already there.
-          script->DeserializeOutOfLine(nullptr, mPrototype->GetScriptGlobalObject());
+          script->DeserializeOutOfLine(nullptr, mPrototype);
       }
 
       nsPrototypeArray* children = nullptr;
       rv = mContextStack.GetTopChildren(&children);
       if (NS_FAILED(rv)) {
           return rv;
       }
 
--- a/content/xul/document/src/nsXULPrototypeDocument.cpp
+++ b/content/xul/document/src/nsXULPrototypeDocument.cpp
@@ -344,26 +344,26 @@ nsXULPrototypeDocument::Read(nsIObjectIn
 
         if ((nsXULPrototypeNode::Type)type == nsXULPrototypeNode::eType_PI) {
             nsRefPtr<nsXULPrototypePI> pi = new nsXULPrototypePI();
             if (! pi) {
                rv = NS_ERROR_OUT_OF_MEMORY;
                break;
             }
 
-            tmp = pi->Deserialize(aStream, mGlobalObject, mURI, &nodeInfos);
+            tmp = pi->Deserialize(aStream, this, mURI, &nodeInfos);
             if (NS_FAILED(tmp)) {
               rv = tmp;
             }
             tmp = AddProcessingInstruction(pi);
             if (NS_FAILED(tmp)) {
               rv = tmp;
             }
         } else if ((nsXULPrototypeNode::Type)type == nsXULPrototypeNode::eType_Element) {
-            tmp = mRoot->Deserialize(aStream, mGlobalObject, mURI, &nodeInfos);
+            tmp = mRoot->Deserialize(aStream, this, mURI, &nodeInfos);
             if (NS_FAILED(tmp)) {
               rv = tmp;
             }
             break;
         } else {
             NS_NOTREACHED("Unexpected prototype node type");
             rv = NS_ERROR_FAILURE;
             break;
@@ -503,30 +503,27 @@ nsXULPrototypeDocument::Write(nsIObjectO
         nodeInfo->GetName(localName);
         tmp = aStream->WriteWStringZ(localName.get());
         if (NS_FAILED(tmp)) {
           rv = tmp;
         }
     }
 
     // Now serialize the document contents
-    nsIScriptGlobalObject* globalObject = GetScriptGlobalObject();
-    NS_ENSURE_TRUE(globalObject, NS_ERROR_UNEXPECTED);
-
     count = mProcessingInstructions.Length();
     for (i = 0; i < count; ++i) {
         nsXULPrototypePI* pi = mProcessingInstructions[i];
-        tmp = pi->Serialize(aStream, globalObject, &nodeInfos);
+        tmp = pi->Serialize(aStream, this, &nodeInfos);
         if (NS_FAILED(tmp)) {
           rv = tmp;
         }
     }
 
     if (mRoot) {
-      tmp = mRoot->Serialize(aStream, globalObject, &nodeInfos);
+      tmp = mRoot->Serialize(aStream, this, &nodeInfos);
       if (NS_FAILED(tmp)) {
         rv = tmp;
       }
     }
  
     return rv;
 }