JSTrapStatus jsd_CallExecutionHook(JSDContext* jsdc, JSContext *cx, unsigned type, JSD_ExecutionHookProc hook, void* hookData, jsval* rval) { unsigned hookanswer = JSD_HOOK_THROW == type ? JSD_HOOK_RETURN_CONTINUE_THROW : JSD_HOOK_RETURN_CONTINUE; JSDThreadState* jsdthreadstate; if(hook && NULL != (jsdthreadstate = jsd_NewThreadState(jsdc,cx))) { if ((type != JSD_HOOK_THROW && type != JSD_HOOK_INTERRUPTED) || jsdc->flags & JSD_MASK_TOP_FRAME_ONLY || !(jsdthreadstate->flags & TS_HAS_DISABLED_FRAME)) { /* * if it's not a throw and it's not an interrupt, * or we're only masking the top frame, * or there are no disabled frames in this stack, * then call out. */ hookanswer = hook(jsdc, jsdthreadstate, type, hookData, rval); jsd_DestroyThreadState(jsdc, jsdthreadstate); } } switch(hookanswer) { case JSD_HOOK_RETURN_ABORT: case JSD_HOOK_RETURN_HOOK_ERROR: return JSTRAP_ERROR; case JSD_HOOK_RETURN_RET_WITH_VAL: return JSTRAP_RETURN; case JSD_HOOK_RETURN_THROW_WITH_VAL: return JSTRAP_THROW; case JSD_HOOK_RETURN_CONTINUE: break; case JSD_HOOK_RETURN_CONTINUE_THROW: /* only makes sense for jsd_ThrowHandler (which init'd rval) */ JS_ASSERT(JSD_HOOK_THROW == type); return JSTRAP_THROW; default: JS_ASSERT(0); break; } return JSTRAP_CONTINUE; }
JSBool jsd_CallCallHook (JSDContext* jsdc, JSContext *cx, unsigned type, JSD_CallHookProc hook, void* hookData) { JSBool hookanswer; JSDThreadState* jsdthreadstate; hookanswer = JS_FALSE; if(hook && NULL != (jsdthreadstate = jsd_NewThreadState(jsdc, cx))) { hookanswer = hook(jsdc, jsdthreadstate, type, hookData); jsd_DestroyThreadState(jsdc, jsdthreadstate); } return hookanswer; }
jsd_ErrorReporter(JSContext *cx, const char *message, JSErrorReport *report) { JSDContextWrapper* wrapper; JSDContext* jsdc; uintN action = JSD_ERROR_REPORTER_PASS_ALONG; JSD_ErrorReporter errorReporter; void* errorReporterData; jsdc = jsd_JSDContextForJSContext(cx); if( ! jsdc ) { PR_ASSERT(0); return; } wrapper = _jsd_JSDContextWrapperForJSContext(jsdc, cx); if( ! wrapper ) { PR_ASSERT(0); return; } /* local in case hook gets cleared on another thread */ JSD_LOCK(); errorReporter = jsdc->errorReporter; errorReporterData = jsdc->errorReporterData; JSD_UNLOCK(); if( errorReporter && ! JSD_IS_DANGEROUS_THREAD(jsdc) ) action = errorReporter(jsdc, cx, message, report, errorReporterData); switch(action) { case JSD_ERROR_REPORTER_PASS_ALONG: if( wrapper->originalErrorReporter ) wrapper->originalErrorReporter(cx, message, report); break; case JSD_ERROR_REPORTER_RETURN: break; case JSD_ERROR_REPORTER_DEBUG: { JSDThreadState* jsdthreadstate; jsdthreadstate = jsd_NewThreadState(jsdc,cx); if( jsdthreadstate ) { JSD_ExecutionHookProc hook; void* hookData; /* local in case hook gets cleared on another thread */ JSD_LOCK(); hook = jsdc->debugBreakHook; hookData = jsdc->debugBreakHookData; JSD_UNLOCK(); if(hook) hook(jsdc, jsdthreadstate, JSD_HOOK_DEBUG_REQUESTED, hookData); jsd_DestroyThreadState(jsdc, jsdthreadstate); } break; } default: PR_ASSERT(0); break; } }