--- src/MoonSharp.Interpreter/Execution/Scopes/BuildTimeScope.cs
+++ src/MoonSharp.Interpreter/Execution/Scopes/BuildTimeScope.cs
@@ -79,6 +79,7 @@
private SymbolRef CreateUpValue(BuildTimeScope buildTimeScope, SymbolRef symb, int closuredFrame, int currentFrame)
{
+ StackGuard.Ensure();
// it's a 0-level upvalue. Just create it and we're done.
if (closuredFrame == currentFrame)
return m_ClosureBuilders[currentFrame + 1].CreateUpvalue(this, symb);
--- /dev/null
+++ src/MoonSharp.Interpreter/StackGuard.cs
@@ -0,0 +1,30 @@
+using System;
+using System.Runtime.CompilerServices;
+
+namespace MoonSharp.Interpreter
+{
+ ///
+ /// Turns a nearly used-up stack into a syntax error.
+ /// It sits where the parser and compiler recurse with no bound of their own.
+ /// Those are the expression and statement parsers, the compilers of nodes that a loop can chain without limit, and
+ /// the walk that links an upvalue through every enclosing function.
+ /// Every other recursion is over a tree no deeper than the parser accepted.
+ ///
+ internal static class StackGuard
+ {
+ ///
+ /// Throws a when the stack is too low to recurse further.
+ ///
+ public static void Ensure()
+ {
+ try
+ {
+ RuntimeHelpers.EnsureSufficientExecutionStack();
+ }
+ catch (InsufficientExecutionStackException)
+ {
+ throw new SyntaxErrorException(null, "chunk has too many syntax levels");
+ }
+ }
+ }
+}
--- src/MoonSharp.Interpreter/Tree/Expression_.cs
+++ src/MoonSharp.Interpreter/Tree/Expression_.cs
@@ -62,6 +62,7 @@
internal static Expression SubExpr(ScriptLoadingContext lcontext, bool isPrimary)
{
+ StackGuard.Ensure();
Expression e = null;
Token T = lcontext.Lexer.Current;
--- src/MoonSharp.Interpreter/Tree/Expressions/BinaryOperatorExpression.cs
+++ src/MoonSharp.Interpreter/Tree/Expressions/BinaryOperatorExpression.cs
@@ -299,6 +299,7 @@
public override void Compile(Execution.VM.ByteCode bc)
{
+ StackGuard.Ensure();
m_Exp1.Compile(bc);
if (m_Operator == Operator.Or)
--- src/MoonSharp.Interpreter/Tree/Expressions/FunctionCallExpression.cs
+++ src/MoonSharp.Interpreter/Tree/Expressions/FunctionCallExpression.cs
@@ -68,6 +68,7 @@
public override void Compile(Execution.VM.ByteCode bc)
{
+ StackGuard.Ensure();
m_Function.Compile(bc);
int argslen = m_Arguments.Count;
--- src/MoonSharp.Interpreter/Tree/Expressions/IndexExpression.cs
+++ src/MoonSharp.Interpreter/Tree/Expressions/IndexExpression.cs
@@ -27,6 +27,7 @@
public override void Compile(ByteCode bc)
{
+ StackGuard.Ensure();
m_BaseExp.Compile(bc);
if (m_Name != null)
--- src/MoonSharp.Interpreter/Tree/Statement.cs
+++ src/MoonSharp.Interpreter/Tree/Statement.cs
@@ -13,6 +13,7 @@
protected static Statement CreateStatement(ScriptLoadingContext lcontext, out bool forceLast)
{
+ StackGuard.Ensure();
Token tkn = lcontext.Lexer.Current;
forceLast = false;