Implement compatibility wrapper so that binary components can be compatible with both Firefox 3.6 and Firefox 4, as a result of registration changes from bug 568691.
authorBenjamin Smedberg <benjamin@smedbergs.us>
Thu, 24 Jun 2010 16:36:27 -0400
changeset 47043 21ebf7198406df08149e7232ac26e92d96930d32
parent 47042 95a67dbd4d36c6fb259a187ef0c5dd6696c41777
child 47044 9e03a4f25df80ca0b4cbadea7978bb8ca43ecd34
push id14223
push userbsmedberg@mozilla.com
push dateThu, 01 Jul 2010 18:30:48 +0000
treeherdermozilla-central@836fd3f8feba [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs568691
milestone1.9.3a6pre
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
Implement compatibility wrapper so that binary components can be compatible with both Firefox 3.6 and Firefox 4, as a result of registration changes from bug 568691.
xpcom/components/GenericFactory.cpp
xpcom/components/GenericFactory.h
xpcom/components/Makefile.in
xpcom/components/ModuleUtils.h
xpcom/glue/GenericFactory.cpp
xpcom/glue/GenericFactory.h
xpcom/glue/GenericModule.cpp
xpcom/glue/Makefile.in
xpcom/glue/objs.mk
xpcom/sample/nsSampleModule.cpp
--- a/xpcom/components/Makefile.in
+++ b/xpcom/components/Makefile.in
@@ -51,28 +51,26 @@ MOZILLA_INTERNAL_API = 1
 
 EXPORTS_NAMESPACES = mozilla
 
 EXPORTS	= \
   nsCategoryManagerUtils.h \
   $(NULL)
 
 EXPORTS_mozilla = \
-  GenericFactory.h \
   Module.h \
   ModuleLoader.h \
   ModuleUtils.h \
   $(NULL)
 
 CPPSRCS		= \
 		nsCategoryManager.cpp \
 		nsComponentManager.cpp \
 		ManifestParser.cpp \
 		nsNativeComponentLoader.cpp \
-		GenericFactory.cpp \
 		$(NULL)
 
 SDK_XPIDLSRCS	= \
 		nsIClassInfo.idl	      \
 		nsIComponentRegistrar.idl     \
 		nsIFactory.idl		      \
 		nsIModule.idl		      \
 		nsIServiceManager.idl	      \
--- a/xpcom/components/ModuleUtils.h
+++ b/xpcom/components/ModuleUtils.h
@@ -122,9 +122,46 @@ static nsresult                         
     }                                                                         \
     /* NS_ADDREF(inst); */                                                    \
     rv = inst->QueryInterface(aIID, aResult);                                 \
     NS_RELEASE(inst);                                                         \
                                                                               \
     return rv;                                                                \
 }
 
+#ifndef MOZILLA_INTERNAL_API
+
+#include "nsIModule.h"
+#include "nsISupportsUtils.h"
+
+namespace mozilla {
+
+class GenericModule : public nsIModule
+{
+public:
+    GenericModule(const mozilla::Module* aData)
+        : mData(aData)
+    {
+    }
+
+    NS_DECL_ISUPPORTS
+    NS_DECL_NSIMODULE
+
+private:
+    const mozilla::Module* mData;
+};
+
+} // namespace mozilla
+
+#define NS_IMPL_MOZILLA192_NSGETMODULE(module)     \
+extern "C" NS_EXPORT nsresult                      \
+NSGetModule(nsIComponentManager* aCompMgr,         \
+            nsIFile* aLocation,                    \
+            nsIModule** aResult)                   \
+{                                                  \
+    *aResult = new mozilla::GenericModule(module); \
+    NS_ADDREF(*aResult);                           \
+    return NS_OK;                                  \
+}
+
+#endif
+
 #endif // mozilla_GenericModule_h
rename from xpcom/components/GenericFactory.cpp
rename to xpcom/glue/GenericFactory.cpp
rename from xpcom/components/GenericFactory.h
rename to xpcom/glue/GenericFactory.h
--- a/xpcom/components/GenericFactory.h
+++ b/xpcom/glue/GenericFactory.h
@@ -39,17 +39,18 @@
 #define mozilla_GenericFactory_h
 
 #include "mozilla/Module.h"
 
 namespace mozilla {
 
 /**
  * A generic factory which uses a constructor function to create instances.
- * This class is intended solely for internal use by the component manager.
+ * This class is intended for use by the component manager and the generic
+ * module.
  */
 class GenericFactory : public nsIFactory
 {
 public:
   typedef Module::ConstructorProcPtr ConstructorProcPtr;
 
   NS_DECL_ISUPPORTS
   NS_DECL_NSIFACTORY
new file mode 100644
--- /dev/null
+++ b/xpcom/glue/GenericModule.cpp
@@ -0,0 +1,125 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is mozilla.org code.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Benjamin Smedberg <benjamin@smedbergs.us>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "mozilla/ModuleUtils.h"
+#include "mozilla/GenericFactory.h"
+
+#include "nsICategoryManager.h"
+#include "nsIComponentManager.h"
+#include "nsIComponentRegistrar.h"
+#include "nsServiceManagerUtils.h"
+#include "nsXPCOMCID.h"
+#include "nsStringAPI.h"
+
+namespace mozilla {
+
+NS_IMPL_THREADSAFE_ISUPPORTS1(GenericModule, nsIModule)
+
+NS_IMETHODIMP
+GenericModule::GetClassObject(nsIComponentManager* aCompMgr,
+                              const nsCID& aCID,
+                              const nsIID& aIID,
+                              void** aResult)
+{
+  for (const Module::CIDEntry* e = mData->mCIDs; e->cid; ++e) {
+    if (e->cid->Equals(aCID)) {
+      nsCOMPtr<nsIFactory> f;
+      if (e->getFactoryProc) {
+        f = e->getFactoryProc(*mData, *e);
+      }
+      else {
+        NS_ASSERTION(e->constructorProc, "No constructor proc?");
+        f = new GenericFactory(e->constructorProc);
+      }
+      if (!f)
+        return NS_ERROR_FAILURE;
+
+      return f->QueryInterface(aIID, aResult);
+    }
+  }
+  NS_ERROR("Asking a module for a CID it doesn't implement.");
+  return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+NS_IMETHODIMP
+GenericModule::RegisterSelf(nsIComponentManager* aCompMgr,
+                            nsIFile* aLocation,
+                            const char* aLoaderStr,
+                            const char* aType)
+{
+  nsCOMPtr<nsIComponentRegistrar> r = do_QueryInterface(aCompMgr);
+  for (const Module::CIDEntry* e = mData->mCIDs; e->cid; ++e)
+    r->RegisterFactoryLocation(*e->cid, "", NULL, aLocation, aLoaderStr, aType);
+
+  for (const Module::ContractIDEntry* e = mData->mContractIDs;
+       e && e->contractid;
+       ++e)
+    r->RegisterFactoryLocation(*e->cid, "", e->contractid, aLocation, aLoaderStr, aType);
+
+  nsCOMPtr<nsICategoryManager> catman;
+  for (const Module::CategoryEntry* e = mData->mCategoryEntries;
+       e && e->category;
+       ++e) {
+    if (!catman)
+      catman = do_GetService(NS_CATEGORYMANAGER_CONTRACTID);
+
+    nsCAutoString r;
+    catman->AddCategoryEntry(e->category, e->entry, e->value, true, true,
+                             getter_Copies(r));
+  }
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+GenericModule::UnregisterSelf(nsIComponentManager* aCompMgr,
+                              nsIFile* aFile,
+                              const char* aLoaderStr)
+{
+  NS_ERROR("Nobody should ever call UnregisterSelf!");
+  return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+NS_IMETHODIMP
+GenericModule::CanUnload(nsIComponentManager* aCompMgr, PRBool* aResult)
+{
+  NS_ERROR("Nobody should ever call CanUnload!");
+  *aResult = false;
+  return NS_OK;
+}
+
+} // namespace mozilla
--- a/xpcom/glue/Makefile.in
+++ b/xpcom/glue/Makefile.in
@@ -60,16 +60,17 @@ LOCAL_INCLUDES	= \
 CSRCS		= \
 		$(XPCOM_GLUE_SRC_LCSRCS) \
 		$(NULL)  
 
 CPPSRCS		= \
 		$(XPCOM_GLUE_SRC_LCPPSRCS) \
 		$(XPCOM_GLUENS_SRC_LCPPSRCS) \
 		nsStringAPI.cpp \
+		GenericModule.cpp \
 		$(NULL)
 
 # TODO nsAutoLock.h should die soon
 SDK_HEADERS = \
 		nsArrayEnumerator.h \
 		nsArrayUtils.h \
 		nsAutoLock.h \
 		nsBaseHashtable.h \
@@ -121,16 +122,17 @@ EXPORTS = \
 		nsXPTCUtils.h \
 		$(NULL)
 
 EXPORTS_mozilla = \
   AutoRestore.h \
   BlockingResourceBase.h \
   CondVar.h \
   DeadlockDetector.h \
+  GenericFactory.h \
   Monitor.h \
   Mutex.h \
   SSE.h \
   unused.h \
   $(NULL)
 
 SDK_LIBRARY     =                        \
 		$(LIB_PREFIX)xpcomglue_s.$(LIB_SUFFIX) \
--- a/xpcom/glue/objs.mk
+++ b/xpcom/glue/objs.mk
@@ -75,11 +75,12 @@ XPCOM_GLUE_SRC_CPPSRCS = $(addprefix $(t
 XPCOM_GLUENS_SRC_LCPPSRCS =      \
   BlockingResourceBase.cpp       \
   DeadlockDetector.cpp           \
   SSE.cpp                        \
   unused.cpp                     \
   nsAutoLock.cpp                 \
   nsProxyRelease.cpp             \
   nsTextFormatter.cpp            \
+  GenericFactory.cpp             \
   $(NULL)
 
 XPCOM_GLUENS_SRC_CPPSRCS = $(addprefix $(topsrcdir)/xpcom/glue/,$(XPCOM_GLUENS_SRC_LCPPSRCS))
--- a/xpcom/sample/nsSampleModule.cpp
+++ b/xpcom/sample/nsSampleModule.cpp
@@ -96,8 +96,14 @@ static const mozilla::Module kSampleModu
     kSampleCIDs,
     kSampleContracts,
     kSampleCategories
 };
 
 // The following line implements the one-and-only "NSModule" symbol exported from this
 // shared library.
 NSMODULE_DEFN(nsSampleModule) = &kSampleModule;
+
+// The following line implements the one-and-only "NSGetModule" symbol
+// for compatibility with mozilla 1.9.2. You should only use this
+// if you need a binary which is backwards-compatible and if you use
+// interfaces carefully across multiple versions.
+NS_IMPL_MOZILLA192_NSGETMODULE(&kSampleModule)