uintptr_t jsd_GetClosestPC(JSDContext* jsdc, JSDScript* jsdscript, unsigned line) { uintptr_t pc; JSCrossCompartmentCall *call; if( !jsdscript ) return 0; #ifdef LIVEWIRE if( jsdscript->lwscript ) { unsigned newline; jsdlw_RawToProcessedLineNumber(jsdc, jsdscript, line, &newline); if( line != newline ) line = newline; } #endif call = JS_EnterCrossCompartmentCallScript(jsdc->dumbContext, jsdscript->script); if(!call) return 0; pc = (uintptr_t) JS_LineNumberToPC(jsdc->dumbContext, jsdscript->script, line ); JS_LeaveCrossCompartmentCall(call); return pc; }
/* * call-seq: * set_trap(script, parsecode, block) * * Set the trap at +script+ and +parsecode+ to +block+ */ static VALUE set_trap(VALUE self, VALUE script, VALUE linenum, VALUE block) { JohnsonRuntime* runtime; Data_Get_Struct(self, JohnsonRuntime, runtime); JSContext * context = johnson_get_current_context(runtime); jsval compiled_js; if(!convert_to_js(runtime, script, &compiled_js)) rb_raise(rb_eRuntimeError, "Couldn't get compiled script."); JSScript * js_script = (JSScript *)JS_GetPrivate(context, JSVAL_TO_OBJECT(compiled_js)); jsbytecode * pc = JS_LineNumberToPC(context, js_script, (uintN)NUM2INT(linenum)); return JS_SetTrap(context, js_script, pc, trap_handler, (void*)block) ? Qtrue : Qfalse; }
jsuword jsd_GetClosestPC(JSDContext* jsdc, JSDScript* jsdscript, uintN line) { #ifdef LIVEWIRE if( jsdscript && jsdscript->lwscript ) { uintN newline; jsdlw_RawToProcessedLineNumber(jsdc, jsdscript, line, &newline); if( line != newline ) line = newline; } #endif return (jsuword) JS_LineNumberToPC(jsdc->dumbContext, jsdscript->script, line ); }
void CThreadDebugger::NewScriptHook(JSContext* cx, const char* filename, unsigned lineno, JSScript* script, JSFunction* UNUSED(fun), void* UNUSED(callerdata)) { uint scriptExtent = JS_GetScriptLineExtent (cx, script); std::string stringFileName(filename); if (stringFileName == "") return; for (uint line = lineno; line < scriptExtent + lineno; ++line) { // If we already have a mapping for this line, we check if the current scipt is more deeply nested. // If it isn't more deeply nested, we don't overwrite the previous mapping // The most deeply nested script is always the one that must be used! uint firstLine = 0; uint lastLine = 0; jsbytecode* oldPC = NULL; if (CheckIfMappingPresent(stringFileName, line)) { firstLine = m->m_LineToPCMap[stringFileName][line].firstLineInFunction; lastLine = m->m_LineToPCMap[stringFileName][line].lastLineInFunction; // If an entry nested equally is present too, we must overwrite it. // The same script(function) can trigger a NewScriptHook multiple times without DestroyScriptHooks between these // calls. In this case the old script becomes invalid. if (lineno < firstLine || scriptExtent + lineno > lastLine) continue; else oldPC = m->m_LineToPCMap[stringFileName][line].pBytecode; } jsbytecode* pc = JS_LineNumberToPC (cx, script, line); m->m_LineToPCMap[stringFileName][line].pBytecode = pc; m->m_LineToPCMap[stringFileName][line].pScript = script; m->m_LineToPCMap[stringFileName][line].firstLineInFunction = lineno; m->m_LineToPCMap[stringFileName][line].lastLineInFunction = lineno + scriptExtent; // If we are replacing a script, the associated traps become invalid if (lineno == firstLine && scriptExtent + lineno == lastLine) { ReturnActiveBreakPoints(oldPC); SetAllNewTraps(); } } }