Back to index

lightning-sunbird  0.9+nobinonly
Public Member Functions | Public Attributes | Protected Member Functions | Static Protected Member Functions | Protected Attributes
mozJSComponentLoader Class Reference

#include <mozJSComponentLoader.h>

Inheritance diagram for mozJSComponentLoader:
Inheritance graph
[legend]
Collaboration diagram for mozJSComponentLoader:
Collaboration graph
[legend]

List of all members.

Public Member Functions

NS_DECL_ISUPPORTS
NS_DECL_NSICOMPONENTLOADER
NS_DECL_NSIOBSERVER 
mozJSComponentLoader ()
virtual ~mozJSComponentLoader ()
nsIFactory getFactory (in nsIIDRef aCID, in string aLocation, in string aType)
 Get the factory for a given component.
void init (in nsIComponentManager aCompMgr, in nsISupports aRegistry)
 Initialize the loader.
void onRegister (in nsIIDRef aCID, in string aType, in string aClassName, in string aContractID, in string aLocation, in boolean aReplace, in boolean aPersist)
 Called when a component of the appropriate type is registered, to give the component loader an opportunity to do things like annotate the registry and such.
void autoRegisterComponents (in long aWhen, in nsIFile aDirectory)
 AutoRegister components in the given directory.
boolean autoRegisterComponent (in long aWhen, in nsIFile aComponent)
 AutoRegister the given component.
boolean autoUnregisterComponent (in long aWhen, in nsIFile aComponent)
 AutoUnregister the given component.
boolean registerDeferredComponents (in long aWhen)
 Register any deferred (NS_ERROR_FACTORY_REGISTER_AGAIN) components.
void unloadAll (in long aWhen)
 Unload all components that are willing.
void observe (in nsISupports aSubject, in string aTopic, in wstring aData)
 Observe will be called when there is a notification for the topic |aTopic|.

Public Attributes

const long Startup = 0
 When is AutoRegistration occuring?
const long Component = 1
const long Timer = 2

Protected Member Functions

nsresult ReallyInit ()
nsresult AttemptRegistration (nsIFile *component, PRBool deferred)
nsresult UnregisterComponent (nsIFile *component)
nsresult RegisterComponentsInDir (PRInt32 when, nsIFile *dir)
nsresult GlobalForLocation (const char *aLocation, nsIFile *aComponent, JSObject **aGlobal)
nsIModuleModuleForLocation (const char *aLocation, nsIFile *component, nsresult *status)
PRBool HasChanged (const char *registryLocation, nsIFile *component)
nsresult SetRegistryInfo (const char *registryLocation, nsIFile *component)
nsresult RemoveRegistryInfo (nsIFile *component, const char *registryLocation)
nsresult StartFastLoad (nsIFastLoadService *flSvc)
nsresult ReadScript (nsIFastLoadService *flSvc, const char *nativePath, nsIURI *uri, JSContext *cx, JSScript **script)
nsresult WriteScript (nsIFastLoadService *flSvc, JSScript *script, nsIFile *component, const char *nativePath, nsIURI *uri, JSContext *cx)
void CloseFastLoad ()

Static Protected Member Functions

static void CloseFastLoad (nsITimer *timer, void *closure)

Protected Attributes

nsCOMPtr< nsIComponentManagermCompMgr
nsCOMPtr
< nsIComponentLoaderManager
mLoaderManager
nsCOMPtr< nsIJSRuntimeServicemRuntimeService
nsCOMPtr< nsIFilemFastLoadFile
nsRefPtr< nsXPCFastLoadIOmFastLoadIO
nsCOMPtr< nsIObjectInputStreammFastLoadInput
nsCOMPtr< nsIObjectOutputStreammFastLoadOutput
nsCOMPtr< nsITimermFastLoadTimer
nsCOMPtr< nsIPrincipalmSystemPrincipal
JSRuntimemRuntime
JSContextmContext
PLHashTablemModules
PLHashTablemGlobals
PRBool mInitialized
nsSupportsArray mDeferredComponents

Detailed Description

Definition at line 92 of file mozJSComponentLoader.h.


Constructor & Destructor Documentation

Definition at line 378 of file mozJSComponentLoader.cpp.

    : mRuntime(nsnull),
      mContext(nsnull),
      mModules(nsnull),
      mGlobals(nsnull),
      mInitialized(PR_FALSE)
{
#ifdef PR_LOGGING
    if (!gJSCLLog) {
        gJSCLLog = PR_NewLogModule("JSComponentLoader");
    }
#endif
}

Definition at line 420 of file mozJSComponentLoader.cpp.

{
    NS_ASSERTION(!mFastLoadTimer,
                 "Fastload file should have been closed via xpcom-shutdown");
}

Member Function Documentation

nsresult mozJSComponentLoader::AttemptRegistration ( nsIFile component,
PRBool  deferred 
) [protected]

Definition at line 742 of file mozJSComponentLoader.cpp.

