Fix for bug 816088 (webIDL bindings try to extract nsISupports from the global object in static properties in workers). r=bz.
authorPeter Van der Beken <peterv@propagandism.org>
Mon, 03 Dec 2012 17:07:49 +0100
changeset 130742 260de4b5771da6d1b644b8f3a9a85312d2c55f34
parent 130741 15500baebbc56cd7b923c048cebdb17c974bd603
child 130743 68e0432939c9fc98a10fd41ee9d21e633474dd2d
push idunknown
push userunknown
push dateunknown
reviewersbz
bugs816088
milestone21.0a1
Fix for bug 816088 (webIDL bindings try to extract nsISupports from the global object in static properties in workers). r=bz.
content/base/public/nsIDocument.h
content/base/src/EventSource.cpp
content/base/src/EventSource.h
content/base/src/WebSocket.cpp
content/base/src/WebSocket.h
content/base/src/nsDOMMutationObserver.cpp
content/base/src/nsDOMMutationObserver.h
content/base/src/nsDOMParser.cpp
content/base/src/nsDOMParser.h
content/base/src/nsDOMSerializer.h
content/base/src/nsDocument.cpp
content/base/src/nsFormData.cpp
content/base/src/nsFormData.h
content/base/src/nsXMLHttpRequest.h
content/media/webaudio/AudioContext.cpp
content/media/webaudio/AudioContext.h
content/xslt/src/xpath/nsXPathEvaluator.cpp
content/xslt/src/xpath/nsXPathEvaluator.h
dom/base/URL.cpp
dom/base/URL.h
dom/bindings/BindingDeclarations.h
dom/bindings/BindingUtils.cpp
dom/bindings/Codegen.py
dom/bindings/test/TestBindingHeader.h
dom/bindings/test/TestCodeGen.webidl
dom/bindings/test/TestExampleGen.webidl
dom/encoding/TextDecoder.h
dom/encoding/TextEncoder.h
dom/workers/FileReaderSync.cpp
dom/workers/FileReaderSync.h
dom/workers/TextDecoder.cpp
dom/workers/TextDecoder.h
dom/workers/TextEncoder.cpp
dom/workers/TextEncoder.h
dom/workers/XMLHttpRequest.cpp
dom/workers/XMLHttpRequest.h
layout/style/CSS.cpp
layout/style/CSS.h
--- a/content/base/public/nsIDocument.h
+++ b/content/base/public/nsIDocument.h
@@ -86,16 +86,17 @@ class ImageLoader;
 
 namespace dom {
 class CDATASection;
 class Comment;
 class DocumentFragment;
 class DocumentType;
 class DOMImplementation;
 class Element;
+class GlobalObject;
 class HTMLBodyElement;
 class Link;
 class ProcessingInstruction;
 class UndoManager;
 template<typename> class Sequence;
 } // namespace dom
 } // namespace mozilla
 
@@ -1796,18 +1797,19 @@ public:
     return mCreatingStaticClone;
   }
 
   // WebIDL API
   nsIScriptGlobalObject* GetParentObject() const
   {
     return GetScopeObject();
   }
-  static already_AddRefed<nsIDocument> Constructor(nsISupports* aGlobal,
-                                                   mozilla::ErrorResult& rv);
+  static already_AddRefed<nsIDocument>
+    Constructor(const mozilla::dom::GlobalObject& aGlobal,
+                mozilla::ErrorResult& rv);
   virtual mozilla::dom::DOMImplementation*
     GetImplementation(mozilla::ErrorResult& rv) = 0;
   void GetURL(nsString& retval) const;
   void GetDocumentURI(nsString& retval) const;
   void GetCompatMode(nsString& retval) const;
   void GetCharacterSet(nsAString& retval) const;
   // Skip GetContentType, because our NS_IMETHOD version above works fine here.
   // GetDoctype defined above
