Bug 1122973 - Use templates instead of macros for NSS module factory constructors. r=Cykesiopka,keeler
authorMasatoshi Kimura <VYV03354@nifty.ne.jp>
Sat, 28 Jan 2017 11:10:42 +0900
changeset 340994 3a1ed6f4ed6aba725e85f8170cc13a25ca02cfe3
parent 340993 7a9666bfb431ba3f94ecbad92aea6690d39d4131
child 340995 ed583f4e5054748738c92e466fd8d2650c8d0888
push id86615
push userkwierso@gmail.com
push dateTue, 07 Feb 2017 01:52:08 +0000
treeherdermozilla-inbound@f0453084d86e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersCykesiopka, keeler
bugs1122973
milestone54.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 1122973 - Use templates instead of macros for NSS module factory constructors. r=Cykesiopka,keeler MozReview-Commit-ID: EcnOKgruorA
security/manager/ssl/nsINSSU2FToken.idl
security/manager/ssl/nsNSSModule.cpp
security/manager/ssl/nsNSSU2FToken.cpp
security/manager/ssl/nsNSSU2FToken.h
--- a/security/manager/ssl/nsINSSU2FToken.idl
+++ b/security/manager/ssl/nsINSSU2FToken.idl
@@ -4,18 +4,13 @@
 
 #include "nsIU2FToken.idl"
 
 /**
  * Interface used to interact with the NSS-backed software U2F Token
  */
 [scriptable, uuid(d9104a00-140b-4f86-a4b0-4998878ef4e6 )]
 interface nsINSSU2FToken : nsIU2FToken {
-  /**
-   * Initializes the token and constructs and persists keys, if needed. Asserts
-   * that it is only called by the main thread.
-   */
-  void init();
 };
 
 %{C++
 #define NS_NSSU2FTOKEN_CONTRACTID  "@mozilla.org/dom/u2f/nss-u2f-token;1"
 %}
--- a/security/manager/ssl/nsNSSModule.cpp
+++ b/security/manager/ssl/nsNSSModule.cpp
@@ -37,184 +37,96 @@
 #include "nsSiteSecurityService.h"
 #include "nsTLSSocketProvider.h"
 #include "nsXULAppAPI.h"
 
 #ifdef MOZ_XUL
 #include "nsCertTree.h"
 #endif
 