{
    nsXPIDLCString registryLocation;
    nsresult rv;
    
    // what I want to do here is QI for a Component Registration Manager.  Since this 
    // has not been invented yet, QI to the obsolete manager.  Kids, don't do this at home.
    nsCOMPtr<nsIComponentManagerObsolete> obsoleteManager = do_QueryInterface(mCompMgr, &rv);
    if (obsoleteManager)
        rv = obsoleteManager->RegistryLocationForSpec(component, 
                                                      getter_Copies(registryLocation));
    if (NS_FAILED(rv))
        return rv;
    
    /* no need to check registry data on deferred reg */
    if (!deferred && !HasChanged(registryLocation, component))
        return NS_OK;
    
    nsIModule *module = ModuleForLocation(registryLocation, component, &rv);
    if (NS_FAILED(rv)) {
        SetRegistryInfo(registryLocation, component);
        return rv;
    }

    // Notify observers, if any, of autoregistration work
    nsCOMPtr<nsIObserverService> observerService = 
        do_GetService(kObserverServiceContractID, &rv);
    NS_ENSURE_SUCCESS(rv, rv);

    nsCOMPtr<nsIServiceManager> mgr;
    rv = NS_GetServiceManager(getter_AddRefs(mgr));
    NS_ENSURE_SUCCESS(rv, rv);

    // this string can't come from a string bundle, because we
    // don't have string bundles yet.
    NS_ConvertASCIItoUCS2 fileName("(no name)");

    // get the file name
    if (component) {
        component->GetLeafName(fileName);
    }

    // this string can't come from a string bundle, because we
    // don't have string bundles yet.
    const nsPromiseFlatString &msg =
        PromiseFlatString(NS_LITERAL_STRING("Registering JS component ") +
                          fileName);

    observerService->NotifyObservers(mgr,
                                     NS_XPCOM_AUTOREGISTRATION_OBSERVER_ID,
                                     msg.get());
    
    rv = module->RegisterSelf(mCompMgr, component, registryLocation,
                              MOZJSCOMPONENTLOADER_TYPE_NAME);
    if (rv == NS_ERROR_FACTORY_REGISTER_AGAIN) {
        if (!deferred) {
            mDeferredComponents.AppendElement(component);
        }
        /*
         * we don't enter in the registry because we may want to
         * try again on a later autoreg, in case a dependency has
         * become available. 
         */
    } else {
        SetRegistryInfo(registryLocation, component);
    }

    return rv;
}

Here is the call graph for this function:

boolean nsIComponentLoader::autoRegisterComponent ( in long  aWhen,
in nsIFile  aComponent 
) [inherited]

AutoRegister the given component.

Returns true if the component was registered, false if it couldn't attempt to register the component (wrong type) and ``throws'' an NS_FAILED code if there was an error during registration.

void nsIComponentLoader::autoRegisterComponents ( in long  aWhen,
in nsIFile  aDirectory 
) [inherited]

AutoRegister components in the given directory.

boolean nsIComponentLoader::autoUnregisterComponent ( in long  aWhen,
in nsIFile  aComponent 
) [inherited]

AutoUnregister the given component.

Returns true if the component was unregistered, false if it coudln't attempt to unregister the component (not found, wrong type).

void mozJSComponentLoader::CloseFastLoad ( nsITimer timer,
void closure 
) [static, protected]

Definition at line 1109 of file mozJSComponentLoader.cpp.

{
    NS_STATIC_CAST(mozJSComponentLoader*, closure)->CloseFastLoad();
}

Definition at line 1115 of file mozJSComponentLoader.cpp.

{
    // Close our fastload streams
    LOG(("Closing fastload file\n"));
    if (mFastLoadOutput) {
        nsresult rv = mFastLoadOutput->Close();
        if (NS_SUCCEEDED(rv)) {
            nsCOMPtr<nsIFastLoadService> flSvc = do_GetFastLoadService(&rv);
            if (NS_SUCCEEDED(rv)) {
                flSvc->CacheChecksum(mFastLoadFile, mFastLoadOutput);
            }
        }
        mFastLoadOutput = nsnull;
    }
    if (mFastLoadInput) {
        mFastLoadInput->Close();
        mFastLoadInput = nsnull;
    }

    mFastLoadIO = nsnull;
    mFastLoadTimer = nsnull;
}

Here is the call graph for this function:

Here is the caller graph for this function:

nsIFactory nsIComponentLoader::getFactory ( in nsIIDRef  aCID,
in string  aLocation,
in string  aType 
) [inherited]

Get the factory for a given component.

nsresult mozJSComponentLoader::GlobalForLocation ( const char *  aLocation,
nsIFile aComponent,
JSObject **  aGlobal 
) [protected]

Definition at line 1330 of file mozJSComponentLoader.cpp.

