/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
 * vim: set ts=8 sts=4 et sw=4 tw=99:
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

/*
 * JavaScript Debugging support - Script support
 */

#include "jsd.h"
#include "jsfriendapi.h"
#include "nsCxPusher.h"

using mozilla::AutoSafeJSContext;

/* Comment this out to disable (NT specific) dumping as we go */
/*
** #ifdef DEBUG      
** #define JSD_DUMP 1
** #endif            
*/

#define NOT_SET_YET -1

/***************************************************************************/

#ifdef DEBUG
void JSD_ASSERT_VALID_SCRIPT(JSDScript* jsdscript)
{
    JS_ASSERT(jsdscript);
    JS_ASSERT(jsdscript->script);
}
void JSD_ASSERT_VALID_EXEC_HOOK(JSDExecHook* jsdhook)
{
    JS_ASSERT(jsdhook);
    JS_ASSERT(jsdhook->hook);
}
#endif

#ifdef LIVEWIRE
static JSBool
HasFileExtention(const char* name, const char* ext)
{
    int i;
    int len = strlen(ext);
    const char* p = strrchr(name,'.');
    if( !p )
        return JS_FALSE;
    p++;
    for(i = 0; i < len; i++ )
    {
        JS_ASSERT(islower(ext[i]));
        if( 0 == p[i] || tolower(p[i]) != ext[i] )
            return JS_FALSE;
    }
    if( 0 != p[i] )
        return JS_FALSE;
    return JS_TRUE;
}    
#endif /* LIVEWIRE */

static JSDScript*
_newJSDScript(JSDContext*  jsdc,
              JSContext    *cx,
              JSScript     *script_)
{
    JS::RootedScript script(cx, script_);
    if ( JS_GetScriptIsSelfHosted(script) )
        return NULL;

    JSDScript*  jsdscript;
    unsigned     lineno;
    const char* raw_filename;

    JS_ASSERT(JSD_SCRIPTS_LOCKED(jsdc));

    /* these are inlined javascript: urls and we can't handle them now */
    lineno = (unsigned) JS_GetScriptBaseLineNumber(cx, script);
    if( lineno == 0 )
        return NULL;

    jsdscript = (JSDScript*) calloc(1, sizeof(JSDScript));
    if( ! jsdscript )
        return NULL;

    raw_filename = JS_GetScriptFilename(cx,script);

    JS_HashTableAdd(jsdc->scriptsTable, (void *)script, (void *)jsdscript);
    JS_APPEND_LINK(&jsdscript->links, &jsdc->scripts);
    jsdscript->jsdc         = jsdc;
    jsdscript->script       = script;  
    jsdscript->lineBase     = lineno;
    jsdscript->lineExtent   = (unsigned)NOT_SET_YET;
    jsdscript->data         = NULL;
#ifndef LIVEWIRE
    jsdscript->url          = (char*) jsd_BuildNormalizedURL(raw_filename);
#else
    jsdscript->app = LWDBG_GetCurrentApp();    
    if( jsdscript->app && raw_filename )
    {
        jsdscript->url = jsdlw_BuildAppRelativeFilename(jsdscript->app, raw_filename);
        if( function )
        {
            JSString* funid = JS_GetFunctionId(function);
            char* funbytes;
            const char* funnanme;
            if( fuinid )
            {
                funbytes = JS_EncodeString(cx, funid);
                funname = funbytes ? funbytes : "";
            }
            else
            {
                funbytes = NULL;
                funname = "anonymous";
            }
            jsdscript->lwscript = 
                LWDBG_GetScriptOfFunction(jsdscript->app,funname);
            JS_Free(cx, funbytes);
    
            /* also, make sure this file is added to filelist if is .js file */
            if( HasFileExtention(raw_filename,"js") || 
                HasFileExtention(raw_filename,"sjs") )
            {
                jsdlw_PreLoadSource(jsdc, jsdscript->app, raw_filename, JS_FALSE);
            }
        }
        else
        {
            jsdscript->lwscript = LWDBG_GetCurrentTopLevelScript();
        }
    }
#endif

    JS_INIT_CLIST(&jsdscript->hooks);
    
    return jsdscript;
}           

