diff --git a/lib/_debugger.js b/lib/_debugger.js index afee9b4a5b3..1e942dd9092 100644 --- a/lib/_debugger.js +++ b/lib/_debugger.js @@ -19,10 +19,11 @@ // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE // USE OR OTHER DEALINGS IN THE SOFTWARE. -var net = require('net'); -var repl = require('repl'); -var inherits = require('util').inherits; -var spawn = require('child_process').spawn; +var net = require('net'), + repl = require('repl'), + vm = require('vm'), + inherits = require('util').inherits, + spawn = require('child_process').spawn; exports.port = 5858; @@ -393,7 +394,6 @@ Client.prototype.listbreakpoints = function(cb) { }); }; - Client.prototype.reqSource = function(from, to, cb) { var req = { command: 'source', @@ -423,6 +423,8 @@ Client.prototype.step = function(action, count, cb) { Client.prototype.mirrorObject = function(handle, cb) { var self = this; + var val; + if (handle.type == 'object') { // The handle looks something like this: // { handle: 8, @@ -477,17 +479,19 @@ Client.prototype.mirrorObject = function(handle, cb) { if (cb) cb(mirror); }); - + return; + } else if (handle.type === 'function') { + val = function() {}; } else if (handle.value) { - process.nextTick(function() { - cb(handle.value); - }); - + val = handle.value; + } else if (handle.type === 'undefined') { + val = undefined; } else { - process.nextTick(function() { - cb(handle); - }); + val = handle; } + process.nextTick(function() { + cb(val); + }); }; @@ -609,11 +613,11 @@ function Interface() { this.stdin = process.openStdin(); - this.repl = repl.start('debug> '); + this.repl = new repl.REPLServer('debug> '); // Lift all instance methods to repl context var proto = Interface.prototype, - ignored = ['pause', 'resume', 'handleSIGINT']; + ignored = ['pause', 'resume', 'exitRepl']; for (var i in proto) { if (proto.hasOwnProperty(i) && ignored.indexOf(i) === -1) { @@ -622,11 +626,9 @@ function Interface() { } this.quitting = false; + this.debugRepl = false; this.paused = 0; - - process.on('SIGINT', function() { - self.handleSIGINT(); - }); + this.context = this.repl.context; }; Interface.prototype.pause = function() { @@ -643,13 +645,8 @@ Interface.prototype.resume = function() { this.repl.displayPrompt(); }; -Interface.prototype.handleSIGINT = function() { - this.child.kill('SIGINT'); -}; - - - Interface.prototype.handleBreak = function(r) { + this.pause(); var result = ''; if (r.breakpoints) { result += 'breakpoint'; @@ -677,7 +674,8 @@ Interface.prototype.handleBreak = function(r) { this.client.currentFrame = 0; this.client.currentScript = r.script.name; - console.log(result); + process.stdout.write(result); + this.resume(); }; @@ -744,7 +742,50 @@ Interface.prototype.version = function() { }); }; +Interface.prototype.repl = function() { + if (!this.child) throw Error('App isn\'t running... Try `run()` instead'); + var self = this; + + this.debugRepl = true; + + this.repl.rli.once('SIGINT', function() { + self.exitRepl(); + }); + + var client = this.client; + + this.repl._eval = this.repl.eval; + this.repl.eval = function(code, context, filename, callback) { + client.reqEval(code, function(res) { + if (!res.success) { + if (res.message) { + callback(new Error(res.message)); + } else { + callback(null); + } + return; + } + + client.mirrorObject(res.body, function(mirror) { + callback(null, mirror); + }); + }); + }; + + this.repl.prompt = '> '; + this.repl.rli.setPrompt('> '); + this.repl.displayPrompt(); +}; + +Interface.prototype.exitRepl = function() { + this.debugRepl = false; + this.repl.eval = this.repl._eval; + this.repl.context = this.context; + this.repl.prompt = 'debug>'; + this.repl.rli.setPrompt('debug>'); + this.repl.displayPrompt(); +}; Interface.prototype.handleCommand = function(cmd) { var self = this;