diff --git a/lib/repl.js b/lib/repl.js index 52de3974a4..43d03dffd6 100644 --- a/lib/repl.js +++ b/lib/repl.js @@ -13,14 +13,25 @@ // repl.start("node > ").scope.foo = "stdin is fun"; // expose foo to repl scope var sys = require('sys'); +var evalcx = process.binding('evals').Script.runInNewContext; +var path = require("path"); +var scope; + +function setScope (self) { + scope = {}; + for (var i in global) scope[i] = global[i]; + scope.module = module; + scope.require = require; +} + // Can overridden with custom print functions, such as `probe` or `eyes.js` exports.writer = sys.inspect; function REPLServer(prompt, stream) { var self = this; - - self.scope = {}; + if (!scope) setScope(); + self.scope = scope; self.buffered_cmd = ''; self.prompt = prompt || "node> "; self.stream = stream || process.openStdin(); @@ -61,20 +72,20 @@ REPLServer.prototype.readline = function (cmd) { // This try is for determining if the command is complete, or should // continue onto the next line. try { - self.buffered_cmd = self.convertToScope(self.buffered_cmd); - - // Scope the readline with self.scope to provide "local" vars and make Douglas Crockford cry - with (self.scope) { - var ret = eval(self.buffered_cmd); - if (ret !== undefined) { - self.scope['_'] = ret; - self.stream.write(exports.writer(ret) + "\n"); - } + // Scope the readline with self.scope + // with(){} and eval() are considered bad. + var ret = evalcx(self.buffered_cmd, scope, "repl"); + if (ret !== undefined) { + scope._ = ret; + self.stream.write(exports.writer(ret) + "\n"); } - + self.buffered_cmd = ''; } catch (e) { - if (!(e instanceof SyntaxError)) throw e; + // instanceof doesn't work across context switches. + if (!(e && e.constructor && e.constructor.name === "SyntaxError")) { + throw e; + } } } catch (e) { // On error: Print the error and clear the buffer @@ -107,7 +118,7 @@ REPLServer.prototype.parseREPLKeyword = function (cmd) { case ".clear": self.stream.write("Clearing Scope...\n"); self.buffered_cmd = ''; - self.scope = {}; + setScope(); self.displayPrompt(); return true; case ".exit":