зеркало из https://github.com/mozilla/pjs.git
Bug 378793: Patch from Mike Moening to implement per-context debug hooks. r=me,brendan
This commit is contained in:
Родитель
381a5bcaf3
Коммит
ce916182a4
|
@ -4699,7 +4699,7 @@ JS_ExecuteScriptPart(JSContext *cx, JSObject *obj, JSScript *script,
|
|||
JSExecPart part, jsval *rval)
|
||||
{
|
||||
JSScript tmp;
|
||||
JSRuntime *rt;
|
||||
JSDebugHooks *hooks;
|
||||
JSBool ok;
|
||||
|
||||
/* Make a temporary copy of the JSScript structure and farble it a bit. */
|
||||
|
@ -4712,16 +4712,16 @@ JS_ExecuteScriptPart(JSContext *cx, JSObject *obj, JSScript *script,
|
|||
}
|
||||
|
||||
/* Tell the debugger about our temporary copy of the script structure. */
|
||||
rt = cx->runtime;
|
||||
if (rt->newScriptHook) {
|
||||
rt->newScriptHook(cx, tmp.filename, tmp.lineno, &tmp, NULL,
|
||||
rt->newScriptHookData);
|
||||
hooks = cx->debugHooks;
|
||||
if (hooks->newScriptHook) {
|
||||
hooks->newScriptHook(cx, tmp.filename, tmp.lineno, &tmp, NULL,
|
||||
hooks->newScriptHookData);
|
||||
}
|
||||
|
||||
/* Execute the farbled struct and tell the debugger to forget about it. */
|
||||
ok = JS_ExecuteScript(cx, obj, &tmp, rval);
|
||||
if (rt->destroyScriptHook)
|
||||
rt->destroyScriptHook(cx, &tmp, rt->destroyScriptHookData);
|
||||
if (hooks->destroyScriptHook)
|
||||
hooks->destroyScriptHook(cx, &tmp, hooks->destroyScriptHookData);
|
||||
return ok;
|
||||
}
|
||||
|
||||
|
|
|
@ -225,6 +225,7 @@ js_NewContext(JSRuntime *rt, size_t stackChunkSize)
|
|||
memset(cx, 0, sizeof *cx);
|
||||
|
||||
cx->runtime = rt;
|
||||
cx->debugHooks = &rt->globalDebugHooks;
|
||||
#if JS_STACK_GROWTH_DIRECTION > 0
|
||||
cx->stackLimit = (jsuword)-1;
|
||||
#endif
|
||||
|
@ -851,11 +852,11 @@ ReportError(JSContext *cx, const char *message, JSErrorReport *reportp)
|
|||
*/
|
||||
if (!js_ErrorToException(cx, message, reportp)) {
|
||||
js_ReportErrorAgain(cx, message, reportp);
|
||||
} else if (cx->runtime->debugErrorHook && cx->errorReporter) {
|
||||
JSDebugErrorHook hook = cx->runtime->debugErrorHook;
|
||||
} else if (cx->debugHooks->debugErrorHook && cx->errorReporter) {
|
||||
JSDebugErrorHook hook = cx->debugHooks->debugErrorHook;
|
||||
/* test local in case debugErrorHook changed on another thread */
|
||||
if (hook)
|
||||
hook(cx, message, reportp, cx->runtime->debugErrorHookData);
|
||||
hook(cx, message, reportp, cx->debugHooks->debugErrorHookData);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -900,9 +901,9 @@ js_ReportOutOfMemory(JSContext *cx)
|
|||
* sending the error on to the regular ErrorReporter.
|
||||
*/
|
||||
if (onError) {
|
||||
JSDebugErrorHook hook = cx->runtime->debugErrorHook;
|
||||
JSDebugErrorHook hook = cx->debugHooks->debugErrorHook;
|
||||
if (hook &&
|
||||
!hook(cx, msg, &report, cx->runtime->debugErrorHookData)) {
|
||||
!hook(cx, msg, &report, cx->debugHooks->debugErrorHookData)) {
|
||||
onError = NULL;
|
||||
}
|
||||
}
|
||||
|
@ -1202,10 +1203,10 @@ js_ReportErrorAgain(JSContext *cx, const char *message, JSErrorReport *reportp)
|
|||
* sending the error on to the regular ErrorReporter.
|
||||
*/
|
||||
if (onError) {
|
||||
JSDebugErrorHook hook = cx->runtime->debugErrorHook;
|
||||
JSDebugErrorHook hook = cx->debugHooks->debugErrorHook;
|
||||
if (hook &&
|
||||
!hook(cx, cx->lastMessage, reportp,
|
||||
cx->runtime->debugErrorHookData)) {
|
||||
cx->debugHooks->debugErrorHookData)) {
|
||||
onError = NULL;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -264,27 +264,8 @@ struct JSRuntime {
|
|||
/* List of active contexts sharing this runtime; protected by gcLock. */
|
||||
JSCList contextList;
|
||||
|
||||
/* These are used for debugging -- see jsprvtd.h and jsdbgapi.h. */
|
||||
JSTrapHandler interruptHandler;
|
||||
void *interruptHandlerData;
|
||||
JSNewScriptHook newScriptHook;
|
||||
void *newScriptHookData;
|
||||
JSDestroyScriptHook destroyScriptHook;
|
||||
void *destroyScriptHookData;
|
||||
JSTrapHandler debuggerHandler;
|
||||
void *debuggerHandlerData;
|
||||
JSSourceHandler sourceHandler;
|
||||
void *sourceHandlerData;
|
||||
JSInterpreterHook executeHook;
|
||||
void *executeHookData;
|
||||
JSInterpreterHook callHook;
|
||||
void *callHookData;
|
||||
JSObjectHook objectHook;
|
||||
void *objectHookData;
|
||||
JSTrapHandler throwHook;
|
||||
void *throwHookData;
|
||||
JSDebugErrorHook debugErrorHook;
|
||||
void *debugErrorHookData;
|
||||
/* Per runtime debug hooks -- see jsprvtd.h and jsdbgapi.h. */
|
||||
JSDebugHooks globalDebugHooks;
|
||||
|
||||
/* More debugging state, see jsdbgapi.c. */
|
||||
JSCList trapList;
|
||||
|
@ -786,6 +767,9 @@ struct JSContext {
|
|||
|
||||
/* Stack of thread-stack-allocated temporary GC roots. */
|
||||
JSTempValueRooter *tempValueRooters;
|
||||
|
||||
/* Debug hooks associated with the current context. */
|
||||
JSDebugHooks *debugHooks;
|
||||
};
|
||||
|
||||
#ifdef JS_THREADSAFE
|
||||
|
|
|
@ -296,8 +296,8 @@ JS_HandleTrap(JSContext *cx, JSScript *script, jsbytecode *pc, jsval *rval)
|
|||
JS_PUBLIC_API(JSBool)
|
||||
JS_SetInterrupt(JSRuntime *rt, JSTrapHandler handler, void *closure)
|
||||
{
|
||||
rt->interruptHandler = handler;
|
||||
rt->interruptHandlerData = closure;
|
||||
rt->globalDebugHooks.interruptHandler = handler;
|
||||
rt->globalDebugHooks.interruptHandlerData = closure;
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
|
@ -305,11 +305,11 @@ JS_PUBLIC_API(JSBool)
|
|||
JS_ClearInterrupt(JSRuntime *rt, JSTrapHandler *handlerp, void **closurep)
|
||||
{
|
||||
if (handlerp)
|
||||
*handlerp = (JSTrapHandler)rt->interruptHandler;
|
||||
*handlerp = (JSTrapHandler)rt->globalDebugHooks.interruptHandler;
|
||||
if (closurep)
|
||||
*closurep = rt->interruptHandlerData;
|
||||
rt->interruptHandler = 0;
|
||||
rt->interruptHandlerData = 0;
|
||||
*closurep = rt->globalDebugHooks.interruptHandlerData;
|
||||
rt->globalDebugHooks.interruptHandler = 0;
|
||||
rt->globalDebugHooks.interruptHandlerData = 0;
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
|
@ -1115,16 +1115,16 @@ JS_GetScriptVersion(JSContext *cx, JSScript *script)
|
|||
JS_PUBLIC_API(void)
|
||||
JS_SetNewScriptHook(JSRuntime *rt, JSNewScriptHook hook, void *callerdata)
|
||||
{
|
||||
rt->newScriptHook = hook;
|
||||
rt->newScriptHookData = callerdata;
|
||||
rt->globalDebugHooks.newScriptHook = hook;
|
||||
rt->globalDebugHooks.newScriptHookData = callerdata;
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(void)
|
||||
JS_SetDestroyScriptHook(JSRuntime *rt, JSDestroyScriptHook hook,
|
||||
void *callerdata)
|
||||
{
|
||||
rt->destroyScriptHook = hook;
|
||||
rt->destroyScriptHookData = callerdata;
|
||||
rt->globalDebugHooks.destroyScriptHook = hook;
|
||||
rt->globalDebugHooks.destroyScriptHookData = callerdata;
|
||||
}
|
||||
|
||||
/***************************************************************************/
|
||||
|
@ -1375,56 +1375,56 @@ JS_PutPropertyDescArray(JSContext *cx, JSPropertyDescArray *pda)
|
|||
JS_PUBLIC_API(JSBool)
|
||||
JS_SetDebuggerHandler(JSRuntime *rt, JSTrapHandler handler, void *closure)
|
||||
{
|
||||
rt->debuggerHandler = handler;
|
||||
rt->debuggerHandlerData = closure;
|
||||
rt->globalDebugHooks.debuggerHandler = handler;
|
||||
rt->globalDebugHooks.debuggerHandlerData = closure;
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(JSBool)
|
||||
JS_SetSourceHandler(JSRuntime *rt, JSSourceHandler handler, void *closure)
|
||||
{
|
||||
rt->sourceHandler = handler;
|
||||
rt->sourceHandlerData = closure;
|
||||
rt->globalDebugHooks.sourceHandler = handler;
|
||||
rt->globalDebugHooks.sourceHandlerData = closure;
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(JSBool)
|
||||
JS_SetExecuteHook(JSRuntime *rt, JSInterpreterHook hook, void *closure)
|
||||
{
|
||||
rt->executeHook = hook;
|
||||
rt->executeHookData = closure;
|
||||
rt->globalDebugHooks.executeHook = hook;
|
||||
rt->globalDebugHooks.executeHookData = closure;
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(JSBool)
|
||||
JS_SetCallHook(JSRuntime *rt, JSInterpreterHook hook, void *closure)
|
||||
{
|
||||
rt->callHook = hook;
|
||||
rt->callHookData = closure;
|
||||
rt->globalDebugHooks.callHook = hook;
|
||||
rt->globalDebugHooks.callHookData = closure;
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(JSBool)
|
||||
JS_SetObjectHook(JSRuntime *rt, JSObjectHook hook, void *closure)
|
||||
{
|
||||
rt->objectHook = hook;
|
||||
rt->objectHookData = closure;
|
||||
rt->globalDebugHooks.objectHook = hook;
|
||||
rt->globalDebugHooks.objectHookData = closure;
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(JSBool)
|
||||
JS_SetThrowHook(JSRuntime *rt, JSTrapHandler hook, void *closure)
|
||||
{
|
||||
rt->throwHook = hook;
|
||||
rt->throwHookData = closure;
|
||||
rt->globalDebugHooks.throwHook = hook;
|
||||
rt->globalDebugHooks.throwHookData = closure;
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(JSBool)
|
||||
JS_SetDebugErrorHook(JSRuntime *rt, JSDebugErrorHook hook, void *closure)
|
||||
{
|
||||
rt->debugErrorHook = hook;
|
||||
rt->debugErrorHookData = closure;
|
||||
rt->globalDebugHooks.debugErrorHook = hook;
|
||||
rt->globalDebugHooks.debugErrorHookData = closure;
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
|
@ -1574,3 +1574,22 @@ JS_FlagSystemObject(JSContext *cx, JSObject *obj)
|
|||
flagp = js_GetGCThingFlags(obj);
|
||||
*flagp |= GCF_SYSTEM;
|
||||
}
|
||||
|
||||
/************************************************************************/
|
||||
|
||||
JS_PUBLIC_API(JSDebugHooks *)
|
||||
JS_GetGlobalDebugHooks(JSRuntime *rt)
|
||||
{
|
||||
return &rt->globalDebugHooks;
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(JSDebugHooks *)
|
||||
JS_SetContextDebugHooks(JSContext *cx, JSDebugHooks *hooks)
|
||||
{
|
||||
JSDebugHooks *old;
|
||||
|
||||
JS_ASSERT(hooks);
|
||||
old = cx->debugHooks;
|
||||
cx->debugHooks = hooks;
|
||||
return old;
|
||||
}
|
||||
|
|
|
@ -404,6 +404,14 @@ JS_IsSystemObject(JSContext *cx, JSObject *obj);
|
|||
extern JS_PUBLIC_API(void)
|
||||
JS_FlagSystemObject(JSContext *cx, JSObject *obj);
|
||||
|
||||
/************************************************************************/
|
||||
|
||||
extern JS_PUBLIC_API(JSDebugHooks *)
|
||||
JS_GetGlobalDebugHooks(JSRuntime *rt);
|
||||
|
||||
extern JS_PUBLIC_API(JSDebugHooks *)
|
||||
JS_SetContextDebugHooks(JSContext *cx, JSDebugHooks *hooks);
|
||||
|
||||
JS_END_EXTERN_C
|
||||
|
||||
#endif /* jsdbgapi_h___ */
|
||||
|
|
|
@ -1208,7 +1208,7 @@ have_fun:
|
|||
cx->fp = &frame;
|
||||
|
||||
/* Init these now in case we goto out before first hook call. */
|
||||
hook = cx->runtime->callHook;
|
||||
hook = cx->debugHooks->callHook;
|
||||
hookData = NULL;
|
||||
|
||||
/* Check for argument slots required by the function. */
|
||||
|
@ -1287,7 +1287,7 @@ have_fun:
|
|||
|
||||
/* call the hook if present */
|
||||
if (hook && (native || script))
|
||||
hookData = hook(cx, &frame, JS_TRUE, 0, cx->runtime->callHookData);
|
||||
hookData = hook(cx, &frame, JS_TRUE, 0, cx->debugHooks->callHookData);
|
||||
|
||||
/* Call the function, either a native method or an interpreted script. */
|
||||
if (native) {
|
||||
|
@ -1331,7 +1331,7 @@ have_fun:
|
|||
|
||||
out:
|
||||
if (hookData) {
|
||||
hook = cx->runtime->callHook;
|
||||
hook = cx->debugHooks->callHook;
|
||||
if (hook)
|
||||
hook(cx, &frame, JS_FALSE, &ok, hookData);
|
||||
}
|
||||
|
@ -1482,7 +1482,7 @@ js_Execute(JSContext *cx, JSObject *chain, JSScript *script,
|
|||
JSObject *obj, *tmp;
|
||||
JSBool ok;
|
||||
|
||||
hook = cx->runtime->executeHook;
|
||||
hook = cx->debugHooks->executeHook;
|
||||
hookData = mark = NULL;
|
||||
oldfp = cx->fp;
|
||||
frame.script = script;
|
||||
|
@ -1555,8 +1555,10 @@ js_Execute(JSContext *cx, JSObject *chain, JSScript *script,
|
|||
}
|
||||
|
||||
cx->fp = &frame;
|
||||
if (hook)
|
||||
hookData = hook(cx, &frame, JS_TRUE, 0, cx->runtime->executeHookData);
|
||||
if (hook) {
|
||||
hookData = hook(cx, &frame, JS_TRUE, 0,
|
||||
cx->debugHooks->executeHookData);
|
||||
}
|
||||
|
||||
/*
|
||||
* Use frame.rval, not result, so the last result stays rooted across any
|
||||
|
@ -1566,7 +1568,7 @@ js_Execute(JSContext *cx, JSObject *chain, JSScript *script,
|
|||
*result = frame.rval;
|
||||
|
||||
if (hookData) {
|
||||
hook = cx->runtime->executeHook;
|
||||
hook = cx->debugHooks->executeHook;
|
||||
if (hook)
|
||||
hook(cx, &frame, JS_FALSE, &ok, hookData);
|
||||
}
|
||||
|
@ -2255,13 +2257,13 @@ js_Interpret(JSContext *cx, jsbytecode *pc, jsval *result)
|
|||
# define LOAD_JUMP_TABLE() /* nothing */
|
||||
#endif
|
||||
|
||||
#define LOAD_INTERRUPT_HANDLER(rt) \
|
||||
#define LOAD_INTERRUPT_HANDLER(cx) \
|
||||
JS_BEGIN_MACRO \
|
||||
interruptHandler = (rt)->interruptHandler; \
|
||||
interruptHandler = (cx)->debugHooks->interruptHandler; \
|
||||
LOAD_JUMP_TABLE(); \
|
||||
JS_END_MACRO
|
||||
|
||||
LOAD_INTERRUPT_HANDLER(rt);
|
||||
LOAD_INTERRUPT_HANDLER(cx);
|
||||
|
||||
/* Check for too much js_Interpret nesting, or too deep a C stack. */
|
||||
++cx->interpLevel;
|
||||
|
@ -2327,7 +2329,7 @@ js_Interpret(JSContext *cx, jsbytecode *pc, jsval *result)
|
|||
interrupt:
|
||||
SAVE_SP_AND_PC(fp);
|
||||
switch (interruptHandler(cx, script, pc, &rval,
|
||||
rt->interruptHandlerData)) {
|
||||
cx->debugHooks->interruptHandlerData)) {
|
||||
case JSTRAP_ERROR:
|
||||
ok = JS_FALSE;
|
||||
goto out;
|
||||
|
@ -2343,7 +2345,7 @@ interrupt:
|
|||
goto out;
|
||||
default:;
|
||||
}
|
||||
LOAD_INTERRUPT_HANDLER(rt);
|
||||
LOAD_INTERRUPT_HANDLER(cx);
|
||||
}
|
||||
|
||||
JS_ASSERT((uintN)op < (uintN)JSOP_LIMIT);
|
||||
|
@ -2386,7 +2388,7 @@ interrupt:
|
|||
if (interruptHandler) {
|
||||
SAVE_SP_AND_PC(fp);
|
||||
switch (interruptHandler(cx, script, pc, &rval,
|
||||
rt->interruptHandlerData)) {
|
||||
cx->debugHooks->interruptHandlerData)) {
|
||||
case JSTRAP_ERROR:
|
||||
ok = JS_FALSE;
|
||||
goto out;
|
||||
|
@ -2402,7 +2404,7 @@ interrupt:
|
|||
goto out;
|
||||
default:;
|
||||
}
|
||||
LOAD_INTERRUPT_HANDLER(rt);
|
||||
LOAD_INTERRUPT_HANDLER(cx);
|
||||
}
|
||||
|
||||
switch (op) {
|
||||
|
@ -2519,11 +2521,11 @@ interrupt:
|
|||
}
|
||||
|
||||
if (hookData) {
|
||||
JSInterpreterHook hook = rt->callHook;
|
||||
JSInterpreterHook hook = cx->debugHooks->callHook;
|
||||
if (hook) {
|
||||
SAVE_SP_AND_PC(fp);
|
||||
hook(cx, fp, JS_FALSE, &ok, hookData);
|
||||
LOAD_INTERRUPT_HANDLER(rt);
|
||||
LOAD_INTERRUPT_HANDLER(cx);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3423,7 +3425,7 @@ interrupt:
|
|||
if (!ok)
|
||||
goto out;
|
||||
RESTORE_SP(fp);
|
||||
LOAD_INTERRUPT_HANDLER(rt);
|
||||
LOAD_INTERRUPT_HANDLER(cx);
|
||||
obj = JSVAL_TO_OBJECT(*vp);
|
||||
len = js_CodeSpec[op].length;
|
||||
DO_NEXT_OP(len);
|
||||
|
@ -3939,12 +3941,12 @@ interrupt:
|
|||
SAVE_SP(&newifp->frame);
|
||||
|
||||
/* Call the debugger hook if present. */
|
||||
hook = rt->callHook;
|
||||
hook = cx->debugHooks->callHook;
|
||||
if (hook) {
|
||||
newifp->frame.pc = NULL;
|
||||
newifp->hookData = hook(cx, &newifp->frame, JS_TRUE, 0,
|
||||
rt->callHookData);
|
||||
LOAD_INTERRUPT_HANDLER(rt);
|
||||
cx->debugHooks->callHookData);
|
||||
LOAD_INTERRUPT_HANDLER(cx);
|
||||
} else {
|
||||
newifp->hookData = NULL;
|
||||
}
|
||||
|
@ -3989,7 +3991,7 @@ interrupt:
|
|||
|
||||
ok = js_Invoke(cx, argc, 0);
|
||||
RESTORE_SP(fp);
|
||||
LOAD_INTERRUPT_HANDLER(rt);
|
||||
LOAD_INTERRUPT_HANDLER(cx);
|
||||
if (!ok)
|
||||
goto out;
|
||||
JS_RUNTIME_METER(rt, nonInlineCalls);
|
||||
|
@ -4025,7 +4027,7 @@ interrupt:
|
|||
SAVE_SP_AND_PC(fp);
|
||||
ok = js_Invoke(cx, argc, 0);
|
||||
RESTORE_SP(fp);
|
||||
LOAD_INTERRUPT_HANDLER(rt);
|
||||
LOAD_INTERRUPT_HANDLER(cx);
|
||||
if (!ok)
|
||||
goto out;
|
||||
if (!cx->rval2set) {
|
||||
|
@ -4479,7 +4481,7 @@ interrupt:
|
|||
JS_ASSERT(JSVAL_IS_INT(rval));
|
||||
op = (JSOp) JSVAL_TO_INT(rval);
|
||||
JS_ASSERT((uintN)op < (uintN)JSOP_LIMIT);
|
||||
LOAD_INTERRUPT_HANDLER(rt);
|
||||
LOAD_INTERRUPT_HANDLER(cx);
|
||||
DO_OP();
|
||||
case JSTRAP_RETURN:
|
||||
fp->rval = rval;
|
||||
|
@ -4491,7 +4493,7 @@ interrupt:
|
|||
goto out;
|
||||
default:;
|
||||
}
|
||||
LOAD_INTERRUPT_HANDLER(rt);
|
||||
LOAD_INTERRUPT_HANDLER(cx);
|
||||
END_CASE(JSOP_TRAP)
|
||||
|
||||
BEGIN_CASE(JSOP_ARGUMENTS)
|
||||
|
@ -5344,11 +5346,11 @@ interrupt:
|
|||
#if JS_HAS_DEBUGGER_KEYWORD
|
||||
BEGIN_CASE(JSOP_DEBUGGER)
|
||||
{
|
||||
JSTrapHandler handler = rt->debuggerHandler;
|
||||
JSTrapHandler handler = cx->debugHooks->debuggerHandler;
|
||||
if (handler) {
|
||||
SAVE_SP_AND_PC(fp);
|
||||
switch (handler(cx, script, pc, &rval,
|
||||
rt->debuggerHandlerData)) {
|
||||
cx->debugHooks->debuggerHandlerData)) {
|
||||
case JSTRAP_ERROR:
|
||||
ok = JS_FALSE;
|
||||
goto out;
|
||||
|
@ -5364,7 +5366,7 @@ interrupt:
|
|||
goto out;
|
||||
default:;
|
||||
}
|
||||
LOAD_INTERRUPT_HANDLER(rt);
|
||||
LOAD_INTERRUPT_HANDLER(cx);
|
||||
}
|
||||
}
|
||||
END_CASE(JSOP_DEBUGGER)
|
||||
|
@ -6001,10 +6003,11 @@ out:
|
|||
/*
|
||||
* Call debugger throw hook if set (XXX thread safety?).
|
||||
*/
|
||||
handler = rt->throwHook;
|
||||
handler = cx->debugHooks->throwHook;
|
||||
if (handler) {
|
||||
SAVE_SP_AND_PC(fp);
|
||||
switch (handler(cx, script, pc, &rval, rt->throwHookData)) {
|
||||
switch (handler(cx, script, pc, &rval,
|
||||
cx->debugHooks->throwHookData)) {
|
||||
case JSTRAP_ERROR:
|
||||
cx->throwing = JS_FALSE;
|
||||
goto no_catch;
|
||||
|
@ -6018,7 +6021,7 @@ out:
|
|||
case JSTRAP_CONTINUE:
|
||||
default:;
|
||||
}
|
||||
LOAD_INTERRUPT_HANDLER(rt);
|
||||
LOAD_INTERRUPT_HANDLER(cx);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -2506,9 +2506,10 @@ js_NewObject(JSContext *cx, JSClass *clasp, JSObject *proto, JSObject *parent)
|
|||
}
|
||||
}
|
||||
|
||||
if (cx->runtime->objectHook) {
|
||||
if (cx->debugHooks->objectHook) {
|
||||
JS_KEEP_ATOMS(cx->runtime);
|
||||
cx->runtime->objectHook(cx, obj, JS_TRUE, cx->runtime->objectHookData);
|
||||
cx->debugHooks->objectHook(cx, obj, JS_TRUE,
|
||||
cx->debugHooks->objectHookData);
|
||||
JS_UNKEEP_ATOMS(cx->runtime);
|
||||
}
|
||||
|
||||
|
@ -2756,8 +2757,10 @@ js_FinalizeObject(JSContext *cx, JSObject *obj)
|
|||
if (!map)
|
||||
return;
|
||||
|
||||
if (cx->runtime->objectHook)
|
||||
cx->runtime->objectHook(cx, obj, JS_FALSE, cx->runtime->objectHookData);
|
||||
if (cx->debugHooks->objectHook) {
|
||||
cx->debugHooks->objectHook(cx, obj, JS_FALSE,
|
||||
cx->debugHooks->objectHookData);
|
||||
}
|
||||
|
||||
/* Remove all watchpoints with weak links to obj. */
|
||||
JS_ClearWatchPointsForObject(cx, obj);
|
||||
|
|
|
@ -199,4 +199,27 @@ typedef JSBool
|
|||
(* JS_DLL_CALLBACK JSDebugErrorHook)(JSContext *cx, const char *message,
|
||||
JSErrorReport *report, void *closure);
|
||||
|
||||
typedef struct JSDebugHooks {
|
||||
JSTrapHandler interruptHandler;
|
||||
void *interruptHandlerData;
|
||||
JSNewScriptHook newScriptHook;
|
||||
void *newScriptHookData;
|
||||
JSDestroyScriptHook destroyScriptHook;
|
||||
void *destroyScriptHookData;
|
||||
JSTrapHandler debuggerHandler;
|
||||
void *debuggerHandlerData;
|
||||
JSSourceHandler sourceHandler;
|
||||
void *sourceHandlerData;
|
||||
JSInterpreterHook executeHook;
|
||||
void *executeHookData;
|
||||
JSInterpreterHook callHook;
|
||||
void *callHookData;
|
||||
JSObjectHook objectHook;
|
||||
void *objectHookData;
|
||||
JSTrapHandler throwHook;
|
||||
void *throwHookData;
|
||||
JSDebugErrorHook debugErrorHook;
|
||||
void *debugErrorHookData;
|
||||
} JSDebugHooks;
|
||||
|
||||
#endif /* jsprvtd_h___ */
|
||||
|
|
|
@ -251,8 +251,8 @@ js_NewBufferTokenStream(JSContext *cx, const jschar *base, size_t length)
|
|||
ts->userbuf.ptr = (jschar *)base;
|
||||
ts->tokenbuf.grow = GrowTokenBuf;
|
||||
ts->tokenbuf.data = cx;
|
||||
ts->listener = cx->runtime->sourceHandler;
|
||||
ts->listenerData = cx->runtime->sourceHandlerData;
|
||||
ts->listener = cx->debugHooks->sourceHandler;
|
||||
ts->listenerData = cx->debugHooks->sourceHandlerData;
|
||||
return ts;
|
||||
}
|
||||
|
||||
|
@ -696,14 +696,14 @@ ReportCompileErrorNumber(JSContext *cx, void *handle, uintN flags,
|
|||
onError = NULL;
|
||||
|
||||
if (onError) {
|
||||
JSDebugErrorHook hook = cx->runtime->debugErrorHook;
|
||||
JSDebugErrorHook hook = cx->debugHooks->debugErrorHook;
|
||||
|
||||
/*
|
||||
* If debugErrorHook is present then we give it a chance to veto
|
||||
* sending the error on to the regular error reporter.
|
||||
*/
|
||||
if (hook && !hook(cx, message, report,
|
||||
cx->runtime->debugErrorHookData)) {
|
||||
cx->debugHooks->debugErrorHookData)) {
|
||||
onError = NULL;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1459,29 +1459,25 @@ bad:
|
|||
JS_FRIEND_API(void)
|
||||
js_CallNewScriptHook(JSContext *cx, JSScript *script, JSFunction *fun)
|
||||
{
|
||||
JSRuntime *rt;
|
||||
JSNewScriptHook hook;
|
||||
|
||||
rt = cx->runtime;
|
||||
hook = rt->newScriptHook;
|
||||
hook = cx->debugHooks->newScriptHook;
|
||||
if (hook) {
|
||||
JS_KEEP_ATOMS(rt);
|
||||
JS_KEEP_ATOMS(cx->runtime);
|
||||
hook(cx, script->filename, script->lineno, script, fun,
|
||||
rt->newScriptHookData);
|
||||
JS_UNKEEP_ATOMS(rt);
|
||||
cx->debugHooks->newScriptHookData);
|
||||
JS_UNKEEP_ATOMS(cx->runtime);
|
||||
}
|
||||
}
|
||||
|
||||
JS_FRIEND_API(void)
|
||||
js_CallDestroyScriptHook(JSContext *cx, JSScript *script)
|
||||
{
|
||||
JSRuntime *rt;
|
||||
JSDestroyScriptHook hook;
|
||||
|
||||
rt = cx->runtime;
|
||||
hook = rt->destroyScriptHook;
|
||||
hook = cx->debugHooks->destroyScriptHook;
|
||||
if (hook)
|
||||
hook(cx, script, rt->destroyScriptHookData);
|
||||
hook(cx, script, cx->debugHooks->destroyScriptHookData);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
Загрузка…
Ссылка в новой задаче