私は C のような言語からスタック マシンまでおもちゃのコンパイラを構築していますが、関数をどう処理し、ローカル変数をブロックするかを理解する必要があるところまで来ています。抽象的に考えると、スペクトルの両端に 2 つのオプションがあるように見えます。1) 各変数のスタック領域を前処理して事前に割り当てる、2) VM に特別な命令を追加してスタックをウォークします。
各変数のスタック領域を前処理して事前に割り当てる
これには、事前に変数のすべてのアドレスが提供されるという利点があるため、非常に賢くする必要も、スタックをウォークするために VM に追加の命令を追加する必要もありません。欠点は、決して実行されずに一連の変数全体を宣言する条件付きコードが多くの不要なスペースを占有するため、非常に無駄になる可能性があることです。例えば、
a : t1 = value;
if (test) {
b : t2; c : t3; d : t4; ...;
}
上記のコードでは、test
が常に false であっても、条件分岐内のすべての変数にスペースを割り当てます。
VM に特別な命令を追加して、スタックをウォークする
私が思いついたもう 1 つのアプローチは、変数宣言ごとにコードを生成し、実行時にそれらの変数のアドレスを把握するための特別な VM 命令を追加することでした。これにより、無駄なスタック スペースの問題は解決されますが、計算オーバーヘッドが追加されます。これは、いくつかのキャッシュ方法で解決できる可能性があります。
では、正しいアプローチは何ですか?私が考えていなかった別のアプローチの方が優れていますか?