-#define NS_IS_PROCESS_DEFAULT                                                 \
-    (GeckoProcessType_Default == XRE_GetProcessType())
-
-#define NS_NSS_INSTANTIATE(ensureOperator, _InstanceClass)                    \
-    PR_BEGIN_MACRO                                                            \
-        _InstanceClass * inst;                                                \
-        inst = new _InstanceClass();                                          \
-        NS_ADDREF(inst);                                                      \
-        rv = inst->QueryInterface(aIID, aResult);                             \
-        NS_RELEASE(inst);                                                     \
-    PR_END_MACRO
+namespace mozilla { namespace psm {
 
-#define NS_NSS_INSTANTIATE_INIT(ensureOperator, _InstanceClass, _InitMethod)  \
-    PR_BEGIN_MACRO                                                            \
-        _InstanceClass * inst;                                                \
-        inst = new _InstanceClass();                                          \
-        NS_ADDREF(inst);                                                      \
-        rv = inst->_InitMethod();                                             \
-        if(NS_SUCCEEDED(rv)) {                                                \
-            rv = inst->QueryInterface(aIID, aResult);                         \
-        }                                                                     \
-        NS_RELEASE(inst);                                                     \
-   PR_END_MACRO
-
-
-#define NS_NSS_GENERIC_FACTORY_CONSTRUCTOR(ensureOperator,                    \
-                                           _InstanceClass)                    \
-   NS_NSS_GENERIC_FACTORY_CONSTRUCTOR_BYPROCESS(ensureOperator,               \
-                                                _InstanceClass,               \
-                                                _InstanceClass)
+MOZ_ALWAYS_INLINE static bool IsProcessDefault()
+{
+  return XRE_GetProcessType() == GeckoProcessType_Default;
+}
 
-// These two macros are ripped off from nsIGenericFactory.h and slightly
-// modified.
-#define NS_NSS_GENERIC_FACTORY_CONSTRUCTOR_BYPROCESS(ensureOperator,          \
-                                                     _InstanceClassChrome,    \
-                                                     _InstanceClassContent)   \
-static nsresult                                                               \
-_InstanceClassChrome##Constructor(nsISupports *aOuter, REFNSIID aIID,         \
-                                  void **aResult)                             \
-{                                                                             \
-    nsresult rv;                                                              \
-                                                                              \
-    *aResult = nullptr;                                                          \
-    if (nullptr != aOuter) {                                                     \
-        rv = NS_ERROR_NO_AGGREGATION;                                         \
-        return rv;                                                            \
-    }                                                                         \
-                                                                              \
-    if (!NS_IS_PROCESS_DEFAULT &&                                             \
-        ensureOperator == nssEnsureChromeOrContent) {                         \
-        if (!EnsureNSSInitializedChromeOrContent()) {                         \
-            return NS_ERROR_FAILURE;                                          \
-        }                                                                     \
-    } else if (!EnsureNSSInitialized(ensureOperator)) {                       \
-        return NS_ERROR_FAILURE;                                              \
-    }                                                                         \
-                                                                              \
-    if (NS_IS_PROCESS_DEFAULT)                                                \
-        NS_NSS_INSTANTIATE(ensureOperator, _InstanceClassChrome);             \
-    else                                                                      \
-        NS_NSS_INSTANTIATE(ensureOperator, _InstanceClassContent);            \
-                                                                              \
-    if (ensureOperator == nssLoadingComponent)                                \
-    {                                                                         \
-        if (NS_SUCCEEDED(rv))                                                 \
-            EnsureNSSInitialized(nssInitSucceeded);                           \
-        else                                                                  \
-            EnsureNSSInitialized(nssInitFailed);                              \
-    }                                                                         \
-                                                                              \
-    return rv;                                                                \
+template<class InstanceClass, nsresult (InstanceClass::*InitMethod)()>
+MOZ_ALWAYS_INLINE static nsresult
+Instantiate(REFNSIID aIID, void** aResult)
+{
+  InstanceClass* inst = new InstanceClass();
+  NS_ADDREF(inst);
+  nsresult rv = InitMethod != nullptr ? (inst->*InitMethod)() : NS_OK;
+  if (NS_SUCCEEDED(rv)) {
+    rv = inst->QueryInterface(aIID, aResult);
+  }
+  NS_RELEASE(inst);
+  return rv;
 }
 
- 
-#define NS_NSS_GENERIC_FACTORY_CONSTRUCTOR_INIT(ensureOperator,               \
-                                                _InstanceClass,               \
-                                                _InitMethod)                  \
-    NS_NSS_GENERIC_FACTORY_CONSTRUCTOR_INIT_BYPROCESS(ensureOperator,         \
-                                                      _InstanceClass,         \
-                                                      _InstanceClass,         \
-                                                      _InitMethod)
+template<EnsureNSSOperator ensureOperator, class InstanceClass,
+         nsresult (InstanceClass::*InitMethod)() = nullptr>
+static nsresult
+Constructor(nsISupports* aOuter, REFNSIID aIID, void** aResult)
+{
+  *aResult = nullptr;
+  if (aOuter != nullptr) {
+    return NS_ERROR_NO_AGGREGATION;
+  }
 
-#define NS_NSS_GENERIC_FACTORY_CONSTRUCTOR_INIT_BYPROCESS(ensureOperator,     \
-                                                _InstanceClassChrome,         \
-                                                _InstanceClassContent,        \
-                                                _InitMethod)                  \
-static nsresult                                                               \
-_InstanceClassChrome##Constructor(nsISupports *aOuter, REFNSIID aIID,         \
-                                  void **aResult)                             \
-{                                                                             \
-    nsresult rv;                                                              \
-                                                                              \
-    *aResult = nullptr;                                                       \
-    if (nullptr != aOuter) {                                                  \
-        rv = NS_ERROR_NO_AGGREGATION;                                         \
-        return rv;                                                            \
-    }                                                                         \
-                                                                              \
-    if (!NS_IS_PROCESS_DEFAULT &&                                             \
-        ensureOperator == nssEnsureChromeOrContent) {                         \
-        if (!EnsureNSSInitializedChromeOrContent()) {                         \
-            return NS_ERROR_FAILURE;                                          \
-        }                                                                     \
-    } else if (!EnsureNSSInitialized(ensureOperator)) {                       \
-        return NS_ERROR_FAILURE;                                              \
-    }                                                                         \
-                                                                              \
-    if (NS_IS_PROCESS_DEFAULT)                                                \
-        NS_NSS_INSTANTIATE_INIT(ensureOperator,                               \
-                                _InstanceClassChrome,                         \
-                                _InitMethod);                                 \
-    else                                                                      \
-        NS_NSS_INSTANTIATE_INIT(ensureOperator,                               \
-                                _InstanceClassContent,                        \
-                                _InitMethod);                                 \
-                                                                              \
-    if (ensureOperator == nssLoadingComponent)                                \
-    {                                                                         \
-        if (NS_SUCCEEDED(rv))                                                 \
-            EnsureNSSInitialized(nssInitSucceeded);                           \
-        else                                                                  \
-            EnsureNSSInitialized(nssInitFailed);                              \
-    }                                                                         \
-                                                                              \
-    return rv;                                                                \
+  if (ensureOperator == nssEnsureChromeOrContent &&
+      !IsProcessDefault()) {
+    if (!EnsureNSSInitializedChromeOrContent()) {
+      return NS_ERROR_FAILURE;
+    }
+  } else if (!EnsureNSSInitialized(ensureOperator)) {
+    return NS_ERROR_FAILURE;
+  }
+
+  nsresult rv = Instantiate<InstanceClass, InitMethod>(aIID, aResult);
+
+  if (ensureOperator == nssLoadingComponent) {
+    if (NS_SUCCEEDED(rv)) {
+      EnsureNSSInitialized(nssInitSucceeded);
+    } else {
+      EnsureNSSInitialized(nssInitFailed);
+    }
+  }
+
+  return rv;
 }
 
