Back to index

lightning-sunbird  0.9+nobinonly
Classes | Defines | Enumerations | Functions | Variables
jsd_xpc.cpp File Reference
#include "jsd_xpc.h"
#include "jsdbgapi.h"
#include "jscntxt.h"
#include "jsfun.h"
#include "nsIXPConnect.h"
#include "nsIGenericFactory.h"
#include "nsIServiceManager.h"
#include "nsIScriptGlobalObject.h"
#include "nsIObserver.h"
#include "nsIObserverService.h"
#include "nsICategoryManager.h"
#include "nsIJSRuntimeService.h"
#include "nsIEventQueueService.h"
#include "nsMemory.h"
#include "jsdebug.h"
#include "nsReadableUtils.h"
#include "nsCRT.h"
#include "nsWidgetsCID.h"
#include "nsIScriptContext.h"
#include "nsIAppShell.h"
#include "nsIJSContextStack.h"

Go to the source code of this file.

Classes

struct  DeadScript
struct  FilterRecord
class  jsdASObserver

Defines

#define DEBUG_CREATE(name, count)
#define DEBUG_DESTROY(name, count)
#define ASSERT_VALID_CONTEXT   { if (!mCx) return NS_ERROR_NOT_AVAILABLE; }
#define ASSERT_VALID_EPHEMERAL   { if (!mValid) return NS_ERROR_NOT_AVAILABLE; }
#define JSDSERVICE_CID
#define JSDASO_CID
#define JSDS_MAJOR_VERSION   1
#define JSDS_MINOR_VERSION   2
#define NS_CATMAN_CTRID   "@mozilla.org/categorymanager;1"
#define NS_JSRT_CTRID   "@mozilla.org/js/xpc/RuntimeService;1"
#define AUTOREG_CATEGORY   "xpcom-autoregistration"
#define APPSTART_CATEGORY   "app-startup"
#define JSD_AUTOREG_ENTRY   "JSDebugger Startup Observer"
#define JSD_STARTUP_ENTRY   "JSDebugger Startup Observer,service"

Enumerations

enum  PatternType {
  ptIgnore = 0U, ptStartsWith = 1U, ptEndsWith = 2U, ptContains = 3U,
  ptEquals = 4U
}

Functions

 jsds_GCCallbackProc (JSContext *cx, JSGCStatus status)
static NS_DEFINE_CID (kAppShellCID, NS_APPSHELL_CID)
static NS_DEFINE_CID (kEventQueueServiceCID, NS_EVENTQUEUESERVICE_CID)
already_AddRefed< jsdIEphemeraljsds_FindEphemeral (LiveEphemeral **listHead, void *key)
void jsds_InvalidateAllEphemerals (LiveEphemeral **listHead)
void jsds_InsertEphemeral (LiveEphemeral **listHead, LiveEphemeral *item)
void jsds_RemoveEphemeral (LiveEphemeral **listHead, LiveEphemeral *item)
void jsds_FreeFilter (FilterRecord *filter)
PRBool jsds_SyncFilter (FilterRecord *rec, jsdIFilter *filter)
FilterRecordjsds_FindFilter (jsdIFilter *filter)
PRBool jsds_FilterHook (JSDContext *jsdc, JSDThreadState *state)
 jsds_NotifyPendingDeadScripts (JSContext *cx)
 jsds_ErrorHookProc (JSDContext *jsdc, JSContext *cx, const char *message, JSErrorReport *report, void *callerdata)
 jsds_CallHookProc (JSDContext *jsdc, JSDThreadState *jsdthreadstate, uintN type, void *callerdata)
 jsds_ExecutionHookProc (JSDContext *jsdc, JSDThreadState *jsdthreadstate, uintN type, void *callerdata, jsval *rval)
 jsds_ScriptHookProc (JSDContext *jsdc, JSDScript *jsdscript, JSBool creating, void *callerdata)

Variables

const char implementationString [] = "Mozilla JavaScript Debugger Service"
const char jsdServiceCtrID [] = "@mozilla.org/js/jsd/debugger-service;1"
const char jsdASObserverCtrID [] = "@mozilla.org/js/jsd/app-start-observer;2"
static jsdServicegJsds = 0
static JSGCCallback gLastGCProc = jsds_GCCallbackProc
static JSGCStatus gGCStatus = JSGC_END
static struct DeadScriptgDeadScripts
static struct FilterRecordgFilters
static struct LiveEphemeralgLiveValues = nsnull
static struct LiveEphemeralgLiveProperties = nsnull
static struct LiveEphemeralgLiveContexts = nsnull
static struct LiveEphemeralgLiveStackFrames = nsnull
static const nsModuleComponentInfo components []

