зеркало из https://github.com/mozilla/gecko-dev.git
fix JS component loader by reimplementing nsGenericModule (r=dveditz,slamm;a=leaf)
This commit is contained in:
Родитель
ae2f6de4f7
Коммит
ab1040199d
|
@ -733,4 +733,222 @@ static nsModuleComponentInfo components[] = {
|
|||
mozJSComponentLoaderProgID, mozJSComponentLoaderConstructor }
|
||||
};
|
||||
|
||||
NS_IMPL_NSGETMODULE("mozJSComponentLoader", components)
|
||||
/*
|
||||
* I would really like to just subclass nsGenericModule here, but I can't
|
||||
* because nsGenericFactory.h isn't exported. If that ever changes, we
|
||||
* only need custom behaviour in the RegisterSelf case, so a simple overriding
|
||||
* of that method would be sufficient, and much smaller.
|
||||
*
|
||||
* Instead, we have nutso copy-and-paste here.
|
||||
*/
|
||||
#include "nsHashtable.h"
|
||||
class mozJSModule : public nsIModule
|
||||
{
|
||||
public:
|
||||
mozJSModule(const char *moduleName, PRUint32 componentCount,
|
||||
nsModuleComponentInfo *components);
|
||||
virtual ~mozJSModule();
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIMODULE
|
||||
|
||||
protected:
|
||||
nsresult Initialize();
|
||||
|
||||
void Shutdown();
|
||||
|
||||
PRBool mInitialized;
|
||||
const char* mModuleName;
|
||||
PRUint32 mComponentCount;
|
||||
nsModuleComponentInfo* mComponents;
|
||||
nsSupportsHashtable mFactories;
|
||||
};
|
||||
|
||||
mozJSModule::mozJSModule(const char* moduleName, PRUint32 componentCount,
|
||||
nsModuleComponentInfo* aComponents)
|
||||
: mInitialized(PR_FALSE),
|
||||
mModuleName(moduleName),
|
||||
mComponentCount(componentCount),
|
||||
mComponents(aComponents),
|
||||
mFactories(8, PR_FALSE)
|
||||
{
|
||||
NS_INIT_ISUPPORTS();
|
||||
}
|
||||
|
||||
mozJSModule::~mozJSModule()
|
||||
{
|
||||
Shutdown();
|
||||
}
|
||||
|
||||
NS_IMPL_ISUPPORTS1(mozJSModule, nsIModule)
|
||||
|
||||
// Perform our one-time intialization for this module
|
||||
nsresult
|
||||
mozJSModule::Initialize()
|
||||
{
|
||||
if (mInitialized) {
|
||||
return NS_OK;
|
||||
}
|
||||
mInitialized = PR_TRUE;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Shutdown this module, releasing all of the module resources
|
||||
void
|
||||
mozJSModule::Shutdown()
|
||||
{
|
||||
// Release the factory objects
|
||||
mFactories.Reset();
|
||||
}
|
||||
|
||||
// Create a factory object for creating instances of aClass.
|
||||
NS_IMETHODIMP
|
||||
mozJSModule::GetClassObject(nsIComponentManager *aCompMgr,
|
||||
const nsCID& aClass,
|
||||
const nsIID& aIID,
|
||||
void** r_classObj)
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
// Defensive programming: Initialize *r_classObj in case of error below
|
||||
if (!r_classObj) {
|
||||
return NS_ERROR_INVALID_POINTER;
|
||||
}
|
||||
*r_classObj = NULL;
|
||||
|
||||
// Do one-time-only initialization if necessary
|
||||
if (!mInitialized) {
|
||||
rv = Initialize();
|
||||
if (NS_FAILED(rv)) {
|
||||
// Initialization failed! yikes!
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
|
||||
// Choose the appropriate factory, based on the desired instance
|
||||
// class type (aClass).
|
||||
nsIDKey key(aClass);
|
||||
nsCOMPtr<nsIGenericFactory> fact = getter_AddRefs(NS_REINTERPRET_CAST(nsIGenericFactory *, mFactories.Get(&key)));
|
||||
if (fact == nsnull) {
|
||||
nsModuleComponentInfo* desc = mComponents;
|
||||
for (PRUint32 i = 0; i < mComponentCount; i++) {
|
||||
if (desc->mCID.Equals(aClass)) {
|
||||
rv = NS_NewGenericFactory(getter_AddRefs(fact), desc->mConstructor);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
(void)mFactories.Put(&key, fact);
|
||||
goto found;
|
||||
}
|
||||
desc++;
|
||||
}
|
||||
// not found in descriptions
|
||||
#ifdef DEBUG
|
||||
char* cs = aClass.ToString();
|
||||
printf("+++ nsGenericModule %s: unable to create factory for %s\n", mModuleName, cs);
|
||||
nsCRT::free(cs);
|
||||
#endif
|
||||
// XXX put in stop-gap so that we don't search for this one again
|
||||
return NS_ERROR_FACTORY_NOT_REGISTERED;
|
||||
}
|
||||
found:
|
||||
rv = fact->QueryInterface(aIID, r_classObj);
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
mozJSModule::RegisterSelf(nsIComponentManager *aCompMgr,
|
||||
nsIFileSpec* aPath,
|
||||
const char* registryLocation,
|
||||
const char* componentType)
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
#ifdef DEBUG
|
||||
printf("*** Registering %s components (all right -- an almost-generic module!)\n", mModuleName);
|
||||
#endif
|
||||
|
||||
nsModuleComponentInfo* cp = mComponents;
|
||||
for (PRUint32 i = 0; i < mComponentCount; i++) {
|
||||
rv = aCompMgr->RegisterComponentSpec(cp->mCID, cp->mDescription,
|
||||
cp->mProgID, aPath, PR_TRUE,
|
||||
PR_TRUE);
|
||||
if (NS_FAILED(rv)) {
|
||||
#ifdef DEBUG
|
||||
printf("nsGenericModule %s: unable to register %s component => %x\n",
|
||||
mModuleName, cp->mDescription, rv);
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
cp++;
|
||||
}
|
||||
|
||||
return aCompMgr->RegisterComponentLoader(jsComponentTypeName,
|
||||
mozJSComponentLoaderProgID,
|
||||
PR_TRUE);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
mozJSModule::UnregisterSelf(nsIComponentManager* aCompMgr,
|
||||
nsIFileSpec* aPath,
|
||||
const char* registryLocation)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
printf("*** Unregistering %s components (all right -- an almost-generic module!)\n", mModuleName);
|
||||
#endif
|
||||
nsModuleComponentInfo* cp = mComponents;
|
||||
for (PRUint32 i = 0; i < mComponentCount; i++) {
|
||||
nsresult rv = aCompMgr->UnregisterComponentSpec(cp->mCID, aPath);
|
||||
if (NS_FAILED(rv)) {
|
||||
#ifdef DEBUG
|
||||
printf("nsGenericModule %s: unable to unregister %s component => %x\n",
|
||||
mModuleName, cp->mDescription, rv);
|
||||
#endif
|
||||
}
|
||||
cp++;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
mozJSModule::CanUnload(nsIComponentManager *aCompMgr, PRBool *okToUnload)
|
||||
{
|
||||
if (!okToUnload) {
|
||||
return NS_ERROR_INVALID_POINTER;
|
||||
}
|
||||
*okToUnload = PR_FALSE;
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
NS_EXPORT nsresult
|
||||
NS_NewJSModule(const char* moduleName,
|
||||
PRUint32 componentCount,
|
||||
nsModuleComponentInfo* aComponents,
|
||||
nsIModule* *result)
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
NS_ASSERTION(result, "Null argument");
|
||||
|
||||
// Create and initialize the module instance
|
||||
mozJSModule *m = new mozJSModule(moduleName, componentCount, aComponents);
|
||||
if (!m) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
// Increase refcnt and store away nsIModule interface to m in return_cobj
|
||||
rv = m->QueryInterface(NS_GET_IID(nsIModule), (void**)result);
|
||||
if (NS_FAILED(rv)) {
|
||||
delete m;
|
||||
m = nsnull;
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
extern "C" NS_EXPORT nsresult NSGetModule(nsIComponentManager *compMgr,
|
||||
nsIFileSpec *location,
|
||||
nsIModule** result)
|
||||
{
|
||||
return NS_NewJSModule("mozJSComponentLoader",
|
||||
sizeof(components) / sizeof(components[0]),
|
||||
components, result);
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче