Bug 658213. Just pass an JSContext to ReparentContentWrappersInScope. r=peterv
authorBoris Zbarsky <bzbarsky@mit.edu>
Thu, 19 May 2011 16:05:46 -0400
changeset 70326 f4273556fc422836d1c9169093c03aed9f18f684
parent 70325 52b8caaeb1d93f4958134ed9061de0bd914dccfb
child 70327 930a3a994ee5505ccadd36932b3ee72f725d8a60
push id20286
push userMs2ger@gmail.com
push dateMon, 30 May 2011 11:39:02 +0000
treeherdermozilla-central@0acc408d9a67 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerspeterv
bugs658213
milestone7.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 658213. Just pass an JSContext to ReparentContentWrappersInScope. r=peterv
content/base/public/nsContentUtils.h
content/base/src/nsContentUtils.cpp
content/html/document/src/nsHTMLDocument.cpp
content/html/document/src/nsHTMLDocument.h
dom/base/nsDOMClassInfo.cpp
dom/interfaces/html/nsIDOMHTMLDocument.idl
js/src/xpconnect/src/dom_quickstubs.qsconf
--- a/content/base/public/nsContentUtils.h
+++ b/content/base/public/nsContentUtils.h
@@ -211,17 +211,18 @@ public:
   static nsresult GetContextAndScope(nsIDocument *aOldDocument,
                                      nsIDocument *aNewDocument,
                                      JSContext **aCx, JSObject **aNewScope);
 
   /**
    * When a document's scope changes (e.g., from document.open(), call this
    * function to move all content wrappers from the old scope to the new one.
    */