Class Documentation

struct DeadScript

Definition at line 139 of file jsd_xpc.cpp.

Collaboration diagram for DeadScript:
Class Members
JSDContext * jsdc
PRCList links
jsdIScript * script
struct FilterRecord

Definition at line 153 of file jsd_xpc.cpp.

Collaboration diagram for FilterRecord:
Class Members
PRUint32 endLine
jsdIFilter * filterObject
void * glob
PRCList links
PRUint32 patternLength
PatternType patternType
PRUint32 startLine
char * urlPattern

Define Documentation

#define APPSTART_CATEGORY   "app-startup"

Definition at line 109 of file jsd_xpc.cpp.

Definition at line 83 of file jsd_xpc.cpp.

Definition at line 84 of file jsd_xpc.cpp.

#define AUTOREG_CATEGORY   "xpcom-autoregistration"

Definition at line 108 of file jsd_xpc.cpp.

#define DEBUG_CREATE (   name,
  count 
)

Definition at line 79 of file jsd_xpc.cpp.

#define DEBUG_DESTROY (   name,
  count 
)

Definition at line 80 of file jsd_xpc.cpp.

#define JSD_AUTOREG_ENTRY   "JSDebugger Startup Observer"

Definition at line 110 of file jsd_xpc.cpp.

#define JSD_STARTUP_ENTRY   "JSDebugger Startup Observer,service"

Definition at line 111 of file jsd_xpc.cpp.

Value:
{ /* 2fd6b7f6-eb8c-4f32-ad26-113f2c02d0fe */         \
     0x2fd6b7f6,                                     \
     0xeb8c,                                         \
     0x4f32,                                         \
    {0xad, 0x26, 0x11, 0x3f, 0x2c, 0x02, 0xd0, 0xfe} \
}

Definition at line 94 of file jsd_xpc.cpp.

Definition at line 102 of file jsd_xpc.cpp.

Definition at line 103 of file jsd_xpc.cpp.

Value:
{ /* f1299dc2-1dd1-11b2-a347-ee6b7660e048 */         \
     0xf1299dc2,                                     \
     0x1dd1,                                         \
     0x11b2,                                         \
    {0xa3, 0x47, 0xee, 0x6b, 0x76, 0x60, 0xe0, 0x48} \
}

Definition at line 86 of file jsd_xpc.cpp.

#define NS_CATMAN_CTRID   "@mozilla.org/categorymanager;1"

Definition at line 105 of file jsd_xpc.cpp.

#define NS_JSRT_CTRID   "@mozilla.org/js/xpc/RuntimeService;1"

Definition at line 106 of file jsd_xpc.cpp.


Enumeration Type Documentation

Enumerator:
ptIgnore 
ptStartsWith 
ptEndsWith 
ptContains 
ptEquals 

Definition at line 145 of file jsd_xpc.cpp.


Function Documentation

jsds_CallHookProc ( JSDContext jsdc,
JSDThreadState jsdthreadstate,
uintN  type,
void callerdata 
)

Definition at line 589 of file jsd_xpc.cpp.

{
    nsCOMPtr<jsdICallHook> hook;

    switch (type)
    {
        case JSD_HOOK_TOPLEVEL_START:
        case JSD_HOOK_TOPLEVEL_END:
            gJsds->GetTopLevelHook(getter_AddRefs(hook));
            break;
            
        case JSD_HOOK_FUNCTION_CALL:
        case JSD_HOOK_FUNCTION_RETURN:
            gJsds->GetFunctionHook(getter_AddRefs(hook));
            break;

        default:
            NS_ASSERTION (0, "Unknown hook type.");
    }
    
    if (!hook)
        return JS_TRUE;

    if (!jsds_FilterHook (jsdc, jsdthreadstate))
        return JS_FALSE;

    JSDStackFrameInfo *native_frame = JSD_GetStackFrame (jsdc, jsdthreadstate);
    nsCOMPtr<jsdIStackFrame> frame =
        getter_AddRefs(jsdStackFrame::FromPtr(jsdc, jsdthreadstate,
                                              native_frame));
    gJsds->Pause(nsnull);
    hook->OnCall(frame, type);    
    gJsds->UnPause(nsnull);
    jsdStackFrame::InvalidateAll();

    return JS_TRUE;
}