-NS_NSS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nssLoadingComponent, nsNSSComponent,
-                                        Init)
+template<class InstanceClassChrome, class InstanceClassContent>
+MOZ_ALWAYS_INLINE static nsresult
+Constructor(nsISupports* aOuter, REFNSIID aIID, void** aResult)
+{
+  if (IsProcessDefault()) {
+    return Constructor<nssEnsureOnChromeOnly,
+                       InstanceClassChrome>(aOuter, aIID, aResult);
+  }
+
+  return Constructor<nssEnsureOnChromeOnly,
+                     InstanceClassContent>(aOuter, aIID, aResult);
+}
+
+template<class InstanceClass>
+MOZ_ALWAYS_INLINE static nsresult
+Constructor(nsISupports* aOuter, REFNSIID aIID, void** aResult)
+{
+  return Constructor<nssEnsure, InstanceClass>(aOuter, aIID, aResult);
+}
+
+} } // namespace mozilla::psm
 
 using namespace mozilla::psm;
 
 namespace {
 
-// Use the special factory constructor for everything this module implements,
-// because all code could potentially require the NSS library.
-// Our factory constructor takes an additional boolean parameter.
-// Only for the nsNSSComponent, set this to true.
-// All other classes must have this set to false.
-
-NS_NSS_GENERIC_FACTORY_CONSTRUCTOR(nssEnsure, nsSSLSocketProvider)
-NS_NSS_GENERIC_FACTORY_CONSTRUCTOR(nssEnsure, nsTLSSocketProvider)
-NS_NSS_GENERIC_FACTORY_CONSTRUCTOR(nssEnsure, SecretDecoderRing)
-NS_NSS_GENERIC_FACTORY_CONSTRUCTOR(nssEnsure, nsPK11TokenDB)
-NS_NSS_GENERIC_FACTORY_CONSTRUCTOR(nssEnsure, nsPKCS11ModuleDB)
 NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(PSMContentListener, init)
-NS_NSS_GENERIC_FACTORY_CONSTRUCTOR_BYPROCESS(nssEnsureOnChromeOnly,
-                                             nsNSSCertificate,
-                                             nsNSSCertificateFakeTransport)
-NS_NSS_GENERIC_FACTORY_CONSTRUCTOR(nssEnsure, nsNSSCertificateDB)
-NS_NSS_GENERIC_FACTORY_CONSTRUCTOR_BYPROCESS(nssEnsureOnChromeOnly,
-                                             nsNSSCertList,
-                                             nsNSSCertListFakeTransport)
-#ifdef MOZ_XUL
-NS_NSS_GENERIC_FACTORY_CONSTRUCTOR(nssEnsure, nsCertTree)
-#endif
-NS_NSS_GENERIC_FACTORY_CONSTRUCTOR(nssEnsure, nsPkcs11)
-NS_NSS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nssEnsure, nsNTLMAuthModule, InitTest)
-NS_NSS_GENERIC_FACTORY_CONSTRUCTOR(nssEnsureChromeOrContent, nsCryptoHash)
-NS_NSS_GENERIC_FACTORY_CONSTRUCTOR(nssEnsureChromeOrContent, nsCryptoHMAC)
-NS_NSS_GENERIC_FACTORY_CONSTRUCTOR(nssEnsureChromeOrContent, nsKeyObject)
-NS_NSS_GENERIC_FACTORY_CONSTRUCTOR(nssEnsureChromeOrContent, nsKeyObjectFactory)
-NS_NSS_GENERIC_FACTORY_CONSTRUCTOR(nssEnsure, nsDataSignatureVerifier)
-NS_NSS_GENERIC_FACTORY_CONSTRUCTOR(nssEnsure, ContentSignatureVerifier)
-NS_NSS_GENERIC_FACTORY_CONSTRUCTOR(nssEnsureChromeOrContent, nsRandomGenerator)
-NS_NSS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nssEnsure, nsNSSU2FToken, Init)
-NS_NSS_GENERIC_FACTORY_CONSTRUCTOR(nssEnsureOnChromeOnly, nsSSLStatus)
-NS_NSS_GENERIC_FACTORY_CONSTRUCTOR(nssEnsureOnChromeOnly, TransportSecurityInfo)
 
 typedef mozilla::psm::NSSErrorsService NSSErrorsService;
 NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(NSSErrorsService, Init)
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsNSSVersion)
 NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsCertOverrideService, Init)
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsSecureBrowserUIImpl)
 NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(CertBlocklist, Init)
 NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsSiteSecurityService, Init)