{
    nsresult rv;
    if (!mInitialized) {
        rv = ReallyInit();
        NS_ENSURE_SUCCESS(rv, rv);
    }

    PLHashNumber hash = PL_HashString(aLocation);
    PLHashEntry **hep = PL_HashTableRawLookup(mGlobals, hash, aLocation);
    PLHashEntry *he = *hep;
    if (he) {
        *aGlobal = NS_STATIC_CAST(JSObject*, he->value);
        return NS_OK;
    }

    *aGlobal = nsnull;

    JSPrincipals* jsPrincipals = nsnull;
    JSCLContextHelper cx(mContext);

#ifndef XPCONNECT_STANDALONE
    rv = mSystemPrincipal->GetJSPrincipals(cx, &jsPrincipals);
    NS_ENSURE_SUCCESS(rv, rv);

    JSPrincipalsHolder princHolder(mContext, jsPrincipals);
#endif

    nsCOMPtr<nsIXPCScriptable> backstagePass;
    rv = mRuntimeService->GetBackstagePass(getter_AddRefs(backstagePass));
    NS_ENSURE_SUCCESS(rv, rv);

    JSCLAutoErrorReporterSetter aers(cx, mozJSLoaderErrorReporter);

    nsCOMPtr<nsIXPConnect> xpc =
        do_GetService(kXPConnectServiceContractID, &rv);
    NS_ENSURE_SUCCESS(rv, rv);

    // Make sure InitClassesWithNewWrappedGlobal() installs the
    // backstage pass as the global in our compilation context.
    JS_SetGlobalObject(cx, nsnull);

    nsCOMPtr<nsIXPConnectJSObjectHolder> holder;
    rv = xpc->InitClassesWithNewWrappedGlobal(cx, backstagePass,
                                              NS_GET_IID(nsISupports),
                                              nsIXPConnect::
                                                  FLAG_SYSTEM_GLOBAL_OBJECT,
                                              getter_AddRefs(holder));
    NS_ENSURE_SUCCESS(rv, rv);

    JSObject *global;
    rv = holder->GetJSObject(&global);
    NS_ENSURE_SUCCESS(rv, rv);

    if (!JS_DefineFunctions(cx, global, gGlobalFun)) {
        return NS_ERROR_FAILURE;
    }

    nsCOMPtr<nsIFile> component = aComponent;
    if (!component) {
        // what I want to do here is QI for a Component Registration Manager.  Since this 
        // has not been invented yet, QI to the obsolete manager.  Kids, don't do this at home.
        nsCOMPtr<nsIComponentManagerObsolete> mgr = do_QueryInterface(mCompMgr,
                                                                      &rv);
        NS_ENSURE_SUCCESS(rv, rv);

        rv = mgr->SpecForRegistryLocation(aLocation,
                                          getter_AddRefs(component));
        NS_ENSURE_SUCCESS(rv, rv);
    }

    nsCOMPtr<nsILocalFile> localFile = do_QueryInterface(component, &rv);
    NS_ENSURE_SUCCESS(rv, rv);

    nsCOMPtr<nsIXPConnectJSObjectHolder> locationHolder;
    rv = xpc->WrapNative(cx, global, localFile,
                         NS_GET_IID(nsILocalFile),
                         getter_AddRefs(locationHolder));
    NS_ENSURE_SUCCESS(rv, rv);

    JSObject *locationObj;
    rv = locationHolder->GetJSObject(&locationObj);
    NS_ENSURE_SUCCESS(rv, rv);

    if (!JS_DefineProperty(cx, global, "__LOCATION__",
                           OBJECT_TO_JSVAL(locationObj), nsnull, nsnull, 0)) {
        return NS_ERROR_FAILURE;
    }

    nsCAutoString nativePath;
    // Quick hack to unbust XPCONNECT_STANDALONE.
    // This leaves the jsdebugger with a non-URL pathname in the 
    // XPCONNECT_STANDALONE case - but at least it builds and runs otherwise.
    // See: http://bugzilla.mozilla.org/show_bug.cgi?id=121438
#ifdef XPCONNECT_STANDALONE
    localFile->GetNativePath(nativePath);
#else
    NS_GetURLSpecFromFile(localFile, nativePath);
#endif

    // Before compiling the script, first check to see if we have it in
    // the fastload file.  Note: as a rule, fastload errors are not fatal
    // to loading the script, since we can always slow-load.
    nsCOMPtr<nsIFastLoadService> flSvc = do_GetFastLoadService(&rv);

    // Save the old state and restore it upon return
    FastLoadStateHolder flState(flSvc);
    PRBool fastLoading = PR_FALSE;

    if (NS_SUCCEEDED(rv)) {
        rv = StartFastLoad(flSvc);
        if (NS_SUCCEEDED(rv)) {
            fastLoading = PR_TRUE;
        }
    }

    nsCOMPtr<nsIURI> uri;
    rv = NS_NewURI(getter_AddRefs(uri), nativePath);
    NS_ENSURE_SUCCESS(rv, rv);

    JSScript *script = nsnull;

    if (fastLoading) {
        rv = ReadScript(flSvc, nativePath.get(), uri, cx, &script);
        if (NS_SUCCEEDED(rv)) {
            LOG(("Successfully loaded %s from fastload\n", nativePath.get()));
            fastLoading = PR_FALSE; // no need to write out the script
        } else if (rv == NS_ERROR_NOT_AVAILABLE) {
            // This is ok, it just means the script is not yet in the
            // fastload file.
            rv = NS_OK;
        } else {
            LOG(("Failed to deserialize %s\n", nativePath.get()));

            // Remove the fastload file, it may be corrupted.
            LOG(("Invalid fastload file detected, removing it\n"));
            nsCOMPtr<nsIObjectOutputStream> objectOutput;
            flSvc->GetOutputStream(getter_AddRefs(objectOutput));
            if (objectOutput) {
                flSvc->SetOutputStream(nsnull);
                objectOutput->Close();
            }
            nsCOMPtr<nsIObjectInputStream> objectInput;
            flSvc->GetInputStream(getter_AddRefs(objectInput));
            if (objectInput) {
                flSvc->SetInputStream(nsnull);
                objectInput->Close();
            }
            if (mFastLoadFile) {
                mFastLoadFile->Remove(PR_FALSE);
            }
            fastLoading = PR_FALSE;
        }
    }


    if (!script || NS_FAILED(rv)) {
        // The script wasn't in the fastload cache, so compile it now.
        LOG(("Slow loading %s\n", nativePath.get()));

#ifdef HAVE_PR_MEMMAP
        PRInt64 fileSize;
        localFile->GetFileSize(&fileSize);

        PRInt64 maxSize;
        LL_UI2L(maxSize, PR_UINT32_MAX);
        if (LL_CMP(fileSize, >, maxSize)) {
            NS_ERROR("file too large");
            return NS_ERROR_FAILURE;
        }

        PRFileDesc *fileHandle;
        rv = localFile->OpenNSPRFileDesc(PR_RDONLY, 0, &fileHandle);
        NS_ENSURE_SUCCESS(rv, rv);

        // Make sure the file is closed, no matter how we return.
        FileAutoCloser fileCloser(fileHandle);

        PRFileMap *map = PR_CreateFileMap(fileHandle, fileSize,
                                          PR_PROT_READONLY);
        if (!map) {
            NS_ERROR("Failed to create file map");
            return NS_ERROR_FAILURE;
        }

        // Make sure the file map is closed, no matter how we return.
        FileMapAutoCloser mapCloser(map);

        PRUint32 fileSize32;
        LL_L2UI(fileSize32, fileSize);

        char *buf = NS_STATIC_CAST(char*, PR_MemMap(map, 0, fileSize32));
        if (!buf) {
            NS_WARNING("Failed to map file");
            return NS_ERROR_FAILURE;
        }

        script = JS_CompileScriptForPrincipals(cx, global,
                                               jsPrincipals,
                                               buf, fileSize32,
                                               nativePath.get(), 0);
        PR_MemUnmap(buf, fileSize32);

#else  /* HAVE_PR_MEMMAP */

        FILE *fileHandle;
        rv = localFile->OpenANSIFileDesc("r", &fileHandle);
        NS_ENSURE_SUCCESS(rv, rv);

        script = JS_CompileFileHandleForPrincipals(cx, global,
                                                   nativePath.get(),
                                                   fileHandle, jsPrincipals);

        /* JS will close the filehandle after compilation is complete. */

#endif /* HAVE_PR_MEMMAP */
    }

    if (!script) {
#ifdef DEBUG_shaver_off
        fprintf(stderr, "mJCL: script compilation of %s FAILED\n",
                nativePath.get());
#endif
        return NS_ERROR_FAILURE;
    }

    // Ensure that we clean up the script on return.
    JSScriptHolder scriptHolder(cx, script);

    // Flag this script as a system script
    // FIXME: BUG 346139: We actually want to flag this exact filename, not
    // anything that starts with this filename... Maybe we need a way to do
    // that?  On the other hand, the fact that this is in our components dir
    // means that if someone snuck a malicious file into this dir we're screwed
    // anyway...  So maybe flagging as a prefix is fine.
    xpc->FlagSystemFilenamePrefix(nativePath.get());

#ifdef DEBUG_shaver_off
    fprintf(stderr, "mJCL: compiled JS component %s\n",
            nativePath.get());
#endif

    if (fastLoading) {
        // We successfully compiled the script, so cache it in fastload.
        rv = WriteScript(flSvc, script, component, nativePath.get(), uri, cx);

        // Don't treat failure to write as fatal, since we might be working
        // with a read-only fastload file.
        if (NS_SUCCEEDED(rv)) {
            LOG(("Successfully wrote to fastload\n"));
        } else {
            LOG(("Failed to write to fastload\n"));
        }
    }

    // Restore the old state of the fastload service.
    flState.pop();

    jsval retval;
    if (!JS_ExecuteScript(cx, global, script, &retval)) {
#ifdef DEBUG_shaver_off
        fprintf(stderr, "mJCL: failed to execute %s\n", nativePath.get());
#endif
        return NS_ERROR_FAILURE;
    }

    *aGlobal = global;

    /* Freed when we remove from the table. */
    char *location = nsCRT::strdup(aLocation);
    NS_ENSURE_TRUE(location, NS_ERROR_OUT_OF_MEMORY);

    he = PL_HashTableRawAdd(mGlobals, hep, hash, location, global);
    JS_AddNamedRoot(cx, &he->value, location);
    return NS_OK;
}

