📄 jsdbgapi.c
字号:
rt->newScriptHookData = callerdata;
}
JS_PUBLIC_API(void)
JS_SetDestroyScriptHook(JSRuntime *rt, JSDestroyScriptHook hook,
void *callerdata)
{
rt->destroyScriptHook = hook;
rt->destroyScriptHookData = callerdata;
}
/***************************************************************************/
JS_PUBLIC_API(JSBool)
JS_EvaluateUCInStackFrame(JSContext *cx, JSStackFrame *fp,
const jschar *bytes, uintN length,
const char *filename, uintN lineno,
jsval *rval)
{
uint32 flags;
JSScript *script;
JSBool ok;
/*
* XXX Hack around ancient compiler API to propagate the JSFRAME_SPECIAL
* flags to the code generator (see js_EmitTree's TOK_SEMI case).
*/
flags = fp->flags;
fp->flags |= JSFRAME_DEBUGGER | JSFRAME_EVAL;
script = JS_CompileUCScriptForPrincipals(cx, fp->scopeChain,
JS_StackFramePrincipals(cx, fp),
bytes, length, filename, lineno);
fp->flags = flags;
if (!script)
return JS_FALSE;
ok = js_Execute(cx, fp->scopeChain, script, fp,
JSFRAME_DEBUGGER | JSFRAME_EVAL, rval);
js_DestroyScript(cx, script);
return ok;
}
JS_PUBLIC_API(JSBool)
JS_EvaluateInStackFrame(JSContext *cx, JSStackFrame *fp,
const char *bytes, uintN length,
const char *filename, uintN lineno,
jsval *rval)
{
jschar *chars;
JSBool ok;
chars = js_InflateString(cx, bytes, length);
if (!chars)
return JS_FALSE;
ok = JS_EvaluateUCInStackFrame(cx, fp, chars, length, filename, lineno,
rval);
JS_free(cx, chars);
return ok;
}
/************************************************************************/
/* XXXbe this all needs to be reworked to avoid requiring JSScope types. */
JS_PUBLIC_API(JSScopeProperty *)
JS_PropertyIterator(JSObject *obj, JSScopeProperty **iteratorp)
{
JSScopeProperty *sprop;
JSScope *scope;
sprop = *iteratorp;
scope = OBJ_SCOPE(obj);
/* XXXbe minor(?) incompatibility: iterate in reverse definition order */
if (!sprop) {
sprop = SCOPE_LAST_PROP(scope);
} else {
while ((sprop = sprop->parent) != NULL) {
if (!SCOPE_HAD_MIDDLE_DELETE(scope))
break;
if (SCOPE_HAS_PROPERTY(scope, sprop))
break;
}
}
*iteratorp = sprop;
return sprop;
}
JS_PUBLIC_API(JSBool)
JS_GetPropertyDesc(JSContext *cx, JSObject *obj, JSScopeProperty *sprop,
JSPropertyDesc *pd)
{
JSPropertyOp getter;
JSScope *scope;
JSScopeProperty *aprop;
jsval lastException;
JSBool wasThrowing;
pd->id = ID_TO_VALUE(sprop->id);
wasThrowing = cx->throwing;
if (wasThrowing) {
lastException = cx->exception;
if (JSVAL_IS_GCTHING(lastException) &&
!js_AddRoot(cx, &lastException, "lastException")) {
return JS_FALSE;
}
cx->throwing = JS_FALSE;
}
if (!js_GetProperty(cx, obj, sprop->id, &pd->value)) {
if (!cx->throwing) {
pd->flags = JSPD_ERROR;
pd->value = JSVAL_VOID;
} else {
pd->flags = JSPD_EXCEPTION;
pd->value = cx->exception;
}
} else {
pd->flags = 0;
}
cx->throwing = wasThrowing;
if (wasThrowing) {
cx->exception = lastException;
if (JSVAL_IS_GCTHING(lastException))
js_RemoveRoot(cx->runtime, &lastException);
}
getter = sprop->getter;
pd->flags |= ((sprop->attrs & JSPROP_ENUMERATE) ? JSPD_ENUMERATE : 0)
| ((sprop->attrs & JSPROP_READONLY) ? JSPD_READONLY : 0)
| ((sprop->attrs & JSPROP_PERMANENT) ? JSPD_PERMANENT : 0)
#if JS_HAS_CALL_OBJECT
| ((getter == js_GetCallVariable) ? JSPD_VARIABLE : 0)
#endif /* JS_HAS_CALL_OBJECT */
| ((getter == js_GetArgument) ? JSPD_ARGUMENT : 0)
| ((getter == js_GetLocalVariable) ? JSPD_VARIABLE : 0);
#if JS_HAS_CALL_OBJECT
/* for Call Object 'real' getter isn't passed in to us */
if (OBJ_GET_CLASS(cx, obj) == &js_CallClass &&
getter == js_CallClass.getProperty) {
/*
* Property of a heavyweight function's variable object having the
* class-default getter. It's either an argument if permanent, or a
* nested function if impermanent. Local variables have a special
* getter (js_GetCallVariable, tested above) and setter, and not the
* class default.
*/
pd->flags |= (sprop->attrs & JSPROP_PERMANENT)
? JSPD_ARGUMENT
: JSPD_VARIABLE;
}
#endif /* JS_HAS_CALL_OBJECT */
pd->spare = 0;
pd->slot = (pd->flags & (JSPD_ARGUMENT | JSPD_VARIABLE))
? sprop->shortid
: 0;
pd->alias = JSVAL_VOID;
scope = OBJ_SCOPE(obj);
if (SPROP_HAS_VALID_SLOT(sprop, scope)) {
for (aprop = SCOPE_LAST_PROP(scope); aprop; aprop = aprop->parent) {
if (aprop != sprop && aprop->slot == sprop->slot) {
pd->alias = ID_TO_VALUE(aprop->id);
break;
}
}
}
return JS_TRUE;
}
JS_PUBLIC_API(JSBool)
JS_GetPropertyDescArray(JSContext *cx, JSObject *obj, JSPropertyDescArray *pda)
{
JSClass *clasp;
JSScope *scope;
uint32 i, n;
JSPropertyDesc *pd;
JSScopeProperty *sprop;
clasp = OBJ_GET_CLASS(cx, obj);
if (!OBJ_IS_NATIVE(obj) || (clasp->flags & JSCLASS_NEW_ENUMERATE)) {
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
JSMSG_CANT_DESCRIBE_PROPS, clasp->name);
return JS_FALSE;
}
if (!clasp->enumerate(cx, obj))
return JS_FALSE;
/* have no props, or object's scope has not mutated from that of proto */
scope = OBJ_SCOPE(obj);
if (scope->object != obj || scope->entryCount == 0) {
pda->length = 0;
pda->array = NULL;
return JS_TRUE;
}
n = scope->entryCount;
if (n > scope->map.nslots)
n = scope->map.nslots;
pd = (JSPropertyDesc *) JS_malloc(cx, (size_t)n * sizeof(JSPropertyDesc));
if (!pd)
return JS_FALSE;
i = 0;
for (sprop = SCOPE_LAST_PROP(scope); sprop; sprop = sprop->parent) {
if (SCOPE_HAD_MIDDLE_DELETE(scope) && !SCOPE_HAS_PROPERTY(scope, sprop))
continue;
if (!js_AddRoot(cx, &pd[i].id, NULL))
goto bad;
if (!js_AddRoot(cx, &pd[i].value, NULL))
goto bad;
if (!JS_GetPropertyDesc(cx, obj, sprop, &pd[i]))
goto bad;
if ((pd[i].flags & JSPD_ALIAS) && !js_AddRoot(cx, &pd[i].alias, NULL))
goto bad;
if (++i == n)
break;
}
pda->length = i;
pda->array = pd;
return JS_TRUE;
bad:
pda->length = i + 1;
pda->array = pd;
JS_PutPropertyDescArray(cx, pda);
return JS_FALSE;
}
JS_PUBLIC_API(void)
JS_PutPropertyDescArray(JSContext *cx, JSPropertyDescArray *pda)
{
JSPropertyDesc *pd;
uint32 i;
pd = pda->array;
for (i = 0; i < pda->length; i++) {
js_RemoveRoot(cx->runtime, &pd[i].id);
js_RemoveRoot(cx->runtime, &pd[i].value);
if (pd[i].flags & JSPD_ALIAS)
js_RemoveRoot(cx->runtime, &pd[i].alias);
}
JS_free(cx, pd);
}
/************************************************************************/
JS_PUBLIC_API(JSBool)
JS_SetDebuggerHandler(JSRuntime *rt, JSTrapHandler handler, void *closure)
{
rt->debuggerHandler = handler;
rt->debuggerHandlerData = closure;
return JS_TRUE;
}
JS_PUBLIC_API(JSBool)
JS_SetSourceHandler(JSRuntime *rt, JSSourceHandler handler, void *closure)
{
rt->sourceHandler = handler;
rt->sourceHandlerData = closure;
return JS_TRUE;
}
JS_PUBLIC_API(JSBool)
JS_SetExecuteHook(JSRuntime *rt, JSInterpreterHook hook, void *closure)
{
rt->executeHook = hook;
rt->executeHookData = closure;
return JS_TRUE;
}
JS_PUBLIC_API(JSBool)
JS_SetCallHook(JSRuntime *rt, JSInterpreterHook hook, void *closure)
{
rt->callHook = hook;
rt->callHookData = closure;
return JS_TRUE;
}
JS_PUBLIC_API(JSBool)
JS_SetObjectHook(JSRuntime *rt, JSObjectHook hook, void *closure)
{
rt->objectHook = hook;
rt->objectHookData = closure;
return JS_TRUE;
}
JS_PUBLIC_API(JSBool)
JS_SetThrowHook(JSRuntime *rt, JSTrapHandler hook, void *closure)
{
rt->throwHook = hook;
rt->throwHookData = closure;
return JS_TRUE;
}
JS_PUBLIC_API(JSBool)
JS_SetDebugErrorHook(JSRuntime *rt, JSDebugErrorHook hook, void *closure)
{
rt->debugErrorHook = hook;
rt->debugErrorHookData = closure;
return JS_TRUE;
}
/************************************************************************/
JS_PUBLIC_API(size_t)
JS_GetObjectTotalSize(JSContext *cx, JSObject *obj)
{
size_t nbytes;
JSScope *scope;
nbytes = sizeof *obj + obj->map->nslots * sizeof obj->slots[0];
if (OBJ_IS_NATIVE(obj)) {
scope = OBJ_SCOPE(obj);
if (scope->object == obj) {
nbytes += sizeof *scope;
nbytes += SCOPE_CAPACITY(scope) * sizeof(JSScopeProperty *);
}
}
return nbytes;
}
static size_t
GetAtomTotalSize(JSContext *cx, JSAtom *atom)
{
size_t nbytes;
nbytes = sizeof *atom;
if (ATOM_IS_STRING(atom)) {
nbytes += sizeof(JSString);
nbytes += (ATOM_TO_STRING(atom)->length + 1) * sizeof(jschar);
} else if (ATOM_IS_DOUBLE(atom)) {
nbytes += sizeof(jsdouble);
} else if (ATOM_IS_OBJECT(atom)) {
nbytes += JS_GetObjectTotalSize(cx, ATOM_TO_OBJECT(atom));
}
return nbytes;
}
JS_PUBLIC_API(size_t)
JS_GetFunctionTotalSize(JSContext *cx, JSFunction *fun)
{
size_t nbytes, obytes;
JSObject *obj;
JSAtom *atom;
nbytes = sizeof *fun;
JS_ASSERT(fun->nrefs);
obj = fun->object;
if (obj) {
obytes = JS_GetObjectTotalSize(cx, obj);
if (fun->nrefs > 1)
obytes = JS_HOWMANY(obytes, fun->nrefs);
nbytes += obytes;
}
if (fun->script)
nbytes += JS_GetScriptTotalSize(cx, fun->script);
atom = fun->atom;
if (atom)
nbytes += GetAtomTotalSize(cx, atom);
return nbytes;
}
#include "jsemit.h"
JS_PUBLIC_API(size_t)
JS_GetScriptTotalSize(JSContext *cx, JSScript *script)
{
size_t nbytes, pbytes;
JSObject *obj;
jsatomid i;
jssrcnote *sn, *notes;
JSTryNote *tn, *tnotes;
JSPrincipals *principals;
nbytes = sizeof *script;
obj = script->object;
if (obj)
nbytes += JS_GetObjectTotalSize(cx, obj);
nbytes += script->length * sizeof script->code[0];
nbytes += script->atomMap.length * sizeof script->atomMap.vector[0];
for (i = 0; i < script->atomMap.length; i++)
nbytes += GetAtomTotalSize(cx, script->atomMap.vector[i]);
if (script->filename)
nbytes += strlen(script->filename) + 1;
notes = SCRIPT_NOTES(script);
for (sn = notes; !SN_IS_TERMINATOR(sn); sn = SN_NEXT(sn))
continue;
nbytes += (sn - notes + 1) * sizeof *sn;
tnotes = script->trynotes;
if (tnotes) {
for (tn = tnotes; tn->catchStart; tn++)
continue;
nbytes += (tn - tnotes + 1) * sizeof *tn;
}
principals = script->principals;
if (principals) {
JS_ASSERT(principals->refcount);
pbytes = sizeof *principals;
if (principals->refcount > 1)
pbytes = JS_HOWMANY(pbytes, principals->refcount);
nbytes += pbytes;
}
return nbytes;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -