Taritsyn / JavaScriptEngineSwitcher

JavaScript Engine Switcher determines unified interface for access to the basic features of popular JavaScript engines. This library allows you to quickly and easily switch to using of another JavaScript engine.
Apache License 2.0
439 stars 49 forks source link

(chakra) recursive evaluation #72

Closed viceice closed 5 years ago

viceice commented 5 years ago

I'm trying to a simple module loading feature which requires recursive script execution:

net -> js -> net -> js

This is currently not possible, because the scriptdispatcher is blocked by the first eval. https://github.com/Taritsyn/JavaScriptEngineSwitcher/blob/753deb75fa62eb82ef1f5ea019a98df708c4eb7d/src/JavaScriptEngineSwitcher.ChakraCore/ScriptDispatcher.cs#L152

My current workaround is to use eval, which i don't like. Is there any way to make recursive calls work?

Taritsyn commented 5 years ago

Hello, Michael!

You could give an example of JS code that causes this error.

viceice commented 5 years ago

Simple test case:

_engine.EmbedHostObject("_test", (Action<string>)(c => _engine.Evaluate(c));
_engine.Evaluate("_test('var test;')");
Taritsyn commented 5 years ago

Why are you doing this? You can use a eval keyword.

viceice commented 5 years ago

What about this:

_engine.EmbedHostObject("_test", (Action<string>)(c => _engine.ExecuteFile($"dist/{c}.js"));
_engine.Evaluate("_test('test')");

I'm trying to implement a simple module system.

Taritsyn commented 5 years ago

Try this variant:

Func<string, string> readFileContent = File.ReadAllText;

_engine.EmbedHostObject("readFileContent", readFileContent);
_engine.Execute(@"function loadModule(moduleName) {
    var modulePath = 'dist/' + moduleName + '.js';
    var moduleContent = readFileContent(modulePath);

    return new Function(moduleContent)();
}");
_engine.CallFunction("loadModule", "test");
viceice commented 5 years ago

That's my workaround 😄

Taritsyn commented 5 years ago

Only here, instead of the eval(…) expression used the new Function(…)(), which is more safe.

Taritsyn commented 5 years ago

When there is free time, I will deal with this problem.

viceice commented 5 years ago

Solution https://github.com/Taritsyn/JavaScriptEngineSwitcher/blob/753deb75fa62eb82ef1f5ea019a98df708c4eb7d/src/JavaScriptEngineSwitcher.ChakraCore/ScriptDispatcher.cs#L147-L153

  1. Inline the execution if we don't specify a max stack size.
  2. Check, if we are the dispatcher thread and inline the execution.

Which solution do you prefer, or another solution? I can send a PR.

Taritsyn commented 5 years ago

Which solution do you prefer, or another solution? I can send a PR.

I'll deal with the problem myself, but later.

viceice commented 5 years ago

OK, the new Function solution is a little bit annoying, because i don't have a filename in the stack traces.

So it is very difficult to find the right source file.

Taritsyn commented 5 years ago

Hello, Michael!

This error is fixed in version 3.0.8.