Skip to content

Commit a4847ff

Browse files
committed
Fix scoping issues with default function parameters
1 parent 479bbe1 commit a4847ff

File tree

9 files changed

+63
-17
lines changed

9 files changed

+63
-17
lines changed

src/MoonSharp.Interpreter/Execution/Scopes/BuildTimeScope.cs

+7-2
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,15 @@ internal class BuildTimeScope
1111
List<BuildTimeScopeFrame> m_Frames = new List<BuildTimeScopeFrame>();
1212
List<IClosureBuilder> m_ClosureBuilders = new List<IClosureBuilder>();
1313

14-
public void PushFunction(IClosureBuilder closureBuilder, bool hasVarArgs)
14+
public void PushFunction(IClosureBuilder closureBuilder)
1515
{
1616
m_ClosureBuilders.Add(closureBuilder);
17-
m_Frames.Add(new BuildTimeScopeFrame(hasVarArgs));
17+
m_Frames.Add(new BuildTimeScopeFrame());
18+
}
19+
20+
public void SetHasVarArgs()
21+
{
22+
m_Frames.Last().HasVarArgs = true;
1823
}
1924

2025
public void PushBlock()

src/MoonSharp.Interpreter/Execution/Scopes/BuildTimeScopeFrame.cs

+2-3
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,10 @@ internal class BuildTimeScopeFrame
1010
BuildTimeScopeBlock m_ScopeTreeHead;
1111
RuntimeScopeFrame m_ScopeFrame = new RuntimeScopeFrame();
1212

13-
public bool HasVarArgs { get; private set;}
13+
public bool HasVarArgs { get; set;}
1414

15-
internal BuildTimeScopeFrame(bool hasVarArgs)
15+
internal BuildTimeScopeFrame()
1616
{
17-
HasVarArgs = hasVarArgs;
1817
m_ScopeTreeHead = m_ScopeTreeRoot = new BuildTimeScopeBlock(null);
1918
}
2019

src/MoonSharp.Interpreter/Tree/Expressions/FunctionDefinitionExpression.cs

+19-11
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,23 @@ private FunctionDefinitionExpression(ScriptLoadingContext lcontext, bool pushSel
4343
if (m_UsesGlobalEnv = usesGlobalEnv)
4444
CheckTokenType(lcontext, TokenType.Function);
4545

46+
47+
// create scope
48+
// This needs to be up here to allow for arguments to correctly close over ENV
49+
// Arguments, however, must come before any other local definitions to avoid closing
50+
// over uninitialised variables. (Note for hoisting).
51+
lcontext.Scope.PushFunction(this);
52+
53+
if (m_UsesGlobalEnv)
54+
{
55+
m_Env = lcontext.Scope.DefineLocal(WellKnownSymbols.ENV);
56+
}
57+
else
58+
{
59+
lcontext.Scope.ForceEnvUpValue();
60+
}
61+
62+
// Parse arguments
4663
// here lexer should be at the '(' or at the '|'
4764
//Token openRound = CheckTokenType(lcontext, isLambda ? TokenType.Lambda : TokenType.Brk_Open_Round);
4865

@@ -78,19 +95,10 @@ private FunctionDefinitionExpression(ScriptLoadingContext lcontext, bool pushSel
7895

7996
m_Begin = openRound.GetSourceRefUpTo(lcontext.Lexer.Current);
8097

81-
// create scope
82-
lcontext.Scope.PushFunction(this, m_HasVarArgs);
83-
84-
if (m_UsesGlobalEnv)
85-
{
86-
m_Env = lcontext.Scope.DefineLocal(WellKnownSymbols.ENV);
87-
}
88-
else
89-
{
90-
lcontext.Scope.ForceEnvUpValue();
91-
}
9298

9399
m_ParamNames = DefineArguments(paramnames, lcontext);
100+
101+
if(m_HasVarArgs) lcontext.Scope.SetHasVarArgs(); //Moved here
94102

95103
if(isLambda)
96104
m_Statement = CreateLambdaBody(lcontext, arrowFunc);

src/MoonSharp.Interpreter/Tree/Statements/ChunkStatement.cs

+2-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,8 @@ class ChunkStatement : Statement, IClosureBuilder
1313
public ChunkStatement(ScriptLoadingContext lcontext)
1414
: base(lcontext)
1515
{
16-
lcontext.Scope.PushFunction(this, true);
16+
lcontext.Scope.PushFunction(this);
17+
lcontext.Scope.SetHasVarArgs();
1718
m_Env = lcontext.Scope.DefineLocal(WellKnownSymbols.ENV);
1819
m_VarArgs = lcontext.Scope.DefineLocal(WellKnownSymbols.VARARGS);
1920

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
local z = 2
2+
3+
f = (x = () => {print(z)}) => {
4+
x()
5+
}
6+
7+
z = 3
8+
9+
f();
10+
11+
function test2() {
12+
local z = 2
13+
f = (x = () => {print(z)}) => {
14+
x()
15+
}
16+
z = 7;
17+
return f;
18+
}
19+
20+
local f2 = test2();
21+
f2();
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
3
2+
7

src/MoonSharp.Tests/EndToEnd/CSyntaxTests.cs

+10
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,16 @@ public void CFor_Closure()
183183
", s => s.Options.Syntax = ScriptSyntax.CLike);
184184
}
185185

186+
[Test]
187+
public void CallDefaultFunc()
188+
{
189+
TestScript.Run(@"
190+
f = (x = () => {print('yes')}) => {
191+
x()
192+
}
193+
f();", s => s.Options.Syntax = ScriptSyntax.CLike);
194+
}
195+
186196
[Test]
187197
public void AddConcat()
188198
{

0 commit comments

Comments
 (0)