Bug 1477432 - Part 6: Stop using nsIJSID inside of WebIDL bindings, r=mccr8
authorNika Layzell <nika@thelayzells.com>
Wed, 18 Jul 2018 00:30:38 -0400
changeset 503337 ab47ae5672ac00f6525f0d109af570a771d97add
parent 503336 c019316fcfd49d74775c9b458b3d611f8081ee7e
child 503338 a68bee9d2168c514ea485deba6c2624934a1c79f
push id10290
push userffxbld-merge
push dateMon, 03 Dec 2018 16:23:23 +0000
treeherdermozilla-beta@700bed2445e6 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmccr8
bugs1477432
milestone65.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 1477432 - Part 6: Stop using nsIJSID inside of WebIDL bindings, r=mccr8 Rather than adding a native type for nsID objects in WebIDL, this patch just takes the approach of switching consumers over to using 'any' and calling the APIs defined in Part 1. Differential Revision: https://phabricator.services.mozilla.com/D2283
dom/base/MozQueryInterface.cpp
dom/base/MozQueryInterface.h
dom/base/nsGlobalWindowInner.cpp
dom/base/nsGlobalWindowInner.h
dom/base/nsGlobalWindowOuter.h
dom/bindings/BindingUtils.cpp
dom/bindings/BindingUtils.h
dom/bindings/Bindings.conf
dom/bindings/Codegen.py
dom/chrome-webidl/ChromeUtils.webidl
dom/webidl/LegacyQueryInterface.webidl
dom/webidl/Window.webidl
dom/webidl/XMLHttpRequest.webidl
dom/xhr/XMLHttpRequest.h
dom/xhr/XMLHttpRequestMainThread.cpp
dom/xhr/XMLHttpRequestMainThread.h
dom/xhr/XMLHttpRequestWorker.h
--- a/dom/base/MozQueryInterface.cpp
+++ b/dom/base/MozQueryInterface.cpp
@@ -75,24 +75,25 @@ ChromeUtils::GenerateQI(const GlobalObje
 bool
 MozQueryInterface::QueriesTo(const nsIID& aIID) const
 {
   return mInterfaces.ContainsSorted(aIID, CompareIIDs);
 }
 
 void
 MozQueryInterface::LegacyCall(JSContext* cx, JS::Handle<JS::Value> thisv,
-                              nsIJSID* aIID,
+                              JS::Handle<JS::Value> aIID,
                               JS::MutableHandle<JS::Value> aResult,
                               ErrorResult& aRv) const
 {
-  if (!QueriesTo(*aIID->GetID())) {
+  Maybe<nsID> id = xpc::JSValue2ID(cx, aIID);
+  if (id && QueriesTo(*id)) {
+    aResult.set(thisv);
+  } else {
     aRv.Throw(NS_ERROR_NO_INTERFACE);
-  } else {
-    aResult.set(thisv);
   }
 }
 
 bool
 MozQueryInterface::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aReflector)
 {
   return MozQueryInterface_Binding::Wrap(aCx, this, aGivenProto, aReflector);
 }
--- a/dom/base/MozQueryInterface.h
+++ b/dom/base/MozQueryInterface.h
@@ -31,17 +31,20 @@ class MozQueryInterface final : public N
 {
 public:
   explicit MozQueryInterface(nsTArray<nsIID>&& aInterfaces)
     : mInterfaces(std::move(aInterfaces))
   {}
 
   bool QueriesTo(const nsIID& aIID) const;
 
-  void LegacyCall(JSContext* cx, JS::Handle<JS::Value> thisv, nsIJSID* aIID, JS::MutableHandle<JS::Value> aResult, ErrorResult& aRv) const;
+  void LegacyCall(JSContext* cx, JS::Handle<JS::Value> thisv,
+                  JS::Handle<JS::Value> aIID,
+                  JS::MutableHandle<JS::Value> aResult,
+                  ErrorResult& aRv) const;
 
   nsISupports* GetParentObject() const { return nullptr; }
 
   bool WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aReflector);
 
 private:
   nsTArray<nsIID> mInterfaces;
 };
--- a/dom/base/nsGlobalWindowInner.cpp
+++ b/dom/base/nsGlobalWindowInner.cpp
@@ -5003,17 +5003,17 @@ nsGlobalWindowInner::GetInterface(const 
   nsresult rv = outer->GetInterfaceInternal(aIID, aSink);
   if (rv == NS_ERROR_NO_INTERFACE) {
     return QueryInterface(aIID, aSink);
   }
   return rv;
 }
 
 void
-nsGlobalWindowInner::GetInterface(JSContext* aCx, nsIJSID* aIID,
+nsGlobalWindowInner::GetInterface(JSContext* aCx, JS::Handle<JS::Value> aIID,
                                   JS::MutableHandle<JS::Value> aRetval,
                                   ErrorResult& aError)
 {
   dom::GetInterface(aCx, this, aIID, aRetval, aError);
 }
 
 already_AddRefed<CacheStorage>
 nsGlobalWindowInner::GetCaches(ErrorResult& aRv)
--- a/dom/base/nsGlobalWindowInner.h
+++ b/dom/base/nsGlobalWindowInner.h
@@ -64,17 +64,16 @@ class nsIArray;
 class nsIBaseWindow;
 class nsIContent;
 class nsICSSDeclaration;
 class nsIDocShellTreeOwner;
 class nsIDOMWindowUtils;
 class nsDOMOfflineResourceList;
 class nsIScrollableFrame;
 class nsIControllers;
-class nsIJSID;
 class nsIScriptContext;
 class nsIScriptTimeoutHandler;
 class nsITabChild;
 class nsITimeoutHandler;
 class nsIWebBrowserChrome;
 class mozIDOMWindowProxy;
 
 class nsDOMWindowList;
@@ -973,17 +972,17 @@ public:
                       mozilla::ErrorResult& aError);
   void SetReturnValueOuter(JSContext* aCx, JS::Handle<JS::Value> aReturnValue,
                            nsIPrincipal& aSubjectPrincipal,
                            mozilla::ErrorResult& aError);
   void SetReturnValue(JSContext* aCx, JS::Handle<JS::Value> aReturnValue,
                       nsIPrincipal& aSubjectPrincipal,
                       mozilla::ErrorResult& aError);
 
