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
446 stars 49 forks source link

Program crash after function call with too much parameters #82

Closed CzaiStefanB closed 4 years ago

CzaiStefanB commented 4 years ago

Hello,

I have a strange behaviour when calling embedded functions with too much parameters.

JavaScriptEngineSwitcher.ChakraCore.JsRt.JsUsageException: Runtime is active on another thread. bei JavaScriptEngineSwitcher.ChakraCore.JsRt.JsErrorHelpers.ThrowIfError(JsErrorCode errorCode) bei JavaScriptEngineSwitcher.ChakraCore.ChakraCoreJsEngine.<>c__DisplayClass24_0.b__0() bei JavaScriptEngineSwitcher.ChakraCore.ScriptDispatcher.ScriptTaskWithResult1.Run() --- Ende der Stapelüberwachung vom vorhergehenden Ort, an dem die Ausnahme ausgelöst wurde --- bei JavaScriptEngineSwitcher.ChakraCore.ScriptDispatcher.Invoke[T](Func1 func) bei JavaScriptEngineSwitcher.ChakraCore.ChakraCoreJsEngine.InnerEvaluate(String expression, String documentName) bei JavaScriptEngineSwitcher.ChakraCore.ChakraCoreJsEngine.InnerEvaluate[T](String expression, String documentName) bei JavaScriptEngineSwitcher.ChakraCore.ChakraCoreJsEngine.InnerEvaluate[T](String expression) bei JavaScriptEngineSwitcher.Core.JsEngineBase.Evaluate[T](String expression) bei TestConsoleRun.Program.JavaScriptEngineSwitcherTest2() in Program.cs:Zeile 335.

I think something gets corrupted in background because with the next function call the program is crashing. When calling a function with too less parameters everything is working like expected. You can use the following code to reproduce this behaviour:

        IJsEngineSwitcher engineSwitcher = JsEngineSwitcher.Current;
        engineSwitcher.EngineFactories.Add(new ChakraCoreJsEngineFactory());
        engineSwitcher.DefaultEngineName = ChakraCoreJsEngine.EngineName;
        IJsEngine javaEngine = engineSwitcher.CreateEngine(ChakraCoreJsEngine.EngineName);
        javaEngine.EmbedHostObject("Sleep", (Action<int>)System.Threading.Thread.Sleep);

        Console.WriteLine("Sleep with correct parameters.");
        Console.WriteLine(javaEngine.Evaluate("Sleep(2000);"));
        try
        {
            Console.WriteLine("Sleep with too less parameters.");
            Console.WriteLine(javaEngine.Evaluate("Sleep();"));   // useful "parameter" exception
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.ToString());
        }
        Console.WriteLine("Sleep with correct parameters.");
        Console.WriteLine(javaEngine.Evaluate("Sleep(2000);"));
        try
        {
            Console.WriteLine("Sleep with too much parameters.");
            Console.WriteLine(javaEngine.Evaluate("Sleep(2000, true);"));   // strange exception ("Runtime is active on another thread."), something is corrupted afterwards
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.ToString());
        }
        Console.WriteLine("Sleep with correct parameters.");
        Console.WriteLine(javaEngine.Evaluate("Sleep(2000);")); // never called because of program crash
        Console.WriteLine("End");
Taritsyn commented 4 years ago

Hello!

This error:

Error: During invocation of the host delegate an error has occurred - "Parameter count mismatch.".
   at Global code (Script Document [2]:1:1) -> Sleep();

occurs because you embedded a delegate to JS engine, which can take only one integer parameter:

javaEngine.EmbedHostObject("Sleep", (Action<int>)System.Threading.Thread.Sleep);

You have only two variants for solving this problem:

  1. Embed a several delegates with different names.
  2. Embed a one object or type containing multiple overloads of the Sleep method.

JsUsageException occurs due to the fact that intercepting entire exception, you continue to use JS engine in which error occurred.

CzaiStefanB commented 4 years ago

I'm expecting the first exception with "parameter count mismatch" when I call Sleep without parameter. From my point of view this is correct behaviour and the JS engine also is still working correctly after that call.

But when I call the Sleep with two parameters I get a different exception with "Runtime is active on another thread." and afterwards the JS engine is not working any longer. The whole program is crashing without any exception or comment (I guess due to problem in native code). Why I don't get the same "parameter count mismatch" exception when using too many parameters? I think the runtime should handle that the same way like when having to less parameters and the JS engine should also not be corrupted after such a call.

Taritsyn commented 4 years ago

I found the cause of error. Tomorrow I will publish a new version.

Thanks for information!

Taritsyn commented 4 years ago

Hello!

This error is fixed in version 3.4.3.

Now the ChakraCore module, like other engines, discards extra parameters before calling the delegate. No exceptions occur during such call.

CzaiStefanB commented 4 years ago

I have tested the functionality in the new version and it works like expected. I will close the issue.

Thanks for the quick bug fixing!