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

InvalidOperationException instead of the JavaScriptException during a recursive call of engine #1241

Closed
Taritsyn opened this issue Jul 24, 2022 · 2 comments · Fixed by #1243

Comments

@Taritsyn
Copy link
Contributor

Hello!

In Jint version Beta 2039 during a recursive call of incorrect code, the following unexpected exception is thrown:

System.InvalidOperationException: stack is empty
   at Jint.Runtime.ExceptionHelper.ThrowInvalidOperationException(String message, Exception exception)
   at Jint.Runtime.CallStack.JintCallStack.Pop()
   at Jint.Engine.Call(FunctionInstance functionInstance, JsValue thisObject, JsValue[] arguments, JintExpression expression)
   at Jint.Engine.Call(ICallable callable, JsValue thisObject, JsValue[] arguments, JintExpression expression)
   at Jint.Runtime.Interpreter.Expressions.JintCallExpression.EvaluateCall(EvaluationContext context, JsValue func, Object reference, NodeList`1& arguments, Boolean tailPosition)
   at Jint.Runtime.Interpreter.Expressions.JintCallExpression.Call(EvaluationContext context)
   at Jint.Runtime.Interpreter.Expressions.JintCallExpression.EvaluateInternal(EvaluationContext context)
   at Jint.Runtime.Interpreter.Statements.JintExpressionStatement.ExecuteInternal(EvaluationContext context)
   at Jint.Runtime.Interpreter.JintStatementList.Execute(EvaluationContext context)
   at Jint.Engine.ScriptEvaluation(ScriptRecord scriptRecord)
   at Jint.Engine.<>c__DisplayClass64_0.<Execute>b__0()
   at Jint.Engine.ExecuteWithConstraints[T](Boolean strict, Func`1 callback)
   at Jint.Engine.Execute(Script script)
   at Jint.Engine.Execute(String source, ParserOptions parserOptions)
   at TestJint.Program.Main(String[] args) in D:\Temp\TestJint\TestJint\Program.cs:line 17

There were no such errors in version Beta 2038. To reproduce this error, I created a example:

using System;

using Esprima;
using Jint;
using Jint.Native;
using Jint.Runtime;

namespace TestJint
{
    class Program
    {
        static void Main(string[] args)
        {
            try
            {
                var engine = new Engine();
                Action<string> executeFile = (path) =>
                {
                    string content = GetFileContent(path);
                    engine.Execute(content, CreateParserOptions(path));
                };
                JsValue executeFileValue = JsValue.FromObject(engine, executeFile);

                engine.SetValue("executeFile", executeFileValue);
                engine.Execute(
                    @"var num = 5;
executeFile(""first-file.js"");",
                    CreateParserOptions("main-file.js")
                );
            }
            catch (JavaScriptException e)
            {
                Console.ForegroundColor = ConsoleColor.Green;
                Console.WriteLine("Success!");

                Console.WriteLine();

                Console.ForegroundColor = ConsoleColor.White;
                Console.WriteLine("Expected error: {0}", e.ToString());
            }
            catch (InvalidOperationException e)
            {
                Console.ForegroundColor = ConsoleColor.Red;
                Console.WriteLine("Failed!");

                Console.WriteLine();

                Console.ForegroundColor = ConsoleColor.White;
                Console.WriteLine("Unexpected error: {0}", e.ToString());
            }
        }

        private static ParserOptions CreateParserOptions(string filePath)
        {
            var parserOptions = new ParserOptions(filePath)
            {
                AdaptRegexp = true,
                Tolerant = true
            };

            return parserOptions;
        }

        private static string GetFileContent(string path)
        {
            string content;

            switch (path)
            {
                case "first-file.js":
                    content = @"num = num * 3;
executeFile(""second-file.js"");";
                    break;
                case "second-file.js":
                    content = @"// Intentionally making a mistake in the variable name
nuм -= 3;";
                    break;
                default:
                    throw new FileNotFoundException(string.Format("File '{0}' not exist.", path), path);
            }

            return content;
        }
    }
}

In fact, I use more complex code in my tests.

@lahma
Copy link
Collaborator

lahma commented Jul 25, 2022

Thanks for yet again well documented bug report! This is hopefully now fixed in main branch.

@Taritsyn
Copy link
Contributor Author

Thank you very much! All my tests worked without errors.

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

Successfully merging a pull request may close this issue.

2 participants