-  void GetInterface(JSContext* aCx, nsIJSID* aIID,
+  void GetInterface(JSContext* aCx, JS::Handle<JS::Value> aIID,
                     JS::MutableHandle<JS::Value> aRetval,
                     mozilla::ErrorResult& aError);
 
   already_AddRefed<nsWindowRoot> GetWindowRoot(mozilla::ErrorResult& aError);
 
   bool ShouldReportForServiceWorkerScope(const nsAString& aScope);
 
   void PropagateClearSiteDataReload(const nsACString& aOrigin);
--- a/dom/base/nsGlobalWindowOuter.h
+++ b/dom/base/nsGlobalWindowOuter.h
@@ -59,17 +59,16 @@
 class nsIArray;
 class nsIBaseWindow;
 class nsIContent;
 class nsICSSDeclaration;
 class nsIDocShellTreeOwner;
 class nsIDOMWindowUtils;
 class nsIScrollableFrame;
 class nsIControllers;
-class nsIJSID;
 class nsIScriptContext;
 class nsIScriptTimeoutHandler;
 class nsITabChild;
 class nsITimeoutHandler;
 class nsIWebBrowserChrome;
 class mozIDOMWindowProxy;
 
 class nsDocShellLoadState;
--- a/dom/bindings/BindingUtils.cpp
+++ b/dom/bindings/BindingUtils.cpp
@@ -1392,61 +1392,59 @@ QueryInterface(JSContext* cx, unsigned a
   if (!native) {
     return Throw(cx, NS_ERROR_FAILURE);
   }
 
   if (argc < 1) {
     return Throw(cx, NS_ERROR_XPC_NOT_ENOUGH_ARGS);
   }
 
-  if (!args[0].isObject()) {
+  Maybe<nsIID> iid = xpc::JSValue2ID(cx, args[0]);
+  if (!iid) {
     return Throw(cx, NS_ERROR_XPC_BAD_CONVERT_JS);
   }
 
-  nsCOMPtr<nsIJSID> iid;
-  obj = &args[0].toObject();
-  if (NS_FAILED(UnwrapArg<nsIJSID>(cx, obj, getter_AddRefs(iid)))) {
-    return Throw(cx, NS_ERROR_XPC_BAD_CONVERT_JS);
-  }
-  MOZ_ASSERT(iid);
-
-  if (iid->GetID()->Equals(NS_GET_IID(nsIClassInfo))) {
+  if (iid->Equals(NS_GET_IID(nsIClassInfo))) {
     nsresult rv;
     nsCOMPtr<nsIClassInfo> ci = do_QueryInterface(native, &rv);
     if (NS_FAILED(rv)) {
       return Throw(cx, rv);
     }
 
     return WrapObject(cx, ci, &NS_GET_IID(nsIClassInfo), args.rval());
   }
 
   nsCOMPtr<nsISupports> unused;
-  nsresult rv = native->QueryInterface(*iid->GetID(), getter_AddRefs(unused));
+  nsresult rv = native->QueryInterface(*iid, getter_AddRefs(unused));
   if (NS_FAILED(rv)) {
     return Throw(cx, rv);
   }
 
   args.rval().set(args.thisv());
   return true;
 }
 
 void
 GetInterfaceImpl(JSContext* aCx, nsIInterfaceRequestor* aRequestor,
-                 nsWrapperCache* aCache, nsIJSID* aIID,
+                 nsWrapperCache* aCache, JS::Handle<JS::Value> aIID,
                  JS::MutableHandle<JS::Value> aRetval, ErrorResult& aError)
 {
-  const nsID* iid = aIID->GetID();
+  Maybe<nsIID> iid = xpc::JSValue2ID(aCx, aIID);
+  if (!iid) {
+    aError.Throw(NS_ERROR_XPC_BAD_CONVERT_JS);
+    return;
+  }
 
   RefPtr<nsISupports> result;
   aError = aRequestor->GetInterface(*iid, getter_AddRefs(result));
   if (aError.Failed()) {
     return;
   }
 
-  if (!WrapObject(aCx, result, iid, aRetval)) {
+  if (!WrapObject(aCx, result, iid.ptr(), aRetval)) {
     aError.Throw(NS_ERROR_FAILURE);
   }
 }
 
 bool
 ThrowingConstructor(JSContext* cx, unsigned argc, JS::Value* vp)
 {
   return ThrowErrorMessage(cx, MSG_ILLEGAL_CONSTRUCTOR);
--- a/dom/bindings/BindingUtils.h
+++ b/dom/bindings/BindingUtils.h
@@ -38,17 +38,16 @@
 #include "xpcObjectHelper.h"
 #include "xpcpublic.h"
 #include "nsIVariant.h"
 #include "mozilla/dom/FakeString.h"
 
 #include "nsWrapperCacheInlines.h"
 
 class nsGenericHTMLElement;
-class nsIJSID;
 
 namespace mozilla {
 
 enum UseCounter : int16_t;
 
 namespace dom {
 class CustomElementReactionsStack;
 class MessageManagerGlobal;
@@ -1902,22 +1901,22 @@ WantsQueryInterface
   static bool Enabled(JSContext* aCx, JSObject* aGlobal)
   {
     return NS_IsMainThread() && IsChromeOrXBL(aCx, aGlobal);
   }
 };
 
 void
 GetInterfaceImpl(JSContext* aCx, nsIInterfaceRequestor* aRequestor,
-                 nsWrapperCache* aCache, nsIJSID* aIID,
+                 nsWrapperCache* aCache, JS::Handle<JS::Value> aIID,
                  JS::MutableHandle<JS::Value> aRetval, ErrorResult& aError);
 
 template<class T>
 void
-GetInterface(JSContext* aCx, T* aThis, nsIJSID* aIID,
+GetInterface(JSContext* aCx, T* aThis, JS::Handle<JS::Value> aIID,
              JS::MutableHandle<JS::Value> aRetval, ErrorResult& aError)
 {
   GetInterfaceImpl(aCx, aThis, aThis, aIID, aRetval, aError);
 }
 
 bool
 ThrowingConstructor(JSContext* cx, unsigned argc, JS::Value* vp);
 
--- a/dom/bindings/Bindings.conf
+++ b/dom/bindings/Bindings.conf
@@ -454,21 +454,16 @@ DOMInterfaces = {
 'IDBOpenDBRequest': {
     'headerFile': 'IDBRequest.h'
 },
 
 'IDBVersionChangeEvent': {
     'headerFile': 'IDBEvents.h',
 },
 
-'IID': {
-    'nativeType': 'nsIJSID',
-    'headerFile': 'xpcjsid.h',
-},
-
 'ImageCapture': {
     'binaryNames': { 'videoStreamTrack': 'GetVideoStreamTrack' }
 },
 
 'ImageData': {
     'wrapperCache': False,
 },
 
--- a/dom/bindings/Codegen.py
+++ b/dom/bindings/Codegen.py
@@ -2283,20 +2283,19 @@ class MethodDefiner(PropertyDefiner):
         for m in methods:
             if m.identifier.name == 'QueryInterface':
                 # QueryInterface is special, because instead of generating an
                 # impl we just call out directly to our shared one.
                 if m.isStatic():
                     raise TypeError("Legacy QueryInterface member shouldn't be static")
                 signatures = m.signatures()
 
-                def argTypeIsIID(arg):
-                    return arg.type.inner.isExternal() and arg.type.inner.identifier.name == 'IID'
-                if len(signatures) > 1 or len(signatures[0][1]) > 1 or not argTypeIsIID(signatures[0][1][0]):
-                    raise TypeError("There should be only one QueryInterface method with 1 argument of type IID")
+                if (len(signatures) > 1 or len(signatures[0][1]) > 1 or
+                    not signatures[0][1][0].type.isAny()):
+                    raise TypeError("There should be only one QueryInterface method with 1 argument of type any")
 
                 # Make sure to not stick QueryInterface on abstract interfaces.
                 if (not self.descriptor.interface.hasInterfacePrototypeObject() or
                     not self.descriptor.concrete):
                     raise TypeError("QueryInterface is only supported on "
                                     "interfaces that are concrete: " +
                                     self.descriptor.name)
 
--- a/dom/chrome-webidl/ChromeUtils.webidl
+++ b/dom/chrome-webidl/ChromeUtils.webidl
@@ -12,17 +12,17 @@
  * called with an unsupported interface, it throws NS_ERROR_NO_INTERFACE.
  *
  * C++ callers use a fast path, and never call the JSAPI or WebIDL methods of
  * this object.
  */
 [ChromeOnly, Exposed=Window]
 interface MozQueryInterface {
   [Throws]
-  legacycaller any (IID aIID);
+  legacycaller any (any aIID);
 };
 
 /**
  * A collection of static utility methods that are only exposed to system code.
  * This is exposed in all the system globals where we can expose stuff by
  * default, so should only include methods that are **thread-safe**.
  */
 [ChromeOnly, Exposed=(Window,Worker)]
--- a/dom/webidl/LegacyQueryInterface.webidl
+++ b/dom/webidl/LegacyQueryInterface.webidl
@@ -1,25 +1,24 @@
 /* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* 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/.
  */
 
 interface nsISupports;
-interface IID;
 
 [NoInterfaceObject,
  // Need Exposed here, because this is a mixin onto things like Event
  // that are exposed in workers.
  Exposed=(Window,Worker)]
 interface LegacyQueryInterface {
   // Legacy QueryInterface, only exposed to chrome code on the main thread.
   [Exposed=Window, ChromeOnly]
-  nsISupports QueryInterface(IID iid);
+  nsISupports QueryInterface(any iid);
 };
 
 DOMParser implements LegacyQueryInterface;
 Document implements LegacyQueryInterface;
 DocumentFragment implements LegacyQueryInterface;
 Element implements LegacyQueryInterface;
 Event implements LegacyQueryInterface;
 Selection implements LegacyQueryInterface;
--- a/dom/webidl/Window.webidl
+++ b/dom/webidl/Window.webidl
@@ -14,17 +14,16 @@
  * https://dvcs.w3.org/hg/webcrypto-api/raw-file/tip/spec/Overview.html
  * http://dvcs.w3.org/hg/speech-api/raw-file/tip/speechapi.html
  * https://w3c.github.io/webappsec-secure-contexts/#monkey-patching-global-object
  * https://w3c.github.io/requestidlecallback/
  * https://drafts.css-houdini.org/css-paint-api-1/#dom-window-paintworklet
  * https://wicg.github.io/visual-viewport/#the-visualviewport-interface
  */
 
-interface IID;
 interface nsIBrowserDOMWindow;
 interface XULControllers;
 interface nsIDOMWindowUtils;
 
 typedef OfflineResourceList ApplicationCache;
 
 // http://www.whatwg.org/specs/web-apps/current-work/
 [PrimaryGlobal, LegacyUnenumerableNamedProperties, NeedResolve]
@@ -335,17 +334,17 @@ partial interface Window {
 
   [
 #ifdef NIGHTLY_BUILD
    ChromeOnly,
 #endif
    NonEnumerable, Replaceable, Throws, NeedsCallerType]
   readonly attribute object? content;
 
-  [Throws, ChromeOnly] any getInterface(IID iid);
+  [Throws, ChromeOnly] any getInterface(any iid);
 
   /**
    * Same as nsIDOMWindow.windowRoot, useful for event listener targeting.
    */
   [ChromeOnly, Throws]
   readonly attribute WindowRoot? windowRoot;
 
   /**
--- a/dom/webidl/XMLHttpRequest.webidl
+++ b/dom/webidl/XMLHttpRequest.webidl
@@ -7,17 +7,16 @@
  * https://xhr.spec.whatwg.org/#interface-xmlhttprequest
  *
  * Copyright © 2012 W3C® (MIT, ERCIM, Keio), All Rights Reserved. W3C
  * liability, trademark and document use rules apply.
  */
 
 interface InputStream;
 interface MozChannel;
-interface IID;
 
 enum XMLHttpRequestResponseType {
   "",
   "arraybuffer",
   "blob",
   "document",
   "json",
   "text",
@@ -122,17 +121,17 @@ interface XMLHttpRequest : XMLHttpReques
 
   [ChromeOnly, SetterThrows]
   attribute boolean mozBackgroundRequest;
 
   [ChromeOnly, Exposed=Window]
   readonly attribute MozChannel? channel;
 
   [Throws, ChromeOnly, Exposed=Window]
-  any getInterface(IID iid);
+  any getInterface(any iid);
 
   [ChromeOnly, Exposed=Window]
   void setOriginAttributes(optional OriginAttributesDictionary originAttributes);
 
   [ChromeOnly, Throws]
   void sendInputStream(InputStream body);
 
   // Only works on MainThread.
--- a/dom/xhr/XMLHttpRequest.h
+++ b/dom/xhr/XMLHttpRequest.h
@@ -6,18 +6,16 @@
 
 #ifndef mozilla_dom_XMLHttpRequest_h
 #define mozilla_dom_XMLHttpRequest_h
 
 #include "mozilla/Attributes.h"
 #include "mozilla/dom/XMLHttpRequestEventTarget.h"
 #include "mozilla/dom/XMLHttpRequestBinding.h"
 
-class nsIJSID;
-
 namespace mozilla {
 namespace dom {
 
 class Blob;
 class DOMString;
 class FormData;
 class URLSearchParams;
 class XMLHttpRequestUpload;
@@ -129,17 +127,17 @@ public:
   virtual void
   SetMozBackgroundRequest(bool aMozBackgroundRequest, ErrorResult& aRv) = 0;
 
   virtual nsIChannel*
   GetChannel() const = 0;
 
   // We need a GetInterface callable from JS for chrome JS
   virtual void
-  GetInterface(JSContext* aCx, nsIJSID* aIID,
+  GetInterface(JSContext* aCx, JS::Handle<JS::Value> aIID,
                JS::MutableHandle<JS::Value> aRetval,
                ErrorResult& aRv) = 0;
 
   virtual void
   SetOriginAttributes(const mozilla::dom::OriginAttributesDictionary& aAttrs) = 0;
 
   virtual uint16_t
   ErrorCode() const = 0;
--- a/dom/xhr/XMLHttpRequestMainThread.cpp
+++ b/dom/xhr/XMLHttpRequestMainThread.cpp
@@ -3503,17 +3503,17 @@ XMLHttpRequestMainThread::GetInterface(c
     *aResult = static_cast<nsITimerCallback*>(EnsureXPCOMifier().take());
     return NS_OK;
   }
 
   return QueryInterface(aIID, aResult);
 }
 
 void
-XMLHttpRequestMainThread::GetInterface(JSContext* aCx, nsIJSID* aIID,
+XMLHttpRequestMainThread::GetInterface(JSContext* aCx, JS::Handle<JS::Value> aIID,
                                        JS::MutableHandle<JS::Value> aRetval,
                                        ErrorResult& aRv)
 {
   dom::GetInterface(aCx, this, aIID, aRetval, aRv);
 }
 
 XMLHttpRequestUpload*
 XMLHttpRequestMainThread::GetUpload(ErrorResult& aRv)
--- a/dom/xhr/XMLHttpRequestMainThread.h
+++ b/dom/xhr/XMLHttpRequestMainThread.h
@@ -53,17 +53,16 @@
 #ifdef Status
 /* Xlib headers insist on this for some reason... Nuke it because
    it'll override our member name */
 #undef Status
 #endif
 
 class nsIJARChannel;
 class nsILoadGroup;
-class nsIJSID;
 
 namespace mozilla {
 namespace dom {
 
 class DOMString;
 class XMLHttpRequestUpload;
 struct OriginAttributesDictionary;
 
@@ -437,17 +436,17 @@ public:
   virtual nsIChannel*
   GetChannel() const override
   {
     return mChannel;
   }
 
   // We need a GetInterface callable from JS for chrome JS
   virtual void
-  GetInterface(JSContext* aCx, nsIJSID* aIID,
+  GetInterface(JSContext* aCx, JS::Handle<JS::Value> aIID,
                JS::MutableHandle<JS::Value> aRetval,
                ErrorResult& aRv) override;
 
   // This fires a trusted readystatechange event, which is not cancelable and
   // doesn't bubble.
   nsresult FireReadystatechangeEvent();
   void DispatchProgressEvent(DOMEventTargetHelper* aTarget,
                              const ProgressEventType aType,
--- a/dom/xhr/XMLHttpRequestWorker.h
+++ b/dom/xhr/XMLHttpRequestWorker.h
@@ -210,17 +210,17 @@ public:
 
   virtual nsIDocument*
   GetResponseXML(ErrorResult& aRv) override
   {
     MOZ_CRASH("This method should not be called.");
   }
 
   virtual void
-  GetInterface(JSContext* aCx, nsIJSID* aIID,
+  GetInterface(JSContext* aCx, JS::Handle<JS::Value> aIID,
                JS::MutableHandle<JS::Value> aRetval,
                ErrorResult& aRv) override
   {
     aRv.Throw(NS_ERROR_FAILURE);
   }
 
   virtual void
   SetOriginAttributes(const mozilla::dom::OriginAttributesDictionary& aAttrs) override