Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Not really possible to use global symbols inside vm #11593

Closed
mitar opened this issue Feb 27, 2017 · 9 comments
Closed

Not really possible to use global symbols inside vm #11593

mitar opened this issue Feb 27, 2017 · 9 comments
Labels
question Issues that look for answers. vm Issues and PRs related to the vm subsystem.

Comments

@mitar
Copy link
Contributor

mitar commented Feb 27, 2017

So in this issue it is suggested in this comment to pass global variables to the vm context if you want them shared:

vm.runInNewContext("a instanceof Array", {a:[], Array:Array}) === true
vm.runInNewContext("a.constructor === Array", {a:[], Array:Array}) === true

But then arrays created inside fail:

vm.runInNewContext("[] instanceof Array", {a:[], Array:Array}) === false
vm.runInNewContext("[].constructor === Array", {a:[], Array:Array}) === false

So how can one share symbols between vm and outside context, fully? I would like that Array (and Error, buffers and others) all behave in the same way and that I can pass objects from inside to outside without issues.

@bnoordhuis
Copy link
Member

That's really more of a V8 question than a node.js question but the reason is efficiency. It's also a fundamental limitation that won't change.

[].__proto__.constructor is the context's native Array function, not the one you passed in. You can override it like this:

vm.runInNewContext(
    'var a = []; a.__proto__ = new Array(); a instanceof Array',
    { Array });  // true

@bnoordhuis bnoordhuis added question Issues that look for answers. vm Issues and PRs related to the vm subsystem. labels Feb 27, 2017
@mitar
Copy link
Contributor Author

mitar commented Feb 28, 2017

Hm, but there is no way to make outside Array be proto for all arrays created inside?

@bnoordhuis
Copy link
Member

No. Array literals are always instances of the native Array constructor. Same with object literals.

@TimothyGu
Copy link
Member

This is one reason why Array.isArray exists:

> vm.runInNewContext("Array.isArray([])", { Array })
true
> vm.runInNewContext("Array.isArray([])")
true
> vm.runInNewContext("Array.isArray(a)", { a: [], Array })
true
> vm.runInNewContext("Array.isArray(a)", { a: [] })
true

@mitar
Copy link
Contributor Author

mitar commented Feb 28, 2017

Yes, but Error.isError does not? And checking for ArrayBuffer?

Also, if I package code which does not expect to be run inside vm, then they do things like using instanceof and it does not work.

@bnoordhuis
Copy link
Member

As a rule of thumb you should obtain references to globals from the other context and operate on those:

const cx = vm.createContext();
const { Error: ThatError } = vm.runInContext('this', cx);
const e = vm.runInContext('new Error("boom")', cx);
console.log(e instanceof Error);  // false
console.log(e instanceof ThatError);  // true

@mitar
Copy link
Contributor Author

mitar commented Feb 28, 2017

vm.runInContext('this', cx) is what did the trick. I tried using cx directly, but it did not yet have all the symbols. Thanks.

But things are still tricky. For example:

const context = vm.createContext({Buffer: Buffer});
vm.runInContext('new Buffer(new ArrayBuffer(10))', context);

Throws an error:

TypeError: First argument must be a string, Buffer, ArrayBuffer, Array, or array-like object.

@bnoordhuis
Copy link
Member

You probably need to upgrade your node, that was fixed a while ago.

@mitar
Copy link
Contributor Author

mitar commented Feb 28, 2017

I used v6.3.0. And you are right, upgrading to v6.10.0 solved the problem. Thanks.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Issues that look for answers. vm Issues and PRs related to the vm subsystem.
Projects
None yet
Development

No branches or pull requests

3 participants