1
0
Fork 0
mirror of https://github.com/rails/execjs synced 2023-03-27 23:21:20 -04:00

Use node's vm module to run in clean context

As suggested by Joshua Peek in a previous issue. Node's vm module gives
us full control over the globals passed to the context the code is run
in.

In order to do this we store our code as a JS string, wrap it in an IFFE
(to support the `return` symantics we use for all runtimes)

vm.runInNewContext is called with {filename: "(execjs)"} in order to
have the proper filename appear in backtraces. Normally this string is
inserted into backtraces via a gsub in external_runtime.rb which
replaces the filename.

See https://nodejs.org/api/vm.html
This commit is contained in:
John Hawthorn 2016-10-10 03:19:38 -07:00
parent ff3f0fd993
commit 06bfd33f7b

View file

@ -1,20 +1,17 @@
(function(program, execJS) { execJS(program) })(function(global, process, module, exports, require, console, setTimeout, setInterval, clearTimeout, clearInterval, setImmediate, clearImmediate) { #{source} (function(execJS) { execJS() })(function() {
}, function(program) { var source = #{::JSON.dump(source)};
source = "(function(){"+ source + "})()";
var output, print = function(string) { var output, print = function(string) {
process.stdout.write('' + string); process.stdout.write('' + string);
}; };
try { try {
var __process__ = process; var program = function(){
delete this.process; var vm = require('vm');
delete this.console; var context = vm.createContext();
delete this.setTimeout; return vm.runInNewContext(source, context, "(execjs)");
delete this.setInterval; }
delete this.clearTimeout;
delete this.clearInterval;
delete this.setImmediate;
delete this.clearImmediate;
result = program(); result = program();
this.process = __process__;
if (typeof result == 'undefined' && result !== null) { if (typeof result == 'undefined' && result !== null) {
print('["ok"]'); print('["ok"]');
} else { } else {
@ -25,7 +22,6 @@
} }
} }
} catch (err) { } catch (err) {
this.process = __process__;
print(JSON.stringify(['err', '' + err, err.stack])); print(JSON.stringify(['err', '' + err, err.stack]));
} }
}); });