Skip to content

Commit

Permalink
Fix switch's case block lexical scope handling (#1392)
Browse files Browse the repository at this point in the history
fixes #1391
  • Loading branch information
lahma committed Dec 29, 2022
1 parent 7480cfc commit dc75d1a
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 1 deletion.
29 changes: 29 additions & 0 deletions Jint.Tests/Runtime/SwitchTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
namespace Jint.Tests.Runtime;

public class JintFailureTest
{
[Fact]
public void ShouldHandleCaseBlockLexicalScopeCorrectly()
{
var engine = new Engine();
engine.SetValue("switchVal", 1);
engine.SetValue("getCoffee", new Func<string>(() => "coffee"));

engine.Execute(@"
function myFunc() {
switch(switchVal) {
case 0:
const text = getCoffee();
return text;
break;
case 1:
const line = getCoffee();
return line;
break;
}
}
");

Assert.Equal("coffee", engine.Evaluate("myFunc()"));
}
}
5 changes: 5 additions & 0 deletions Jint/Runtime/Environments/DeclarativeEnvironmentRecord.cs
Original file line number Diff line number Diff line change
Expand Up @@ -180,5 +180,10 @@ public override JsValue GetThisBinding()
{
return Undefined;
}

public void Clear()
{
_dictionary = null;
}
}
}
11 changes: 10 additions & 1 deletion Jint/Runtime/Interpreter/Statements/JintSwitchBlock.cs
Original file line number Diff line number Diff line change
Expand Up @@ -42,14 +42,18 @@ public Completion Execute(EvaluationContext context, JsValue input)
EnvironmentRecord? oldEnv = null;
var temp = _jintSwitchBlock;

DeclarativeEnvironmentRecord? blockEnv = null;

start:
for (; i < temp.Length; i++)
{
var clause = temp[i];
if (clause.LexicalDeclarations is not null && oldEnv is null)
{
oldEnv = context.Engine.ExecutionContext.LexicalEnvironment;
var blockEnv = JintEnvironment.NewDeclarativeEnvironment(context.Engine, oldEnv);
blockEnv ??= JintEnvironment.NewDeclarativeEnvironment(context.Engine, oldEnv);
blockEnv.Clear();

JintStatementList.BlockDeclarationInstantiation(context.Engine, blockEnv, clause.LexicalDeclarations);
context.Engine.UpdateLexicalEnvironment(blockEnv);
}
Expand All @@ -71,6 +75,11 @@ public Completion Execute(EvaluationContext context, JsValue input)

if (!hit)
{
if (oldEnv is not null)
{
context.Engine.UpdateLexicalEnvironment(oldEnv);
oldEnv = null;
}
continue;
}

Expand Down

0 comments on commit dc75d1a

Please sign in to comment.