Gauche:YAGHG:VM:フレームのヒープへのコピー
スタックに保存されているフレームは次の時にヒープへ移される。
- 環境フレーム(save_env)
- コンティニュエーションフレームがヒープへ移されるとき
- クロージャを作成するとき
- コンティニュエーションフレーム(save_cont)
- スタックが溢れるとき
- 継続を作成するとき
save_env
環境フレームをヒープにコピーしたあと、スタックに残っている環境フレームのsizeフィールドにフォーワードされたことを示す-1を設定する。 ヒープに移す対象となるのは現在の環境の直系のものだけである。
BEFORE AFTER +=========+ +=========+ : : : : : : : : +=========+<---+ +=========+ | | | | | | E#0 | | | E#0 | | | | | | up | NULL | | up | --+---------->+=========+<---+ +=========+ | size | -1 | | | | : : | +=========+ | E#0' | | : : | : : | | | : : | : : up | NULL | | +=========+ | +=========+ +=========+ | | | | | | | | E#1 | | | E#1 | | | | | | | | +=========+ | +=========+ | : : | : : | : : | : : | env ---->+=========+ | env ---->+=========+ | | | | | | | | E#2 | | | E#2 | | | | | | | | up | --+----+ up | --+---------->+=========+ | +=========+ size | -1 | | | | | | +=========+ | E#2' | | | | | | | | | | | up | --+----+ +=========+
envレジスタやコンティニュエーションフレームが指す環境フレームを、 新しく作られたそれを指すように設定し直すのはsave_envを呼び出す次の関数の仕事である。
- get_env
- save_cont
save_cont
save_envしてからコンティニュエーションフレームをヒープにコピーする。各コンティニュエーションフレームごとに環境フレームの保存を行うため、 最終的にはスタックに含まれる(最後の引数フレームを除いた)すべてのフレームがヒープに移される(はず)。
BEFORE AFTER +=========+<---+ +=========+ | | | | | | C#0 | | | C#0 | | | | | | prev | NULL | | prev | --+---------->+=========+<--------+ +=========+ | size | -1 | | | | : : | +=========+ | C#0' | | : : | : : | | | : : | : : prev | NULL | | : : | : : +=========+ | : : | : : | +=========+<---+----+ +=========+ +=========+<--------+----+ | | | | | | copy | | | | | E#0 | | | | E#0 | ====> | E#0' | | | | | | | | | | | | | +=========+ | | +=========+ +=========+ | | : : | | : : | | : : | | : : | | cont ---->+=========+ | | +=========+ | | | | | | | | | | | C#1 | | | | C#1 | | | | | | | | | | | prev | --+----+ | prev | --+-------+------>+=========+ | | env | --+---------+ size | -1 | | | | | | +=========+ +=========+ | | C#1' | | | | | | | | | | | | | | | | | prev | --+-----+ | | env | --+----------+ | +=========+ | cont ---+
注意点として、ここでいうコンティニュエーションフレームとは積みかけの引数フレームも含むと言うことが挙げられる。そういったフレームは コピー時に引数フレームの場所が変更される。
TARGET COPIED +=========+<---+ +=========+ | arg#1 | | prev | | +---------+ | env | | : : | argp | --+----+ +---------+ | size | | | | arg#N | | pc | | | +=========+ | base | | | prev | | | +=========+<---+ env | | | | arg#1 | argp | --+----+ +---------+ size | | : : pc | | +---------+ base | | | arg#N | +=========+ +=========+
(他にEscapePointの処理もあり。Gauche:EscapeHandlerAndFrameRelocation)