static void 
_destroyJSDScript(JSDContext*  jsdc,
                  JSDScript*   jsdscript)
{
    JS_ASSERT(JSD_SCRIPTS_LOCKED(jsdc));

    /* destroy all hooks */
    jsd_ClearAllExecutionHooksForScript(jsdc, jsdscript);

    JS_REMOVE_LINK(&jsdscript->links);
    if(jsdscript->url)
        free(jsdscript->url);

    if (jsdscript->profileData)
        free(jsdscript->profileData);
    
    free(jsdscript);
}

/***************************************************************************/

#ifdef JSD_DUMP
#ifndef XP_WIN
void
OutputDebugString (char *buf)
{
    fprintf (stderr, "%s", buf);
}
#endif

static void
_dumpJSDScript(JSDContext* jsdc, JSDScript* jsdscript, const char* leadingtext)
{
    const char* name;
    JSString* fun;
    unsigned base;
    unsigned extent;
    char Buf[256];
    size_t n;

    name   = jsd_GetScriptFilename(jsdc, jsdscript);
    fun    = jsd_GetScriptFunctionId(jsdc, jsdscript);
    base   = jsd_GetScriptBaseLineNumber(jsdc, jsdscript);
    extent = jsd_GetScriptLineExtent(jsdc, jsdscript);
    n = size_t(snprintf(Buf, sizeof(Buf), "%sscript=%08X, %s, ",
                        leadingtext, (unsigned) jsdscript->script,
                        name ? name : "no URL"));
    if (n + 1 < sizeof(Buf)) {
        if (fun) {
            n += size_t(snprintf(Buf + n, sizeof(Buf) - n, "%s", "no fun"));
        } else {
            n += JS_PutEscapedFlatString(Buf + n, sizeof(Buf) - n,
                                         JS_ASSERT_STRING_IS_FLAT(fun), 0);
            Buf[sizeof(Buf) - 1] = '\0';
        }
        if (n + 1 < sizeof(Buf))
            snprintf(Buf + n, sizeof(Buf) - n, ", %d-%d\n", base, base + extent - 1);
    }
    OutputDebugString( Buf );
}

static void
_dumpJSDScriptList( JSDContext* jsdc )
{
    JSDScript* iterp = NULL;
    JSDScript* jsdscript = NULL;
    
    OutputDebugString( "*** JSDScriptDump\n" );
    while( NULL != (jsdscript = jsd_IterateScripts(jsdc, &iterp)) )
        _dumpJSDScript( jsdc, jsdscript, "  script: " );
}
#endif /* JSD_DUMP */

/***************************************************************************/
static JSHashNumber
jsd_hash_script(const void *key)
{
    return ((JSHashNumber)(ptrdiff_t) key) >> 2; /* help lame MSVC1.5 on Win16 */
}

static void *
jsd_alloc_script_table(void *priv, size_t size)
{
    return malloc(size);
}

static void
jsd_free_script_table(void *priv, void *item, size_t size)
{
    free(item);
}

static JSHashEntry *
jsd_alloc_script_entry(void *priv, const void *item)
{
    return (JSHashEntry*) malloc(sizeof(JSHashEntry));
}

static void
jsd_free_script_entry(void *priv, JSHashEntry *he, unsigned flag)
{
    if (flag == HT_FREE_ENTRY)
    {
        _destroyJSDScript((JSDContext*) priv, (JSDScript*) he->value);
        free(he);
    }
}

static JSHashAllocOps script_alloc_ops = {
    jsd_alloc_script_table, jsd_free_script_table,
    jsd_alloc_script_entry, jsd_free_script_entry
};

#ifndef JSD_SCRIPT_HASH_SIZE
#define JSD_SCRIPT_HASH_SIZE 1024
#endif

JSBool
jsd_InitScriptManager(JSDContext* jsdc)
{
    JS_INIT_CLIST(&jsdc->scripts);
    jsdc->scriptsTable = JS_NewHashTable(JSD_SCRIPT_HASH_SIZE, jsd_hash_script,
                                         JS_CompareValues, JS_CompareValues,
                                         &script_alloc_ops, (void*) jsdc);
    return !!jsdc->scriptsTable;
}

void
jsd_DestroyScriptManager(JSDContext* jsdc)
{
    JSD_LOCK_SCRIPTS(jsdc);
    if (jsdc->scriptsTable)
        JS_HashTableDestroy(jsdc->scriptsTable);
    JSD_UNLOCK_SCRIPTS(jsdc);
}

JSDScript*
jsd_FindJSDScript( JSDContext*  jsdc,
                   JSScript     *script )
{
    JS_ASSERT(JSD_SCRIPTS_LOCKED(jsdc));
    return (JSDScript*) JS_HashTableLookup(jsdc->scriptsTable, (void *)script);
}

JSDScript *
jsd_FindOrCreateJSDScript(JSDContext    *jsdc,
                          JSContext     *cx,
                          JSScript      *script_,
                          JSAbstractFramePtr frame)
{
    JS::RootedScript script(cx, script_);
    JSDScript *jsdscript;
    JS_ASSERT(JSD_SCRIPTS_LOCKED(jsdc));

    jsdscript = jsd_FindJSDScript(jsdc, script);
    if (jsdscript)
        return jsdscript;

    /* Fallback for unknown scripts: create a new script. */
    if (!frame) {
        JSBrokenFrameIterator iter(cx);
        if (!iter.done())
            frame = iter.abstractFramePtr();
    }
    if (frame)
        jsdscript = _newJSDScript(jsdc, cx, script);

    return jsdscript;
}

JSDProfileData*
jsd_GetScriptProfileData(JSDContext* jsdc, JSDScript *script)
{
    if (!script->profileData)
        script->profileData = (JSDProfileData*)calloc(1, sizeof(JSDProfileData));

    return script->profileData;
}

uint32_t
jsd_GetScriptFlags(JSDContext *jsdc, JSDScript *script)
{
    return script->flags;
}

void
jsd_SetScriptFlags(JSDContext *jsdc, JSDScript *script, uint32_t flags)
{
    script->flags = flags;
}

unsigned
jsd_GetScriptCallCount(JSDContext* jsdc, JSDScript *script)
{
    if (script->profileData)
        return script->profileData->callCount;

    return 0;
}

unsigned
jsd_GetScriptMaxRecurseDepth(JSDContext* jsdc, JSDScript *script)
{
    if (script->profileData)
        return script->profileData->maxRecurseDepth;

    return 0;
}

double
jsd_GetScriptMinExecutionTime(JSDContext* jsdc, JSDScript *script)
{
    if (script->profileData)
        return script->profileData->minExecutionTime;

    return 0.0;
}

double
jsd_GetScriptMaxExecutionTime(JSDContext* jsdc, JSDScript *script)
{
    if (script->profileData)
        return script->profileData->maxExecutionTime;

    return 0.0;
}

double
jsd_GetScriptTotalExecutionTime(JSDContext* jsdc, JSDScript *script)
{
    if (script->profileData)
        return script->profileData->totalExecutionTime;

    return 0.0;
}

double
jsd_GetScriptMinOwnExecutionTime(JSDContext* jsdc, JSDScript *script)
{
    if (script->profileData)
        return script->profileData->minOwnExecutionTime;

    return 0.0;
}

double
jsd_GetScriptMaxOwnExecutionTime(JSDContext* jsdc, JSDScript *script)
{
    if (script->profileData)
        return script->profileData->maxOwnExecutionTime;

    return 0.0;
}

double
jsd_GetScriptTotalOwnExecutionTime(JSDContext* jsdc, JSDScript *script)
{
    if (script->profileData)
        return script->profileData->totalOwnExecutionTime;

    return 0.0;
}

void
jsd_ClearScriptProfileData(JSDContext* jsdc, JSDScript *script)
{
    if (script->profileData)
    {
        free(script->profileData);
        script->profileData = NULL;
    }
}    

JSScript *
jsd_GetJSScript (JSDContext *jsdc, JSDScript *script)
{
    return script->script;
}

JSFunction *
jsd_GetJSFunction (JSDContext *jsdc, JSDScript *script)
{
    AutoSafeJSContext cx; // NB: Actually unused.
    return JS_GetScriptFunction(cx, script->script);
}