Here is the call graph for this function:

Here is the caller graph for this function:

PRBool mozJSComponentLoader::HasChanged ( const char *  registryLocation,
nsIFile component 
) [protected]

Definition at line 640 of file mozJSComponentLoader.cpp.

{
    if (!mLoaderManager)
        return NS_ERROR_FAILURE;
    
    PRInt64 lastTime;
    component->GetLastModifiedTime(&lastTime);

    PRBool hasChanged = PR_TRUE;
    mLoaderManager->HasFileChanged(component, registryLocation, lastTime, &hasChanged);                                                          
    return hasChanged;
}

Here is the caller graph for this function:

void nsIComponentLoader::init ( in nsIComponentManager  aCompMgr,
in nsISupports  aRegistry 
) [inherited]

Initialize the loader.

We use nsISupports here because nsIRegistry isn't IDLized yet.

nsIModule * mozJSComponentLoader::ModuleForLocation ( const char *  aLocation,
nsIFile component,
nsresult status 
) [protected]

Definition at line 901 of file mozJSComponentLoader.cpp.

{
    nsresult rv;
    if (!mInitialized) {
        rv = ReallyInit();
        if (NS_FAILED(rv)) {
            *status = rv;
            return nsnull;
        }
    }

    PLHashNumber hash = PL_HashString(registryLocation);
    PLHashEntry **hep = PL_HashTableRawLookup(mModules, hash,
                                              registryLocation);
    PLHashEntry *he = *hep;
    if (he) {
        *status = NS_OK;
        return NS_STATIC_CAST(nsIModule*, he->value);
    }

    JSObject *global;
    rv = GlobalForLocation(registryLocation, component, &global);
    if (NS_FAILED(rv)) {
#ifdef DEBUG_shaver
        fprintf(stderr, "GlobalForLocation failed!\n");
#endif
        *status = rv;
        return nsnull;
    }

    nsCOMPtr<nsIXPConnect> xpc = do_GetService(kXPConnectServiceContractID,
                                               &rv);
    if (NS_FAILED(rv)) {
        *status = rv;
        return nsnull;
    }

    JSCLContextHelper cx(mContext);

    JSObject* cm_jsobj;
    nsCOMPtr<nsIXPConnectJSObjectHolder> cm_holder;
    rv = xpc->WrapNative(cx, global, mCompMgr, 
                         NS_GET_IID(nsIComponentManager),
                         getter_AddRefs(cm_holder));

    if (NS_FAILED(rv)) {
#ifdef DEBUG_shaver
        fprintf(stderr, "WrapNative(%p,%p,nsIComponentManager) failed: %x\n",
                (void *)(JSContext*)cx, (void *)mCompMgr, rv);
#endif
        *status = rv;
        return nsnull;
    }

    rv = cm_holder->GetJSObject(&cm_jsobj);
    if (NS_FAILED(rv)) {
#ifdef DEBUG_shaver
        fprintf(stderr, "GetJSObject of ComponentManager failed\n");
#endif
        *status = rv;
        return nsnull;
    }

    JSCLAutoErrorReporterSetter aers(cx, mozJSLoaderErrorReporter);

    jsval argv[2], retval, NSGetModule_val;

    if (!JS_GetProperty(cx, global, "NSGetModule", &NSGetModule_val) ||
        JSVAL_IS_VOID(NSGetModule_val)) {
        *status = NS_ERROR_FAILURE;
        return nsnull;
    }

    if (JS_TypeOfValue(cx, NSGetModule_val) != JSTYPE_FUNCTION) {
        JS_ReportError(cx, "%s has NSGetModule property that is not a function",
                       registryLocation);
        *status = NS_ERROR_FAILURE;
        return nsnull;
    }
    
    argv[0] = OBJECT_TO_JSVAL(cm_jsobj);
    argv[1] = STRING_TO_JSVAL(JS_NewStringCopyZ(cx, registryLocation));
    if (!JS_CallFunctionValue(cx, global, NSGetModule_val, 2, argv, &retval)) {
        *status = NS_ERROR_FAILURE;
        return nsnull;
    }

#ifdef DEBUG_shaver_off
    JSString *s = JS_ValueToString(cx, retval);
    fprintf(stderr, "mJCL: %s::NSGetModule returned %s\n",
            registryLocation, JS_GetStringBytes(s));
#endif

    JSObject *jsModuleObj;
    if (!JS_ValueToObject(cx, retval, &jsModuleObj)) {
        /* XXX report error properly */
#ifdef DEBUG
        fprintf(stderr, "mJCL: couldn't convert %s's nsIModule to obj\n",
                registryLocation);
#endif
        *status = NS_ERROR_FAILURE;
        return nsnull;
    }

    nsIModule *module;
    rv = xpc->WrapJS(cx, jsModuleObj, NS_GET_IID(nsIModule), (void**)&module);
    if (NS_FAILED(rv)) {
        /* XXX report error properly */
#ifdef DEBUG
        fprintf(stderr, "mJCL: couldn't get nsIModule from jsval\n");
#endif
        *status = rv;
        return nsnull;
    }

    /* we hand our reference to the hash table, it'll be released much later */
    he = PL_HashTableRawAdd(mModules, hep, hash,
                            nsCRT::strdup(registryLocation), module);

    *status = NS_OK;
    return module;
}

