Call Stack
from ローカル変数
Call Stack
駆動レコード、アクティベーションレコードとも言う
stack frame
activation record
関数呼び出しごとに確保されるメモリ領域
関数の実行時に生成される一時領域
関数のローカル変数や、脱出時の戻り先を保持する記憶領域
サブルーチン毎にコールスタックに格納する情報をスタックフレームと呼ぶ
ワインド
winding
あるサブルーチンに関する情報をコールスタックに乗せること
アンワインド
unwinding
あるサブルーチンに関するコールスタックから削除すること
具体例
関数呼び出しのアセンブリ
Schemeのコールスタック
レジスタマシン?での関数呼び出し
3種類のレジスタがある
caller-sabe register
callee saved register
special register
http://www.ertl.jp/~takayuki/readings/info/no04.html
タイガーブック p.119
C言語では
クロージャのような関数を返す関数を書くことはできない
なのでhccのように、関数内部で使う実引数を保持するためにスタック領域構造で済む
つまり、コンパイラの実装は単純になる
ML、Scheme、Haskellなどでは
関数を返す関数を書くことが出来る
code:hs
f :: Int -> Int -> Int
f x = \y -> x + y
main = do
let h = f 3 -- ①
let j = f 4 -- ②
print $ h 5 -- 8 -- ③
print $ j 6 -- 10 -- ④
この場合、単純なスタック構造だと
①で3をスタックを積んだ後に、②で4をその上に積むことになるので、
③や④で実際に適用されるときにうまく機能しないことがわかる
①や②で使っているのはどちらも関数fだが、これらの実態は全く別物を見ている
こんな風に、クロージャが書けるような言語ではコンパイラは単純なスタック構造だと無理
なので、コンパイラの実装はより複雑になってしまう
が、言語が柔軟になる
実際どう実装するかは知らんmrsekut.icon
タイガーブックの15章に書いている
参考
タイガーブック 6章
p.116の解説がわかりやすい
https://ja.wikipedia.org/wiki/コールスタック
Schemeの実装におけるスタックフレーム(Draft)
図もある