JSDScript*
jsd_IterateScripts(JSDContext* jsdc, JSDScript **iterp)
{
    JSDScript *jsdscript = *iterp;
    
    JS_ASSERT(JSD_SCRIPTS_LOCKED(jsdc));

    if( !jsdscript )
        jsdscript = (JSDScript *)jsdc->scripts.next;
    if( jsdscript == (JSDScript *)&jsdc->scripts )
        return NULL;
    *iterp = (JSDScript*) jsdscript->links.next;
    return jsdscript;
}

void *
jsd_SetScriptPrivate(JSDScript *jsdscript, void *data)
{
    void *rval = jsdscript->data;
    jsdscript->data = data;
    return rval;
}

void *
jsd_GetScriptPrivate(JSDScript *jsdscript)
{
    return jsdscript->data;
}

JSBool
jsd_IsActiveScript(JSDContext* jsdc, JSDScript *jsdscript)
{
    JSDScript *current;

    JS_ASSERT(JSD_SCRIPTS_LOCKED(jsdc));

    for( current = (JSDScript *)jsdc->scripts.next;
         current != (JSDScript *)&jsdc->scripts;
         current = (JSDScript *)current->links.next )
    {
        if(jsdscript == current)
            return JS_TRUE;
    }
    return JS_FALSE;
}        

const char*
jsd_GetScriptFilename(JSDContext* jsdc, JSDScript *jsdscript)
{
    return jsdscript->url;
}

JSString*
jsd_GetScriptFunctionId(JSDContext* jsdc, JSDScript *jsdscript)
{
    JSString* str;
    JSFunction *fun = jsd_GetJSFunction(jsdc, jsdscript);

    if( ! fun )
        return NULL;
    str = JS_GetFunctionId(fun);

    /* For compatibility we return "anonymous", not an empty string here. */
    return str ? str : JS_GetAnonymousString(jsdc->jsrt);
}

unsigned
jsd_GetScriptBaseLineNumber(JSDContext* jsdc, JSDScript *jsdscript)
{
    return jsdscript->lineBase;
}

unsigned
jsd_GetScriptLineExtent(JSDContext* jsdc, JSDScript *jsdscript)
{
    AutoSafeJSContext cx;
    JSAutoCompartment ac(cx, jsdc->glob); // Just in case.
    if( NOT_SET_YET == (int)jsdscript->lineExtent )
        jsdscript->lineExtent = JS_GetScriptLineExtent(cx, jsdscript->script);
    return jsdscript->lineExtent;
}

uintptr_t
jsd_GetClosestPC(JSDContext* jsdc, JSDScript* jsdscript, unsigned line)
{
    uintptr_t pc;

    if( !jsdscript )
        return 0;
#ifdef LIVEWIRE
    if( jsdscript->lwscript )
    {
        unsigned newline;
        jsdlw_RawToProcessedLineNumber(jsdc, jsdscript, line, &newline);
        if( line != newline )
            line = newline;
    }
#endif

    AutoSafeJSContext cx;
    JSAutoCompartment ac(cx, jsdscript->script);
    pc = (uintptr_t) JS_LineNumberToPC(cx, jsdscript->script, line );
    return pc;
}

unsigned
jsd_GetClosestLine(JSDContext* jsdc, JSDScript* jsdscript, uintptr_t pc)
{
    unsigned first = jsdscript->lineBase;
    unsigned last = first + jsd_GetScriptLineExtent(jsdc, jsdscript) - 1;
    unsigned line = 0;

    if (pc) {
        AutoSafeJSContext cx;
        JSAutoCompartment ac(cx, jsdscript->script);
        line = JS_PCToLineNumber(cx, jsdscript->script, (jsbytecode*)pc);
    }

    if( line < first )
        return first;
    if( line > last )
        return last;

#ifdef LIVEWIRE
    if( jsdscript && jsdscript->lwscript )
    {
        unsigned newline;
        jsdlw_ProcessedToRawLineNumber(jsdc, jsdscript, line, &newline);
        line = newline;
    }
#endif

    return line;    
}

JSBool
jsd_GetLinePCs(JSDContext* jsdc, JSDScript* jsdscript,
               unsigned startLine, unsigned maxLines,
               unsigned* count, unsigned** retLines, uintptr_t** retPCs)
{
    unsigned first = jsdscript->lineBase;
    unsigned last = first + jsd_GetScriptLineExtent(jsdc, jsdscript) - 1;
    JSBool ok;
    jsbytecode **pcs;
    unsigned i;

    if (last < startLine)
        return JS_TRUE;

    AutoSafeJSContext cx;
    JSAutoCompartment ac(cx, jsdscript->script);

    ok = JS_GetLinePCs(cx, jsdscript->script,
                       startLine, maxLines,
                       count, retLines, &pcs);

    if (ok) {
        if (retPCs) {
            for (i = 0; i < *count; ++i) {
                (*retPCs)[i] = (*pcs)[i];
            }
        }

        JS_free(cx, pcs);
    }

    return ok;
}

JSBool
jsd_SetScriptHook(JSDContext* jsdc, JSD_ScriptHookProc hook, void* callerdata)
{
    JSD_LOCK();
    jsdc->scriptHook = hook;
    jsdc->scriptHookData = callerdata;
    JSD_UNLOCK();
    return JS_TRUE;
}

JSBool
jsd_GetScriptHook(JSDContext* jsdc, JSD_ScriptHookProc* hook, void** callerdata)
{
    JSD_LOCK();
    if( hook )
        *hook = jsdc->scriptHook;
    if( callerdata )
        *callerdata = jsdc->scriptHookData;
    JSD_UNLOCK();
    return JS_TRUE;
}    

JSBool
jsd_EnableSingleStepInterrupts(JSDContext* jsdc, JSDScript* jsdscript, JSBool enable)
{
    JSBool rv;
    AutoSafeJSContext cx;
    JSAutoCompartment ac(cx, jsdscript->script);
    JSD_LOCK();
    rv = JS_SetSingleStepMode(cx, jsdscript->script, enable);
    JSD_UNLOCK();
    return rv;
}


/***************************************************************************/

void
jsd_NewScriptHookProc( 
                JSContext   *cx,
                const char  *filename,      /* URL this script loads from */
                unsigned       lineno,         /* line where this script starts */
                JSScript    *script,
                JSFunction  *fun,                
                void*       callerdata )
{
    JSDScript* jsdscript = NULL;
    JSDContext* jsdc = (JSDContext*) callerdata;
    JSD_ScriptHookProc      hook;
    void*                   hookData;
    
    JSD_ASSERT_VALID_CONTEXT(jsdc);

    if( JSD_IS_DANGEROUS_THREAD(jsdc) )
        return;
    
    JSD_LOCK_SCRIPTS(jsdc);
    jsdscript = _newJSDScript(jsdc, cx, script);
    JSD_UNLOCK_SCRIPTS(jsdc);
    if( ! jsdscript )
        return;

#ifdef JSD_DUMP
    JSD_LOCK_SCRIPTS(jsdc);
    _dumpJSDScript(jsdc, jsdscript, "***NEW Script: ");
    _dumpJSDScriptList( jsdc );
    JSD_UNLOCK_SCRIPTS(jsdc);
#endif /* JSD_DUMP */

    /* local in case jsdc->scriptHook gets cleared on another thread */
    JSD_LOCK();
    hook = jsdc->scriptHook;
    if( hook )
        jsdscript->flags = jsdscript->flags | JSD_SCRIPT_CALL_DESTROY_HOOK_BIT;
    hookData = jsdc->scriptHookData;
    JSD_UNLOCK();

    if( hook )
        hook(jsdc, jsdscript, JS_TRUE, hookData);
}

