mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-17 23:35:34 +00:00
Bug 1448880
- Part 1: Always close a generator on early forced return. r=jimb
The previous code failed to close the generator in the case where JSOP_GENERATOR had run but JSOP_INITIAL_YIELD had not, a bit of sloppiness that created yet another special case. Things will get more complicated when we start keeping frames live while suspended; it's better to not have this special case. Differential Revision: https://phabricator.services.mozilla.com/D6982 --HG-- extra : moz-landing-system : lando
This commit is contained in:
parent
8ae065a347
commit
165c31f88e
@ -0,0 +1,42 @@
|
||||
// The debugger can force an early return from any instruction before the initial yield.
|
||||
|
||||
let g = newGlobal();
|
||||
g.eval(`
|
||||
function* f() {
|
||||
yield 1;
|
||||
}
|
||||
`);
|
||||
|
||||
function test(ttl) {
|
||||
let dbg = new Debugger(g);
|
||||
let exiting = false; // we ran out of time-to-live and have forced return
|
||||
let done = false; // we reached the initial yield without forced return
|
||||
dbg.onEnterFrame = frame => {
|
||||
assertEq(frame.callee.name, "f");
|
||||
frame.onEnterFrame = undefined;
|
||||
frame.onStep = () => {
|
||||
if (ttl == 0) {
|
||||
exiting = true;
|
||||
// Forced return here causes the generator object, if any, not
|
||||
// to be exposed.
|
||||
return {return: "ponies"};
|
||||
}
|
||||
ttl--;
|
||||
};
|
||||
frame.onPop = completion => {
|
||||
if (!exiting)
|
||||
done = true;
|
||||
};
|
||||
};
|
||||
|
||||
let result = g.f();
|
||||
if (done)
|
||||
assertEq(result instanceof g.f, true);
|
||||
else
|
||||
assertEq(result, "ponies");
|
||||
|
||||
dbg.enabled = false;
|
||||
return done;
|
||||
}
|
||||
|
||||
for (let ttl = 0; !test(ttl); ttl++) {}
|
@ -1543,18 +1543,20 @@ AdjustGeneratorResumptionValue(JSContext* cx, AbstractFramePtr frame,
|
||||
// on that bytecode sequence existing in the debuggee, somehow jump to
|
||||
// it, and then avoid re-entering the debugger from it.
|
||||
Rooted<GeneratorObject*> genObj(cx, GetGeneratorObjectForFrame(cx, frame));
|
||||
if (genObj && !genObj->isBeforeInitialYield()) {
|
||||
if (genObj) {
|
||||
// 1. `return <value>` creates and returns a new object,
|
||||
// `{value: <value>, done: true}`.
|
||||
JSObject *pair = CreateIterResultObject(cx, vp, true);
|
||||
if (!pair) {
|
||||
// Out of memory in debuggee code. Arrange for this to propagate.
|
||||
MOZ_ALWAYS_TRUE(cx->getPendingException(vp));
|
||||
cx->clearPendingException();
|
||||
resumeMode = ResumeMode::Throw;
|
||||
return;
|
||||
if (!genObj->isBeforeInitialYield()) {
|
||||
JSObject *pair = CreateIterResultObject(cx, vp, true);
|
||||
if (!pair) {
|
||||
// Out of memory in debuggee code. Arrange for this to propagate.
|
||||
MOZ_ALWAYS_TRUE(cx->getPendingException(vp));
|
||||
cx->clearPendingException();
|
||||
resumeMode = ResumeMode::Throw;
|
||||
return;
|
||||
}
|
||||
vp.setObject(*pair);
|
||||
}
|
||||
vp.setObject(*pair);
|
||||
|
||||
// 2. The generator must be closed.
|
||||
genObj->setClosed();
|
||||
|
Loading…
Reference in New Issue
Block a user