Here is the call graph for this function:

jsds_ErrorHookProc ( JSDContext jsdc,
JSContext cx,
const char *  message,
JSErrorReport report,
void callerdata 
)

Definition at line 532 of file jsd_xpc.cpp.

{
    static PRBool running = PR_FALSE;

    nsCOMPtr<jsdIErrorHook> hook;
    gJsds->GetErrorHook(getter_AddRefs(hook));
    if (!hook)
        return JSD_ERROR_REPORTER_PASS_ALONG;

    if (running)
        return JSD_ERROR_REPORTER_PASS_ALONG;
    
    running = PR_TRUE;
    
    nsCOMPtr<jsdIValue> val;
    if (JS_IsExceptionPending(cx)) {
        jsval jv;
        JS_GetPendingException(cx, &jv);
        JSDValue *jsdv = JSD_NewValue (jsdc, jv);
        val = getter_AddRefs(jsdValue::FromPtr(jsdc, jsdv));
    }
    
    const char *fileName;
    PRUint32    line;
    PRUint32    pos;
    PRUint32    flags;
    PRUint32    errnum;
    PRBool      rval;
    if (report) {
        fileName = report->filename;
        line = report->lineno;
        pos = report->tokenptr - report->linebuf;
        flags = report->flags;
        errnum = report->errorNumber;
    }
    else
    {
        fileName = 0;
        line     = 0;
        pos      = 0;
        flags    = 0;
        errnum   = 0;
    }
    
    gJsds->Pause(nsnull);
    hook->OnError (message, fileName, line, pos, flags, errnum, val, &rval);
    gJsds->UnPause(nsnull);
    
    running = PR_FALSE;
    if (!rval)
        return JSD_ERROR_REPORTER_DEBUG;
    
    return JSD_ERROR_REPORTER_PASS_ALONG;
}

Here is the call graph for this function:

jsds_ExecutionHookProc ( JSDContext jsdc,
JSDThreadState jsdthreadstate,
uintN  type,
void callerdata,
jsval rval 
)

Definition at line 629 of file jsd_xpc.cpp.

{
    nsCOMPtr<jsdIExecutionHook> hook(0);
    PRUint32 hook_rv = JSD_HOOK_RETURN_CONTINUE;
    nsCOMPtr<jsdIValue> js_rv;

    switch (type)
    {
        case JSD_HOOK_INTERRUPTED:
            gJsds->GetInterruptHook(getter_AddRefs(hook));
            break;
        case JSD_HOOK_DEBUG_REQUESTED:
            gJsds->GetDebugHook(getter_AddRefs(hook));
            break;
        case JSD_HOOK_DEBUGGER_KEYWORD:
            gJsds->GetDebuggerHook(getter_AddRefs(hook));
            break;
        case JSD_HOOK_BREAKPOINT:
            {
                /* we can't pause breakpoints the way we pause the other
                 * execution hooks (at least, not easily.)  Instead we bail
                 * here if the service is paused. */
                PRUint32 level;
                gJsds->GetPauseDepth(&level);
                if (!level)
                    gJsds->GetBreakpointHook(getter_AddRefs(hook));
            }
            break;
        case JSD_HOOK_THROW:
        {
            hook_rv = JSD_HOOK_RETURN_CONTINUE_THROW;
            gJsds->GetThrowHook(getter_AddRefs(hook));
            if (hook) {
                JSDValue *jsdv = JSD_GetException (jsdc, jsdthreadstate);
                js_rv = getter_AddRefs(jsdValue::FromPtr (jsdc, jsdv));
            }
            break;
        }
        default:
            NS_ASSERTION (0, "Unknown hook type.");
    }

    if (!hook)
        return hook_rv;
    
    if (!jsds_FilterHook (jsdc, jsdthreadstate))
        return JSD_HOOK_RETURN_CONTINUE;
    
    JSDStackFrameInfo *native_frame = JSD_GetStackFrame (jsdc, jsdthreadstate);
    nsCOMPtr<jsdIStackFrame> frame =
        getter_AddRefs(jsdStackFrame::FromPtr(jsdc, jsdthreadstate,
                                              native_frame));
    gJsds->Pause(nsnull);
    jsdIValue *inout_rv = js_rv;
    NS_IF_ADDREF(inout_rv);
    hook->OnExecute (frame, type, &inout_rv, &hook_rv);
    js_rv = inout_rv;
    NS_IF_RELEASE(inout_rv);
    gJsds->UnPause(nsnull);
    jsdStackFrame::InvalidateAll();
        
    if (hook_rv == JSD_HOOK_RETURN_RET_WITH_VAL ||
        hook_rv == JSD_HOOK_RETURN_THROW_WITH_VAL) {
        if (js_rv) {
            JSDValue *jsdv;
            js_rv->GetJSDValue (&jsdv);
            *rval = JSD_GetValueWrappedJSVal(jsdc, jsdv);
        } else {
            *rval = JSVAL_VOID;
        }
    }
    
    return hook_rv;
}