void
jsd_DestroyScriptHookProc( 
                JSFreeOp    *fop,
                JSScript    *script_,
                void*       callerdata )
{
    JSDScript* jsdscript = NULL;
    JSDContext* jsdc = (JSDContext*) callerdata;
    // NB: We're called during GC, so we can't push a cx. Root directly with
    // the runtime.
    JS::RootedScript script(jsdc->jsrt, script_);
    JSD_ScriptHookProc      hook;
    void*                   hookData;

    JSD_ASSERT_VALID_CONTEXT(jsdc);

    if( JSD_IS_DANGEROUS_THREAD(jsdc) )
        return;

    JSD_LOCK_SCRIPTS(jsdc);
    jsdscript = jsd_FindJSDScript(jsdc, script);
    JSD_UNLOCK_SCRIPTS(jsdc);

    if( ! jsdscript )
        return;

#ifdef JSD_DUMP
    JSD_LOCK_SCRIPTS(jsdc);
    _dumpJSDScript(jsdc, jsdscript, "***DESTROY Script: ");
    JSD_UNLOCK_SCRIPTS(jsdc);
#endif /* JSD_DUMP */

    /* local in case hook gets cleared on another thread */
    JSD_LOCK();
    hook = (jsdscript->flags & JSD_SCRIPT_CALL_DESTROY_HOOK_BIT) ? jsdc->scriptHook : NULL;
    hookData = jsdc->scriptHookData;
    JSD_UNLOCK();

    if( hook )
        hook(jsdc, jsdscript, JS_FALSE, hookData);

    JSD_LOCK_SCRIPTS(jsdc);
    JS_HashTableRemove(jsdc->scriptsTable, (void *)script);
    JSD_UNLOCK_SCRIPTS(jsdc);

#ifdef JSD_DUMP
    JSD_LOCK_SCRIPTS(jsdc);
    _dumpJSDScriptList(jsdc);
    JSD_UNLOCK_SCRIPTS(jsdc);
#endif /* JSD_DUMP */
}                


/***************************************************************************/

static JSDExecHook*
_findHook(JSDContext* jsdc, JSDScript* jsdscript, uintptr_t pc)
{
    JSDExecHook* jsdhook;
    JSCList* list = &jsdscript->hooks;

    for( jsdhook = (JSDExecHook*)list->next;
         jsdhook != (JSDExecHook*)list;
         jsdhook = (JSDExecHook*)jsdhook->links.next )
    {
        if (jsdhook->pc == pc)
            return jsdhook;
    }
    return NULL;
}

static JSBool
_isActiveHook(JSDContext* jsdc, JSScript *script, JSDExecHook* jsdhook)
{
    JSDExecHook* current;
    JSCList* list;
    JSDScript* jsdscript;

    JSD_LOCK_SCRIPTS(jsdc);
    jsdscript = jsd_FindJSDScript(jsdc, script);
    if( ! jsdscript)
    {
        JSD_UNLOCK_SCRIPTS(jsdc);
        return JS_FALSE;
    }

    list = &jsdscript->hooks;

    for( current = (JSDExecHook*)list->next;
         current != (JSDExecHook*)list;
         current = (JSDExecHook*)current->links.next )
    {
        if(current == jsdhook)
        {
            JSD_UNLOCK_SCRIPTS(jsdc);
            return JS_TRUE;
        }
    }
    JSD_UNLOCK_SCRIPTS(jsdc);
    return JS_FALSE;
}


JSTrapStatus
jsd_TrapHandler(JSContext *cx, JSScript *script_, jsbytecode *pc, jsval *rval,
                jsval closure)
{
    JS::RootedScript script(cx, script_);
    JSDExecHook* jsdhook = (JSDExecHook*) JSVAL_TO_PRIVATE(closure);
    JSD_ExecutionHookProc hook;
    void* hookData;
    JSDContext*  jsdc;
    JSDScript* jsdscript;

    JSD_LOCK();

    if( NULL == (jsdc = jsd_JSDContextForJSContext(cx)) ||
        ! _isActiveHook(jsdc, script, jsdhook) )
    {
        JSD_UNLOCK();
        return JSTRAP_CONTINUE;
    }

    JSD_ASSERT_VALID_EXEC_HOOK(jsdhook);
    JS_ASSERT(!jsdhook->pc || jsdhook->pc == (uintptr_t)pc);
    JS_ASSERT(jsdhook->jsdscript->script == script);
    JS_ASSERT(jsdhook->jsdscript->jsdc == jsdc);

    hook = jsdhook->hook;
    hookData = jsdhook->callerdata;
    jsdscript = jsdhook->jsdscript;

    /* do not use jsdhook-> after this point */
    JSD_UNLOCK();

    if( ! jsdc || ! jsdc->inited )
        return JSTRAP_CONTINUE;

    if( JSD_IS_DANGEROUS_THREAD(jsdc) )
        return JSTRAP_CONTINUE;

#ifdef LIVEWIRE
    if( ! jsdlw_UserCodeAtPC(jsdc, jsdscript, (uintptr_t)pc) )
        return JSTRAP_CONTINUE;
#endif

    return jsd_CallExecutionHook(jsdc, cx, JSD_HOOK_BREAKPOINT,
                                 hook, hookData, rval);
}



