1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 * JavaScript Debugging support - Hook support
13 jsd_InterruptHandler(JSContext
*cx
, JSScript
*script
, jsbytecode
*pc
, jsval
*rval
,
17 JSDContext
* jsdc
= (JSDContext
*) closure
;
18 JSD_ExecutionHookProc hook
;
21 if( ! jsdc
|| ! jsdc
->inited
)
22 return JSTRAP_CONTINUE
;
24 if( JSD_IS_DANGEROUS_THREAD(jsdc
) )
25 return JSTRAP_CONTINUE
;
27 /* local in case jsdc->interruptHook gets cleared on another thread */
29 hook
= jsdc
->interruptHook
;
30 hookData
= jsdc
->interruptHookData
;
34 return JSTRAP_CONTINUE
;
36 JSD_LOCK_SCRIPTS(jsdc
);
37 jsdscript
= jsd_FindOrCreateJSDScript(jsdc
, cx
, script
, NULL
);
38 JSD_UNLOCK_SCRIPTS(jsdc
);
40 return JSTRAP_CONTINUE
;
43 if( ! jsdlw_UserCodeAtPC(jsdc
, jsdscript
, (uintptr_t)pc
) )
44 return JSTRAP_CONTINUE
;
47 return jsd_CallExecutionHook(jsdc
, cx
, JSD_HOOK_INTERRUPTED
,
48 hook
, hookData
, rval
);
52 jsd_DebuggerHandler(JSContext
*cx
, JSScript
*script
, jsbytecode
*pc
,
53 jsval
*rval
, void *closure
)
56 JSDContext
* jsdc
= (JSDContext
*) closure
;
57 JSD_ExecutionHookProc hook
;
60 if( ! jsdc
|| ! jsdc
->inited
)
61 return JSTRAP_CONTINUE
;
63 if( JSD_IS_DANGEROUS_THREAD(jsdc
) )
64 return JSTRAP_CONTINUE
;
66 /* local in case jsdc->debuggerHook gets cleared on another thread */
68 hook
= jsdc
->debuggerHook
;
69 hookData
= jsdc
->debuggerHookData
;
72 return JSTRAP_CONTINUE
;
74 JSD_LOCK_SCRIPTS(jsdc
);
75 jsdscript
= jsd_FindOrCreateJSDScript(jsdc
, cx
, script
, NULL
);
76 JSD_UNLOCK_SCRIPTS(jsdc
);
78 return JSTRAP_CONTINUE
;
80 return jsd_CallExecutionHook(jsdc
, cx
, JSD_HOOK_DEBUGGER_KEYWORD
,
81 hook
, hookData
, rval
);
86 jsd_ThrowHandler(JSContext
*cx
, JSScript
*script
, jsbytecode
*pc
,
87 jsval
*rval
, void *closure
)
90 JSDContext
* jsdc
= (JSDContext
*) closure
;
91 JSD_ExecutionHookProc hook
;
94 if( ! jsdc
|| ! jsdc
->inited
)
95 return JSTRAP_CONTINUE
;
97 if( JSD_IS_DANGEROUS_THREAD(jsdc
) )
98 return JSTRAP_CONTINUE
;
100 /* local in case jsdc->throwHook gets cleared on another thread */
102 hook
= jsdc
->throwHook
;
103 hookData
= jsdc
->throwHookData
;
106 return JSTRAP_CONTINUE
;
108 JSD_LOCK_SCRIPTS(jsdc
);
109 jsdscript
= jsd_FindOrCreateJSDScript(jsdc
, cx
, script
, NULL
);
110 JSD_UNLOCK_SCRIPTS(jsdc
);
112 return JSTRAP_CONTINUE
;
114 JS_GetPendingException(cx
, rval
);
116 return jsd_CallExecutionHook(jsdc
, cx
, JSD_HOOK_THROW
,
117 hook
, hookData
, rval
);
121 jsd_CallExecutionHook(JSDContext
* jsdc
,
124 JSD_ExecutionHookProc hook
,
128 unsigned hookanswer
= JSD_HOOK_THROW
== type
?
129 JSD_HOOK_RETURN_CONTINUE_THROW
:
130 JSD_HOOK_RETURN_CONTINUE
;
131 JSDThreadState
* jsdthreadstate
;
133 if(hook
&& NULL
!= (jsdthreadstate
= jsd_NewThreadState(jsdc
,cx
)))
135 if ((type
!= JSD_HOOK_THROW
&& type
!= JSD_HOOK_INTERRUPTED
) ||
136 jsdc
->flags
& JSD_MASK_TOP_FRAME_ONLY
||
137 !(jsdthreadstate
->flags
& TS_HAS_DISABLED_FRAME
))
140 * if it's not a throw and it's not an interrupt,
141 * or we're only masking the top frame,
142 * or there are no disabled frames in this stack,
145 hookanswer
= hook(jsdc
, jsdthreadstate
, type
, hookData
, rval
);
146 jsd_DestroyThreadState(jsdc
, jsdthreadstate
);
152 case JSD_HOOK_RETURN_ABORT
:
153 case JSD_HOOK_RETURN_HOOK_ERROR
:
155 case JSD_HOOK_RETURN_RET_WITH_VAL
:
156 return JSTRAP_RETURN
;
157 case JSD_HOOK_RETURN_THROW_WITH_VAL
:
159 case JSD_HOOK_RETURN_CONTINUE
:
161 case JSD_HOOK_RETURN_CONTINUE_THROW
:
162 /* only makes sense for jsd_ThrowHandler (which init'd rval) */
163 JS_ASSERT(JSD_HOOK_THROW
== type
);
169 return JSTRAP_CONTINUE
;
173 jsd_CallCallHook (JSDContext
* jsdc
,
176 JSD_CallHookProc hook
,
180 JSDThreadState
* jsdthreadstate
;
182 hookanswer
= JS_FALSE
;
183 if(hook
&& NULL
!= (jsdthreadstate
= jsd_NewThreadState(jsdc
, cx
)))
185 hookanswer
= hook(jsdc
, jsdthreadstate
, type
, hookData
);
186 jsd_DestroyThreadState(jsdc
, jsdthreadstate
);
193 jsd_SetInterruptHook(JSDContext
* jsdc
,
194 JSD_ExecutionHookProc hook
,
198 jsdc
->interruptHookData
= callerdata
;
199 jsdc
->interruptHook
= hook
;
200 JS_SetInterrupt(jsdc
->jsrt
, jsd_InterruptHandler
, (void*) jsdc
);
207 jsd_ClearInterruptHook(JSDContext
* jsdc
)
210 JS_ClearInterrupt(jsdc
->jsrt
, NULL
, NULL
);
211 jsdc
->interruptHook
= NULL
;
218 jsd_SetDebugBreakHook(JSDContext
* jsdc
,
219 JSD_ExecutionHookProc hook
,
223 jsdc
->debugBreakHookData
= callerdata
;
224 jsdc
->debugBreakHook
= hook
;
231 jsd_ClearDebugBreakHook(JSDContext
* jsdc
)
234 jsdc
->debugBreakHook
= NULL
;
241 jsd_SetDebuggerHook(JSDContext
* jsdc
,
242 JSD_ExecutionHookProc hook
,
246 jsdc
->debuggerHookData
= callerdata
;
247 jsdc
->debuggerHook
= hook
;
254 jsd_ClearDebuggerHook(JSDContext
* jsdc
)
257 jsdc
->debuggerHook
= NULL
;
264 jsd_SetThrowHook(JSDContext
* jsdc
,
265 JSD_ExecutionHookProc hook
,
269 jsdc
->throwHookData
= callerdata
;
270 jsdc
->throwHook
= hook
;
277 jsd_ClearThrowHook(JSDContext
* jsdc
)
280 jsdc
->throwHook
= NULL
;
287 jsd_SetFunctionHook(JSDContext
* jsdc
,
288 JSD_CallHookProc hook
,
292 jsdc
->functionHookData
= callerdata
;
293 jsdc
->functionHook
= hook
;
300 jsd_ClearFunctionHook(JSDContext
* jsdc
)
303 jsdc
->functionHook
= NULL
;
310 jsd_SetTopLevelHook(JSDContext
* jsdc
,
311 JSD_CallHookProc hook
,
315 jsdc
->toplevelHookData
= callerdata
;
316 jsdc
->toplevelHook
= hook
;
323 jsd_ClearTopLevelHook(JSDContext
* jsdc
)
326 jsdc
->toplevelHook
= NULL
;