Bug 1570178 - Part 4: Support setting onPop when the frame is not live. r=jimb

Since we're now allowing onStep when not live, it makes sense to do the same
for onPop, and since it does not have any implementation details preventing
setting it while the frame is dead, we might as well.

Differential Revision: https://phabricator.services.mozilla.com/D50432

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Logan Smyth 2019-10-28 08:27:54 +00:00
Родитель 5eb14d59ba
Коммит d9f546cf87
6 изменённых файлов: 119 добавлений и 33 удалений

Просмотреть файл

@ -1042,8 +1042,6 @@ OnPopHandler* DebuggerFrame::onPopHandler() const {
}
void DebuggerFrame::setOnPopHandler(JSContext* cx, OnPopHandler* handler) {
MOZ_ASSERT(isLive());
OnPopHandler* prior = onPopHandler();
if (handler == prior) {
return;
@ -1232,7 +1230,9 @@ bool DebuggerFrame::CallData::ToNative(JSContext* cx, unsigned argc,
// These methods do not require liveness.
bool checkLive = MyMethod != &CallData::liveGetter &&
MyMethod != &CallData::onStepGetter &&
MyMethod != &CallData::onStepSetter;
MyMethod != &CallData::onStepSetter &&
MyMethod != &CallData::onPopGetter &&
MyMethod != &CallData::onPopSetter;
RootedDebuggerFrame frame(cx,
DebuggerFrame::check(cx, args.thisv(), checkLive));

Двоичный файл не отображается.

Двоичный файл не отображается.

Просмотреть файл

@ -1,30 +0,0 @@
// Trying to set an onPop handler on a dead frame throws an exception.
var g = newGlobal({newCompartment: true});
g.eval("function f() { }");
g.eval("function g() { f(); }");
g.eval("function h() { g(); }");
g.eval("function i() { h(); }");
var dbg = new Debugger(g);
var log;
var frames = [];
dbg.onEnterFrame = function handleEnter(f) {
log += "(";
assertEq(f.live, true);
frames.push(f);
};
log = '';
g.i();
assertEq(log, "((((");
assertEq(frames.length, 4);
for (i = 0; i < frames.length; i++) {
assertEq(frames[i].live, false);
var set = false;
try {
frames[i].onPop = function unappreciated() { };
set = true; // don't assert in a 'try' block
} catch (x) {
assertEq(x instanceof Error, true);
}
assertEq(set, false);
}

Просмотреть файл

@ -0,0 +1,48 @@
// Changing onPop while the function is dead is allowed.
load(libdir + "asserts.js");
const g = newGlobal({ newCompartment: true });
const dbg = new Debugger(g);
let steps = new Set();
dbg.onDebuggerStatement = function(frame) {
// Setting 'onPop' while alive is allowed.
steps.add("debugger 1");
assertEq(frame.live, true);
frame.onPop = function() {
steps.add("onpop 1");
};
dbg.onDebuggerStatement = function() {
// Clear the 'onPop' while dead.
steps.add("debugger 2");
assertEq(frame.live, false);
// Clearing 'onPop' while dead is allowed.
frame.onPop = undefined;
// Setting 'onPop' while dead is allowed.
frame.onPop = function() {
steps.add("onpop 2");
};
};
};
g.eval(
`
function myGen() {
debugger;
}
const g = myGen();
debugger;
`
);
assertDeepEq(Array.from(steps), [
"debugger 1",
"onpop 1",
"debugger 2",
]);

Просмотреть файл

@ -0,0 +1,68 @@
// Changing onPop while the generator is suspended/dead is allowed.
load(libdir + "asserts.js");
const g = newGlobal({ newCompartment: true });
const dbg = new Debugger(g);
let steps = new Set();
dbg.onDebuggerStatement = function(frame) {
// Setting 'onStep' while alive is allowed.
steps.add("debugger 1");
assertEq(frame.live, true);
frame.onPop = function() {
steps.add("onpop 1");
};
dbg.onDebuggerStatement = function() {
// Clear the 'onPop' while suspended.
steps.add("debugger 2");
assertEq(frame.live, false);
// Clearing 'onPop' while suspended is allowed.
frame.onPop = undefined;
// Setting 'onPop' while suspended is allowed.
frame.onPop = function() {
steps.add("onpop 2");
};
dbg.onDebuggerStatement = function() {
steps.add("debugger 3");
assertEq(frame.live, false);
// Clearing 'onPop' while dead is allowed.
frame.onPop = undefined;
// Setting 'onPop' while dead is allowed.
frame.onPop = function() {
steps.add("onpop 3");
};
};
};
};
g.eval(
`
function* myGen() {
debugger;
yield;
}
const g = myGen();
g.next();
debugger;
g.next();
debugger;
`
);
assertDeepEq(Array.from(steps), [
"debugger 1",
"onpop 1",
"debugger 2",
"onpop 2",
"debugger 3",
]);