JSBool
jsd_SetExecutionHook(JSDContext*           jsdc, 
                     JSDScript*            jsdscript,
                     uintptr_t             pc,
                     JSD_ExecutionHookProc hook,
                     void*                 callerdata)
{
    JSDExecHook* jsdhook;
    JSBool rv;

    JSD_LOCK();
    if( ! hook )
    {
        jsd_ClearExecutionHook(jsdc, jsdscript, pc);
        JSD_UNLOCK();
        return JS_TRUE;
    }

    jsdhook = _findHook(jsdc, jsdscript, pc);
    if( jsdhook )
    {
        jsdhook->hook       = hook;
        jsdhook->callerdata = callerdata;
        JSD_UNLOCK();
        return JS_TRUE;
    }
    /* else... */

    jsdhook = (JSDExecHook*)calloc(1, sizeof(JSDExecHook));
    if( ! jsdhook ) {
        JSD_UNLOCK();
        return JS_FALSE;
    }
    jsdhook->jsdscript  = jsdscript;
    jsdhook->pc         = pc;
    jsdhook->hook       = hook;
    jsdhook->callerdata = callerdata;

    {
        AutoSafeJSContext cx;
        JSAutoCompartment ac(cx, jsdscript->script);
        rv = JS_SetTrap(cx, jsdscript->script, 
                        (jsbytecode*)pc, jsd_TrapHandler,
                        PRIVATE_TO_JSVAL(jsdhook));
    }

    if ( ! rv ) {
        free(jsdhook);
        JSD_UNLOCK();
        return JS_FALSE;
    }

    JS_APPEND_LINK(&jsdhook->links, &jsdscript->hooks);
    JSD_UNLOCK();

    return JS_TRUE;
}

JSBool
jsd_ClearExecutionHook(JSDContext*           jsdc, 
                       JSDScript*            jsdscript,
                       uintptr_t             pc)
{
    JSDExecHook* jsdhook;

    JSD_LOCK();

    jsdhook = _findHook(jsdc, jsdscript, pc);
    if( ! jsdhook )
    {
        JSD_UNLOCK();
        return JS_FALSE;
    }

    {
        AutoSafeJSContext cx;
        JSAutoCompartment ac(cx, jsdscript->script);
        JS_ClearTrap(cx, jsdscript->script, 
                     (jsbytecode*)pc, NULL, NULL );
    }

    JS_REMOVE_LINK(&jsdhook->links);
    free(jsdhook);

    JSD_UNLOCK();
    return JS_TRUE;
}

JSBool
jsd_ClearAllExecutionHooksForScript(JSDContext* jsdc, JSDScript* jsdscript)
{
    JSDExecHook* jsdhook;
    JSCList* list = &jsdscript->hooks;
    JSD_LOCK();

    while( (JSDExecHook*)list != (jsdhook = (JSDExecHook*)list->next) )
    {
        JS_REMOVE_LINK(&jsdhook->links);
        free(jsdhook);
    }

    JS_ClearScriptTraps(jsdc->jsrt, jsdscript->script);
    JSD_UNLOCK();

    return JS_TRUE;
}

JSBool
jsd_ClearAllExecutionHooks(JSDContext* jsdc)
{
    JSDScript* jsdscript;
    JSDScript* iterp = NULL;

    JSD_LOCK();
    while( NULL != (jsdscript = jsd_IterateScripts(jsdc, &iterp)) )
        jsd_ClearAllExecutionHooksForScript(jsdc, jsdscript);
    JSD_UNLOCK();
    return JS_TRUE;
}

void
jsd_ScriptCreated(JSDContext* jsdc,
                  JSContext   *cx,
                  const char  *filename,    /* URL this script loads from */
                  unsigned       lineno,       /* line where this script starts */
                  JSScript    *script,
                  JSFunction  *fun)
{
    jsd_NewScriptHookProc(cx, filename, lineno, script, fun, jsdc);
}

void
jsd_ScriptDestroyed(JSDContext* jsdc,
                    JSFreeOp    *fop,
                    JSScript    *script)
{
    jsd_DestroyScriptHookProc(fop, script, jsdc);
}
