Skip to content

Commit

Permalink
gracefully handle recursive engine invocations
Browse files Browse the repository at this point in the history
  • Loading branch information
lahma committed Feb 4, 2021
1 parent 7e44891 commit 8ef9830
Show file tree
Hide file tree
Showing 4 changed files with 19 additions and 8 deletions.
2 changes: 1 addition & 1 deletion Jint.Tests.Test262/Test262Test.cs
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ protected void RunTestCode(string code, bool strict)
var parser = new JavaScriptParser(args.At(0).AsString(), options);
var script = parser.ParseScript(strict);
var value = engine.Execute(script, false).GetCompletionValue();
var value = engine.Execute(script).GetCompletionValue();
return value;
}), true, true, true));
Expand Down
13 changes: 13 additions & 0 deletions Jint.Tests/Runtime/EngineTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2934,6 +2934,19 @@ public void ShouldReuseOptions()
Assert.Equal(1, Convert.ToInt32(engine2.GetValue("x").ToObject()));
}

[Fact]
public void RecursiveCallStack()
{
var engine = new Engine();
Func<string, object> evaluateCode = code => engine.Execute(code).GetCompletionValue();
var evaluateCodeValue = JsValue.FromObject(engine, evaluateCode);

engine.SetValue("evaluateCode", evaluateCodeValue);
var result = (int) engine.Execute(@"evaluateCode('678 + 711')").GetCompletionValue().AsNumber();

Assert.Equal(1389, result);
}

private class Wrapper
{
public Testificate Test { get; set; }
Expand Down
10 changes: 3 additions & 7 deletions Jint/Engine.cs
Original file line number Diff line number Diff line change
Expand Up @@ -349,16 +349,12 @@ public Engine Execute(string source, ParserOptions parserOptions)

public Engine Execute(Script script)
{
return Execute(script, true);
}

internal Engine Execute(Script script, bool resetState)
{
if (resetState)
// only if we are not in a recursive call, we can reset constraints and last statement
// we assume that call stack will be empty only when exited on top level of call chain
if (CallStack.Count == 0)
{
ResetConstraints();
ResetLastStatement();
ResetCallStack();
}

using (new StrictModeScope(_isStrict || script.Strict))
Expand Down
2 changes: 2 additions & 0 deletions Jint/Runtime/CallStack/JintCallStack.cs
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,8 @@ public CallStackElement Pop()
return item;
}

public int Count => _stack._size;

public void Clear()
{
_stack.Clear();
Expand Down

0 comments on commit 8ef9830

Please sign in to comment.