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

context.call: does not support non-global function names #224

Open
gi opened this issue Jan 4, 2022 · 5 comments
Open

context.call: does not support non-global function names #224

gi opened this issue Jan 4, 2022 · 5 comments
Labels

Comments

@gi
Copy link

gi commented Jan 4, 2022

When calling a function, only global function names are supported. Functions which are properties of an object, or otherwise nested/scoped, are not supported: e.g. object.fn.

This works:

context = MiniRacer::Context.new
context.eval('bare = () => 1')
# => #<MiniRacer::JavaScriptFunction:0x00007f96e8acf798>
context.call('bare')
# => 1

This breaks:

context = MiniRacer::Context.new
context.eval('object = {}')
context.eval('object.nested = () => 1')
# => #<MiniRacer::JavaScriptFunction:0x00007f96e899d5a0>
context.call('object.nested')
# => Unknown JavaScript method invoked (MiniRacer::RuntimeError)

Environment:

  • ruby: 3.0.2
  • mini_racer: 0.5.0
@SamSaffron
Copy link
Collaborator

SamSaffron commented Jan 5, 2022 via email

@tisba tisba added the bug label Jan 19, 2022
@tisba
Copy link
Collaborator

tisba commented Feb 13, 2022

While looking at #136, I noticed, that MiniRacer cannot invoke functions that are defined with const. This looks related to the original error.

require "mini_racer"
require "date"

ctx = MiniRacer::Context.new
ctx.eval("const echoFn = (obj) => obj;")
ctx.call("echoFn", "hello world!")
#  => /Users/basti/.rvm/gems/ruby-3.1.0/gems/mini_racer-0.6.2/lib/mini_racer.rb:237:in `call_unsafe': Unknown JavaScript method invoked (MiniRacer::RuntimeError)

@gi
Copy link
Author

gi commented Feb 14, 2022

@tisba That is a different issue and may be by design.

As you may know, const and let define lexically scoped identifiers. Thus, it is possible that MiniRacer or V8 isolates the visibility of those identifiers between eval calls, where each evaluation could be seen as a separate lexical scope.

@gi
Copy link
Author

gi commented Feb 14, 2022

The original issue here is that the string used to identify the function to call is not evaluated to lookup the function:

In Ruby,

context.call("a.b")

is interpreted in JavaScript as

this["a.b"]()

instead of

this["a"]["b"]()

@tisba
Copy link
Collaborator

tisba commented Feb 14, 2022

That's a good point, @gi, thx!

For reference https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/const:

Constants are block-scoped, much like variables declared using the let keyword.[…]

But what surprises me then is that the defined constant is still visible on subsequent invocations:

require "mini_racer"

ctx = MiniRacer::Context.new
ctx.eval("const foo = 42;")
a = ctx.eval("foo + 1;")
# a => 43
ctx.eval("foo = 42;")

# JavaScript at <anonymous>:1:5: TypeError: Assignment to constant variable. (MiniRacer::RuntimeError)

Since I can also use foo in subsequent #eval calls, it looks like the same scope is used every time. I think these issues are related after all and it feels like a similar lookup issue 🤔

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants