mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Add Debug.Frame.prototype.older.
This commit is contained in:
parent
03415943ee
commit
5dc65a5a16
52
js/src/jit-test/tests/debug/Frame-identity-03.js
Normal file
52
js/src/jit-test/tests/debug/Frame-identity-03.js
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
// |jit-test| debug
|
||||||
|
// Test that we create new Debug.Frames and reuse old ones correctly with recursion.
|
||||||
|
|
||||||
|
var g = newGlobal('new-compartment');
|
||||||
|
g.debuggeeGlobal = this;
|
||||||
|
g.eval("(" + function () {
|
||||||
|
function id(f) {
|
||||||
|
return ("id" in f) ? f.id : (f.id = nextid++);
|
||||||
|
}
|
||||||
|
|
||||||
|
var dbg = new Debug(debuggeeGlobal);
|
||||||
|
dbg.hooks = {
|
||||||
|
debuggerHandler: function (frame) {
|
||||||
|
var a = [];
|
||||||
|
for (; frame; frame = frame.older)
|
||||||
|
a.push(frame);
|
||||||
|
var s = '';
|
||||||
|
while (a.length)
|
||||||
|
s += id(a.pop());
|
||||||
|
results.push(s);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
} + ")();");
|
||||||
|
|
||||||
|
function cons(a, b) {
|
||||||
|
debugger;
|
||||||
|
return [a, b];
|
||||||
|
}
|
||||||
|
|
||||||
|
function tree(n) {
|
||||||
|
if (n < 2)
|
||||||
|
return n;
|
||||||
|
return cons(tree(n - 1), tree(n - 2));
|
||||||
|
}
|
||||||
|
|
||||||
|
g.eval("results = []; nextid = 0;");
|
||||||
|
debugger;
|
||||||
|
assertEq(g.results.join(","), "0");
|
||||||
|
assertEq(g.nextid, 1);
|
||||||
|
|
||||||
|
g.eval("results = [];");
|
||||||
|
tree(2);
|
||||||
|
assertEq(g.results.join(","), "012"); // 0=global, 1=tree, 2=cons
|
||||||
|
|
||||||
|
g.eval("results = []; nextid = 1;");
|
||||||
|
tree(3);
|
||||||
|
assertEq(g.results.join(","), "0123,014"); //0=global, 1=tree(3), 2=tree(2), 3=cons, 4=cons
|
||||||
|
|
||||||
|
g.eval("results = []; nextid = 1;");
|
||||||
|
tree(4);
|
||||||
|
// 0=global, 1=tree(4), 2=tree(3), 3=tree(2), 4=cons, tree(1), 5=cons, 6=tree(2), 7=cons, 8=cons
|
||||||
|
assertEq(g.results.join(","), "01234,0125,0167,018");
|
25
js/src/jit-test/tests/debug/Frame-older-01.js
Normal file
25
js/src/jit-test/tests/debug/Frame-older-01.js
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
// |jit-test| debug
|
||||||
|
// Basic call chain.
|
||||||
|
|
||||||
|
var g = newGlobal('new-compartment');
|
||||||
|
g.debuggeeGlobal = this;
|
||||||
|
g.result = null;
|
||||||
|
g.eval("(" + function () {
|
||||||
|
var dbg = new Debug(debuggeeGlobal);
|
||||||
|
dbg.hooks = {
|
||||||
|
debuggerHandler: function (frame) {
|
||||||
|
var a = [];
|
||||||
|
assertEq(frame === frame.older, false);
|
||||||
|
for (; frame; frame = frame.older)
|
||||||
|
a.push(frame.type === 'call' ? frame.callee.name : frame.type);
|
||||||
|
a.reverse();
|
||||||
|
result = a.join(", ");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
} + ")();");
|
||||||
|
|
||||||
|
function first() { return second(); }
|
||||||
|
function second() { return eval("third()"); }
|
||||||
|
function third() { debugger; }
|
||||||
|
first();
|
||||||
|
assertEq(g.result, "global, first, second, eval, third");
|
@ -149,9 +149,22 @@ Debug::init()
|
|||||||
return frames.init() && objects.init();
|
return frames.init() && objects.init();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
JS_STATIC_ASSERT(uintN(JSSLOT_DEBUGFRAME_OWNER) == uintN(JSSLOT_DEBUGOBJECT_OWNER));
|
||||||
|
|
||||||
|
Debug *
|
||||||
|
Debug::fromChildJSObject(JSObject *obj)
|
||||||
|
{
|
||||||
|
JS_ASSERT(obj->clasp == &DebugFrame_class ||
|
||||||
|
obj->clasp == &DebugObject_class ||
|
||||||
|
obj->clasp == &DebugFunction_class);
|
||||||
|
JSObject *dbgobj = &obj->getReservedSlot(JSSLOT_DEBUGOBJECT_OWNER).toObject();
|
||||||
|
return fromJSObject(dbgobj);
|
||||||
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
Debug::getScriptFrame(JSContext *cx, StackFrame *fp, Value *vp)
|
Debug::getScriptFrame(JSContext *cx, StackFrame *fp, Value *vp)
|
||||||
{
|
{
|
||||||
|
JS_ASSERT(fp->isScriptFrame());
|
||||||
FrameMap::AddPtr p = frames.lookupForAdd(fp);
|
FrameMap::AddPtr p = frames.lookupForAdd(fp);
|
||||||
if (!p) {
|
if (!p) {
|
||||||
// Create script frame. First copy the arguments.
|
// Create script frame. First copy the arguments.
|
||||||
@ -734,28 +747,12 @@ DebugFrame_getType(JSContext *cx, uintN argc, Value *vp)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
JS_STATIC_ASSERT(uintN(JSSLOT_DEBUGFRAME_OWNER) == uintN(JSSLOT_DEBUGOBJECT_OWNER));
|
|
||||||
|
|
||||||
static JSBool
|
|
||||||
DebugChild_wrapDebuggeeValue(JSContext *cx, JSObject *frameobj, Value *vp)
|
|
||||||
{
|
|
||||||
// This uses JSSLOT_DEBUGOBJECT_OWNER, but it will work for any object that
|
|
||||||
// has a pointer to the owning Debug object in reserved slot 0.
|
|
||||||
JSObject *dbgobj = &frameobj->getReservedSlot(JSSLOT_DEBUGOBJECT_OWNER).toObject();
|
|
||||||
Debug *dbg = Debug::fromJSObject(dbgobj);
|
|
||||||
if (!dbg->wrapDebuggeeValue(cx, vp)) {
|
|
||||||
vp->setUndefined();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
static JSBool
|
static JSBool
|
||||||
DebugFrame_getCallee(JSContext *cx, uintN argc, Value *vp)
|
DebugFrame_getCallee(JSContext *cx, uintN argc, Value *vp)
|
||||||
{
|
{
|
||||||
THIS_FRAME(cx, vp, "get callee", thisobj, fp);
|
THIS_FRAME(cx, vp, "get callee", thisobj, fp);
|
||||||
*vp = (fp->isFunctionFrame() && !fp->isEvalFrame()) ? fp->calleev() : NullValue();
|
*vp = (fp->isFunctionFrame() && !fp->isEvalFrame()) ? fp->calleev() : NullValue();
|
||||||
return DebugChild_wrapDebuggeeValue(cx, thisobj, vp);
|
return Debug::fromChildJSObject(thisobj)->wrapDebuggeeValue(cx, vp);
|
||||||
}
|
}
|
||||||
|
|
||||||
static JSBool
|
static JSBool
|
||||||
@ -779,7 +776,19 @@ DebugFrame_getThis(JSContext *cx, uintN argc, Value *vp)
|
|||||||
*vp = fp->thisValue();
|
*vp = fp->thisValue();
|
||||||
ac.leave();
|
ac.leave();
|
||||||
}
|
}
|
||||||
return DebugChild_wrapDebuggeeValue(cx, thisobj, vp);
|
return Debug::fromChildJSObject(thisobj)->wrapDebuggeeValue(cx, vp);
|
||||||
|
}
|
||||||
|
|
||||||
|
static JSBool
|
||||||
|
DebugFrame_getOlder(JSContext *cx, uintN argc, Value *vp)
|
||||||
|
{
|
||||||
|
THIS_FRAME(cx, vp, "get this", thisobj, thisfp);
|
||||||
|
for (StackFrame *fp = thisfp->prev(); fp; fp = fp->prev()) {
|
||||||
|
if (!fp->isDummyFrame())
|
||||||
|
return Debug::fromChildJSObject(thisobj)->getScriptFrame(cx, fp, vp);
|
||||||
|
}
|
||||||
|
vp->setNull();
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
JSBool
|
JSBool
|
||||||
@ -811,11 +820,12 @@ DebugFrame_construct(JSContext *cx, uintN argc, Value *vp)
|
|||||||
|
|
||||||
static JSPropertySpec DebugFrame_properties[] = {
|
static JSPropertySpec DebugFrame_properties[] = {
|
||||||
JS_PSG("type", DebugFrame_getType, 0),
|
JS_PSG("type", DebugFrame_getType, 0),
|
||||||
|
JS_PSG("this", DebugFrame_getThis, 0),
|
||||||
|
JS_PSG("older", DebugFrame_getOlder, 0),
|
||||||
|
JS_PSG("live", DebugFrame_getLive, 0),
|
||||||
JS_PSG("callee", DebugFrame_getCallee, 0),
|
JS_PSG("callee", DebugFrame_getCallee, 0),
|
||||||
JS_PSG("generator", DebugFrame_getGenerator, 0),
|
JS_PSG("generator", DebugFrame_getGenerator, 0),
|
||||||
JS_PSG("this", DebugFrame_getThis, 0),
|
|
||||||
JS_PSG("arguments", DebugFrame_getArguments, 0),
|
JS_PSG("arguments", DebugFrame_getArguments, 0),
|
||||||
JS_PSG("live", DebugFrame_getLive, 0),
|
|
||||||
JS_PS_END
|
JS_PS_END
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -922,7 +932,7 @@ DebugFunction_getName(JSContext *cx, uintN argc, Value *vp)
|
|||||||
THIS_DEBUGFUNCTION_REFERENT(cx, vp, "get name", funobj);
|
THIS_DEBUGFUNCTION_REFERENT(cx, vp, "get name", funobj);
|
||||||
if (JSString *name = funobj->getFunctionPrivate()->atom) {
|
if (JSString *name = funobj->getFunctionPrivate()->atom) {
|
||||||
vp->setString(name);
|
vp->setString(name);
|
||||||
return DebugChild_wrapDebuggeeValue(cx, &vp[1].toObject(), vp);
|
return Debug::fromChildJSObject(&vp[1].toObject())->wrapDebuggeeValue(cx, vp);
|
||||||
}
|
}
|
||||||
vp->setNull();
|
vp->setNull();
|
||||||
return true;
|
return true;
|
||||||
|
@ -92,7 +92,6 @@ class Debug {
|
|||||||
|
|
||||||
inline bool hasAnyLiveHooks() const;
|
inline bool hasAnyLiveHooks() const;
|
||||||
|
|
||||||
bool getScriptFrame(JSContext *cx, StackFrame *fp, Value *vp);
|
|
||||||
static void slowPathLeaveStackFrame(JSContext *cx);
|
static void slowPathLeaveStackFrame(JSContext *cx);
|
||||||
|
|
||||||
inline bool observesDebuggerStatement() const;
|
inline bool observesDebuggerStatement() const;
|
||||||
@ -104,8 +103,10 @@ class Debug {
|
|||||||
bool init();
|
bool init();
|
||||||
inline JSObject *toJSObject() const;
|
inline JSObject *toJSObject() const;
|
||||||
static inline Debug *fromJSObject(JSObject *obj);
|
static inline Debug *fromJSObject(JSObject *obj);
|
||||||
|
static Debug *fromChildJSObject(JSObject *obj);
|
||||||
|
|
||||||
|
/*********************************** Methods for interaction with the GC. */
|
||||||
|
|
||||||
// Methods for interaction with the GC.
|
|
||||||
//
|
//
|
||||||
// A Debug object is live if:
|
// A Debug object is live if:
|
||||||
// * the Debug JSObject is live (Debug::trace handles this case); OR
|
// * the Debug JSObject is live (Debug::trace handles this case); OR
|
||||||
@ -131,6 +132,8 @@ class Debug {
|
|||||||
static inline void leaveStackFrame(JSContext *cx);
|
static inline void leaveStackFrame(JSContext *cx);
|
||||||
static inline JSTrapStatus onDebuggerStatement(JSContext *cx, js::Value *vp);
|
static inline JSTrapStatus onDebuggerStatement(JSContext *cx, js::Value *vp);
|
||||||
|
|
||||||
|
/**************************************** Functions for use by jsdbg.cpp. */
|
||||||
|
|
||||||
// Precondition: *vp is a value from a debuggee compartment and cx is in
|
// Precondition: *vp is a value from a debuggee compartment and cx is in
|
||||||
// the debugger's compartment.
|
// the debugger's compartment.
|
||||||
//
|
//
|
||||||
@ -151,6 +154,8 @@ class Debug {
|
|||||||
//
|
//
|
||||||
bool unwrapDebuggeeValue(JSContext *cx, Value *vp);
|
bool unwrapDebuggeeValue(JSContext *cx, Value *vp);
|
||||||
|
|
||||||
|
// Store the Debug.Frame object for the frame fp in *vp.
|
||||||
|
bool getScriptFrame(JSContext *cx, StackFrame *fp, Value *vp);
|
||||||
};
|
};
|
||||||
|
|
||||||
bool
|
bool
|
||||||
|
Loading…
Reference in New Issue
Block a user