diff --git a/lib/_debugger.js b/lib/_debugger.js index 58e29fb16a..f8af6810e6 100644 --- a/lib/_debugger.js +++ b/lib/_debugger.js @@ -235,23 +235,64 @@ Client.prototype.reqLookup = function(refs, cb) { }); }; - +// This is like reqEval, except it will look up the expression in each of the +// scopes associated with the current frame. Client.prototype.reqEval = function(expression, cb) { var self = this; + + if (this.currentFrame == NO_FRAME) { + // Only need to eval in global scope. + this.reqFrameEval(expression, NO_FRAME, cb); + return; + } + + // Otherwise we need to get the current frame to see which scopes it has. + this.reqBacktrace(function (bt) { + var frame = bt.frames[self.currentFrame]; + + var evalFrames = frame.scopes.map(function(s) { + return bt.frames[s.index].index; + }); + + self._reqFramesEval(expression, evalFrames, cb); + }); +}; + + +// Finds the first scope in the array in which the epxression evals. +Client.prototype._reqFramesEval = function(expression, evalFrames, cb) { + if (evalFrames.length == 0) { + // Just eval in global scope. + this.reqFrameEval(expression, NO_FRAME, cb); + return; + } + + var self = this; + var i = evalFrames.shift(); + + this.reqFrameEval(expression, i, function(res) { + if (res.success) { + if (cb) cb(res); + } else { + self._reqFramesEval(expression, evalFrames, cb); + } + }); +}; + + +Client.prototype.reqFrameEval = function(expression, frame, cb) { + var self = this; var req = { command: 'evaluate', arguments: { expression: expression } }; - - if (this.currentFrame == NO_FRAME) { + if (frame == NO_FRAME) { req.arguments.global = true; } else { - req.arguments.frame = this.currentFrame; + req.arguments.frame = frame; } - console.error("currentFrame: %d", this.currentFrame); - this.req(req, function(res) { if (res.success) { self._addHandle(res.body);