Back to index

lightning-sunbird  0.9+nobinonly
Classes | Defines | Functions | Variables
mozJSComponentLoader.cpp File Reference
#include "prlog.h"
#include "nsCOMPtr.h"
#include "nsICategoryManager.h"
#include "nsIComponentLoader.h"
#include "nsIComponentManager.h"
#include "nsIComponentManagerObsolete.h"
#include "nsIGenericFactory.h"
#include "nsILocalFile.h"
#include "nsIModule.h"
#include "nsIServiceManager.h"
#include "nsISupports.h"
#include "mozJSComponentLoader.h"
#include "nsIJSRuntimeService.h"
#include "nsIJSContextStack.h"
#include "nsIXPConnect.h"
#include "nsCRT.h"
#include "nsMemory.h"
#include "nsXPIDLString.h"
#include "nsIObserverService.h"
#include "nsIXPCScriptable.h"
#include "nsString.h"
#include "nsIScriptSecurityManager.h"
#include "nsIURI.h"
#include "nsNetUtil.h"
#include "nsIComponentLoaderManager.h"
#include "jsxdrapi.h"
#include "nsIFastLoadFileControl.h"
#include "nsIScriptError.h"
#include "nsIConsoleService.h"

Go to the source code of this file.

Classes

class  JSCLContextHelper
class  JSCLAutoErrorReporterSetter
class  FileAutoCloser
class  FileMapAutoCloser
class  JSPrincipalsHolder
class  JSScriptHolder
class  FastLoadStateHolder

Defines

#define HAVE_PR_MEMMAP
#define XPC_SERIALIZATION_BUFFER_SIZE   (64 * 1024)
 Buffer sizes for serialization and deserialization of scripts.
#define XPC_DESERIALIZATION_BUFFER_SIZE   (8 * 1024)
#define LOG(args)   PR_LOG(gJSCLLog, PR_LOG_DEBUG, args)

Functions

