C言語解釈器-22補足:再帰的にStackOverflowExceptionを引き起こす


複数の再帰呼び出しに含まれる次のテストCコードを実行する場合:
...
void fork2(int a, int b)
{
	if ((a + b) % 1024 == 0)
		print("iterate fork2: a=%i, b=%i
", a, b); if (a + b == 2) return; else fork2(--a, --b); } ... void main() { ... fork2(65535, 65535); ... }

StackOverflowExceptionエラーが発生します.これは、デフォルトのスタックサイズが1 Mなので、すぐに消費されます.
解決策:
1.再帰の代わりに循環を使用します.
2.より小さい回数の再帰を使用します.
3.SharpCを修正し、適任させる.
明らかに1,2は考慮されていない.
SharpCは以下の変更が可能です.
まず大きなスタックサイズを設定し、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;  // 512M 
        ...

プログラムのスタックを設定できないため、別のスレッドしか開くことができません.
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();
            }
        }

        ....

また、FunctionDefine.csでパラメータを保存して復元する方法は間違っています.正しい方法は、それらを注釈することです.
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);
                }
            }
        }

       ...

今では大再帰が可能になりました.
テストコードを実行し続け、65535回再帰し、512回ごとに再帰結果を出力します.実行結果は次のとおりです.