@@ -247,44 +159,70 @@ NS_DEFINE_NAMED_CID(NS_NSSU2FTOKEN_CID);
 NS_DEFINE_NAMED_CID(NS_SSLSTATUS_CID);
 NS_DEFINE_NAMED_CID(TRANSPORTSECURITYINFO_CID);
 NS_DEFINE_NAMED_CID(NS_NSSERRORSSERVICE_CID);
 NS_DEFINE_NAMED_CID(NS_NSSVERSION_CID);
 NS_DEFINE_NAMED_CID(NS_SECURE_BROWSER_UI_CID);
 NS_DEFINE_NAMED_CID(NS_SITE_SECURITY_SERVICE_CID);
 NS_DEFINE_NAMED_CID(NS_CERT_BLOCKLIST_CID);
 
+// Use the special factory constructor for everything this module implements,
+// because all code could potentially require the NSS library.
+// Our factory constructor takes an optional EnsureNSSOperator template
+// parameter.
+// Only for the nsNSSComponent, set this to nssLoadingComponent.
+// For classes available from a content process, set this to
+// nssEnsureOnChromeOnly.
+// All other classes must have this set to nssEnsure (default).
+
 static const mozilla::Module::CIDEntry kNSSCIDs[] = {
-  { &kNS_NSSCOMPONENT_CID, false, nullptr, nsNSSComponentConstructor },
-  { &kNS_SSLSOCKETPROVIDER_CID, false, nullptr, nsSSLSocketProviderConstructor },
-  { &kNS_STARTTLSSOCKETPROVIDER_CID, false, nullptr, nsTLSSocketProviderConstructor },
-  { &kNS_SECRETDECODERRING_CID, false, nullptr, SecretDecoderRingConstructor },
-  { &kNS_PK11TOKENDB_CID, false, nullptr, nsPK11TokenDBConstructor },
-  { &kNS_PKCS11MODULEDB_CID, false, nullptr, nsPKCS11ModuleDBConstructor },
+  { &kNS_NSSCOMPONENT_CID, false, nullptr,
+    Constructor<nssLoadingComponent, nsNSSComponent, &nsNSSComponent::Init> },
+  { &kNS_SSLSOCKETPROVIDER_CID, false, nullptr,
+    Constructor<nsSSLSocketProvider> },
+  { &kNS_STARTTLSSOCKETPROVIDER_CID, false, nullptr,
+    Constructor<nsTLSSocketProvider> },
+  { &kNS_SECRETDECODERRING_CID, false, nullptr,
+    Constructor<SecretDecoderRing> },
+  { &kNS_PK11TOKENDB_CID, false, nullptr, Constructor<nsPK11TokenDB> },
+  { &kNS_PKCS11MODULEDB_CID, false, nullptr, Constructor<nsPKCS11ModuleDB> },
   { &kNS_PSMCONTENTLISTEN_CID, false, nullptr, PSMContentListenerConstructor },
-  { &kNS_X509CERT_CID, false, nullptr, nsNSSCertificateConstructor },
-  { &kNS_X509CERTDB_CID, false, nullptr, nsNSSCertificateDBConstructor },
-  { &kNS_X509CERTLIST_CID, false, nullptr, nsNSSCertListConstructor },
+  { &kNS_X509CERT_CID, false, nullptr,
+    Constructor<nsNSSCertificate, nsNSSCertificateFakeTransport> },
+  { &kNS_X509CERTDB_CID, false, nullptr, Constructor<nsNSSCertificateDB> },
+  { &kNS_X509CERTLIST_CID, false, nullptr,
+    Constructor<nsNSSCertList, nsNSSCertListFakeTransport> },
   { &kNS_FORMPROCESSOR_CID, false, nullptr, nsKeygenFormProcessor::Create },
 #ifdef MOZ_XUL
-  { &kNS_CERTTREE_CID, false, nullptr, nsCertTreeConstructor },
+  { &kNS_CERTTREE_CID, false, nullptr, Constructor<nsCertTree> },
 #endif
-  { &kNS_PKCS11_CID, false, nullptr, nsPkcs11Constructor },
-  { &kNS_CRYPTO_HASH_CID, false, nullptr, nsCryptoHashConstructor },
-  { &kNS_CRYPTO_HMAC_CID, false, nullptr, nsCryptoHMACConstructor },
-  { &kNS_NTLMAUTHMODULE_CID, false, nullptr, nsNTLMAuthModuleConstructor },
-  { &kNS_KEYMODULEOBJECT_CID, false, nullptr, nsKeyObjectConstructor },
-  { &kNS_KEYMODULEOBJECTFACTORY_CID, false, nullptr, nsKeyObjectFactoryConstructor },
-  { &kNS_DATASIGNATUREVERIFIER_CID, false, nullptr, nsDataSignatureVerifierConstructor },
-  { &kNS_CONTENTSIGNATUREVERIFIER_CID, false, nullptr, ContentSignatureVerifierConstructor },
+  { &kNS_PKCS11_CID, false, nullptr, Constructor<nsPkcs11> },
+  { &kNS_CRYPTO_HASH_CID, false, nullptr,
+    Constructor<nssEnsureChromeOrContent, nsCryptoHash> },
+  { &kNS_CRYPTO_HMAC_CID, false, nullptr,
+    Constructor<nssEnsureChromeOrContent, nsCryptoHMAC> },
+  { &kNS_NTLMAUTHMODULE_CID, false, nullptr,
+    Constructor<nssEnsure, nsNTLMAuthModule, &nsNTLMAuthModule::InitTest> },
+  { &kNS_KEYMODULEOBJECT_CID, false, nullptr,
+    Constructor<nssEnsureChromeOrContent, nsKeyObject> },
+  { &kNS_KEYMODULEOBJECTFACTORY_CID, false, nullptr,
+    Constructor<nssEnsureChromeOrContent, nsKeyObjectFactory> },
+  { &kNS_DATASIGNATUREVERIFIER_CID, false, nullptr,
+    Constructor<nsDataSignatureVerifier> },
+  { &kNS_CONTENTSIGNATUREVERIFIER_CID, false, nullptr,
+    Constructor<ContentSignatureVerifier> },
   { &kNS_CERTOVERRIDE_CID, false, nullptr, nsCertOverrideServiceConstructor },
-  { &kNS_RANDOMGENERATOR_CID, false, nullptr, nsRandomGeneratorConstructor },
-  { &kNS_NSSU2FTOKEN_CID, false, nullptr, nsNSSU2FTokenConstructor },
-  { &kNS_SSLSTATUS_CID, false, nullptr, nsSSLStatusConstructor },
-  { &kTRANSPORTSECURITYINFO_CID, false, nullptr, TransportSecurityInfoConstructor },
+  { &kNS_RANDOMGENERATOR_CID, false, nullptr,
+    Constructor<nssEnsureChromeOrContent, nsRandomGenerator> },
+  { &kNS_NSSU2FTOKEN_CID, false, nullptr,
+    Constructor<nssEnsure, nsNSSU2FToken, &nsNSSU2FToken::Init> },
+  { &kNS_SSLSTATUS_CID, false, nullptr,
+    Constructor<nssEnsureOnChromeOnly, nsSSLStatus> },
+  { &kTRANSPORTSECURITYINFO_CID, false, nullptr,
+    Constructor<nssEnsureOnChromeOnly, TransportSecurityInfo> },
   { &kNS_NSSERRORSSERVICE_CID, false, nullptr, NSSErrorsServiceConstructor },
   { &kNS_NSSVERSION_CID, false, nullptr, nsNSSVersionConstructor },
   { &kNS_SECURE_BROWSER_UI_CID, false, nullptr, nsSecureBrowserUIImplConstructor },
   { &kNS_SITE_SECURITY_SERVICE_CID, false, nullptr, nsSiteSecurityServiceConstructor },
   { &kNS_CERT_BLOCKLIST_CID, false, nullptr, CertBlocklistConstructor},
   { nullptr }
 };
 