Here is the call graph for this function:

Here is the caller graph for this function:

void nsIObserver::observe ( in nsISupports  aSubject,
in string  aTopic,
in wstring  aData 
) [inherited]

Observe will be called when there is a notification for the topic |aTopic|.

This assumes that the object implementing this interface has been registered with an observer service such as the nsIObserverService.

If you expect multiple topics/subjects, the impl is responsible for filtering.

You should not modify, add, remove, or enumerate notifications in the implemention of observe.

Parameters:
aSubject: Notification specific interface pointer.
aTopic: The notification topic or subject.
aData: Notification specific wide string. subject event.
void nsIComponentLoader::onRegister ( in nsIIDRef  aCID,
in string  aType,
in string  aClassName,
in string  aContractID,
in string  aLocation,
in boolean  aReplace,
in boolean  aPersist 
) [inherited]

Called when a component of the appropriate type is registered, to give the component loader an opportunity to do things like annotate the registry and such.

nsresult mozJSComponentLoader::ReadScript ( nsIFastLoadService flSvc,
const char *  nativePath,
nsIURI uri,
JSContext cx,
JSScript **  script 
) [protected]

Definition at line 1264 of file mozJSComponentLoader.cpp.

{
    NS_ASSERTION(flSvc, "fastload not initialized");

    nsresult rv = flSvc->StartMuxedDocument(uri, nativePath,
                                            nsIFastLoadService::NS_FASTLOAD_READ);
    if (NS_FAILED(rv)) {
        return rv; // don't warn since NOT_AVAILABLE is an ok error
    }

    LOG(("Found %s in fastload file\n", nativePath));

    nsCOMPtr<nsIURI> oldURI;
    rv = flSvc->SelectMuxedDocument(uri, getter_AddRefs(oldURI));
    NS_ENSURE_SUCCESS(rv, rv);

    NS_ASSERTION(mFastLoadInput,
                 "FASTLOAD_READ should only succeed with an input stream");

    rv = ReadScriptFromStream(cx, mFastLoadInput, script);
    if (NS_SUCCEEDED(rv)) {
        rv = flSvc->EndMuxedDocument(uri);
    }

    return rv;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 474 of file mozJSComponentLoader.cpp.

{
    nsresult rv;

    /*
     * Get the JSRuntime from the runtime svc, if possible.
     * We keep a reference around, because it's a Bad Thing if the runtime
     * service gets shut down before we're done.  Bad!
     */

    mRuntimeService = do_GetService(kJSRuntimeServiceContractID, &rv);
    if (NS_FAILED(rv) ||
        NS_FAILED(rv = mRuntimeService->GetRuntime(&mRuntime)))
        return rv;

    // Create our compilation context.
    mContext = JS_NewContext(mRuntime, 256);
    if (!mContext)
        return NS_ERROR_OUT_OF_MEMORY;

    uint32 options = JS_GetOptions(mContext);
    JS_SetOptions(mContext, options | JSOPTION_XML);

    // enable Javascript 1.7 features (let, yield, etc. - see bug#351515)
    JS_SetVersion(mContext, JSVERSION_1_7);
    
#ifndef XPCONNECT_STANDALONE
    nsCOMPtr<nsIScriptSecurityManager> secman = 
        do_GetService(NS_SCRIPTSECURITYMANAGER_CONTRACTID);
    if (!secman)
        return NS_ERROR_FAILURE;

    rv = secman->GetSystemPrincipal(getter_AddRefs(mSystemPrincipal));
    if (NS_FAILED(rv) || !mSystemPrincipal)
        return NS_ERROR_FAILURE;
#endif

    mModules = PL_NewHashTable(16, PL_HashString, PL_CompareStrings,
                               PL_CompareValues, 0, 0);
    if (!mModules)
        return NS_ERROR_OUT_OF_MEMORY;
    
    mGlobals = PL_NewHashTable(16, PL_HashString, PL_CompareStrings,
                               PL_CompareValues, 0, 0);
    if (!mGlobals)
        return NS_ERROR_OUT_OF_MEMORY;

    // Set up our fastload file
    nsCOMPtr<nsIFastLoadService> flSvc = do_GetFastLoadService(&rv);
    if (flSvc)
    {
        rv = flSvc->NewFastLoadFile("XPC", getter_AddRefs(mFastLoadFile));
        if (NS_FAILED(rv)) {
            LOG(("Could not get fastload file location\n"));
        }
        // Listen for xpcom-shutdown so that we can close out our fastload file
        // at that point (after that we can no longer create an input stream).
        nsCOMPtr<nsIObserverService> obsSvc =
            do_GetService(kObserverServiceContractID, &rv);
        NS_ENSURE_SUCCESS(rv, rv);
        
        rv = obsSvc->AddObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID, PR_FALSE);
        NS_ENSURE_SUCCESS(rv, rv);
        
#ifdef DEBUG_shaver_off
        fprintf(stderr, "mJCL: ReallyInit success!\n");
#endif
    }

    mInitialized = PR_TRUE;

    return NS_OK;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 556 of file mozJSComponentLoader.cpp.

{
    nsresult rv;
    PRBool isDir;
    
    if (NS_FAILED(rv = dir->IsDirectory(&isDir)))
        return rv;
    
    if (!isDir)
        return NS_ERROR_INVALID_ARG;

    // Create a directory iterator
    nsCOMPtr<nsISimpleEnumerator> dirIterator;
    rv = dir->GetDirectoryEntries(getter_AddRefs(dirIterator));
    
    if (NS_FAILED(rv)) return rv;
    
   // whip through the directory to register every file
    nsIFile *dirEntry = NULL;
    PRBool more = PR_FALSE;

    rv = dirIterator->HasMoreElements(&more);
    if (NS_FAILED(rv)) return rv;
    while (more == PR_TRUE)
    {
        rv = dirIterator->GetNext((nsISupports**)&dirEntry);
        if (NS_SUCCEEDED(rv))
        {
            rv = dirEntry->IsDirectory(&isDir);
            if (NS_SUCCEEDED(rv))
            {
                if (isDir == PR_TRUE)
                {
                    // This is a directory. Grovel for components into the directory.
                    rv = RegisterComponentsInDir(when, dirEntry);
                }
                else
                {
                    PRBool registered;
                    // This is a file. Try to register it.
                    rv = AutoRegisterComponent(when, dirEntry, &registered);
                }
            }
            NS_RELEASE(dirEntry);
        }
        rv = dirIterator->HasMoreElements(&more);
        if (NS_FAILED(rv)) return rv;
    }

    return NS_OK;
}

Here is the call graph for this function:

Register any deferred (NS_ERROR_FACTORY_REGISTER_AGAIN) components.

Return registered-any-components?

nsresult mozJSComponentLoader::RemoveRegistryInfo ( nsIFile component,
const char *  registryLocation 
) [protected]

Definition at line 630 of file mozJSComponentLoader.cpp.

{
    if (!mLoaderManager)
        return NS_ERROR_FAILURE;
    
    return mLoaderManager->RemoveFileInfo(component, registryLocation);                                                          
}

Here is the caller graph for this function:

nsresult mozJSComponentLoader::SetRegistryInfo ( const char *  registryLocation,
nsIFile component 
) [protected]

Definition at line 610 of file mozJSComponentLoader.cpp.

{
    nsresult rv;
    if (!mLoaderManager)
        return NS_ERROR_FAILURE;
    
    PRInt64 modDate;
    rv = component->GetLastModifiedTime(&modDate);
    if (NS_FAILED(rv))
        return rv;

#ifdef DEBUG_shaver_off
    fprintf(stderr, "SetRegistryInfo(%s) => (%d,%d)\n", registryLocation,
            modDate, fileSize);
#endif
    return mLoaderManager->SaveFileInfo(component, registryLocation, modDate);                                                          
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 1139 of file mozJSComponentLoader.cpp.

{
    if (!mFastLoadFile || !flSvc) {
        return NS_ERROR_NOT_AVAILABLE;
    }

    // Now set our IO object as current, and create our streams.
    if (!mFastLoadIO) {
        mFastLoadIO = new nsXPCFastLoadIO(mFastLoadFile);
        NS_ENSURE_TRUE(mFastLoadIO, NS_ERROR_OUT_OF_MEMORY);
    }

    nsresult rv = flSvc->SetFileIO(mFastLoadIO);
    NS_ENSURE_SUCCESS(rv, rv);

    if (!mFastLoadInput && !mFastLoadOutput) {
        // First time accessing the fastload file
        PRBool exists;
        mFastLoadFile->Exists(&exists);
        if (exists) {
            LOG(("trying to use existing fastload file\n"));

            nsCOMPtr<nsIInputStream> input;
            rv = mFastLoadIO->GetInputStream(getter_AddRefs(input));
            NS_ENSURE_SUCCESS(rv, rv);

            rv = flSvc->NewInputStream(input, getter_AddRefs(mFastLoadInput));
            if (NS_SUCCEEDED(rv)) {
                LOG(("opened fastload file for reading\n"));

                nsCOMPtr<nsIFastLoadReadControl>
                    readControl(do_QueryInterface(mFastLoadInput));
                if (readControl) {
                    // Verify checksum, using the FastLoadService's
                    // checksum cache to avoid computing more than once
                    // per session.
                    PRUint32 checksum;
                    rv = readControl->GetChecksum(&checksum);
                    if (NS_SUCCEEDED(rv)) {
                        PRUint32 verified;
                        rv = flSvc->ComputeChecksum(mFastLoadFile,
                                                    readControl, &verified);
                        if (NS_SUCCEEDED(rv) && verified != checksum) {
                            LOG(("Incorrect checksum detected"));
                            rv = NS_ERROR_FAILURE;
                        }
                    }
                }

                if (NS_SUCCEEDED(rv)) {
                    /* Get the JS bytecode version number and validate it. */
                    PRUint32 version;
                    rv = mFastLoadInput->Read32(&version);
                    if (NS_SUCCEEDED(rv) && version != JSXDR_BYTECODE_VERSION) {
                        LOG(("Bad JS bytecode version\n"));
                        rv = NS_ERROR_UNEXPECTED;
                    }
                }
            }
            if (NS_FAILED(rv)) {
                LOG(("Invalid fastload file detected, removing it\n"));
                if (mFastLoadInput) {
                    mFastLoadInput->Close();
                    mFastLoadInput = nsnull;
                } else {
                    input->Close();
                }
                mFastLoadIO->SetInputStream(nsnull);
                mFastLoadFile->Remove(PR_FALSE);
                exists = PR_FALSE;
            }
        }

        if (!exists) {
            LOG(("Creating new fastload file\n"));

            nsCOMPtr<nsIOutputStream> output;
            rv = mFastLoadIO->GetOutputStream(getter_AddRefs(output));
            NS_ENSURE_SUCCESS(rv, rv);

            rv = flSvc->NewOutputStream(output,
                                        getter_AddRefs(mFastLoadOutput));

            if (NS_SUCCEEDED(rv))
                rv = mFastLoadOutput->Write32(JSXDR_BYTECODE_VERSION);

            if (NS_FAILED(rv)) {
                LOG(("Fatal error, could not create fastload file\n"));

                if (mFastLoadOutput) {
                    mFastLoadOutput->Close();
                    mFastLoadOutput = nsnull;
                } else {
                    output->Close();
                }
                mFastLoadIO->SetOutputStream(nsnull);
                mFastLoadFile->Remove(PR_FALSE);
                return rv;
            }
        }
    }

    flSvc->SetInputStream(mFastLoadInput);
    flSvc->SetOutputStream(mFastLoadOutput);

    // Start our update timer.  This allows us to keep the stream open
    // when many components are loaded in succession, but close it once
    // there has been a period of inactivity.

    if (!mFastLoadTimer) {
        mFastLoadTimer = do_CreateInstance(NS_TIMER_CONTRACTID, &rv);
        NS_ENSURE_SUCCESS(rv, rv);

        rv = mFastLoadTimer->InitWithFuncCallback(&mozJSComponentLoader::CloseFastLoad,
                                                  this,
                                                  kFastLoadWriteDelay,
                                                  nsITimer::TYPE_ONE_SHOT);
    } else {
        rv = mFastLoadTimer->SetDelay(kFastLoadWriteDelay);
    }

    return rv;
}

Here is the call graph for this function:

Here is the caller graph for this function:

void nsIComponentLoader::unloadAll ( in long  aWhen) [inherited]

Unload all components that are willing.

Definition at line 814 of file mozJSComponentLoader.cpp.

{
    nsXPIDLCString registryLocation;
    nsresult rv;
    
    // what I want to do here is QI for a Component Registration Manager.  Since this 
    // has not been invented yet, QI to the obsolete manager.  Kids, don't do this at home.
    nsCOMPtr<nsIComponentManagerObsolete> obsoleteManager = do_QueryInterface(mCompMgr, &rv);
    if (obsoleteManager)
        rv = obsoleteManager->RegistryLocationForSpec(component, 
                                                      getter_Copies(registryLocation));
    if (NS_FAILED(rv))
        return rv;
    
    nsIModule *module = ModuleForLocation(registryLocation, component, &rv);
    NS_ENSURE_SUCCESS(rv, rv);
    
    // Notify observers, if any, of autoregistration work
    nsCOMPtr<nsIObserverService> observerService = 
        do_GetService(kObserverServiceContractID, &rv);
    NS_ENSURE_SUCCESS(rv, rv);

    nsCOMPtr<nsIServiceManager> mgr;
    rv = NS_GetServiceManager(getter_AddRefs(mgr));
    NS_ENSURE_SUCCESS(rv, rv);

    const nsAFlatString &msg = NS_LITERAL_STRING("Unregistering JS component");
    observerService->NotifyObservers(mgr,
                                     NS_XPCOM_AUTOREGISTRATION_OBSERVER_ID,
                                     msg.get());
    
    rv = module->UnregisterSelf(mCompMgr, component, registryLocation);
    if (NS_SUCCEEDED(rv)) {
        // Remove any autoreg specific info. Ignore error.
        RemoveRegistryInfo(component, registryLocation);
    }
        
    return rv;
}

Here is the call graph for this function:

nsresult mozJSComponentLoader::WriteScript ( nsIFastLoadService flSvc,
JSScript script,
nsIFile component,
const char *  nativePath,
nsIURI uri,
JSContext cx 
) [protected]

Definition at line 1294 of file mozJSComponentLoader.cpp.

{
    NS_ASSERTION(flSvc, "fastload not initialized");
    nsresult rv;

    if (!mFastLoadOutput) {
        // Trying to read a URI that was not in the fastload file will have
        // created an output stream for us.  But, if we haven't tried to
        // load anything that was missing, it will still be null.
        rv = flSvc->GetOutputStream(getter_AddRefs(mFastLoadOutput));
        NS_ENSURE_SUCCESS(rv, rv);
    }

    NS_ASSERTION(mFastLoadOutput, "must have an output stream here");

    LOG(("Writing %s to fastload\n", nativePath));
    rv = flSvc->AddDependency(component);
    NS_ENSURE_SUCCESS(rv, rv);

    rv = flSvc->StartMuxedDocument(uri, nativePath,
                                   nsIFastLoadService::NS_FASTLOAD_WRITE);
    NS_ENSURE_SUCCESS(rv, rv);

    nsCOMPtr<nsIURI> oldURI;
    rv = flSvc->SelectMuxedDocument(uri, getter_AddRefs(oldURI));
    NS_ENSURE_SUCCESS(rv, rv);

    rv = WriteScriptToStream(cx, script, mFastLoadOutput);
    NS_ENSURE_SUCCESS(rv, rv);

    return flSvc->EndMuxedDocument(uri);
}

Here is the call graph for this function:

Here is the caller graph for this function:


Member Data Documentation

Definition at line 74 of file nsIComponentLoader.idl.

Definition at line 125 of file mozJSComponentLoader.h.

Definition at line 137 of file mozJSComponentLoader.h.

nsSupportsArray mozJSComponentLoader::mDeferredComponents [protected]

Definition at line 142 of file mozJSComponentLoader.h.

Definition at line 128 of file mozJSComponentLoader.h.

Definition at line 130 of file mozJSComponentLoader.h.

Definition at line 129 of file mozJSComponentLoader.h.

Definition at line 131 of file mozJSComponentLoader.h.

Definition at line 132 of file mozJSComponentLoader.h.

Definition at line 139 of file mozJSComponentLoader.h.

Definition at line 141 of file mozJSComponentLoader.h.

Definition at line 126 of file mozJSComponentLoader.h.

Definition at line 138 of file mozJSComponentLoader.h.

Definition at line 136 of file mozJSComponentLoader.h.

Definition at line 127 of file mozJSComponentLoader.h.

Definition at line 134 of file mozJSComponentLoader.h.

When is AutoRegistration occuring?

Definition at line 73 of file nsIComponentLoader.idl.

Definition at line 75 of file nsIComponentLoader.idl.


The documentation for this class was generated from the following files: