If you run the following test C code contained in multiple recursive calls:
... void fork2(int a, int b) { if ((a + b) % 1024 == 0) print("iterate fork2: a=%i, b=%i\n", a, b); if (a + b == 2) return; else fork2(--a, --b); } ... void main() { ... fork2(65535, 65535); ... }
Will cause a StackOverflowException error. This is because the default stack size is 1M and will be exhausted soon.
terms of settlement:
- Use loops instead of recursion.
- Use a smaller number of recursions.
- Modify SharpC to be competent.
Obviously, 1 and 2 are not considered.
You can make the following changes to SharpC:
First, set a large stack size. In SharpC:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.IO; using System.Diagnostics; namespace SharpC { using Grammar; public class SharpC { // Static static public int MaxStackSize = 1024 * 1024 * 512; //Open a 512M stack ...
Because the program's stack cannot be set, only one more thread can be opened:
namespace SharpC { using Grammar; public class SharpC { .... public void Run(bool forceReparsing = false) { if (!m_lastParsingResult || forceReparsing) Parse(); if (m_context != null) { if (OnBeforeRun != null) OnBeforeRun(this, m_context); (new System.Threading.Thread(delegate() { try { IsRunning = true; m_context.Run(m_context); } finally { IsRunning = false; if (OnAfterRun != null) OnAfterRun(this, m_context); } }, MaxStackSize)).Start(); } } ....
In addition, the method of saving and restoring parameters in functiondefinition.cs is wrong. The correct way is to comment them out!
namespace SharpC.Grammar.Function { public class FunctionDefine : Context { ... private void BeforeRun(Context ctx, List<Expression.Operand.Operand> parameters) { if (IsFirstRunning) { ConfigReturnEvent(ctx); AllocateFixedArguments(ctx); IsFirstRunning = false; } if (IsVariableArgument) { FreeVariableArgument(ctx); AllocateVariableArguments(ctx, parameters); } //SavePreviousParameters(ctx); InitArguments(ctx, parameters); IteratorCount++; } .... private void AfterRun(Context ctx) { IteratorCount--; if (IteratorCount > 0) { /* if (m_parameterStack.Count > 0) { RestoreParameter(ctx); } */ } else { // Clean variable arguments if (IsVariableArgument) { FreeVariableArgument(ctx); } } } ...
Now you can do deep recursion.
Continue to run the test code, recurse 65535 times, and output the result of recursion every 512 times. The operation results are as follows:
Operation result: