From de57e48cff9652915f688f57c4c15a085d2e3128 Mon Sep 17 00:00:00 2001 From: Anthony Laibe Date: Fri, 24 Aug 2018 14:05:19 +0100 Subject: [PATCH] Isolate the code runner --- cmd/dashboard/repl.js | 4 ++ lib/core/modules/coderunner/codeRunner.js | 22 ++++++---- lib/core/modules/coderunner/runCode.js | 52 +++++++++++------------ 3 files changed, 42 insertions(+), 36 deletions(-) diff --git a/cmd/dashboard/repl.js b/cmd/dashboard/repl.js index 0432943b..b89c20f1 100644 --- a/cmd/dashboard/repl.js +++ b/cmd/dashboard/repl.js @@ -44,6 +44,10 @@ class REPL { writer: this.enhancedWriter.bind(this) }); + this.events.request("runcode:getContext", (context) => { + this.replServer.context = context; + }); + this.replServer.on("exit", () => { process.exit(); }); diff --git a/lib/core/modules/coderunner/codeRunner.js b/lib/core/modules/coderunner/codeRunner.js index fc308bea..4924c5f4 100644 --- a/lib/core/modules/coderunner/codeRunner.js +++ b/lib/core/modules/coderunner/codeRunner.js @@ -8,13 +8,12 @@ class CodeRunner { this.events = options.events; this.ipc = options.ipc; this.commands = []; + this.runCode = new RunCode(); let self = this; - // necessary to init the context - RunCode.initContext(); if (this.ipc.isServer()) { this.ipc.on('runcode:getCommands', (_err, callback) => { - let result = {web3Config: RunCode.getWeb3Config(), commands: self.commands}; + let result = {web3Config: self.runCode.getWeb3Config(), commands: self.commands}; callback(null, result); }); } @@ -34,7 +33,11 @@ class CodeRunner { self.commands.push({varName, code}); self.ipc.broadcast("runcode:newCommand", {varName, code}); } - RunCode.registerVar(varName, code); + self.runCode.registerVar(varName, code); + }); + + this.events.setCommandHandler('runcode:getContext', (cb) => { + cb(self.runCode.context); }); this.events.setCommandHandler('runcode:eval', (code, cb, forConsoleOnly = false) => { @@ -53,14 +56,17 @@ class CodeRunner { code = `(async function() {${code}})();`; } } - let result = RunCode.doEval(code); - if (result instanceof Promise) { - return result.then((value) => cb(null, value)).catch(cb); - } + let result = self.runCode.doEval(code); + if (forConsoleOnly && self.ipc.isServer()) { self.commands.push({code}); self.ipc.broadcast("runcode:newCommand", {code}); } + + if (result instanceof Promise) { + return result.then((value) => cb(null, value)).catch(cb); + } + cb(null, result); }); } diff --git a/lib/core/modules/coderunner/runCode.js b/lib/core/modules/coderunner/runCode.js index 4e354213..73078091 100644 --- a/lib/core/modules/coderunner/runCode.js +++ b/lib/core/modules/coderunner/runCode.js @@ -1,31 +1,27 @@ -/*eslint no-unused-vars: off*/ -let __mainContext = this; +const vm = require('vm'); -function initContext() { - doEval("__mainContext = this"); +class RunCode { + constructor() { + this.context = Object.assign({}, global.this); + } + + doEval(code) { + return vm.runInNewContext(code, this.context); + } + + registerVar(varName, code) { + // TODO: Update all the code being dependent of web3 + // To identify, look at the top of the file for something like: + // /*global web3*/ + if (varName === 'web3') { + global.web3 = code; + } + this.context[varName] = code; + } + + getWeb3Config() { + return {defaultAccount: this.context.web3.eth.defaultAccount, provider: this.context.web3.currentProvider}; + } } -// ====================== -// the eval is used for evaluating some of the contact calls for different purposes -// this should be at least moved to a different process and scope -// for now it is defined here -// ====================== -function doEval(code) { - // TODO: add trace log here - return eval(code); -} - -function registerVar(varName, code) { - __mainContext[varName] = code; -} - -function getWeb3Config() { - return {defaultAccount:__mainContext.web3.eth.defaultAccount, provider: __mainContext.web3.currentProvider}; -} - -module.exports = { - doEval, - registerVar, - initContext, - getWeb3Config -}; +module.exports = RunCode;