--- a/content/base/src/EventSource.cpp
+++ b/content/base/src/EventSource.cpp
@@ -279,22 +279,23 @@ EventSource::Init(nsISupports* aOwner,
 
 /* virtual */ JSObject*
 EventSource::WrapObject(JSContext* aCx, JSObject* aScope, bool* aTriedToWrap)
 {
   return EventSourceBinding::Wrap(aCx, aScope, this, aTriedToWrap);
 }
 
 /* static */ already_AddRefed<EventSource>
-EventSource::Constructor(nsISupports* aOwner, const nsAString& aURL,
+EventSource::Constructor(const GlobalObject& aGlobal, const nsAString& aURL,
                          const EventSourceInit& aEventSourceInitDict,
                          ErrorResult& aRv)
 {
   nsRefPtr<EventSource> eventSource = new EventSource();
-  aRv = eventSource->Init(aOwner, aURL, aEventSourceInitDict.mWithCredentials);
+  aRv = eventSource->Init(aGlobal.Get(), aURL,
+                          aEventSourceInitDict.mWithCredentials);
   return eventSource.forget();
 }
 
 //-----------------------------------------------------------------------------
 // EventSource::nsIObserver
 //-----------------------------------------------------------------------------
 
 NS_IMETHODIMP
--- a/content/base/src/EventSource.h
+++ b/content/base/src/EventSource.h
@@ -70,17 +70,17 @@ public:
 
   // WebIDL
   nsPIDOMWindow*
   GetParentObject() const
   {
     return GetOwner();
   }
   static already_AddRefed<EventSource>
-  Constructor(nsISupports* aOwner, const nsAString& aURL,
+  Constructor(const GlobalObject& aGlobal, const nsAString& aURL,
               const EventSourceInit& aEventSourceInitDict,
               ErrorResult& aRv);
 
   void GetUrl(nsAString& aURL) const
   {
     aURL = mOriginalURL;
   }
   bool WithCredentials() const
--- a/content/base/src/WebSocket.cpp
+++ b/content/base/src/WebSocket.cpp
@@ -482,68 +482,69 @@ WebSocket::WrapObject(JSContext* cx, JSO
 }
 
 //---------------------------------------------------------------------------
 // WebIDL
 //---------------------------------------------------------------------------
 
 // Constructor:
 already_AddRefed<WebSocket>
-WebSocket::Constructor(JSContext* aCx,
-                       nsISupports* aGlobal,
+WebSocket::Constructor(const GlobalObject& aGlobal,
+                       JSContext* aCx,
                        const nsAString& aUrl,
                        ErrorResult& aRv)
 {
   Sequence<nsString> protocols;
-  return WebSocket::Constructor(aCx, aGlobal, aUrl, protocols, aRv);
+  return WebSocket::Constructor(aGlobal, aCx, aUrl, protocols, aRv);
 }
 
 already_AddRefed<WebSocket>
-WebSocket::Constructor(JSContext* aCx,
-                       nsISupports* aGlobal,
+WebSocket::Constructor(const GlobalObject& aGlobal,
+                       JSContext* aCx,
                        const nsAString& aUrl,
                        const nsAString& aProtocol,
                        ErrorResult& aRv)
 {
   Sequence<nsString> protocols;
   protocols.AppendElement(aProtocol);
-  return WebSocket::Constructor(aCx, aGlobal, aUrl, protocols, aRv);
+  return WebSocket::Constructor(aGlobal, aCx, aUrl, protocols, aRv);
 }
 
 already_AddRefed<WebSocket>
-WebSocket::Constructor(JSContext* aCx,
-                       nsISupports* aGlobal,
+WebSocket::Constructor(const GlobalObject& aGlobal,
+                       JSContext* aCx,
                        const nsAString& aUrl,
                        const Sequence<nsString>& aProtocols,
                        ErrorResult& aRv)
 {
   if (!PrefEnabled()) {
     aRv.Throw(NS_ERROR_DOM_SECURITY_ERR);
     return nullptr;
   }
 
-  nsCOMPtr<nsIScriptObjectPrincipal> scriptPrincipal = do_QueryInterface(aGlobal);
+  nsCOMPtr<nsIScriptObjectPrincipal> scriptPrincipal =
+    do_QueryInterface(aGlobal.Get());
   if (!scriptPrincipal) {
     aRv.Throw(NS_ERROR_FAILURE);
     return nullptr;
   }
 
   nsCOMPtr<nsIPrincipal> principal = scriptPrincipal->GetPrincipal();
   if (!principal) {
     aRv.Throw(NS_ERROR_FAILURE);
     return nullptr;
   }
 
-  nsCOMPtr<nsIScriptGlobalObject> sgo = do_QueryInterface(aGlobal);
+  nsCOMPtr<nsIScriptGlobalObject> sgo = do_QueryInterface(aGlobal.Get());
   if (!sgo) {
     aRv.Throw(NS_ERROR_FAILURE);
     return nullptr;
   }
 
-  nsCOMPtr<nsPIDOMWindow> ownerWindow = do_QueryInterface(aGlobal);
+  nsCOMPtr<nsPIDOMWindow> ownerWindow = do_QueryInterface(aGlobal.Get());
   if (!ownerWindow) {
     aRv.Throw(NS_ERROR_FAILURE);
     return nullptr;
   }
 
   nsTArray<nsString> protocolArray;
 
   for (uint32_t index = 0, len = aProtocols.Length(); index < len; ++index) {
--- a/content/base/src/WebSocket.h
+++ b/content/base/src/WebSocket.h
@@ -93,29 +93,29 @@ public:
 public: // static helpers:
 
   // Determine if preferences allow WebSocket
   static bool PrefEnabled();
 
 public: // WebIDL interface:
 
   // Constructor:
-  static already_AddRefed<WebSocket> Constructor(JSContext *aCx,
-                                                 nsISupports* aGlobal,
+  static already_AddRefed<WebSocket> Constructor(const GlobalObject& aGlobal,
+                                                 JSContext *aCx,
                                                  const nsAString& aUrl,
                                                  ErrorResult& rv);
 
-  static already_AddRefed<WebSocket> Constructor(JSContext *aCx,
-                                                 nsISupports* aGlobal,
+  static already_AddRefed<WebSocket> Constructor(const GlobalObject& aGlobal,
+                                                 JSContext *aCx,
                                                  const nsAString& aUrl,
                                                  const nsAString& aProtocol,
                                                  ErrorResult& rv);
 
-  static already_AddRefed<WebSocket> Constructor(JSContext *aCx,
-                                                 nsISupports* aGlobal,
+  static already_AddRefed<WebSocket> Constructor(const GlobalObject& aGlobal,
+                                                 JSContext *aCx,
                                                  const nsAString& aUrl,
                                                  const Sequence<nsString>& aProtocols,
                                                  ErrorResult& rv);
 
   // webIDL: readonly attribute DOMString url
   void GetUrl(nsAString& aResult);
 
   // webIDL: readonly attribute unsigned short readyState;
--- a/content/base/src/nsDOMMutationObserver.cpp
+++ b/content/base/src/nsDOMMutationObserver.cpp
@@ -543,21 +543,21 @@ nsDOMMutationObserver::TakeRecords(
                          nsTArray<nsRefPtr<nsDOMMutationRecord> >& aRetVal)
 {
   aRetVal.Clear();
   mPendingMutations.SwapElements(aRetVal);
 }
 
 // static
 already_AddRefed<nsDOMMutationObserver>
-nsDOMMutationObserver::Constructor(nsISupports* aGlobal,
+nsDOMMutationObserver::Constructor(const mozilla::dom::GlobalObject& aGlobal,
                                    mozilla::dom::MutationCallback& aCb,
                                    mozilla::ErrorResult& aRv)
 {
-  nsCOMPtr<nsPIDOMWindow> window = do_QueryInterface(aGlobal);
+  nsCOMPtr<nsPIDOMWindow> window = do_QueryInterface(aGlobal.Get());
   if (!window) {
     aRv.Throw(NS_ERROR_FAILURE);
     return nullptr;
   }
   MOZ_ASSERT(window->IsInnerWindow());
   nsRefPtr<nsDOMMutationObserver> observer =
     new nsDOMMutationObserver(window.forget(), aCb);
   return observer.forget();
--- a/content/base/src/nsDOMMutationObserver.h
+++ b/content/base/src/nsDOMMutationObserver.h
@@ -350,17 +350,18 @@ public:
     mTransientReceivers.Init();
     SetIsDOMBinding();
   }
   virtual ~nsDOMMutationObserver();
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(nsDOMMutationObserver)
 
   static already_AddRefed<nsDOMMutationObserver>
-  Constructor(nsISupports* aGlobal, mozilla::dom::MutationCallback& aCb,
+  Constructor(const mozilla::dom::GlobalObject& aGlobal,
+              mozilla::dom::MutationCallback& aCb,
               mozilla::ErrorResult& aRv);
 
   virtual JSObject* WrapObject(JSContext* aCx, JSObject* aScope,
                                bool* aTriedToWrap)
   {
     return mozilla::dom::MutationObserverBinding::Wrap(aCx, aScope,
                                                        this, aTriedToWrap);
   }
--- a/content/base/src/nsDOMParser.cpp
+++ b/content/base/src/nsDOMParser.cpp
@@ -348,34 +348,35 @@ nsDOMParser::Init(nsIPrincipal* principa
 
   NS_POSTCONDITION(mPrincipal, "Must have principal");
   NS_POSTCONDITION(mOriginalPrincipal, "Must have original principal");
   NS_POSTCONDITION(mDocumentURI, "Must have document URI");
   return NS_OK;
 }
 
 /*static */already_AddRefed<nsDOMParser>
-nsDOMParser::Constructor(nsISupports* aOwner, nsIPrincipal* aPrincipal,
+nsDOMParser::Constructor(const GlobalObject& aOwner, nsIPrincipal* aPrincipal,
                          nsIURI* aDocumentURI, nsIURI* aBaseURI,
                          ErrorResult& rv)
 {
   if (!nsContentUtils::IsCallerChrome()) {
     rv.Throw(NS_ERROR_DOM_SECURITY_ERR);
     return nullptr;
   }
-  nsRefPtr<nsDOMParser> domParser = new nsDOMParser(aOwner);
-  rv = domParser->InitInternal(aOwner, aPrincipal, aDocumentURI, aBaseURI);
+  nsRefPtr<nsDOMParser> domParser = new nsDOMParser(aOwner.Get());
+  rv = domParser->InitInternal(aOwner.Get(), aPrincipal, aDocumentURI,
+                               aBaseURI);
   if (rv.Failed()) {
     return nullptr;
   }
   return domParser.forget();
 }
 
 /*static */already_AddRefed<nsDOMParser>
-nsDOMParser::Constructor(nsISupports* aOwner, mozilla::ErrorResult& rv)
+nsDOMParser::Constructor(const GlobalObject& aOwner, ErrorResult& rv)
 {
   nsCOMPtr<nsIPrincipal> prin;
   nsCOMPtr<nsIURI> documentURI;
   nsCOMPtr<nsIURI> baseURI;
   // No arguments; use the subject principal
   nsIScriptSecurityManager* secMan = nsContentUtils::GetSecurityManager();
   if (!secMan) {
     rv.Throw(NS_ERROR_UNEXPECTED);
@@ -388,18 +389,18 @@ nsDOMParser::Constructor(nsISupports* aO
   }
 
   // We're called from JS; there better be a subject principal, really.
   if (!prin) {
     rv.Throw(NS_ERROR_UNEXPECTED);
     return nullptr;
   }
 
-  nsRefPtr<nsDOMParser> domParser = new nsDOMParser(aOwner);
-  rv = domParser->InitInternal(aOwner, prin, documentURI, baseURI);
+  nsRefPtr<nsDOMParser> domParser = new nsDOMParser(aOwner.Get());
+  rv = domParser->InitInternal(aOwner.Get(), prin, documentURI, baseURI);
   if (rv.Failed()) {
     return nullptr;
   }
   return domParser.forget();
 }
 
 nsresult
 nsDOMParser::InitInternal(nsISupports* aOwner, nsIPrincipal* prin,
--- a/content/base/src/nsDOMParser.h
+++ b/content/base/src/nsDOMParser.h
@@ -27,21 +27,22 @@ public:
   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_AMBIGUOUS(nsDOMParser,
                                                          nsIDOMParser)
 
   // nsIDOMParser
   NS_DECL_NSIDOMPARSER
 
   // WebIDL API
   static already_AddRefed<nsDOMParser>
-  Constructor(nsISupports* aOwner, mozilla::ErrorResult& rv);
+  Constructor(const mozilla::dom::GlobalObject& aOwner,
+              mozilla::ErrorResult& rv);
 
   static already_AddRefed<nsDOMParser>
-  Constructor(nsISupports* aOwner, nsIPrincipal* aPrincipal,
-              nsIURI* aDocumentURI, nsIURI* aBaseURI,
+  Constructor(const mozilla::dom::GlobalObject& aOwner,
+              nsIPrincipal* aPrincipal, nsIURI* aDocumentURI, nsIURI* aBaseURI,
               mozilla::ErrorResult& rv);
 
   already_AddRefed<nsIDocument>
   ParseFromString(const nsAString& aStr, mozilla::dom::SupportedType aType,
                   mozilla::ErrorResult& rv);
 
   already_AddRefed<nsIDocument>
   ParseFromBuffer(const mozilla::dom::Sequence<uint8_t>& aBuf,
--- a/content/base/src/nsDOMSerializer.h
+++ b/content/base/src/nsDOMSerializer.h
@@ -24,19 +24,20 @@ public:
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(nsDOMSerializer)
 
   // nsIDOMSerializer
   NS_DECL_NSIDOMSERIALIZER
 
   // WebIDL API
   static already_AddRefed<nsDOMSerializer>
-  Constructor(nsISupports* aOwner, mozilla::ErrorResult& rv)
+  Constructor(const mozilla::dom::GlobalObject& aOwner,
+              mozilla::ErrorResult& rv)
   {
-    nsRefPtr<nsDOMSerializer> domSerializer = new nsDOMSerializer(aOwner);
+    nsRefPtr<nsDOMSerializer> domSerializer = new nsDOMSerializer(aOwner.Get());
     return domSerializer.forget();
   }
 
   void
   SerializeToString(nsINode& aRoot, nsAString& aStr,
                     mozilla::ErrorResult& rv);
 
   void
--- a/content/base/src/nsDocument.cpp
+++ b/content/base/src/nsDocument.cpp
@@ -10444,25 +10444,25 @@ nsDocument::DocSizeOfExcludingThis(nsWin
                                        aWindowSizes->mMallocSizeOf);
 
   // Measurement of the following members may be added later if DMD finds it
   // is worthwhile:
   // - many!
 }
 
 already_AddRefed<nsIDocument>
-nsIDocument::Constructor(nsISupports* aGlobal, ErrorResult& rv)
-{
-  nsCOMPtr<nsIScriptGlobalObject> global = do_QueryInterface(aGlobal);
+nsIDocument::Constructor(const GlobalObject& aGlobal, ErrorResult& rv)
+{
+  nsCOMPtr<nsIScriptGlobalObject> global = do_QueryInterface(aGlobal.Get());
   if (!global) {
     rv.Throw(NS_ERROR_UNEXPECTED);
     return nullptr;
   }
 
-  nsCOMPtr<nsIScriptObjectPrincipal> prin = do_QueryInterface(aGlobal);
+  nsCOMPtr<nsIScriptObjectPrincipal> prin = do_QueryInterface(aGlobal.Get());
   if (!prin) {
     rv.Throw(NS_ERROR_UNEXPECTED);
     return nullptr;
   }
 
   nsCOMPtr<nsIURI> uri;
   NS_NewURI(getter_AddRefs(uri), "about:blank");
   if (!uri) {
--- a/content/base/src/nsFormData.cpp
+++ b/content/base/src/nsFormData.cpp
@@ -101,21 +101,21 @@ nsFormData::Append(const nsAString& aNam
 
 /* virtual */ JSObject*
 nsFormData::WrapObject(JSContext* aCx, JSObject* aScope, bool* aTriedToWrap)
 {
   return FormDataBinding::Wrap(aCx, aScope, this, aTriedToWrap);
 }
 
 /* static */ already_AddRefed<nsFormData>
-nsFormData::Constructor(nsISupports* aGlobal,
+nsFormData::Constructor(const GlobalObject& aGlobal,
                         const Optional<nsHTMLFormElement*>& aFormElement,
                         ErrorResult& aRv)
 {
-  nsRefPtr<nsFormData> formData = new nsFormData(aGlobal);
+  nsRefPtr<nsFormData> formData = new nsFormData(aGlobal.Get());
   if (aFormElement.WasPassed()) {
     MOZ_ASSERT(aFormElement.Value());
     aRv = aFormElement.Value()->WalkFormElements(formData);
   }
   return formData.forget();
 }
 
 // -------------------------------------------------------------------------
--- a/content/base/src/nsFormData.h
+++ b/content/base/src/nsFormData.h
@@ -14,16 +14,17 @@
 
 class nsHTMLFormElement;
 class nsIDOMFile;
 
 namespace mozilla {
 class ErrorResult;
 
 namespace dom {
+class GlobalObject;
 template<class> class Optional;
 } // namespace dom
 } // namespace mozilla
 
 class nsFormData : public nsIDOMFormData,
                    public nsIXHRSendable,
                    public nsFormSubmission,
                    public nsWrapperCache
@@ -44,17 +45,17 @@ public:
 
   // WebIDL
   nsISupports*
   GetParentObject() const
   {
     return mOwner;
   }
   static already_AddRefed<nsFormData>
-  Constructor(nsISupports* aGlobal,
+  Constructor(const mozilla::dom::GlobalObject& aGlobal,
               const mozilla::dom::Optional<nsHTMLFormElement*>& aFormElement,
               mozilla::ErrorResult& aRv);
   void Append(const nsAString& aName, const nsAString& aValue);
   void Append(const nsAString& aName, nsIDOMBlob* aBlob);
 
   // nsFormSubmission
   virtual nsresult GetEncodedSubmission(nsIURI* aURI,
                                         nsIInputStream** aPostDataStream);
--- a/content/base/src/nsXMLHttpRequest.h
+++ b/content/base/src/nsXMLHttpRequest.h
@@ -143,48 +143,49 @@ public:
   }
   nsISupports* GetParentObject()
   {
     return GetOwner();
   }
 
   // The WebIDL constructors.
   static already_AddRefed<nsXMLHttpRequest>
-  Constructor(JSContext* aCx,
-              nsISupports* aGlobal,
+  Constructor(const mozilla::dom::GlobalObject& aGlobal,
+              JSContext* aCx,
               const mozilla::dom::MozXMLHttpRequestParameters& aParams,
               ErrorResult& aRv)
   {
-    nsCOMPtr<nsPIDOMWindow> window = do_QueryInterface(aGlobal);
-    nsCOMPtr<nsIScriptObjectPrincipal> principal = do_QueryInterface(aGlobal);
+    nsCOMPtr<nsPIDOMWindow> window = do_QueryInterface(aGlobal.Get());
+    nsCOMPtr<nsIScriptObjectPrincipal> principal =
+      do_QueryInterface(aGlobal.Get());
     if (!window || ! principal) {
       aRv.Throw(NS_ERROR_FAILURE);
       return NULL;
     }
 
     nsRefPtr<nsXMLHttpRequest> req = new nsXMLHttpRequest();
     req->Construct(principal->GetPrincipal(), window);
     req->InitParameters(aParams.mMozAnon, aParams.mMozSystem);
     return req.forget();
   }
 
   static already_AddRefed<nsXMLHttpRequest>
-  Constructor(JSContext* aCx,
-              nsISupports* aGlobal,
+  Constructor(const mozilla::dom::GlobalObject& aGlobal,
+              JSContext* aCx,
               const nsAString& ignored,
               ErrorResult& aRv)
   {
     // Pretend like someone passed null, so we can pick up the default values
     mozilla::dom::MozXMLHttpRequestParameters params;
     if (!params.Init(aCx, nullptr, JS::NullValue())) {
       aRv.Throw(NS_ERROR_UNEXPECTED);
       return nullptr;
     }
 
-    return Constructor(aCx, aGlobal, params, aRv);
+    return Constructor(aGlobal, aCx, params, aRv);
   }
 
   void Construct(nsIPrincipal* aPrincipal,
                  nsPIDOMWindow* aOwnerWindow,
                  nsIURI* aBaseURI = NULL)
   {
     MOZ_ASSERT(aPrincipal);
     MOZ_ASSERT_IF(aOwnerWindow, aOwnerWindow->IsInnerWindow());
--- a/content/media/webaudio/AudioContext.cpp
+++ b/content/media/webaudio/AudioContext.cpp
@@ -43,19 +43,19 @@ AudioContext::~AudioContext()
 JSObject*
 AudioContext::WrapObject(JSContext* aCx, JSObject* aScope,
                          bool* aTriedToWrap)
 {
   return AudioContextBinding::Wrap(aCx, aScope, this, aTriedToWrap);
 }
 
 /* static */ already_AddRefed<AudioContext>
-AudioContext::Constructor(nsISupports* aGlobal, ErrorResult& aRv)
+AudioContext::Constructor(const GlobalObject& aGlobal, ErrorResult& aRv)
 {
-  nsCOMPtr<nsPIDOMWindow> window = do_QueryInterface(aGlobal);
+  nsCOMPtr<nsPIDOMWindow> window = do_QueryInterface(aGlobal.Get());
   if (!window) {
     aRv.Throw(NS_ERROR_FAILURE);
     return nullptr;
   }
 
   AudioContext* object = new AudioContext(window);
   NS_ADDREF(object);
   window->AddAudioContext(object);
--- a/content/media/webaudio/AudioContext.h
+++ b/content/media/webaudio/AudioContext.h
@@ -26,16 +26,17 @@ namespace dom {
 class AudioBuffer;
 class AudioBufferSourceNode;
 class AudioDestinationNode;
 class AudioListener;
 class BiquadFilterNode;
 class DelayNode;
 class DynamicsCompressorNode;
 class GainNode;
+class GlobalObject;
 class PannerNode;
 
 class AudioContext MOZ_FINAL : public nsWrapperCache,
                                public EnableWebAudioCheck
 {
   explicit AudioContext(nsIDOMWindow* aParentWindow);
 
 public:
@@ -50,17 +51,17 @@ public:
   }
 
   void Shutdown() {}
 
   virtual JSObject* WrapObject(JSContext* aCx, JSObject* aScope,
                                bool* aTriedToWrap);
 
   static already_AddRefed<AudioContext>
-  Constructor(nsISupports* aGlobal, ErrorResult& aRv);
+  Constructor(const GlobalObject& aGlobal, ErrorResult& aRv);
 
   AudioDestinationNode* Destination() const
   {
     return mDestination;
   }
 
   float SampleRate() const
   {
--- a/content/xslt/src/xpath/nsXPathEvaluator.cpp
+++ b/content/xslt/src/xpath/nsXPathEvaluator.cpp
@@ -17,16 +17,17 @@
 #include "nsIDocument.h"
 #include "nsIDOMDocument.h"
 #include "nsDOMString.h"
 #include "nsINameSpaceManager.h"
 #include "nsContentUtils.h"
 #include "mozilla/dom/XPathEvaluatorBinding.h"
 
 using namespace mozilla;
+using namespace mozilla::dom;
 
 // txIParseContext implementation
 class nsXPathEvaluatorParseContext : public txIParseContext
 {
 public:
     nsXPathEvaluatorParseContext(nsIDOMXPathNSResolver* aResolver,
                                  nsTArray<int32_t> *aNamespaceIDs,
                                  nsTArray<nsCString> *aContractIDs,
@@ -215,17 +216,17 @@ nsXPathEvaluator::CreateExpression(const
 JSObject*
 nsXPathEvaluator::WrapObject(JSContext* aCx, JSObject* aScope)
 {
     return dom::XPathEvaluatorBinding::Wrap(aCx, aScope, this);
 }
 
 /* static */
 already_AddRefed<nsXPathEvaluator>
-nsXPathEvaluator::Constructor(nsISupports* aGlobal, ErrorResult& rv)
+nsXPathEvaluator::Constructor(const GlobalObject& aGlobal, ErrorResult& rv)
 {
     nsRefPtr<nsXPathEvaluator> newObj = new nsXPathEvaluator(nullptr);
     newObj->Init();
     return newObj.forget();
 }
 
 already_AddRefed<nsIDOMXPathExpression>
 nsXPathEvaluator::CreateExpression(const nsAString& aExpression,
--- a/content/xslt/src/xpath/nsXPathEvaluator.h
+++ b/content/xslt/src/xpath/nsXPathEvaluator.h
@@ -12,16 +12,21 @@
 #include "nsAutoPtr.h"
 #include "nsString.h"
 #include "txResultRecycler.h"
 #include "nsAgg.h"
 #include "nsTArray.h"
 #include "mozilla/Attributes.h"
 #include "mozilla/ErrorResult.h"
 
+namespace mozilla {
+namespace dom {
+class GlobalObject;
+}
+}
 class nsINode;
 
 /**
  * A class for evaluating an XPath expression string
  */
 class nsXPathEvaluator MOZ_FINAL : public nsIDOMXPathEvaluator,
                                    public nsIXPathEvaluatorInternal
 {
@@ -43,17 +48,18 @@ public:
                                 nsTArray<nsString> *aNamespaceURIs,
                                 nsTArray<nsCString> *aContractIDs,
                                 nsCOMArray<nsISupports> *aState,
                                 nsIDOMXPathExpression **aResult);
 
     // WebIDL API
     JSObject* WrapObject(JSContext* aCx, JSObject* aScope);
     static already_AddRefed<nsXPathEvaluator>
-        Constructor(nsISupports* aGlobal, mozilla::ErrorResult& rv);
+        Constructor(const mozilla::dom::GlobalObject& aGlobal,
+                    mozilla::ErrorResult& rv);
     already_AddRefed<nsIDOMXPathExpression>
         CreateExpression(const nsAString& aExpression,
                          nsIDOMXPathNSResolver* aResolver,
                          mozilla::ErrorResult& rv);
     already_AddRefed<nsIDOMXPathNSResolver>
         CreateNSResolver(nsINode* aNodeResolver, mozilla::ErrorResult& rv);
     already_AddRefed<nsISupports>
         Evaluate(const nsAString& aExpression, nsINode* aContextNode,
--- a/dom/base/URL.cpp
+++ b/dom/base/URL.cpp
@@ -12,40 +12,42 @@
 #include "nsIPrincipal.h"
 #include "nsContentUtils.h"
 #include "nsHostObjectProtocolHandler.h"
 
 namespace mozilla {
 namespace dom {
 
 void
-URL::CreateObjectURL(nsISupports* aGlobal, nsIDOMBlob* aBlob,
+URL::CreateObjectURL(const GlobalObject& aGlobal, nsIDOMBlob* aBlob,
                      const objectURLOptions& aOptions,
-                     nsAString& aResult,
+                     nsString& aResult,
                      ErrorResult& aError)
 {
-  CreateObjectURLInternal(aGlobal, aBlob, NS_LITERAL_CSTRING(BLOBURI_SCHEME),
-                          aOptions, aResult, aError);
+  CreateObjectURLInternal(aGlobal.Get(), aBlob,
+                          NS_LITERAL_CSTRING(BLOBURI_SCHEME), aOptions, aResult,
+                          aError);
 }
 
 void
-URL::CreateObjectURL(nsISupports* aGlobal, nsIDOMMediaStream* aStream,
+URL::CreateObjectURL(const GlobalObject& aGlobal, nsIDOMMediaStream* aStream,
                      const mozilla::dom::objectURLOptions& aOptions,
-                     nsAString& aResult,
+                     nsString& aResult,
                      ErrorResult& aError)
 {
-  CreateObjectURLInternal(aGlobal, aStream, NS_LITERAL_CSTRING(MEDIASTREAMURI_SCHEME),
-                          aOptions, aResult, aError);
+  CreateObjectURLInternal(aGlobal.Get(), aStream,
+                          NS_LITERAL_CSTRING(MEDIASTREAMURI_SCHEME), aOptions,
+                          aResult, aError);
 }
 
 void
 URL::CreateObjectURLInternal(nsISupports* aGlobal, nsISupports* aObject,
                              const nsACString& aScheme,
                              const mozilla::dom::objectURLOptions& aOptions,
-                             nsAString& aResult,
+                             nsString& aResult,
                              ErrorResult& aError)
 {
   nsCOMPtr<nsPIDOMWindow> w = do_QueryInterface(aGlobal);
   nsGlobalWindow* window = static_cast<nsGlobalWindow*>(w.get());
   NS_PRECONDITION(!window || window->IsInnerWindow(),
                   "Should be inner window");
 
   if (!window || !window->GetExtantDoc()) {
@@ -63,19 +65,19 @@ URL::CreateObjectURLInternal(nsISupports
     return;
   }
 
   doc->RegisterHostObjectUri(url);
   CopyASCIItoUTF16(url, aResult);
 }
 
 void
-URL::RevokeObjectURL(nsISupports* aGlobal, const nsAString& aURL)
+URL::RevokeObjectURL(const GlobalObject& aGlobal, const nsAString& aURL)
 {
-  nsCOMPtr<nsPIDOMWindow> w = do_QueryInterface(aGlobal);
+  nsCOMPtr<nsPIDOMWindow> w = do_QueryInterface(aGlobal.Get());
   nsGlobalWindow* window = static_cast<nsGlobalWindow*>(w.get());
   NS_PRECONDITION(!window || window->IsInnerWindow(),
                   "Should be inner window");
   if (!window)
     return;
 
   NS_LossyConvertUTF16toASCII asciiurl(aURL);
 
--- a/dom/base/URL.h
+++ b/dom/base/URL.h
@@ -13,30 +13,32 @@ class nsIDOMMediaStream;
 
 namespace mozilla {
 namespace dom {
 
 class URL MOZ_FINAL
 {
 public:
   // WebIDL methods
-  static void CreateObjectURL(nsISupports* aGlobal, nsIDOMBlob* aBlob,
+  static void CreateObjectURL(const GlobalObject& aGlobal, nsIDOMBlob* aBlob,
                               const objectURLOptions& aOptions,
-                              nsAString& aResult,
+                              nsString& aResult,
                               ErrorResult& aError);
-  static void CreateObjectURL(nsISupports* aGlobal, nsIDOMMediaStream* aStream,
+  static void CreateObjectURL(const GlobalObject& aGlobal,
+                              nsIDOMMediaStream* aStream,
                               const mozilla::dom::objectURLOptions& aOptions,
-                              nsAString& aResult,
+                              nsString& aResult,
                               mozilla::ErrorResult& aError);
-  static void RevokeObjectURL(nsISupports* aGlobal, const nsAString& aURL);
+  static void RevokeObjectURL(const GlobalObject& aGlobal,
+                              const nsAString& aURL);
 
 private:
   static void CreateObjectURLInternal(nsISupports* aGlobal, nsISupports* aObject,
                                       const nsACString& aScheme,
                                       const mozilla::dom::objectURLOptions& aOptions,
-                                      nsAString& aResult,
+                                      nsString& aResult,
                                       mozilla::ErrorResult& aError);
 };
 
 }
 }
 
 #endif /* URL_h___ */
--- a/dom/bindings/BindingDeclarations.h
+++ b/dom/bindings/BindingDeclarations.h
@@ -11,16 +11,17 @@
  * BindingUtils.h
  */
 #ifndef mozilla_dom_BindingDeclarations_h__
 #define mozilla_dom_BindingDeclarations_h__
 
 #include "nsStringGlue.h"
 #include "jsapi.h"
 #include "mozilla/Util.h"
+#include "nsCOMPtr.h"
 
 namespace mozilla {
 namespace dom {
 
 struct MainThreadDictionaryBase
 {
 protected:
   JSContext* ParseJSON(const nsAString& aJSON,
@@ -29,12 +30,60 @@ protected:
                        JS::Value& aVal);
 };
 
 struct EnumEntry {
   const char* value;
   size_t length;
 };
 
+class NS_STACK_CLASS GlobalObject
+{
+public:
+  GlobalObject(JSContext* aCx, JSObject* aObject);
+
+  nsISupports* Get() const
+  {
+    return mGlobalObject;
+  }
+
+  bool Failed() const
+  {
+    return !Get();
+  }
+
+private:
+  js::RootedObject mGlobalJSObject;
+  nsISupports* mGlobalObject;
+  nsCOMPtr<nsISupports> mGlobalObjectRef;
+};
+
+class NS_STACK_CLASS WorkerGlobalObject
+{
+public:
+  WorkerGlobalObject(JSContext* aCx, JSObject* aObject);
+
+  JSObject* Get() const
+  {
+    return mGlobalJSObject;
+  }
+  // The context that this returns is not guaranteed to be in the compartment of
+  // the object returned from Get(), in fact it's generally in the caller's
+  // compartment.
+  JSContext* GetContext() const
+  {
+    return mCx;
+  }
+
+  bool Failed() const
+  {
+    return !Get();
+  }
+
+private:
+  js::RootedObject mGlobalJSObject;
+  JSContext* mCx;
+};
+
 } // namespace dom
 } // namespace mozilla
 
 #endif // mozilla_dom_BindingDeclarations_h__
--- a/dom/bindings/BindingUtils.cpp
+++ b/dom/bindings/BindingUtils.cpp
@@ -12,16 +12,17 @@
 #include "BindingUtils.h"
 
 #include "AccessCheck.h"
 #include "nsContentUtils.h"
 #include "nsIXPConnect.h"
 #include "WrapperFactory.h"
 #include "xpcprivate.h"
 #include "XPCQuickStubs.h"
+#include "XPCWrapper.h"
 #include "XrayWrapper.h"
 
 namespace mozilla {
 namespace dom {
 
 JSErrorFormatString ErrorFormatString[] = {
 #define MSG_DEF(_name, _argc, _str) \
   { _str, _argc, JSEXN_TYPEERR },
@@ -1433,10 +1434,58 @@ ReparentWrapper(JSContext* aCx, JSObject
 
   if (newParent && !JS_SetParent(aCx, aObj, newParent)) {
     MOZ_CRASH();
   }
 
   return NS_OK;
 }
 
+template<bool mainThread>
+inline JSObject*
+GetGlobalObject(JSContext* aCx, JSObject* aObject,
+                Maybe<JSAutoCompartment>& aAutoCompartment)
+{
+  if (js::IsWrapper(aObject)) {
+    aObject = XPCWrapper::Unwrap(aCx, aObject, false);
+    if (!aObject) {
+      Throw<mainThread>(aCx, NS_ERROR_XPC_SECURITY_MANAGER_VETO);
+      return nullptr;
+    }
+    aAutoCompartment.construct(aCx, aObject);
+  }
+
+  return JS_GetGlobalForObject(aCx, aObject);
+}
+
+GlobalObject::GlobalObject(JSContext* aCx, JSObject* aObject)
+  : mGlobalJSObject(aCx)
+{
+  Maybe<JSAutoCompartment> ac;
+  mGlobalJSObject = GetGlobalObject<true>(aCx, aObject, ac);
+  if (!mGlobalJSObject) {
+    return;
+  }
+
+  JS::Value val;
+  val.setObject(*mGlobalJSObject);
+
+  // Switch this to UnwrapDOMObjectToISupports once our global objects are
+  // using new bindings.
+  nsresult rv = xpc_qsUnwrapArg<nsISupports>(aCx, val, &mGlobalObject,
+                                             static_cast<nsISupports**>(getter_AddRefs(mGlobalObjectRef)),
+                                             &val);
+  if (NS_FAILED(rv)) {
+    mGlobalObject = nullptr;
+    Throw<true>(aCx, NS_ERROR_XPC_BAD_CONVERT_JS);
+  }
+}
+
+WorkerGlobalObject::WorkerGlobalObject(JSContext* aCx, JSObject* aObject)
+  : mGlobalJSObject(aCx),
+    mCx(aCx)
+{
+  Maybe<JSAutoCompartment> ac;
+  mGlobalJSObject = GetGlobalObject<false>(aCx, aObject, ac);
+}
+
 } // namespace dom
 } // namespace mozilla
--- a/dom/bindings/Codegen.py
+++ b/dom/bindings/Codegen.py
@@ -937,39 +937,22 @@ class CGClassConstructHook(CGAbstractSta
             return ""
         return CGAbstractStaticMethod.define(self)
 
     def definition_body(self):
         return self.generate_code()
 
     def generate_code(self):
         preamble = """
-  JSObject* obj = JS_GetGlobalForObject(cx, JSVAL_TO_OBJECT(JS_CALLEE(cx, vp)));
+  JSObject* obj = JSVAL_TO_OBJECT(JS_CALLEE(cx, vp));
 """
-        if self.descriptor.workers:
-            preArgs = ["cx", "obj"]
-        else:
-            preamble += """
-  nsISupports* global;
-  xpc_qsSelfRef globalRef;
-  {
-    nsresult rv;
-    JS::Value val = OBJECT_TO_JSVAL(obj);
-    rv = xpc_qsUnwrapArg<nsISupports>(cx, val, &global, &globalRef.ptr, &val);
-    if (NS_FAILED(rv)) {
-      return ThrowErrorMessage(cx, MSG_GLOBAL_NOT_NATIVE);
-    }
-  }
-"""
-            preArgs = ["global"]
-
         name = self._ctor.identifier.name
         nativeName = MakeNativeName(self.descriptor.binaryNames.get(name, name))
-        callGenerator = CGMethodCall(preArgs, nativeName, True,
-                                     self.descriptor, self._ctor)
+        callGenerator = CGMethodCall(nativeName, True, self.descriptor,
+                                     self._ctor)
         return preamble + callGenerator.define();
 
 class CGClassConstructHookHolder(CGGeneric):
     def __init__(self, descriptor):
         if descriptor.interface.ctor():
             constructHook = CONSTRUCT_HOOK_NAME
         else:
             constructHook = "ThrowingConstructor"
@@ -3650,17 +3633,17 @@ def getRetvalDeclarationForType(returnTy
                     returnType)
 
 def isResultAlreadyAddRefed(descriptor, extendedAttributes):
     # Default to already_AddRefed on the main thread, raw pointer in workers
     return not descriptor.workers and not 'resultNotAddRefed' in extendedAttributes
 
 def needCx(returnType, arguments, extendedAttributes, descriptorProvider):
     return (typeNeedsCx(returnType, descriptorProvider, True) or
-            any(typeNeedsCx(a.type, descriptorProvider) for (a, _) in arguments) or
+            any(typeNeedsCx(a.type, descriptorProvider) for a in arguments) or
             'implicitJSContext' in extendedAttributes)
 
 class CGCallGenerator(CGThing):
     """
     A class to generate an actual call to a C++ object.  Assumes that the C++
     object is stored in a variable whose name is given by the |object| argument.
 
     errorReport should be a CGThing for an error report or None if no
@@ -3689,29 +3672,21 @@ class CGCallGenerator(CGThing):
             args.append(CGGeneric(name))
 
         # Return values that go in outparams go here
         if resultOutParam:
             args.append(CGGeneric("result"))
         if isFallible:
             args.append(CGGeneric("rv"))
 
-        needsCx = needCx(returnType, arguments, extendedAttributes,
-                         descriptorProvider)
-
-        if not "cx" in argsPre and needsCx:
-            args.prepend(CGGeneric("cx"))
-
         # Build up our actual call
         self.cgRoot = CGList([], "\n")
 
         call = CGGeneric(nativeMethodName)
-        if static:
-            call = CGWrapper(call, pre="%s::" % descriptorProvider.nativeType)
-        else: 
+        if not static:
             call = CGWrapper(call, pre="%s->" % object)
         call = CGList([call, CGWrapper(args, pre="(", post=");")])
         if result is not None:
             result = CGWrapper(result, post=" result;")
             self.cgRoot.prepend(result)
             if not resultOutParam:
                 call = CGWrapper(call, pre="result = ")
 
@@ -3749,54 +3724,73 @@ class CGPerSignatureCall(CGThing):
     The idlNode parameter can be either a method or an attr. We can query
     |idlNode.identifier| in both cases, so we can be agnostic between the two.
     """
     # XXXbz For now each entry in the argument list is either an
     # IDLArgument or a FakeArgument, but longer-term we may want to
     # have ways of flagging things like JSContext* or optional_argc in
     # there.
 
-    def __init__(self, returnType, argsPre, arguments, nativeMethodName, static,
-                 descriptor, idlNode, argConversionStartsAt=0,
-                 getter=False, setter=False):
+    def __init__(self, returnType, arguments, nativeMethodName, static,
+                 descriptor, idlNode, argConversionStartsAt=0, getter=False,
+                 setter=False):
         assert idlNode.isMethod() == (not getter and not setter)
         assert idlNode.isAttr() == (getter or setter)
 
         CGThing.__init__(self)
         self.returnType = returnType
         self.descriptor = descriptor
         self.idlNode = idlNode
         self.extendedAttributes = descriptor.getExtendedAttributes(idlNode,
                                                                    getter=getter,
                                                                    setter=setter)
-        self.argsPre = argsPre
         self.arguments = arguments
         self.argCount = len(arguments)
         if self.argCount > argConversionStartsAt:
             # Insert our argv in there
             cgThings = [CGGeneric(self.getArgvDecl())]
         else:
             cgThings = []
         lenientFloatCode = None
         if idlNode.getExtendedAttribute('LenientFloat') is not None:
             if setter:
                 lenientFloatCode = "return true;"
             elif idlNode.isMethod():
                 lenientFloatCode = ("*vp = JSVAL_VOID;\n"
                                     "return true;")
+
+        argsPre = []
+        if static:
+            nativeMethodName = "%s::%s" % (descriptor.nativeType,
+                                           nativeMethodName)
+            globalObjectType = "GlobalObject"
+            if descriptor.workers:
+                globalObjectType = "Worker" + globalObjectType
+            cgThings.append(CGGeneric("""%s global(cx, obj);
+if (global.Failed()) {
+  return false;
+}
+""" % globalObjectType))
+            argsPre.append("global")
+
+        needsCx = needCx(returnType, arguments, self.extendedAttributes,
+                         descriptor)
+        if needsCx and not (static and descriptor.workers):
+            argsPre.append("cx")
+
         cgThings.extend([CGArgumentConverter(arguments[i], i, self.getArgv(),
                                              self.getArgc(), self.descriptor,
                                              invalidEnumValueFatal=not setter,
                                              allowTreatNonCallableAsNull=setter,
                                              lenientFloatCode=lenientFloatCode) for
                          i in range(argConversionStartsAt, self.argCount)])
 
         cgThings.append(CGCallGenerator(
                     self.getErrorReport() if self.isFallible() else None,
-                    self.getArguments(), self.argsPre, returnType,
+                    self.getArguments(), argsPre, returnType,
                     self.extendedAttributes, descriptor, nativeMethodName,
                     static))
         self.cgRoot = CGList(cgThings, "\n")
 
     def getArgv(self):
         return "argv" if self.argCount > 0 else ""
     def getArgvDecl(self):
         return "\nJS::Value* argv = JS_ARGV(cx, vp);\n"
@@ -3885,32 +3879,32 @@ class CGCase(CGList):
         self.append(CGIndenter(bodyList));
         self.append(CGGeneric("}"))
 
 class CGMethodCall(CGThing):
     """
     A class to generate selection of a method signature from a set of
     signatures and generation of a call to that signature.
     """
-    def __init__(self, argsPre, nativeMethodName, static, descriptor, method):
+    def __init__(self, nativeMethodName, static, descriptor, method):
         CGThing.__init__(self)
 
         methodName = '"%s.%s"' % (descriptor.interface.identifier.name, method.identifier.name)
 
         def requiredArgCount(signature):
             arguments = signature[1]
             if len(arguments) == 0:
                 return 0
             requiredArgs = len(arguments)
             while requiredArgs and arguments[requiredArgs-1].optional:
                 requiredArgs -= 1
             return requiredArgs
 
         def getPerSignatureCall(signature, argConversionStartsAt=0):
-            return CGPerSignatureCall(signature[0], argsPre, signature[1],
+            return CGPerSignatureCall(signature[0], signature[1],
                                       nativeMethodName, static, descriptor,
                                       method, argConversionStartsAt)
             
 
         signatures = method.signatures()
         if len(signatures) == 1:
             # Special case: we can just do a per-signature method call
             # here for our one signature and not worry about switching
@@ -4188,23 +4182,19 @@ class CGMethodCall(CGThing):
         return self.cgRoot.define()
 
 class CGGetterCall(CGPerSignatureCall):
     """
     A class to generate a native object getter call for a particular IDL
     getter.
     """
     def __init__(self, returnType, nativeMethodName, descriptor, attr):
-        if attr.isStatic():
-            argsPre = [ "global" ]
-        else:
-            argsPre = []
-        CGPerSignatureCall.__init__(self, returnType, argsPre, [],
-                                    nativeMethodName, attr.isStatic(),
-                                    descriptor, attr, getter=True)
+        CGPerSignatureCall.__init__(self, returnType, [], nativeMethodName,
+                                    attr.isStatic(), descriptor, attr,
+                                    getter=True)
 
 class FakeArgument():
     """
     A class that quacks like an IDLArgument.  This is used to make
     setters look like method calls or for special operations.
     """
     def __init__(self, type, interfaceMember, name="arg"):
         self.type = type
@@ -4221,22 +4211,17 @@ class FakeArgument():
         self.identifier = FakeIdentifier()
 
 class CGSetterCall(CGPerSignatureCall):
     """
     A class to generate a native object setter call for a particular IDL
     setter.
     """
     def __init__(self, argType, nativeMethodName, descriptor, attr):
-        if attr.isStatic():
-            argsPre = [ "global" ]
-        else:
-            argsPre = []
-        CGPerSignatureCall.__init__(self, None, argsPre,
-                                    [FakeArgument(argType, attr)],
+        CGPerSignatureCall.__init__(self, None, [FakeArgument(argType, attr)],
                                     nativeMethodName, attr.isStatic(),
                                     descriptor, attr, setter=True)
     def wrap_return_value(self):
         # We have no return value
         return "\nreturn true;"
     def getArgc(self):
         return "1"
     def getArgvDecl(self):
@@ -4295,47 +4280,21 @@ class CGAbstractStaticBindingMethod(CGAb
     global object.  Subclasses are expected to override the generate_code
     function to do the rest of the work.  This function should return a
     CGThing which is already properly indented.
     """
     def __init__(self, descriptor, name, args):
         CGAbstractStaticMethod.__init__(self, descriptor, name, "JSBool", args)
 
     def definition_body(self):
-        isMainThread = toStringBool(not self.descriptor.workers)
         unwrap = CGGeneric("""js::RootedObject obj(cx, JS_THIS_OBJECT(cx, vp));
 if (!obj) {
   return false;
 }
-
-// We have to be careful to leave "obj" in its existing compartment, even
-// while we grab our global from the real underlying object, because we
-// use it for unwrapping the other arguments later.
-nsISupports* global;
-xpc_qsSelfRef globalRef;
-{
-  JS::Value val;
-  Maybe<JSAutoCompartment> ac;
-  if (js::IsWrapper(obj)) {
-    JSObject* realObj = XPCWrapper::Unwrap(cx, obj, false);
-    if (!realObj) {
-      return Throw<%s>(cx, NS_ERROR_XPC_SECURITY_MANAGER_VETO);
-    }
-    ac.construct(cx, realObj);
-    val.setObject(*JS_GetGlobalForObject(cx, realObj));
-  } else {
-    val.setObject(*JS_GetGlobalForObject(cx, obj));
-  }
-
-  nsresult rv = xpc_qsUnwrapArg<nsISupports>(cx, val, &global, &globalRef.ptr,
-                                             &val);
-  if (NS_FAILED(rv)) {
-    return Throw<%s>(cx, NS_ERROR_XPC_BAD_CONVERT_JS);
-  }
-}""" % (isMainThread, isMainThread))
+""")
         return CGList([ CGIndenter(unwrap),
                         self.generate_code() ], "\n\n").define()
 
     def generate_code(self):
         assert(False) # Override me
 
 def MakeNativeName(name):
     return name[0].upper() + name[1:]
@@ -4367,18 +4326,18 @@ class CGSpecializedMethod(CGAbstractStat
         args = [Argument('JSContext*', 'cx'), Argument('JSHandleObject', 'obj'),
                 Argument('%s*' % descriptor.nativeType, 'self'),
                 Argument('unsigned', 'argc'), Argument('JS::Value*', 'vp')]
         CGAbstractStaticMethod.__init__(self, descriptor, name, 'bool', args)
 
     def definition_body(self):
         nativeName = CGSpecializedMethod.makeNativeName(self.descriptor,
                                                         self.method)
-        return CGMethodCall([], nativeName, self.method.isStatic(),
-                            self.descriptor, self.method).define()
+        return CGMethodCall(nativeName, self.method.isStatic(), self.descriptor,
+                            self.method).define()
 
     @staticmethod
     def makeNativeName(descriptor, method):
         name = method.identifier.name
         return MakeNativeName(descriptor.binaryNames.get(name, name))
 
 class CppKeywords():
     """
@@ -4410,18 +4369,17 @@ class CGStaticMethod(CGAbstractStaticBin
         name = method.identifier.name
         args = [Argument('JSContext*', 'cx'), Argument('unsigned', 'argc'),
                 Argument('JS::Value*', 'vp')]
         CGAbstractStaticBindingMethod.__init__(self, descriptor, name, args)
 
     def generate_code(self):
         nativeName = CGSpecializedMethod.makeNativeName(self.descriptor,
                                                         self.method)
-        return CGMethodCall([ "global" ], nativeName, True, self.descriptor,
-                            self.method)
+        return CGMethodCall(nativeName, True, self.descriptor, self.method)
 
 class CGGenericGetter(CGAbstractBindingMethod):
     """
     A class for generating the C++ code for an IDL attribute getter.
     """
     def __init__(self, descriptor, lenientThis=False):
         args = [Argument('JSContext*', 'cx'), Argument('unsigned', 'argc'),
                 Argument('JS::Value*', 'vp')]
@@ -5720,17 +5678,17 @@ class CGProxySpecialOperation(CGPerSigna
         operation = descriptor.operations[operation]
         assert len(operation.signatures()) == 1
         signature = operation.signatures()[0]
 
         (returnType, arguments) = signature
 
         # We pass len(arguments) as the final argument so that the
         # CGPerSignatureCall won't do any argument conversion of its own.
-        CGPerSignatureCall.__init__(self, returnType, "", arguments, nativeName,
+        CGPerSignatureCall.__init__(self, returnType, arguments, nativeName,
                                     False, descriptor, operation,
                                     len(arguments))
 
         if operation.isSetter() or operation.isCreator():
             # arguments[0] is the index or name of the item that we're setting.
             argument = arguments[1]
             template = getJSToNativeConversionTemplate(argument.type, descriptor,
                                                        treatNullAs=argument.treatNullAs,
@@ -7300,25 +7258,27 @@ class CGNativeMember(ClassMethod):
             type = CGWrapper(CGGeneric(elementDecl), pre="nsTArray< ", post=" >")
             if nullable:
                 type = CGWrapper(type, pre="Nullable< ", post=" >")
             args.append(Argument("%s&" % type.define(), "retval"))
         # And the ErrorResult
         if not 'infallible' in self.extendedAttrs:
             # Use aRv so it won't conflict with local vars named "rv"
             args.append(Argument("ErrorResult&", "aRv"))
+        # And jscontext bits.
+        if (self.passCxAsNeeded and
+            needCx(returnType, argList, self.extendedAttrs,
+                   self.descriptor)):
+            args.insert(0, Argument("JSContext*", "cx"))
         # And if we're static, a global
         if self.member.isStatic():
-            args.insert(0, Argument("nsISupports*", "global"))
-        # And jscontext bits.  needCx expects a list of tuples, in each of which
-        # the first element is the actual argument
-        if (self.passCxAsNeeded and
-            needCx(returnType, ((a, "") for a in argList), self.extendedAttrs,
-                   self.descriptor)):
-            args.insert(0, Argument("JSContext*", "cx"))
+            globalObjectType = "GlobalObject"
+            if self.descriptor.workers:
+                globalObjectType = "Worker" + globalObjectType
+            args.insert(0, Argument("const %s&" % globalObjectType, "global"))
         return args
 
     def doGetArgType(self, type, optional, isMember):
         """
         The main work of getArgType.  Returns a string type decl, whether this
         is a const ref, as well as whether the type should be wrapped in
         Nullable as needed.
         """
--- a/dom/bindings/test/TestBindingHeader.h
+++ b/dom/bindings/test/TestBindingHeader.h
@@ -106,36 +106,35 @@ public:
   NS_DECL_ISUPPORTS
 
   // We need a GetParentObject to make binding codegen happy
   virtual nsISupports* GetParentObject();
 
   // And now our actual WebIDL API
   // Constructors
   static
-  already_AddRefed<TestInterface> Constructor(nsISupports*, ErrorResult&);
+  already_AddRefed<TestInterface>
+    Constructor(const GlobalObject&, ErrorResult&);
   static
-  already_AddRefed<TestInterface> Constructor(nsISupports*, const nsAString&,
-                                              ErrorResult&);
+  already_AddRefed<TestInterface>
+    Constructor(const GlobalObject&, const nsAString&, ErrorResult&);
   static
-  already_AddRefed<TestInterface> Constructor(nsISupports*, uint32_t,
-                                              const Nullable<bool>&,
-                                              ErrorResult&);
+  already_AddRefed<TestInterface>
+    Constructor(const GlobalObject&, uint32_t, const Nullable<bool>&,
+                ErrorResult&);
   static
-  already_AddRefed<TestInterface> Constructor(nsISupports*, TestInterface*,
-                                              ErrorResult&);
+  already_AddRefed<TestInterface>
+    Constructor(const GlobalObject&, TestInterface*, ErrorResult&);
   static
-  already_AddRefed<TestInterface> Constructor(nsISupports*,
-                                              TestNonCastableInterface&,
-                                              ErrorResult&);
+  already_AddRefed<TestInterface>
+    Constructor(const GlobalObject&, TestNonCastableInterface&, ErrorResult&);
   /*  static
-  already_AddRefed<TestInterface> Constructor(nsISupports*,
-                                              uint32_t, uint32_t,
-                                              const TestInterfaceOrOnlyForUseInConstructor&,
-                                              ErrorResult&);
+  already_AddRefed<TestInterface>
+    Constructor(const GlobalObject&, uint32_t, uint32_t,
+                const TestInterfaceOrOnlyForUseInConstructor&, ErrorResult&);
   */
   
   // Integer types
   int8_t ReadonlyByte();
   int8_t WritableByte();
   void SetWritableByte(int8_t);
   void PassByte(int8_t);
   int8_t ReceiveByte();
@@ -459,19 +458,21 @@ public:
   void ReceiveDictContainingSequence(DictContainingSequence&);
 
   // Typedefs
   void ExerciseTypedefInterfaces1(TestInterface&);
   already_AddRefed<TestInterface> ExerciseTypedefInterfaces2(TestInterface*);
   void ExerciseTypedefInterfaces3(TestInterface&);
 
   // Static methods and attributes
-  static void StaticMethod(nsISupports*, bool);
-  static bool StaticAttribute(nsISupports*);
-  static void SetStaticAttribute(nsISupports*, bool);
+  static void StaticMethod(const GlobalObject&, bool);
+  static void StaticMethodWithContext(const GlobalObject&, JSContext*,
+                                      JS::Value);
+  static bool StaticAttribute(const GlobalObject&);
+  static void SetStaticAttribute(const GlobalObject&, bool);
 
   // Overload resolution tests
   bool Overload1(TestInterface&);
   TestInterface* Overload1(const nsAString&, TestInterface&);
   void Overload2(TestInterface&);
   void Overload2(const Dict&);
   void Overload2(const nsAString&);
   void Overload3(TestInterface&);
--- a/dom/bindings/test/TestCodeGen.webidl
+++ b/dom/bindings/test/TestCodeGen.webidl
@@ -428,16 +428,17 @@ interface TestInterface {
   const myLong myLongConstant = 5;
   void exerciseTypedefInterfaces1(AnotherNameForTestInterface arg);
   AnotherNameForTestInterface exerciseTypedefInterfaces2(NullableTestInterface arg);
   void exerciseTypedefInterfaces3(YetAnotherNameForTestInterface arg);
 
   // Static methods and attributes
   static attribute boolean staticAttribute;
   static void staticMethod(boolean arg);
+  static void staticMethodWithContext(any arg);
 
   // Overload resolution tests
   //void overload1(DOMString... strs);
   boolean overload1(TestInterface arg);
   TestInterface overload1(DOMString strs, TestInterface arg);
   void overload2(TestInterface arg);
   void overload2(optional Dict arg);
   void overload2(DOMString arg);
--- a/dom/bindings/test/TestExampleGen.webidl
+++ b/dom/bindings/test/TestExampleGen.webidl
@@ -341,16 +341,17 @@ interface TestExampleInterface {
   const myLong myLongConstant = 5;
   void exerciseTypedefInterfaces1(AnotherNameForTestInterface arg);
   AnotherNameForTestInterface exerciseTypedefInterfaces2(NullableTestInterface arg);
   void exerciseTypedefInterfaces3(YetAnotherNameForTestInterface arg);
 
   // Static methods and attributes
   static attribute boolean staticAttribute;
   static void staticMethod(boolean arg);
+  static void staticMethodWithContext(any arg);
 
   // Overload resolution tests
   //void overload1(DOMString... strs);
   boolean overload1(TestInterface arg);
   TestInterface overload1(DOMString strs, TestInterface arg);
   void overload2(TestInterface arg);
   void overload2(optional Dict arg);
   void overload2(DOMString arg);
--- a/dom/encoding/TextDecoder.h
+++ b/dom/encoding/TextDecoder.h
@@ -15,22 +15,22 @@ class TextDecoder MOZ_FINAL
   : public nsISupports, public nsWrapperCache, public TextDecoderBase
 {
 public:
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(TextDecoder)
 
   // The WebIDL constructor.
   static already_AddRefed<TextDecoder>
-  Constructor(nsISupports* aGlobal,
+  Constructor(const GlobalObject& aGlobal,
               const nsAString& aEncoding,
               const TextDecoderOptions& aOptions,
               ErrorResult& aRv)
   {
-    nsRefPtr<TextDecoder> txtDecoder = new TextDecoder(aGlobal);
+    nsRefPtr<TextDecoder> txtDecoder = new TextDecoder(aGlobal.Get());
     txtDecoder->Init(aEncoding, aOptions.mFatal, aRv);
     if (aRv.Failed()) {
       return nullptr;
     }
     return txtDecoder.forget();
   }
 
   TextDecoder(nsISupports* aGlobal)
--- a/dom/encoding/TextEncoder.h
+++ b/dom/encoding/TextEncoder.h
@@ -15,21 +15,21 @@ class TextEncoder MOZ_FINAL
   : public nsISupports, public nsWrapperCache, public TextEncoderBase
 {
 public:
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(TextEncoder)
 
   // The WebIDL constructor.
   static already_AddRefed<TextEncoder>
-  Constructor(nsISupports* aGlobal,
+  Constructor(const GlobalObject& aGlobal,
               const nsAString& aEncoding,
               ErrorResult& aRv)
   {
-    nsRefPtr<TextEncoder> txtEncoder = new TextEncoder(aGlobal);
+    nsRefPtr<TextEncoder> txtEncoder = new TextEncoder(aGlobal.Get());
     txtEncoder->Init(aEncoding, aRv);
     if (aRv.Failed()) {
       return nullptr;
     }
     return txtEncoder.forget();
   }
 
   TextEncoder(nsISupports* aGlobal)
--- a/dom/workers/FileReaderSync.cpp
+++ b/dom/workers/FileReaderSync.cpp
@@ -26,16 +26,17 @@
 #include "DOMBindingInlines.h"
 
 #include "mozilla/Base64.h"
 #include "mozilla/dom/EncodingUtils.h"
 
 USING_WORKERS_NAMESPACE
 using namespace mozilla;
 using mozilla::dom::Optional;
+using mozilla::dom::WorkerGlobalObject;
 
 NS_IMPL_ADDREF_INHERITED(FileReaderSync, DOMBindingBase)
 NS_IMPL_RELEASE_INHERITED(FileReaderSync, DOMBindingBase)
 NS_INTERFACE_MAP_BEGIN(FileReaderSync)
   NS_INTERFACE_MAP_ENTRY(nsICharsetDetectionObserver)
 NS_INTERFACE_MAP_END_INHERITING(DOMBindingBase)
 
 FileReaderSync::FileReaderSync(JSContext* aCx)
@@ -52,22 +53,21 @@ FileReaderSync::_trace(JSTracer* aTrc)
 void
 FileReaderSync::_finalize(JSFreeOp* aFop)
 {
   DOMBindingBase::_finalize(aFop);
 }
 
 // static
 FileReaderSync*
-FileReaderSync::Constructor(JSContext* aCx, JSObject* aGlobal,
-                            ErrorResult& aRv)
+FileReaderSync::Constructor(const WorkerGlobalObject& aGlobal, ErrorResult& aRv)
 {
-  nsRefPtr<FileReaderSync> frs = new FileReaderSync(aCx);
+  nsRefPtr<FileReaderSync> frs = new FileReaderSync(aGlobal.GetContext());
 
-  if (!Wrap(aCx, aGlobal, frs)) {
+  if (!Wrap(aGlobal.GetContext(), aGlobal.Get(), frs)) {
     aRv.Throw(NS_ERROR_FAILURE);
     return nullptr;
   }
 
   return frs;
 }
 
 JSObject*
--- a/dom/workers/FileReaderSync.h
+++ b/dom/workers/FileReaderSync.h
@@ -31,17 +31,17 @@ class FileReaderSync MOZ_FINAL : public 
 public:
   virtual void
   _trace(JSTracer* aTrc) MOZ_OVERRIDE;
 
   virtual void
   _finalize(JSFreeOp* aFop) MOZ_OVERRIDE;
 
   static FileReaderSync*
-  Constructor(JSContext* aCx, JSObject* aGlobal, ErrorResult& aRv);
+  Constructor(const WorkerGlobalObject& aGlobal, ErrorResult& aRv);
 
   NS_DECL_ISUPPORTS_INHERITED
 
   FileReaderSync(JSContext* aCx);
 
   JSObject* ReadAsArrayBuffer(JSContext* aCx, JSObject* aBlob,
                               ErrorResult& aRv);
   void ReadAsBinaryString(JSObject* aBlob, nsAString& aResult,
--- a/dom/workers/TextDecoder.cpp
+++ b/dom/workers/TextDecoder.cpp
@@ -4,41 +4,42 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "TextDecoder.h"
 #include "DOMBindingInlines.h"
 
 USING_WORKERS_NAMESPACE
 using mozilla::ErrorResult;
 using mozilla::dom::TextDecoderOptionsWorkers;
+using mozilla::dom::WorkerGlobalObject;
 
 void
 TextDecoder::_trace(JSTracer* aTrc)
 {
   DOMBindingBase::_trace(aTrc);
 }
 
 void
 TextDecoder::_finalize(JSFreeOp* aFop)
 {
   DOMBindingBase::_finalize(aFop);
 }
 
 // static
 TextDecoder*
-TextDecoder::Constructor(JSContext* aCx, JSObject* aObj,
+TextDecoder::Constructor(const WorkerGlobalObject& aGlobal,
                          const nsAString& aEncoding,
                          const TextDecoderOptionsWorkers& aOptions,
                          ErrorResult& aRv)
 {
-  nsRefPtr<TextDecoder> txtDecoder = new TextDecoder(aCx);
+  nsRefPtr<TextDecoder> txtDecoder = new TextDecoder(aGlobal.GetContext());
   txtDecoder->Init(aEncoding, aOptions.mFatal, aRv);
   if (aRv.Failed()) {
     return nullptr;
   }
 
-  if (!Wrap(aCx, aObj, txtDecoder)) {
+  if (!Wrap(aGlobal.GetContext(), aGlobal.Get(), txtDecoder)) {
     aRv.Throw(NS_ERROR_FAILURE);
     return nullptr;
   }
 
   return txtDecoder;
 }
--- a/dom/workers/TextDecoder.h
+++ b/dom/workers/TextDecoder.h
@@ -27,17 +27,17 @@ protected:
 public:
   virtual void
   _trace(JSTracer* aTrc) MOZ_OVERRIDE;
 
   virtual void
   _finalize(JSFreeOp* aFop) MOZ_OVERRIDE;
 
   static TextDecoder*
-  Constructor(JSContext* aCx, JSObject* aObj,
+  Constructor(const WorkerGlobalObject& aGlobal,
               const nsAString& aEncoding,
               const TextDecoderOptionsWorkers& aOptions,
               ErrorResult& aRv);
 
   void
   Decode(nsAString& aOutDecodedString,
          ErrorResult& aRv) {
     TextDecoderBase::Decode(nullptr, 0, false,
--- a/dom/workers/TextEncoder.cpp
+++ b/dom/workers/TextEncoder.cpp
@@ -3,40 +3,41 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "TextEncoder.h"
 #include "DOMBindingInlines.h"
 
 USING_WORKERS_NAMESPACE
 using mozilla::ErrorResult;
+using mozilla::dom::WorkerGlobalObject;
 
 void
 TextEncoder::_trace(JSTracer* aTrc)
 {
   DOMBindingBase::_trace(aTrc);
 }
 
 void
 TextEncoder::_finalize(JSFreeOp* aFop)
 {
   DOMBindingBase::_finalize(aFop);
 }
 
 // static
 TextEncoder*
-TextEncoder::Constructor(JSContext* aCx, JSObject* aObj,
+TextEncoder::Constructor(const WorkerGlobalObject& aGlobal,
                          const nsAString& aEncoding,
                          ErrorResult& aRv)
 {
-  nsRefPtr<TextEncoder> txtEncoder = new TextEncoder(aCx);
+  nsRefPtr<TextEncoder> txtEncoder = new TextEncoder(aGlobal.GetContext());
   txtEncoder->Init(aEncoding, aRv);
   if (aRv.Failed()) {
     return nullptr;
   }
 
-  if (!Wrap(aCx, aObj, txtEncoder)) {
+  if (!Wrap(aGlobal.GetContext(), aGlobal.Get(), txtEncoder)) {
     aRv.Throw(NS_ERROR_FAILURE);
     return nullptr;
   }
 
   return txtEncoder;
 }
--- a/dom/workers/TextEncoder.h
+++ b/dom/workers/TextEncoder.h
@@ -34,17 +34,17 @@ protected:
 public:
   virtual void
   _trace(JSTracer* aTrc) MOZ_OVERRIDE;
 
   virtual void
   _finalize(JSFreeOp* aFop) MOZ_OVERRIDE;
 
   static TextEncoder*
-  Constructor(JSContext* aCx, JSObject* aObj,
+  Constructor(const WorkerGlobalObject& aGlobal,
               const nsAString& aEncoding,
               ErrorResult& aRv);
 
   JSObject*
   Encode(JSContext* aCx,
          const nsAString& aString,
          const TextEncodeOptionsWorkers& aOptions,
          ErrorResult& aRv) {
--- a/dom/workers/XMLHttpRequest.cpp
+++ b/dom/workers/XMLHttpRequest.cpp
@@ -1479,27 +1479,27 @@ void
 XMLHttpRequest::_finalize(JSFreeOp* aFop)
 {
   ReleaseProxy(XHRIsGoingAway);
   XMLHttpRequestEventTarget::_finalize(aFop);
 }
 
 // static
 XMLHttpRequest*
-XMLHttpRequest::Constructor(JSContext* aCx,
-                            JSObject* aGlobal,
+XMLHttpRequest::Constructor(const WorkerGlobalObject& aGlobal,
                             const MozXMLHttpRequestParametersWorkers& aParams,
                             ErrorResult& aRv)
 {
-  WorkerPrivate* workerPrivate = GetWorkerPrivateFromContext(aCx);
+  JSContext* cx = aGlobal.GetContext();
+  WorkerPrivate* workerPrivate = GetWorkerPrivateFromContext(cx);
   MOZ_ASSERT(workerPrivate);
 
-  nsRefPtr<XMLHttpRequest> xhr = new XMLHttpRequest(aCx, workerPrivate);
+  nsRefPtr<XMLHttpRequest> xhr = new XMLHttpRequest(cx, workerPrivate);
 
-  if (!Wrap(aCx, aGlobal, xhr)) {
+  if (!Wrap(cx, aGlobal.Get(), xhr)) {
     aRv.Throw(NS_ERROR_FAILURE);
     return NULL;
   }
 
   if (workerPrivate->XHRParamsAllowed()) {
     xhr->mMozAnon = aParams.mMozAnon;
     xhr->mMozSystem = aParams.mMozSystem;
   }
--- a/dom/workers/XMLHttpRequest.h
+++ b/dom/workers/XMLHttpRequest.h
@@ -69,32 +69,32 @@ protected:
 public:
   virtual void
   _trace(JSTracer* aTrc) MOZ_OVERRIDE;
 
   virtual void
   _finalize(JSFreeOp* aFop) MOZ_OVERRIDE;
 
   static XMLHttpRequest*
-  Constructor(JSContext* aCx, JSObject* aGlobal,
+  Constructor(const WorkerGlobalObject& aGlobal,
               const MozXMLHttpRequestParametersWorkers& aParams,
               ErrorResult& aRv);
 
   static XMLHttpRequest*
-  Constructor(JSContext* aCx, JSObject* aGlobal,
-              const nsAString& ignored, ErrorResult& aRv)
+  Constructor(const WorkerGlobalObject& aGlobal, const nsAString& ignored,
+              ErrorResult& aRv)
   {
     // Pretend like someone passed null, so we can pick up the default values
     MozXMLHttpRequestParametersWorkers params;
-    if (!params.Init(aCx, nullptr, JS::NullValue())) {
+    if (!params.Init(aGlobal.GetContext(), nullptr, JS::NullValue())) {
       aRv.Throw(NS_ERROR_UNEXPECTED);
       return nullptr;
     }
 
-    return Constructor(aCx, aGlobal, params, aRv);
+    return Constructor(aGlobal, params, aRv);
   }
 
   void
   Unpin();
 
   bool
   Notify(JSContext* aCx, Status aStatus) MOZ_OVERRIDE;
 
--- a/layout/style/CSS.cpp
+++ b/layout/style/CSS.cpp
@@ -2,16 +2,17 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 /* DOM object holding utility CSS functions */
 
 #include "CSS.h"
 
+#include "mozilla/dom/BindingDeclarations.h"
 #include "nsCSSParser.h"
 #include "nsGlobalWindow.h"
 #include "nsIDOMDocument.h"
 #include "nsIDocument.h"
 #include "nsIPrincipal.h"
 #include "nsIURI.h"
 
 namespace mozilla {
@@ -40,43 +41,43 @@ GetParsingInfo(nsISupports* aGlobal,
 
   aInfo.mDocURI = nsCOMPtr<nsIURI>(doc->GetDocumentURI());
   aInfo.mBaseURI = nsCOMPtr<nsIURI>(doc->GetBaseURI());
   aInfo.mPrincipal = win->GetPrincipal();
   return NS_OK;
 }
 
 /* static */ bool
-CSS::Supports(nsISupports* aGlobal,
+CSS::Supports(const GlobalObject& aGlobal,
               const nsAString& aProperty,
               const nsAString& aValue,
               ErrorResult& aRv)
 {
   nsCSSParser parser;
   SupportsParsingInfo info;
 
-  nsresult rv = GetParsingInfo(aGlobal, info);
+  nsresult rv = GetParsingInfo(aGlobal.Get(), info);
   if (NS_FAILED(rv)) {
     aRv.Throw(rv);
     return false;
   }
 
   return parser.EvaluateSupportsDeclaration(aProperty, aValue, info.mDocURI,
                                             info.mBaseURI, info.mPrincipal);
 }
 
 /* static */ bool
-CSS::Supports(nsISupports* aGlobal,
+CSS::Supports(const GlobalObject& aGlobal,
               const nsAString& aCondition,
               ErrorResult& aRv)
 {
   nsCSSParser parser;
   SupportsParsingInfo info;
 
-  nsresult rv = GetParsingInfo(aGlobal, info);
+  nsresult rv = GetParsingInfo(aGlobal.Get(), info);
   if (NS_FAILED(rv)) {
     aRv.Throw(rv);
     return false;
   }
 
   return parser.EvaluateSupportsCondition(aCondition, info.mDocURI,
                                           info.mBaseURI, info.mPrincipal);
 }
--- a/layout/style/CSS.h
+++ b/layout/style/CSS.h
@@ -10,27 +10,29 @@
 
 #include "mozilla/Attributes.h"
 #include "mozilla/ErrorResult.h"
 #include "mozilla/Preferences.h"
 
 namespace mozilla {
 namespace dom {
 
+class GlobalObject;
+
 class CSS {
 private:
   CSS() MOZ_DELETE;
 
 public:
-  static bool Supports(nsISupports* aGlobal,
+  static bool Supports(const GlobalObject& aGlobal,
                        const nsAString& aProperty,
                        const nsAString& aValue,
                        ErrorResult& aRv);
 
-  static bool Supports(nsISupports* aGlobal,
+  static bool Supports(const GlobalObject& aGlobal,
                        const nsAString& aDeclaration,
                        ErrorResult& aRv);
 
   static bool PrefEnabled()
   {
     return Preferences::GetBool("layout.css.supports-rule.enabled");
   }
 };