-  static nsresult ReparentContentWrappersInScope(nsIScriptGlobalObject *aOldScope,
+  static nsresult ReparentContentWrappersInScope(JSContext *cx,
+                                                 nsIScriptGlobalObject *aOldScope,
                                                  nsIScriptGlobalObject *aNewScope);
 
   static PRBool   IsCallerChrome();
 
   static PRBool   IsCallerTrustedForRead();
 
   static PRBool   IsCallerTrustedForWrite();
 
--- a/content/base/src/nsContentUtils.cpp
+++ b/content/base/src/nsContentUtils.cpp
@@ -1331,52 +1331,20 @@ nsContentUtils::GetContextAndScope(nsIDo
 
   *aCx = cx;
   *aNewScope = newScope;
 
   return NS_OK;
 }
 
 nsresult
-nsContentUtils::ReparentContentWrappersInScope(nsIScriptGlobalObject *aOldScope,
+nsContentUtils::ReparentContentWrappersInScope(JSContext *cx,
+                                               nsIScriptGlobalObject *aOldScope,
                                                nsIScriptGlobalObject *aNewScope)
 {
-  JSContext *cx = nsnull;
-
-  // Try really hard to find a context to work on.
-  nsIScriptContext *context = aOldScope->GetContext();
-  if (context) {
-    cx = static_cast<JSContext *>(context->GetNativeContext());
-  }
-
-  if (!cx) {
-    context = aNewScope->GetContext();
-    if (context) {
-      cx = static_cast<JSContext *>(context->GetNativeContext());
-    }
-
-    if (!cx) {
-      sThreadJSContextStack->Peek(&cx);
-
-      if (!cx) {
-        sThreadJSContextStack->GetSafeJSContext(&cx);
-
-        if (!cx) {
-          // Wow, this is really bad!
-          NS_WARNING("No context reachable in ReparentContentWrappers()!");
-
-          return NS_ERROR_NOT_AVAILABLE;
-        }
-      }
-    }
-  }
-
-  // Now that we have a context, let's get the global objects from the two
-  // scopes and ask XPConnect to do the rest of the work.
-
   JSObject *oldScopeObj = aOldScope->GetGlobalJSObject();
   JSObject *newScopeObj = aNewScope->GetGlobalJSObject();
 
   if (!newScopeObj || !oldScopeObj) {
     // We can't really do anything without the JSObjects.
 
     return NS_ERROR_NOT_AVAILABLE;
   }
--- a/content/html/document/src/nsHTMLDocument.cpp
+++ b/content/html/document/src/nsHTMLDocument.cpp
@@ -1513,17 +1513,18 @@ nsHTMLDocument::SetCookie(const nsAStrin
     service->SetCookieString(codebaseURI, prompt, cookie.get(), mChannel);
   }
 
   return NS_OK;
 }
 
 // XXX TBI: accepting arguments to the open method.
 nsresult
-nsHTMLDocument::OpenCommon(const nsACString& aContentType, PRBool aReplace)
+nsHTMLDocument::OpenCommon(JSContext *cx, const nsACString& aContentType,
+                           PRBool aReplace)
 {
   if (!IsHTML() || mDisableDocWrite) {
     // No calling document.open() on XHTML
 
     return NS_ERROR_DOM_INVALID_STATE_ERR;
   }
 
   PRBool loadAsHtml5 = nsHtml5Module::sEnabled;
@@ -1681,17 +1682,17 @@ nsHTMLDocument::OpenCommon(const nsACStr
 
     // Now make sure we're not flagged as the initial document anymore, now
     // that we've had stuff done to us.  From now on, if anyone tries to
     // document.open() us, they get a new inner window.
     SetIsInitialDocument(PR_FALSE);
 
     nsCOMPtr<nsIScriptGlobalObject> newScope(do_QueryReferent(mScopeObject));
     if (oldScope && newScope != oldScope) {
-      nsContentUtils::ReparentContentWrappersInScope(oldScope, newScope);
+      nsContentUtils::ReparentContentWrappersInScope(cx, oldScope, newScope);
     }
   }
 
   // Call Reset(), this will now do the full reset
   Reset(channel, group);
   if (baseURI) {
     mDocumentBaseURI = baseURI;
   }
@@ -1762,19 +1763,19 @@ nsHTMLDocument::OpenCommon(const nsACStr
 
   --mWriteLevel;
 
   return rv;
 }
 
 NS_IMETHODIMP
 nsHTMLDocument::Open(const nsACString& aContentType, PRBool aReplace,
-                     nsIDOMDocument** aReturn)
+                     JSContext *cx, nsIDOMDocument** aReturn)
 {
-  nsresult rv = OpenCommon(aContentType, aReplace);
+  nsresult rv = OpenCommon(cx, aContentType, aReplace);
   NS_ENSURE_SUCCESS(rv, rv);
 
   return CallQueryInterface(this, aReturn);
 }
 
 NS_IMETHODIMP
 nsHTMLDocument::Clear()
 {
@@ -1838,17 +1839,18 @@ nsHTMLDocument::Close()
     NS_ASSERTION(!mWyciwygChannel, "nsHTMLDocument::Close(): "
                  "nsIWyciwygChannel could not be removed!");
   }
 
   return NS_OK;
 }
 
 nsresult
-nsHTMLDocument::WriteCommon(const nsAString& aText,
+nsHTMLDocument::WriteCommon(JSContext *cx,
+                            const nsAString& aText,
                             PRBool aNewlineTerminate)
 {
   mTooDeepWriteRecursion =
     (mWriteLevel > NS_MAX_DOCUMENT_WRITE_DEPTH || mTooDeepWriteRecursion);
   NS_ENSURE_STATE(!mTooDeepWriteRecursion);
 
   if (!IsHTML() || mDisableDocWrite) {
     // No calling document.write*() on XHTML!
@@ -1887,17 +1889,17 @@ nsHTMLDocument::WriteCommon(const nsAStr
                                       nsnull, 0,
                                       mDocumentURI,
                                       EmptyString(), 0, 0,
                                       nsIScriptError::warningFlag,
                                       "DOM Events", this);
       return NS_OK;
     }
     nsCOMPtr<nsIDOMDocument> ignored;
-    rv = Open(NS_LITERAL_CSTRING("text/html"), PR_FALSE,
+    rv = Open(NS_LITERAL_CSTRING("text/html"), PR_FALSE, cx,
               getter_AddRefs(ignored));
 
     // If Open() fails, or if it didn't create a parser (as it won't
     // if the user chose to not discard the current document through
     // onbeforeunload), don't write anything.
     if (NS_FAILED(rv) || !mParser) {
       return rv;
     }
@@ -1935,25 +1937,25 @@ nsHTMLDocument::WriteCommon(const nsAStr
   --mWriteLevel;
 
   mTooDeepWriteRecursion = (mWriteLevel != 0 && mTooDeepWriteRecursion);
 
   return rv;
 }
 
 NS_IMETHODIMP
-nsHTMLDocument::Write(const nsAString& aText)
+nsHTMLDocument::Write(const nsAString& aText, JSContext *cx)
 {
-  return WriteCommon(aText, PR_FALSE);
+  return WriteCommon(cx, aText, PR_FALSE);
 }
 
 NS_IMETHODIMP
-nsHTMLDocument::Writeln(const nsAString& aText)
+nsHTMLDocument::Writeln(const nsAString& aText, JSContext *cx)
 {
-  return WriteCommon(aText, PR_TRUE);
+  return WriteCommon(cx, aText, PR_TRUE);
 }
 
 PRBool
 nsHTMLDocument::MatchNameAttribute(nsIContent* aContent, PRInt32 aNamespaceID,
                                    nsIAtom* aAtom, void* aData)
 {
   NS_PRECONDITION(aContent, "Must have content node to work with!");
   nsString* elementName = static_cast<nsString*>(aData);
--- a/content/html/document/src/nsHTMLDocument.h
+++ b/content/html/document/src/nsHTMLDocument.h
@@ -228,19 +228,20 @@ protected:
   static PRBool MatchNameAttribute(nsIContent* aContent, PRInt32 aNamespaceID,
                                    nsIAtom* aAtom, void* aData);
   static void* UseExistingNameString(nsINode* aRootNode, const nsString* aName);
 
   static void DocumentWriteTerminationFunc(nsISupports *aRef);
 
   void GetDomainURI(nsIURI **uri);
 
-  nsresult WriteCommon(const nsAString& aText,
+  nsresult WriteCommon(JSContext *cx, const nsAString& aText,
                        PRBool aNewlineTerminate);
-  nsresult OpenCommon(const nsACString& aContentType, PRBool aReplace);
+  nsresult OpenCommon(JSContext *cx, const nsACString& aContentType,
+                      PRBool aReplace);
 
   nsresult CreateAndAddWyciwygChannel(void);
   nsresult RemoveWyciwygChannel(void);
 
   /**
    * Like IsEditingOn(), but will flush as needed first.
    */
   PRBool IsEditingOnAfterFlush();
--- a/dom/base/nsDOMClassInfo.cpp
+++ b/dom/base/nsDOMClassInfo.cpp
@@ -8981,17 +8981,17 @@ nsHTMLDocumentSH::DocumentOpen(JSContext
       nsDOMClassInfo::ThrowJSException(cx, NS_ERROR_OUT_OF_MEMORY);
       return JS_FALSE;
     }
 
     replace = NS_LITERAL_STRING("replace").Equals(chars);
   }
 
   nsCOMPtr<nsIDOMDocument> retval;
-  nsresult rv = doc->Open(contentType, replace, getter_AddRefs(retval));
+  nsresult rv = doc->Open(contentType, replace, cx, getter_AddRefs(retval));
   if (NS_FAILED(rv)) {
     nsDOMClassInfo::ThrowJSException(cx, rv);
 
     return JS_FALSE;
   }
 
   *vp = OBJECT_TO_JSVAL(obj);
   return NS_SUCCEEDED(rv);
--- a/dom/interfaces/html/nsIDOMHTMLDocument.idl
+++ b/dom/interfaces/html/nsIDOMHTMLDocument.idl
@@ -34,24 +34,28 @@
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #include "nsIDOMDocument.idl"
 
+%{C++
+#include "jspubtd.h"
+%}
+
 /**
  * The nsIDOMHTMLDocument interface is the interface to a [X]HTML
  * document object.
  *
  * @see <http://www.whatwg.org/html/>
  */
 
-[scriptable, uuid(6dd39b10-65ec-46f3-8c41-939300f6a7ce)]
+[scriptable, uuid(3c0ca40f-72c5-4d15-935e-ccaff7953f2c)]
 interface nsIDOMHTMLDocument : nsIDOMDocument
 {
   readonly attribute DOMString            URL;
            attribute DOMString            domain;
            attribute DOMString            cookie;
   // returns "BackCompat" if we're in quirks mode,
   // or "CSS1Compat" if we're in strict mode
   readonly attribute DOMString            compatMode;
@@ -69,21 +73,24 @@ interface nsIDOMHTMLDocument : nsIDOMDoc
 
   // This is the internal version of open(); note that the version
   // scriptable with JS is defined entirely in classinfo.
   // If aContentType is not something supported by nsHTMLDocument and
   // the HTML content sink, trying to write to the document will
   // probably throw.
   // Pass aReplace = true to trigger a replacement of the previous
   // document in session history; pass false for normal history handling.
+  [implicit_jscontext]
   nsIDOMDocument            open(in ACString aContentType,
                                  in boolean aReplace);
   void                      close();
 
+  [implicit_jscontext]
   void                      write([optional, Null(Stringify)] in DOMString text);
+  [implicit_jscontext]
   void                      writeln([optional, Null(Stringify)] in DOMString text);
 
   /**
    * Midas additions
    */
   attribute DOMString       designMode;
 
   boolean                   execCommand(in DOMString commandID,
--- a/js/src/xpconnect/src/dom_quickstubs.qsconf
+++ b/js/src/xpconnect/src/dom_quickstubs.qsconf
@@ -548,17 +548,17 @@ nsIDOMHTMLDocument_Write_customMethodCal
                                xpc_qsDOMString::eStringify,
                                xpc_qsDOMString::eStringify);
       if (!next_arg.IsValid())
         return JS_FALSE;
 
       str.Append(next_arg);
     }
 
-    rv = self->%s(arg0);
+    rv = self->%s(arg0, cx);
 """
 
 nsIDOMStorage_Clear_customMethodCallCode = """
     rv = self->Clear();
     if (NS_SUCCEEDED(rv))
         JS_ClearScope(cx, obj);
 """