If you run the following test C code that contains 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;elsefork2(--a, --b);}...void main(){ ... fork2(65535, 65535); ...}
This will cause the stackoverflowexception error. This is because the default stack size is 1 m and will soon be exhausted.
Solution:
1. Use loops instead of recursion.
2. Use recursion with a small number of times.
3. Modify the sharpc to make it 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 public int maxstacksize = 1024*1024*512; // open a m stack...
Because the program stack cannot be set, only one 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, it is wrong to save and restore parameters in functiondefine. cs. The correct method is to comment out them!
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 we can perform large recursion.
Continue to run the test code, recursively returning 65535 times, and outputting recursive results every 512 times. The running result is as follows: