Bug 1448880 - Part 5: Tell removeFromFrameMapsAndClearBreakpointsIn() if we are suspending. r=jimb

Since the argument is not used yet, this too is a pure refactoring, with no
change in behavior yet.

Depends on D6985

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

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Jason Orendorff 2018-10-23 23:36:35 +00:00
parent 1e6e0fb65b
commit c031e6104d
2 changed files with 24 additions and 11 deletions

View File

@ -1070,9 +1070,26 @@ Debugger::slowPathOnLeaveFrame(JSContext* cx, AbstractFramePtr frame, jsbytecode
{
mozilla::DebugOnly<Handle<GlobalObject*>> debuggeeGlobal = cx->global();
// Determine if we are suspending this frame or popping it forever.
bool suspending = false;
Rooted<GeneratorObject*> genObj(cx);
if (frame.isGeneratorFrame()) {
// If we're leaving successfully at a yield opcode, we're probably
// suspending; the `isClosed()` check detects a debugger forced return
// from an `onStep` handler, which looks almost the same.
genObj = GetGeneratorObjectForFrame(cx, frame);
suspending =
frameOk &&
pc && (*pc == JSOP_INITIALYIELD || *pc == JSOP_YIELD || *pc == JSOP_AWAIT) &&
!genObj->isClosed();
}
bool success = false;
auto frameMapsGuard = MakeScopeExit([&] {
// Clean up all Debugger.Frame instances.
removeFromFrameMapsAndClearBreakpointsIn(cx, frame);
// Clean up all Debugger.Frame instances on exit. On suspending, pass
// the flag that says to leave those frames `.live`. Note that if
// suspending && !success, the generator is closed, not suspended.
removeFromFrameMapsAndClearBreakpointsIn(cx, frame, suspending && success);
});
// The onPop handler and associated clean up logic should not run multiple
@ -1091,13 +1108,6 @@ Debugger::slowPathOnLeaveFrame(JSContext* cx, AbstractFramePtr frame, jsbytecode
RootedValue value(cx);
Debugger::resultToCompletion(cx, frameOk, frame.returnValue(), &resumeMode, &value);
// If we are yielding or awaiting, we'll need to mark the generator as
// "running" temporarily.
Rooted<GeneratorObject*> genObj(cx);
if (frame.isFunctionFrame() && (frame.callee()->isGenerator() || frame.callee()->isAsync())) {
genObj = GetGeneratorObjectForFrame(cx, frame);
}
// This path can be hit via unwinding the stack due to over-recursion or
// OOM. In those cases, don't fire the frames' onPop handlers, because
// invoking JS will only trigger the same condition. See
@ -1151,6 +1161,7 @@ Debugger::slowPathOnLeaveFrame(JSContext* cx, AbstractFramePtr frame, jsbytecode
switch (resumeMode) {
case ResumeMode::Return:
frame.setReturnValue(value);
success = true;
return true;
case ResumeMode::Throw:
@ -7289,7 +7300,8 @@ Debugger::inFrameMaps(AbstractFramePtr frame)
}
/* static */ void
Debugger::removeFromFrameMapsAndClearBreakpointsIn(JSContext* cx, AbstractFramePtr frame)
Debugger::removeFromFrameMapsAndClearBreakpointsIn(JSContext* cx, AbstractFramePtr frame,
bool suspending)
{
forEachDebuggerFrame(frame, [&](DebuggerFrame* frameobj) {
Debugger* dbg = Debugger::fromChildJSObject(frameobj);

View File

@ -789,7 +789,8 @@ class Debugger : private mozilla::LinkedListElement<Debugger>
static const JSFunctionSpec methods[];
static const JSFunctionSpec static_methods[];
static void removeFromFrameMapsAndClearBreakpointsIn(JSContext* cx, AbstractFramePtr frame);
static void removeFromFrameMapsAndClearBreakpointsIn(JSContext* cx, AbstractFramePtr frame,
bool suspending = false);
static bool updateExecutionObservabilityOfFrames(JSContext* cx, const ExecutionObservableSet& obs,
IsObserving observing);
static bool updateExecutionObservabilityOfScripts(JSContext* cx, const ExecutionObservableSet& obs,