--- a/security/manager/ssl/nsNSSU2FToken.cpp
+++ b/security/manager/ssl/nsNSSU2FToken.cpp
@@ -346,17 +346,17 @@ GetAttestationCertificate(const UniquePK
 
   MOZ_LOG(gNSSTokenLog, LogLevel::Debug,
           ("U2F Soft Token attestation certificate generated."));
   return NS_OK;
 }
 
 // Set up the context for the soft U2F Token. This is called by NSS
 // initialization.
-NS_IMETHODIMP
+nsresult
 nsNSSU2FToken::Init()
 {
   MOZ_ASSERT(NS_IsMainThread());
   MOZ_ASSERT(!mInitialized);
   if (mInitialized) {
     return NS_ERROR_FAILURE;
   }
 
--- a/security/manager/ssl/nsNSSU2FToken.h
+++ b/security/manager/ssl/nsNSSU2FToken.h
@@ -24,16 +24,20 @@ public:
   NS_DECL_NSINSSU2FTOKEN
 
   nsNSSU2FToken();
 
   // For nsNSSShutDownObject
   virtual void virtualDestroyNSSReference() override;
   void destructorSafeDestroyNSSReference();
 
+  // Initializes the token and constructs and persists keys, if needed. Asserts
+  // that it is only called by the main thread.
+  nsresult Init();
+
 private:
   bool mInitialized;
   mozilla::UniquePK11SymKey mWrappingKey;
 
   static const nsCString mSecretNickname;
   static const nsString mVersion;
 
   ~nsNSSU2FToken();