void JS_DLL_CALLBACK mozJSLoaderErrorReporter (JSContext *cx, const char *message, JSErrorReport *rep)
 Dump (JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
 Debug (JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
static nsresult ReadScriptFromStream (JSContext *cx, nsIObjectInputStream *stream, JSScript **script)
static nsresult WriteScriptToStream (JSContext *cx, JSScript *script, nsIObjectOutputStream *stream)
static PRIntn PR_CALLBACK UnrootGlobals (PLHashEntry *he, PRIntn i, void *arg)
static PRIntn PR_CALLBACK UnloadAndReleaseModules (PLHashEntry *he, PRIntn i, void *arg)

Variables

static const char kJSRuntimeServiceContractID [] = "@mozilla.org/js/xpc/RuntimeService;1"
static const char kXPConnectServiceContractID [] = "@mozilla.org/js/xpc/XPConnect;1"
static const char kObserverServiceContractID [] = "@mozilla.org/observer-service;1"
static const int kFastLoadWriteDelay = 5000
static JSFunctionSpec gGlobalFun []

Define Documentation

Definition at line 89 of file mozJSComponentLoader.cpp.

#define LOG (   args)    PR_LOG(gJSCLLog, PR_LOG_DEBUG, args)

Definition at line 107 of file mozJSComponentLoader.cpp.

Definition at line 97 of file mozJSComponentLoader.cpp.

Buffer sizes for serialization and deserialization of scripts.

These should be tuned at some point.

Definition at line 96 of file mozJSComponentLoader.cpp.


Function Documentation

Debug ( JSContext cx,
JSObject obj,
uintN  argc,
jsval argv,
jsval rval 
)

Definition at line 187 of file mozJSComponentLoader.cpp.

{
#ifdef DEBUG
    return Dump(cx, obj, argc, argv, rval);
#else
    return JS_TRUE;
#endif
}

Here is the call graph for this function:

Dump ( JSContext cx,
JSObject obj,
uintN  argc,
jsval argv,
jsval rval 
)

Definition at line 168 of file mozJSComponentLoader.cpp.

{
    JSString *str;
    if (!argc)
        return JS_TRUE;
    
    str = JS_ValueToString(cx, argv[0]);
    if (!str)
        return JS_FALSE;

    char *bytes = JS_GetStringBytes(str);
    bytes = nsCRT::strdup(bytes);

    fputs(bytes, stderr);
    nsMemory::Free(bytes);
    return JS_TRUE;
}

Here is the call graph for this function:

Here is the caller graph for this function:

void JS_DLL_CALLBACK mozJSLoaderErrorReporter ( JSContext cx,
const char *  message,
JSErrorReport rep 
)

Definition at line 110 of file mozJSComponentLoader.cpp.

{
    nsresult rv;

    /* Use the console service to register the error. */
    nsCOMPtr<nsIConsoleService> consoleService =
        do_GetService(NS_CONSOLESERVICE_CONTRACTID);

    /*
     * Make an nsIScriptError, populate it with information from this
     * error, then log it with the console service.  The UI can then
     * poll the service to update the Error console.
     */
    nsCOMPtr<nsIScriptError> errorObject = 
        do_CreateInstance(NS_SCRIPTERROR_CONTRACTID);
    
    if (consoleService && errorObject) {
        /*
         * Got an error object; prepare appropriate-width versions of
         * various arguments to it.
         */
        nsAutoString fileUni;
        fileUni.AssignWithConversion(rep->filename);

        PRUint32 column = rep->uctokenptr - rep->uclinebuf;

        rv = errorObject->Init(NS_REINTERPRET_CAST(const PRUnichar*,
                                                   rep->ucmessage),
                               fileUni.get(),
                               NS_REINTERPRET_CAST(const PRUnichar*,
                                                   rep->uclinebuf),
                               rep->lineno, column, rep->flags,
                               "component javascript");
        if (NS_SUCCEEDED(rv)) {
            rv = consoleService->LogMessage(errorObject);
            if (NS_SUCCEEDED(rv)) {
                // We're done!  Skip return to fall thru to stderr
                // printout, for the benefit of those invoking the
                // browser with -console
                // return;
            }
        }
    }

    /*
     * If any of the above fails for some reason, fall back to
     * printing to stderr.
     */
#ifdef DEBUG
    fprintf(stderr, "JS Component Loader: %s %s:%d\n"
            "                     %s\n",
            JSREPORT_IS_WARNING(rep->flags) ? "WARNING" : "ERROR",
            rep->filename, rep->lineno,
            message ? message : "<no message>");
#endif
}

Here is the call graph for this function:

Here is the caller graph for this function:

static nsresult ReadScriptFromStream ( JSContext cx,
nsIObjectInputStream stream,
JSScript **  script 
) [static]

Definition at line 276 of file mozJSComponentLoader.cpp.

{
    *script = nsnull;

    PRUint32 size;
    nsresult rv = stream->Read32(&size);
    NS_ENSURE_SUCCESS(rv, rv);

    char *data;
    rv = stream->ReadBytes(size, &data);
    NS_ENSURE_SUCCESS(rv, rv);

    JSXDRState *xdr = JS_XDRNewMem(cx, JSXDR_DECODE);
    NS_ENSURE_TRUE(xdr, NS_ERROR_OUT_OF_MEMORY);

    xdr->userdata = stream;
    JS_XDRMemSetData(xdr, data, size);

    if (!JS_XDRScript(xdr, script)) {
        rv = NS_ERROR_FAILURE;
    }

    // Update data in case ::JS_XDRScript called back into C++ code to
    // read an XPCOM object.
    //
    // In that case, the serialization process must have flushed a run
    // of counted bytes containing JS data at the point where the XPCOM
    // object starts, after which an encoding C++ callback from the JS
    // XDR code must have written the XPCOM object directly into the
    // nsIObjectOutputStream.
    //
    // The deserialization process will XDR-decode counted bytes up to
    // but not including the XPCOM object, then call back into C++ to
    // read the object, then read more counted bytes and hand them off
    // to the JSXDRState, so more JS data can be decoded.
    //
    // This interleaving of JS XDR data and XPCOM object data may occur
    // several times beneath the call to ::JS_XDRScript, above.  At the
    // end of the day, we need to free (via nsMemory) the data owned by
    // the JSXDRState.  So we steal it back, nulling xdr's buffer so it
    // doesn't get passed to ::JS_free by ::JS_XDRDestroy.

    uint32 length;
    data = NS_STATIC_CAST(char*, JS_XDRMemGetData(xdr, &length));
    if (data) {
        JS_XDRMemSetData(xdr, nsnull, 0);
    }

    JS_XDRDestroy(xdr);

    // If data is null now, it must have been freed while deserializing an
    // XPCOM object (e.g., a principal) beneath ::JS_XDRScript.
    if (data) {
        nsMemory::Free(data);
    }

    return rv;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static PRIntn PR_CALLBACK UnloadAndReleaseModules ( PLHashEntry he,
PRIntn  i,
void arg 
) [static]

Definition at line 404 of file mozJSComponentLoader.cpp.

{
    nsIModule *module = NS_STATIC_CAST(nsIModule *, he->value);
    nsIComponentManager *mgr = NS_STATIC_CAST(nsIComponentManager *, arg);
    PRBool canUnload;
    nsresult rv = module->CanUnload(mgr, &canUnload);
    NS_ASSERTION(NS_SUCCEEDED(rv), "module CanUnload failed");
    if (NS_SUCCEEDED(rv) && canUnload) {
        NS_RELEASE(module);
        /* XXX need to unroot the global for the module as well */
        nsCRT::free((char *)he->key);
        return HT_ENUMERATE_REMOVE;
    }
    return HT_ENUMERATE_NEXT;
}
static PRIntn PR_CALLBACK UnrootGlobals ( PLHashEntry he,
PRIntn  i,
void arg 
) [static]

Definition at line 393 of file mozJSComponentLoader.cpp.

{
    JSContext *cx = (JSContext *)arg;
    JSObject *global = (JSObject *)he->value;
    JS_ClearScope(cx, global);
    JS_RemoveRoot(cx, &he->value);
    nsCRT::free((char *)he->key);
    return HT_ENUMERATE_REMOVE;
}

Here is the call graph for this function:

static nsresult WriteScriptToStream ( JSContext cx,
JSScript script,
nsIObjectOutputStream stream 
) [static]

Definition at line 337 of file mozJSComponentLoader.cpp.

{
    JSXDRState *xdr = JS_XDRNewMem(cx, JSXDR_ENCODE);
    NS_ENSURE_TRUE(xdr, NS_ERROR_OUT_OF_MEMORY);

    xdr->userdata = stream;
    nsresult rv = NS_OK;

    if (JS_XDRScript(xdr, &script)) {
        // Get the encoded JSXDRState data and write it.  The JSXDRState owns
        // this buffer memory and will free it beneath ::JS_XDRDestroy.
        //
        // If an XPCOM object needs to be written in the midst of the JS XDR
        // encoding process, the C++ code called back from the JS engine (e.g.,
        // nsEncodeJSPrincipals in caps/src/nsJSPrincipals.cpp) will flush data
        // from the JSXDRState to aStream, then write the object, then return
        // to JS XDR code with xdr reset so new JS data is encoded at the front
        // of the xdr's data buffer.
        //
        // However many XPCOM objects are interleaved with JS XDR data in the
        // stream, when control returns here from ::JS_XDRScript, we'll have
        // one last buffer of data to write to aStream.

        uint32 size;
        const char* data = NS_REINTERPRET_CAST(const char*,
                                               JS_XDRMemGetData(xdr, &size));
        NS_ASSERTION(data, "no decoded JSXDRState data!");

        rv = stream->Write32(size);
        if (NS_SUCCEEDED(rv)) {
            rv = stream->WriteBytes(data, size);
        }
    } else {
        rv = NS_ERROR_FAILURE; // likely to be a principals serialization error
    }

    JS_XDRDestroy(xdr);
    return rv;
}

Here is the call graph for this function:

Here is the caller graph for this function:


Variable Documentation

Initial value:
 {
    {"dump", Dump, 1 },
    {"debug", Debug, 1 },
    {0}
}

Definition at line 196 of file mozJSComponentLoader.cpp.

const int kFastLoadWriteDelay = 5000 [static]

Definition at line 100 of file mozJSComponentLoader.cpp.

const char kJSRuntimeServiceContractID[] = "@mozilla.org/js/xpc/RuntimeService;1" [static]

Definition at line 82 of file mozJSComponentLoader.cpp.

const char kObserverServiceContractID[] = "@mozilla.org/observer-service;1" [static]

Definition at line 84 of file mozJSComponentLoader.cpp.

const char kXPConnectServiceContractID[] = "@mozilla.org/js/xpc/XPConnect;1" [static]

Definition at line 83 of file mozJSComponentLoader.cpp.