mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 749697 - Support debugging when multiple JSContexts are on the stack. Part 2, fix evcross-context eval-in-frame. r=luke.
--HG-- extra : rebase_source : 216bdac31ec88af4130ffd9ffac9bf0ebb1a9b39
This commit is contained in:
parent
617373c265
commit
1eb2ec4e0b
20
js/src/jit-test/tests/debug/cross-context-1.js
Normal file
20
js/src/jit-test/tests/debug/cross-context-1.js
Normal file
@ -0,0 +1,20 @@
|
||||
// frame.eval can evaluate code in a frame pushed in another context. Bug 749697.
|
||||
|
||||
// In other words, the debugger can see all frames on the stack, even though
|
||||
// each frame is attached to a particular JSContext and multiple JSContexts may
|
||||
// have frames on the stack.
|
||||
|
||||
var g = newGlobal('new-compartment');
|
||||
g.eval('function f(a) { debugger; evaluate("debugger;", {newContext: true}); }');
|
||||
|
||||
var dbg = new Debugger(g);
|
||||
var hits = 0;
|
||||
dbg.onDebuggerStatement = function (frame1) {
|
||||
dbg.onDebuggerStatement = function (frame2) {
|
||||
assertEq(frame1.eval("a").return, 31);
|
||||
hits++;
|
||||
};
|
||||
};
|
||||
|
||||
g.f(31);
|
||||
assertEq(hits, 1);
|
32
js/src/jit-test/tests/debug/cross-context-2.js
Normal file
32
js/src/jit-test/tests/debug/cross-context-2.js
Normal file
@ -0,0 +1,32 @@
|
||||
// The debugger can eval in any frame in the stack even if every frame was
|
||||
// pushed in a different context.
|
||||
|
||||
var g = newGlobal('new-compartment');
|
||||
g.eval('function f(a) {\n' +
|
||||
' if (a == 1)\n' +
|
||||
' debugger;\n' +
|
||||
' else\n' +
|
||||
' evaluate("f(" + a + " - 1);", {newContext: true});\n' +
|
||||
'}\n');
|
||||
var N = 9;
|
||||
|
||||
var dbg = new Debugger(g);
|
||||
var frames = [];
|
||||
var hits = 0;
|
||||
dbg.onEnterFrame = function (frame) {
|
||||
if (frame.type == "call" && frame.callee.name == "f") {
|
||||
frames.push(frame);
|
||||
frame.onPop = function () { assertEq(frames.pop(), frame); };
|
||||
}
|
||||
};
|
||||
dbg.onDebuggerStatement = function (frame) {
|
||||
assertEq(frames.length, N);
|
||||
var i = N;
|
||||
for (var f of frames)
|
||||
assertEq(f.eval('a').return, i--);
|
||||
hits++;
|
||||
};
|
||||
|
||||
g.f(N);
|
||||
assertEq(hits, 1);
|
||||
assertEq(frames.length, 0);
|
@ -822,7 +822,8 @@ ContextStack::pushExecuteFrame(JSContext *cx, JSScript *script, const Value &thi
|
||||
MaybeExtend extend;
|
||||
if (evalInFrame) {
|
||||
/* Though the prev-frame is given, need to search for prev-call. */
|
||||
StackIter iter(cx, StackIter::GO_THROUGH_SAVED);
|
||||
StackSegment &seg = cx->stack.space().containingSegment(evalInFrame);
|
||||
StackIter iter(cx->runtime, seg);
|
||||
while (!iter.isScript() || iter.fp() != evalInFrame)
|
||||
++iter;
|
||||
evalInFrameCalls = iter.calls_;
|
||||
@ -1167,8 +1168,8 @@ StackIter::settleOnNewState()
|
||||
if (op == JSOP_CALL || op == JSOP_FUNCALL) {
|
||||
unsigned argc = GET_ARGC(pc_);
|
||||
DebugOnly<unsigned> spoff = sp_ - fp_->base();
|
||||
JS_ASSERT_IF(cx_->stackIterAssertionEnabled,
|
||||
spoff == js_ReconstructStackDepth(cx_, fp_->script(), pc_));
|
||||
JS_ASSERT_IF(maybecx_ && maybecx_->stackIterAssertionEnabled,
|
||||
spoff == js_ReconstructStackDepth(maybecx_, fp_->script(), pc_));
|
||||
Value *vp = sp_ - (2 + argc);
|
||||
|
||||
CrashIfInvalidSlot(fp_, vp);
|
||||
@ -1217,7 +1218,7 @@ StackIter::settleOnNewState()
|
||||
}
|
||||
|
||||
StackIter::StackIter(JSContext *cx, SavedOption savedOption)
|
||||
: cx_(cx),
|
||||
: maybecx_(cx),
|
||||
savedOption_(savedOption)
|
||||
{
|
||||
#ifdef JS_METHODJIT
|
||||
@ -1234,6 +1235,18 @@ StackIter::StackIter(JSContext *cx, SavedOption savedOption)
|
||||
}
|
||||
}
|
||||
|
||||
StackIter::StackIter(JSRuntime *rt, StackSegment &seg)
|
||||
: maybecx_(NULL), savedOption_(STOP_AT_SAVED)
|
||||
{
|
||||
#ifdef JS_METHODJIT
|
||||
CompartmentVector &v = rt->compartments;
|
||||
for (size_t i = 0; i < v.length(); i++)
|
||||
mjit::ExpandInlineFrames(v[i]);
|
||||
#endif
|
||||
startOnSegment(&seg);
|
||||
settleOnNewState();
|
||||
}
|
||||
|
||||
StackIter &
|
||||
StackIter::operator++()
|
||||
{
|
||||
|
@ -1819,7 +1819,7 @@ class GeneratorFrameGuard : public FrameGuard
|
||||
class StackIter
|
||||
{
|
||||
friend class ContextStack;
|
||||
JSContext *cx_;
|
||||
JSContext *maybecx_;
|
||||
public:
|
||||
enum SavedOption { STOP_AT_SAVED, GO_THROUGH_SAVED };
|
||||
private:
|
||||
@ -1846,6 +1846,7 @@ class StackIter
|
||||
|
||||
public:
|
||||
StackIter(JSContext *cx, SavedOption = STOP_AT_SAVED);
|
||||
StackIter(JSRuntime *rt, StackSegment &seg);
|
||||
|
||||
bool done() const { return state_ == DONE; }
|
||||
StackIter &operator++();
|
||||
|
Loading…
Reference in New Issue
Block a user