Exemple #1
0
void CThreadDebugger::DestroyScriptHook(JSContext* cx, JSScript* script)
{
	uint scriptExtent = JS_GetScriptLineExtent (cx, script);
	uint baseLine = JS_GetScriptBaseLineNumber(cx, script);
	
	char* pStr = NULL;
	pStr = (char*)JS_GetScriptFilename(cx, script);
	if (pStr != NULL)
	{
		std::string fileName(pStr);

		for (uint line = baseLine; line < scriptExtent + baseLine; ++line) 
		{
			if (CheckIfMappingPresent(fileName, line))
			{
				if (m->m_LineToPCMap[fileName][line].pScript == script)
				{
					ReturnActiveBreakPoints(m->m_LineToPCMap[fileName][line].pBytecode);
					m->m_LineToPCMap[fileName].erase(line);
					if (m->m_LineToPCMap[fileName].empty())
						m->m_LineToPCMap.erase(fileName);
				}
			}
		}
	}
}
unsigned
jsd_GetScriptLineExtent(JSDContext* jsdc, JSDScript *jsdscript)
{
    if( NOT_SET_YET == (int)jsdscript->lineExtent )
        jsdscript->lineExtent = JS_GetScriptLineExtent(jsdc->dumbContext, jsdscript->script);
    return jsdscript->lineExtent;
}
Exemple #3
0
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();
		}
	}
}
nsresult
leakmonJSObjectInfo::Init(leakmonObjectsInReportTable &aObjectsInReport)
{
	mIsInitialized = PR_TRUE;

	JSContext *cx = leakmonService::GetJSContext();
	NS_ENSURE_TRUE(cx, NS_ERROR_UNEXPECTED);

	JSAutoRequest ar(cx);

	if (!JSVAL_IS_PRIMITIVE(mJSValue)) {
		JSObject *obj = JSVAL_TO_OBJECT(mJSValue);

		// All of the objects in obj's prototype chain, and all
		// objects reachable from JS_NewPropertyIterator should
		// (I think?) be in the same compartment.
		JSAutoEnterCompartment ac;
		if (!ac.enter(cx, obj)) {
			return NS_ERROR_FAILURE;
		}

		JSObject *p;

		for (p = obj; p; p = JS_GetPrototype(cx, p)) {
			// Stack-scanning protects newly-created objects
			// (etor) from GC.  (And protecting |etor|
			// should in turn protect |id|.)

			// JS_NewPropertyIterator has the nice property that it
			// avoids JS_Enumerate on native objects (where it can
			// execute code) and uses the scope properties, but doesn't
			// require this code to use the unstable OBJ_IS_NATIVE API.
			JSObject *etor = JS_NewPropertyIterator(cx, p);
			if (!etor)
			    return NS_ERROR_OUT_OF_MEMORY;

			jsid id;
			while (JS_NextProperty(cx, etor, &id) && !JSID_IS_VOID(id)) {
				nsresult rv = AppendProperty(id, cx, aObjectsInReport);
				NS_ENSURE_SUCCESS(rv, rv);
			}
		}

		if (JS_ObjectIsFunction(cx, obj)) {
			JSFunction *fun = JS_ValueToFunction(cx, mJSValue);
			NS_ENSURE_TRUE(fun, NS_ERROR_UNEXPECTED);
			JSScript *script = JS_GetFunctionScript(cx, fun);
			if (script) { // null for native code
				const char *fname = JS_GetScriptFilename(cx, script);
				// XXX Do we know the encoding of this file name?
				mFileName = NS_ConvertUTF8toUTF16(fname);

				mLineStart = JS_GetScriptBaseLineNumber(cx, script);
				mLineEnd = mLineStart + JS_GetScriptLineExtent(cx, script) - 1;
			}
		}
	}

	ValueToString(cx, mJSValue, mString);

	return NS_OK;
}