зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1479058 Part 6 - ReplayDebugger and server/client changes to support time warps, r=jimb.
--HG-- extra : rebase_source : 5972ae72f0601e3daa2506e1be3844dc77e3bafc
This commit is contained in:
Родитель
cb73c42b70
Коммит
9844ce064b
|
@ -61,6 +61,7 @@ ReplayDebugger.prototype = {
|
|||
canRewind: RecordReplayControl.canRewind,
|
||||
replayResumeBackward() { RecordReplayControl.resume(/* forward = */ false); },
|
||||
replayResumeForward() { RecordReplayControl.resume(/* forward = */ true); },
|
||||
replayTimeWarp: RecordReplayControl.timeWarp,
|
||||
replayPause: RecordReplayControl.pause,
|
||||
|
||||
addDebuggee() {},
|
||||
|
@ -293,6 +294,14 @@ ReplayDebugger.prototype = {
|
|||
}
|
||||
},
|
||||
|
||||
get replayingOnForcedPause() {
|
||||
return this._breakpointKindGetter("ForcedPause");
|
||||
},
|
||||
set replayingOnForcedPause(handler) {
|
||||
this._breakpointKindSetter("ForcedPause", handler,
|
||||
() => handler.call(this, this.getNewestFrame()));
|
||||
},
|
||||
|
||||
clearAllBreakpoints: NYI,
|
||||
|
||||
}; // ReplayDebugger.prototype
|
||||
|
|
|
@ -108,6 +108,9 @@ const ThreadActor = ActorClassWithSpec(threadSpec, {
|
|||
this._dbg.onDebuggerStatement = this.onDebuggerStatement;
|
||||
this._dbg.onNewScript = this.onNewScript;
|
||||
this._dbg.on("newGlobal", this.onNewGlobal);
|
||||
if (this._dbg.replaying) {
|
||||
this._dbg.replayingOnForcedPause = this.replayingOnForcedPause.bind(this);
|
||||
}
|
||||
// Keep the debugger disabled until a client attaches.
|
||||
this._dbg.enabled = this._state != "detached";
|
||||
}
|
||||
|
@ -645,13 +648,18 @@ const ThreadActor = ActorClassWithSpec(threadSpec, {
|
|||
_handleResumeLimit: async function(request) {
|
||||
const steppingType = request.resumeLimit.type;
|
||||
const rewinding = request.rewind;
|
||||
if (!["break", "step", "next", "finish"].includes(steppingType)) {
|
||||
if (!["break", "step", "next", "finish", "warp"].includes(steppingType)) {
|
||||
return Promise.reject({
|
||||
error: "badParameterType",
|
||||
message: "Unknown resumeLimit type"
|
||||
});
|
||||
}
|
||||
|
||||
if (steppingType == "warp") {
|
||||
// Time warp resume limits are handled by the caller.
|
||||
return true;
|
||||
}
|
||||
|
||||
const generatedLocation = this.sources.getFrameLocation(this.youngestFrame);
|
||||
const originalLocation = await this.sources.getOriginalLocation(generatedLocation);
|
||||
const { onEnterFrame, onPop, onStep } = this._makeSteppingHooks(
|
||||
|
@ -660,7 +668,8 @@ const ThreadActor = ActorClassWithSpec(threadSpec, {
|
|||
rewinding
|
||||
);
|
||||
|
||||
// Make sure there is still a frame on the stack if we are to continue stepping.
|
||||
// Make sure there is still a frame on the stack if we are to continue
|
||||
// stepping.
|
||||
const stepFrame = this._getNextStepFrame(this.youngestFrame, rewinding);
|
||||
if (stepFrame) {
|
||||
switch (steppingType) {
|
||||
|
@ -799,7 +808,9 @@ const ThreadActor = ActorClassWithSpec(threadSpec, {
|
|||
// When replaying execution in a separate process we need to explicitly
|
||||
// notify that process when to resume execution.
|
||||
if (this.dbg.replaying) {
|
||||
if (rewinding) {
|
||||
if (request && request.resumeLimit && request.resumeLimit.type == "warp") {
|
||||
this.dbg.replayTimeWarp(request.resumeLimit.target);
|
||||
} else if (rewinding) {
|
||||
this.dbg.replayResumeBackward();
|
||||
} else {
|
||||
this.dbg.replayResumeForward();
|
||||
|
@ -1635,6 +1646,29 @@ const ThreadActor = ActorClassWithSpec(threadSpec, {
|
|||
return { skip };
|
||||
},
|
||||
|
||||
/**
|
||||
* A function that the engine calls when replay has hit a point where it will
|
||||
* pause, even if no breakpoint has been set. Such points include hitting the
|
||||
* beginning or end of the replay, or reaching the target of a time warp.
|
||||
*
|
||||
* @param frame Debugger.Frame
|
||||
* The youngest stack frame, or null.
|
||||
*/
|
||||
replayingOnForcedPause: function(frame) {
|
||||
if (frame) {
|
||||
this._pauseAndRespond(frame, { type: "replayForcedPause" });
|
||||
} else {
|
||||
const packet = this._paused(frame);
|
||||
if (!packet) {
|
||||
return;
|
||||
}
|
||||
packet.why = "replayForcedPause";
|
||||
|
||||
this.conn.send(packet);
|
||||
this._pushThreadPause();
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* A function that the engine calls when an exception has been thrown and has
|
||||
* propagated to the specified frame.
|
||||
|
|
|
@ -245,6 +245,25 @@ ThreadClient.prototype = {
|
|||
return this._doInterrupt("onNext", onResponse);
|
||||
},
|
||||
|
||||
/**
|
||||
* Warp through time to an execution point in the past or future.
|
||||
*
|
||||
* @param object aTarget
|
||||
* Description of the warp destination.
|
||||
* @param function aOnResponse
|
||||
* Called with the response packet.
|
||||
*/
|
||||
timeWarp: function(target, onResponse) {
|
||||
const warp = () => {
|
||||
this._doResume({ type: "warp", target }, true, onResponse);
|
||||
};
|
||||
if (this.paused) {
|
||||
warp();
|
||||
} else {
|
||||
this.interrupt(warp);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Interrupt a running thread.
|
||||
*
|
||||
|
|
Загрузка…
Ссылка в новой задаче