-
Notifications
You must be signed in to change notification settings - Fork 7.3k
Issue of Script.runInNewContext and vm.runInNewContext #1105
Comments
If I use the vm, the error is the same: tigger-pro:robin ~$ cat test_vm.js
var util = require('util'),
vm = require('vm');
// test 1.
(function(){
console.log('execute test1');
var window = {};
window.window = window;
var sandbox = {};
sandbox.__proto__ = window;
vm.runInNewContext('window.google = {};', sandbox);
vm.runInNewContext('google.test = "test";', sandbox);
console.log(util.inspect(window));
})();
// test 2.
(function(){
console.log('execute test2');
var window = {};
window.window = window;
var sandbox = {};
sandbox.__proto__ = window;
vm.runInNewContext('window.google = {};google.test = "test";', sandbox);
console.log(util.inspect(window));
})();tigger-pro:robin ~$ node test_vm.js
execute test1
{ window: [Circular], google: { test: 'test' } }
execute test2
node.js:134
throw e; // process.nextTick error, or 'error' event on first tick
^
ReferenceError: google is not defined
at evalmachine.<anonymous>:1:20
at /Users/robin/test_vm.js:30:8
at Object.<anonymous> (/Users/robin/test_vm.js:33:2)
at Module._compile (module.js:407:26)
at Object..js (module.js:413:10)
at Module.load (module.js:339:31)
at Function._load (module.js:298:12)
at Array.<anonymous> (module.js:426:10)
at EventEmitter._tickCallback (node.js:126:26)
tigger-pro:robin ~$ |
After discussion with indutny on irc channel of Node.JS, he gives the following code to make it works as expected: tigger-pro:robin ~$ cat test_vm.js
var util = require('util'),
vm = require('vm');
// test 1.
(function(){
console.log('execute test1');
var window = {};
window.window = window;
var sandbox = {};
sandbox.__proto__ = window;
vm.runInNewContext('window.google = {};', sandbox);
vm.runInNewContext('google.test = "test";', sandbox);
console.log(util.inspect(window));
})();
// test 2.
(function(){
console.log('execute test2');
var window = {};
window.window = window;
var sandbox = {};
sandbox.__proto__ = window;
sandbox.window = sandbox;
vm.runInNewContext('window.google = {};google.test = "test";', sandbox);
console.log(util.inspect(sandbox));
console.log(util.inspect(window));
})();tigger-pro:robin ~$ node test_vm.js
execute test1
{ window: [Circular], google: { test: 'test' } }
execute test2
{ window: [Circular], google: { test: 'test' } }
{ window: [Circular] } |
Sorry for mis-operation. Anyone could help me to explain the internal differences of those test codes? Thanks. |
runInNewContext does not use sandbox object itself as the global for the new context, the sandbox is copied from before running and copied to after running. proto is not copied, of course (nor are getters and setters), so forget proto. Second thing is, first level self-references (sandbox.window = sandbox) are translated to self-references in the actual global object and vice-versa, that's why window.google = ... assigns to (new context's) global google and the next assignment works. |
@Herby is it correct what nodejs does with self-references? Node translates first level refs, but other refs on sublevels are not translated. |
This can't be the cause of memory leaks at all - just imagine it would not translate anything at all. It's just the object reference like any other. If a memory leak occurs, then something else did not release the pointer. |
@Herby I'm not sure, but I think that the LOOP references between javascript objects in different contexts are not garbage collected correctly. Due to V8::Context is a special type of handle and should be freed manualy. |
Maybe. I coded node_script.cc by borrowing from process.evalcx and process.compile and adding a possibility of standalone Script object, which is functionality in runInThisContext and runInNewContext methods. They work fine (well, runInThisContext does not when called from other than main context, which I filed as a bug, and which is not a matter of the code itself but it's proper wiring into v8, but no one got interested); but as for runInContext, it's someone else's addon, so either he or someone else should devise some solution if it is at all possible (maybe MakeWeak and gc callback if it is possible for a Context?). |
As documented in #1801, I believe I’ve closed this with elliottcable@cf21650. I’d appreciate if you’d clone and compile against that, and see if you can still reproduce this issue. (Many of these issues seem related.) |
@ELLIOTTCABLE This doesn't appear to be affected by the referenced pull. Inherited properties of the sandbox object don't make it into the context.
|
@isaacs I … must be mis-reading something. Wasn’t that the entire point of what we just changed? Now, the context should receive the entire prototype chain of the sandbox. I can’t build and test from here, on my iPad; but that massively surprises me. :x |
Not sure what is supposed to be the output, but running @fbzhong latest test case against v0.8.14 I get the following for test 1:
and the following for test 2:
So... any feedback on what has happened to test 1? |
You can't use |
Hi all,
I may found a issue of vm in Node.JS 0.4.8. Actually, the issue are founded from executing external javascript for url http://www.google.com in jsdom. When executing javascripts in jsdom, it always throw "google is not defined" error.
After debug, I know how to reproduce and write down the following test code:
The result is the following:
Those two tests do the same thing. The only difference is in test 2 the codes are merge to one line to execute.
I have no idea on this, could anyone help me to solve this issue?
The text was updated successfully, but these errors were encountered: