Add Debug.prototype.getYoungestFrame.

This commit is contained in:
Jason Orendorff 2011-05-13 22:08:26 -05:00
parent f40876f67e
commit 3cde4b2dce
4 changed files with 80 additions and 1 deletions

View File

@ -0,0 +1,20 @@
// |jit-test| debug
// getYoungestFrame basics.
load(libdir + "asserts.js");
var g = newGlobal('new-compartment');
var dbg = new Debug(g);
assertEq(dbg.getYoungestFrame(), null);
var frame;
function f() {
frame = dbg.getYoungestFrame();
assertEq(frame instanceof Debug.Frame, true);
assertEq(frame.type, "eval");
assertEq(frame.older, null);
}
g.h = this;
g.eval("h.f()");
assertEq(frame.live, false);
assertThrowsInstanceOf(function () { frame.older; }, Error);

View File

@ -0,0 +1,23 @@
// |jit-test| debug
// Hooks and Debug.prototype.getYoungestFrame produce the same Frame object.
var g = newGlobal('new-compartment');
var dbg = Debug(g);
var hits = 0;
var savedFrame, savedCallee;
dbg.hooks = {
debuggerHandler: function (frame) {
assertEq(frame, savedFrame);
assertEq(frame.live, true);
assertEq(frame.callee, savedCallee);
hits++;
}
};
g.h = function () {
savedFrame = dbg.getYoungestFrame();
savedCallee = savedFrame.callee;
assertEq(savedCallee.name, "f");
};
g.eval("function f() { h(); debugger; }");
g.f();
assertEq(hits, 1);

View File

@ -690,6 +690,20 @@ Debug::setUncaughtExceptionHook(JSContext *cx, uintN argc, Value *vp)
return true;
}
JSBool
Debug::getYoungestFrame(JSContext *cx, uintN argc, Value *vp)
{
THISOBJ(cx, vp, Debug, "getYoungestFrame", thisobj, dbg);
StackFrame *fp = cx->fp();
while (fp && !dbg->observesFrame(fp))
fp = fp->prev();
if (!fp) {
vp->setNull();
return true;
}
return dbg->getScriptFrame(cx, fp, vp);
}
JSBool
Debug::construct(JSContext *cx, uintN argc, Value *vp)
{
@ -755,6 +769,11 @@ JSPropertySpec Debug::properties[] = {
JS_PS_END
};
JSFunctionSpec Debug::methods[] = {
JS_FN("getYoungestFrame", Debug::getYoungestFrame, 0, 0),
JS_FS_END
};
// === Debug.Frame
Class DebugFrame_class = {
@ -1102,7 +1121,7 @@ JS_DefineDebugObject(JSContext *cx, JSObject *obj)
JSObject *debugCtor;
JSObject *debugProto = js_InitClass(cx, obj, objProto, &Debug::jsclass, Debug::construct, 1,
Debug::properties, NULL, NULL, NULL, &debugCtor);
Debug::properties, Debug::methods, NULL, NULL, &debugCtor);
if (!debugProto || !debugProto->ensureClassReservedSlots(cx))
return false;

View File

@ -88,8 +88,10 @@ class Debug {
static JSBool setEnabled(JSContext *cx, uintN argc, Value *vp);
static JSBool getUncaughtExceptionHook(JSContext *cx, uintN argc, Value *vp);
static JSBool setUncaughtExceptionHook(JSContext *cx, uintN argc, Value *vp);
static JSBool getYoungestFrame(JSContext *cx, uintN argc, Value *vp);
static JSBool construct(JSContext *cx, uintN argc, Value *vp);
static JSPropertySpec properties[];
static JSFunctionSpec methods[];
inline bool hasAnyLiveHooks() const;
@ -101,6 +103,9 @@ class Debug {
DebugObservesMethod observesEvent,
DebugHandleMethod handleEvent);
inline bool observesScope(JSObject *obj) const;
inline bool observesFrame(StackFrame *fp) const;
bool observesDebuggerStatement() const;
JSTrapStatus handleDebuggerStatement(JSContext *cx, Value *vp);
@ -189,6 +194,18 @@ Debug::hasAnyLiveHooks() const
return observesDebuggerStatement();
}
bool
Debug::observesScope(JSObject *obj) const
{
return observesCompartment(obj->compartment());
}
bool
Debug::observesFrame(StackFrame *fp) const
{
return observesScope(&fp->scopeChain());
}
bool
Debug::observesCompartment(JSCompartment *c) const
{