Here is the call graph for this function:

PRBool jsds_FilterHook ( JSDContext jsdc,
JSDThreadState state 
)

Definition at line 371 of file jsd_xpc.cpp.

{
    JSContext *cx = JSD_GetJSContext (jsdc, state);
    void *glob = NS_STATIC_CAST(void *, JS_GetGlobalObject (cx));

    if (!glob) {
        NS_WARNING("No global in threadstate");
        return PR_FALSE;
    }
    
    JSDStackFrameInfo *frame = JSD_GetStackFrame (jsdc, state);

    if (!frame) {
        NS_WARNING("No frame in threadstate");
        return PR_FALSE;
    }

    JSDScript *script = JSD_GetScriptForStackFrame (jsdc, state, frame);
    if (!script)
        return PR_TRUE;

    jsuint pc = JSD_GetPCForStackFrame (jsdc, state, frame);

    const char *url = JSD_GetScriptFilename (jsdc, script);
    if (!url) {
        NS_WARNING ("Script with no filename");
        return PR_FALSE;
    }

    if (!gFilters)
        return PR_TRUE;    

    PRUint32 currentLine = JSD_GetClosestLine (jsdc, script, pc);
    PRUint32 len = 0;
    FilterRecord *currentFilter = gFilters;
    do {
        PRUint32 flags = 0;
        nsresult rv = currentFilter->filterObject->GetFlags(&flags);
        NS_ASSERTION(NS_SUCCEEDED(rv), "Error getting flags for filter");
        if (flags & jsdIFilter::FLAG_ENABLED) {
            /* if there is no glob, or the globs match */
            if ((!currentFilter->glob || currentFilter->glob == glob) &&
                /* and there is no start line, or the start line is before 
                 * or equal to the current */
                (!currentFilter->startLine || 
                 currentFilter->startLine <= currentLine) &&
                /* and there is no end line, or the end line is after
                 * or equal to the current */
                (!currentFilter->endLine ||
                 currentFilter->endLine >= currentLine)) {
                /* then we're going to have to compare the url. */
                if (currentFilter->patternType == ptIgnore)
                    return flags & jsdIFilter::FLAG_PASS;

                if (!len)
                    len = PL_strlen(url);
                
                if (len >= currentFilter->patternLength) {
                    switch (currentFilter->patternType) {
                        case ptEquals:
                            if (!PL_strcmp(currentFilter->urlPattern, url))
                                return flags & jsdIFilter::FLAG_PASS;
                            break;
                        case ptStartsWith:
                            if (!PL_strncmp(currentFilter->urlPattern, url, 
                                           currentFilter->patternLength))
                                return flags & jsdIFilter::FLAG_PASS;
                            break;
                        case ptEndsWith:
                            if (!PL_strcmp(currentFilter->urlPattern,
                                           &url[len - 
                                               currentFilter->patternLength]))
                                return flags & jsdIFilter::FLAG_PASS;
                            break;
                        case ptContains:
                            if (PL_strstr(url, currentFilter->urlPattern))
                                return flags & jsdIFilter::FLAG_PASS;
                            break;
                        default:
                            NS_ASSERTION(0, "Invalid pattern type");
                    }
                }                
            }
        }
        currentFilter = NS_REINTERPRET_CAST(FilterRecord *,
                                            PR_NEXT_LINK(&currentFilter->links));
    } while (currentFilter != gFilters);

    return PR_TRUE;
    
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 173 of file jsd_xpc.cpp.

{
    if (!*listHead)
        return nsnull;
    
    LiveEphemeral *lv_record = 
        NS_REINTERPRET_CAST (LiveEphemeral *,
                             PR_NEXT_LINK(&(*listHead)->links));
    do
    {
        if (lv_record->key == key)
        {
            NS_IF_ADDREF(lv_record->value);
            return lv_record->value;
        }
        lv_record = NS_REINTERPRET_CAST (LiveEphemeral *,
                                         PR_NEXT_LINK(&lv_record->links));
    }
    while (lv_record != *listHead);

    return nsnull;
}

Here is the caller graph for this function:

Definition at line 352 of file jsd_xpc.cpp.

{
    if (!gFilters)
        return nsnull;
    
    FilterRecord *current = gFilters;
    
    do {
        if (current->filterObject == filter)
            return current;
        current = NS_REINTERPRET_CAST(FilterRecord *,
                                      PR_NEXT_LINK(&current->links));
    } while (current != gFilters);
    
    return nsnull;
}

Definition at line 252 of file jsd_xpc.cpp.

{
    NS_IF_RELEASE (filter->filterObject);
    if (filter->urlPattern)
        nsMemory::Free(filter->urlPattern);
    PR_Free (filter);
}
jsds_GCCallbackProc ( JSContext cx,
JSGCStatus  status 
)

Definition at line 512 of file jsd_xpc.cpp.

{
#ifdef DEBUG_verbose
    printf ("new gc status is %i\n", status);
#endif
    if (status == JSGC_END) {
        /* just to guard against reentering. */
        gGCStatus = JSGC_BEGIN;
        while (gDeadScripts)
            jsds_NotifyPendingDeadScripts (cx);
    }

    gGCStatus = status;
    if (gLastGCProc)
        return gLastGCProc (cx, status);
    
    return JS_TRUE;
}

Here is the call graph for this function:

void jsds_InsertEphemeral ( LiveEphemeral **  listHead,
LiveEphemeral item 
)

Definition at line 213 of file jsd_xpc.cpp.

{
    if (*listHead) {
        /* if the list exists, add to it */
        PR_APPEND_LINK(&item->links, &(*listHead)->links);
    } else {
        /* otherwise create the list */
        PR_INIT_CLIST(&item->links);
        *listHead = item;
    }
}

Here is the caller graph for this function:

Definition at line 197 of file jsd_xpc.cpp.

{
    LiveEphemeral *lv_record = 
        NS_REINTERPRET_CAST (LiveEphemeral *,
                             PR_NEXT_LINK(&(*listHead)->links));
    while (*listHead)
    {
        LiveEphemeral *next =
            NS_REINTERPRET_CAST (LiveEphemeral *,
                                 PR_NEXT_LINK(&lv_record->links));
        lv_record->value->Invalidate();
        lv_record = next;
    }
}

Here is the caller graph for this function:

Definition at line 468 of file jsd_xpc.cpp.

{
    nsCOMPtr<jsdIScriptHook> hook = 0;   
    gJsds->GetScriptHook (getter_AddRefs(hook));

#ifdef CAUTIOUS_SCRIPTHOOK
    JSRuntime *rt = JS_GetRuntime(cx);
#endif
    gJsds->Pause(nsnull);
    DeadScript *deadScripts = gDeadScripts;
    gDeadScripts = nsnull;
    while (deadScripts) {
        DeadScript *ds = deadScripts;
        /* get next deleted script */
        deadScripts = NS_REINTERPRET_CAST(DeadScript *,
                                          PR_NEXT_LINK(&ds->links));
        if (deadScripts == ds)
            deadScripts = nsnull;

        if (hook)
        {
            /* tell the user this script has been destroyed */
#ifdef CAUTIOUS_SCRIPTHOOK
            JS_UNKEEP_ATOMS(rt);
#endif
            hook->OnScriptDestroyed (ds->script);
#ifdef CAUTIOUS_SCRIPTHOOK
            JS_KEEP_ATOMS(rt);
#endif
        }

        /* take it out of the circular list */
        PR_REMOVE_LINK(&ds->links);

        /* addref came from the FromPtr call in jsds_ScriptHookProc */
        NS_RELEASE(ds->script);
        /* free the struct! */
        PR_Free(ds);
    }

    gJsds->UnPause(nsnull);
}

Here is the call graph for this function:

Here is the caller graph for this function:

void jsds_RemoveEphemeral ( LiveEphemeral **  listHead,
LiveEphemeral item 
)

Definition at line 226 of file jsd_xpc.cpp.

{
    LiveEphemeral *next = NS_REINTERPRET_CAST (LiveEphemeral *,
                                               PR_NEXT_LINK(&item->links));

    if (next == item)
    {
        /* if the current item is also the next item, we're the only element,
         * null out the list head */
        NS_ASSERTION (*listHead == item,
                      "How could we not be the head of a one item list?");
        *listHead = nsnull;
    }
    else if (item == *listHead)
    {
        /* otherwise, if we're currently the list head, change it */
        *listHead = next;
    }
    
    PR_REMOVE_AND_INIT_LINK(&item->links);
}
jsds_ScriptHookProc ( JSDContext jsdc,
JSDScript jsdscript,
JSBool  creating,
void callerdata 
)

Definition at line 706 of file jsd_xpc.cpp.

{
#ifdef CAUTIOUS_SCRIPTHOOK
    JSContext *cx = JSD_GetDefaultJSContext(jsdc);
    JSRuntime *rt = JS_GetRuntime(cx);
#endif

    nsCOMPtr<jsdIScriptHook> hook;
    gJsds->GetScriptHook (getter_AddRefs(hook));
    
    if (creating) {
        /* a script is being created */
        if (!hook) {
            /* nobody cares, just exit */
            return;
        }
            
        nsCOMPtr<jsdIScript> script = 
            getter_AddRefs(jsdScript::FromPtr(jsdc, jsdscript));
#ifdef CAUTIOUS_SCRIPTHOOK
        JS_UNKEEP_ATOMS(rt);
#endif
        gJsds->Pause(nsnull);
        hook->OnScriptCreated (script);
        gJsds->UnPause(nsnull);
#ifdef CAUTIOUS_SCRIPTHOOK
        JS_KEEP_ATOMS(rt);
#endif
    } else {
        /* a script is being destroyed.  even if there is no registered hook
         * we'll still need to invalidate the jsdIScript record, in order
         * to remove the reference held in the JSDScript private data. */
        nsCOMPtr<jsdIScript> jsdis = 
            NS_STATIC_CAST(jsdIScript *, JSD_GetScriptPrivate(jsdscript));
        if (!jsdis)
            return;
        
        jsdis->Invalidate();
        if (!hook)
            return;
        
        if (gGCStatus == JSGC_END) {
            /* if GC *isn't* running, we can tell the user about the script
             * delete now. */
#ifdef CAUTIOUS_SCRIPTHOOK
            JS_UNKEEP_ATOMS(rt);
#endif
                
            gJsds->Pause(nsnull);
            hook->OnScriptDestroyed (jsdis);
            gJsds->UnPause(nsnull);
#ifdef CAUTIOUS_SCRIPTHOOK
            JS_KEEP_ATOMS(rt);
#endif
        } else {
            /* if a GC *is* running, we've got to wait until it's done before
             * we can execute any JS, so we queue the notification in a PRCList
             * until GC tells us it's done. See jsds_GCCallbackProc(). */
            DeadScript *ds = PR_NEW(DeadScript);
            if (!ds)
                return; /* NS_ERROR_OUT_OF_MEMORY */
        
            ds->jsdc = jsdc;
            ds->script = jsdis;
            NS_ADDREF(ds->script);
            if (gDeadScripts)
                /* if the queue exists, add to it */
                PR_APPEND_LINK(&ds->links, &gDeadScripts->links);
            else {
                /* otherwise create the queue */
                PR_INIT_CLIST(&ds->links);
                gDeadScripts = ds;
            }
        }
    }            
}

Here is the call graph for this function:

PRBool jsds_SyncFilter ( FilterRecord rec,
jsdIFilter filter 
)

Definition at line 264 of file jsd_xpc.cpp.

{
    NS_ASSERTION (rec, "jsds_SyncFilter without rec");
    NS_ASSERTION (filter, "jsds_SyncFilter without filter");
    
    JSObject *glob_proper = nsnull;
    nsCOMPtr<nsISupports> glob;
    nsresult rv = filter->GetGlobalObject(getter_AddRefs(glob));
    if (NS_FAILED(rv))
        return PR_FALSE;
    if (glob) {
        nsCOMPtr<nsIScriptGlobalObject> nsiglob = do_QueryInterface(glob);
        if (nsiglob)
            glob_proper = nsiglob->GetGlobalJSObject();
    }
    
    PRUint32 startLine;
    rv = filter->GetStartLine(&startLine);
    if (NS_FAILED(rv))
        return PR_FALSE;

    PRUint32 endLine;
    rv = filter->GetStartLine(&endLine);
    if (NS_FAILED(rv))
        return PR_FALSE;    

    char *urlPattern;
    rv = filter->GetUrlPattern (&urlPattern);
    if (NS_FAILED(rv))
        return PR_FALSE;
    
    if (urlPattern) {
        PRUint32 len = PL_strlen(urlPattern);
        if (urlPattern[0] == '*') {
            /* pattern starts with a *, shift all chars once to the left,
             * including the trailing null. */
            memmove (&urlPattern[0], &urlPattern[1], len);

            if (urlPattern[len - 2] == '*') {
                /* pattern is in the format "*foo*", overwrite the final * with
                 * a null. */
                urlPattern[len - 2] = '\0';
                rec->patternType = ptContains;
                rec->patternLength = len - 2;
            } else {
                /* pattern is in the format "*foo", just make a note of the
                 * new length. */
                rec->patternType = ptEndsWith;
                rec->patternLength = len - 1;
            }
        } else if (urlPattern[len - 1] == '*') {
            /* pattern is in the format "foo*", overwrite the final * with a 
             * null. */
            urlPattern[len - 1] = '\0';
            rec->patternType = ptStartsWith;
            rec->patternLength = len - 1;
        } else {
            /* pattern is in the format "foo". */
            rec->patternType = ptEquals;
            rec->patternLength = len;
        }
    } else {
        rec->patternType = ptIgnore;
        rec->patternLength = 0;
    }

    /* we got everything we need without failing, now copy it into rec. */

    if (rec->filterObject != filter) {
        NS_IF_RELEASE(rec->filterObject);
        NS_ADDREF(filter);
        rec->filterObject = filter;
    }
    
    rec->glob = glob_proper;
    
    rec->startLine     = startLine;
    rec->endLine       = endLine;
    
    if (rec->urlPattern)
        nsMemory::Free (rec->urlPattern);
    rec->urlPattern = urlPattern;

    return PR_TRUE;
            
}

Here is the call graph for this function:

static NS_DEFINE_CID ( kAppShellCID  ,
NS_APPSHELL_CID   
) [static]

Variable Documentation

Initial value:
 {
    {"JSDService", JSDSERVICE_CID,    jsdServiceCtrID, jsdServiceConstructor},
    {"JSDASObserver",  JSDASO_CID, jsdASObserverCtrID, jsdASObserverConstructor}
}

Definition at line 3327 of file jsd_xpc.cpp.

struct DeadScript * gDeadScripts [static]
struct FilterRecord * gFilters [static]

Definition at line 137 of file jsd_xpc.cpp.

jsdService* gJsds = 0 [static]

Definition at line 135 of file jsd_xpc.cpp.

JSGCCallback gLastGCProc = jsds_GCCallbackProc [static]

Definition at line 136 of file jsd_xpc.cpp.

struct LiveEphemeral* gLiveContexts = nsnull [static]

Definition at line 166 of file jsd_xpc.cpp.

struct LiveEphemeral* gLiveProperties = nsnull [static]

Definition at line 165 of file jsd_xpc.cpp.

Definition at line 167 of file jsd_xpc.cpp.

struct LiveEphemeral* gLiveValues = nsnull [static]

Definition at line 164 of file jsd_xpc.cpp.

const char implementationString[] = "Mozilla JavaScript Debugger Service"

Definition at line 120 of file jsd_xpc.cpp.

const char jsdASObserverCtrID[] = "@mozilla.org/js/jsd/app-start-observer;2"

Definition at line 125 of file jsd_xpc.cpp.

const char jsdServiceCtrID[] = "@mozilla.org/js/jsd/debugger-service;1"

Definition at line 124 of file jsd_xpc.cpp.