C言語でCurrying2
http://d.hatena.ne.jp/shinichiro_h/20060119の手法は引数を積みなおして関数ポインタを呼ぶというもの(だと思う)。
call cを呼んだ直後のスタック | …… | 100 | ret(c) | |||
---|---|---|---|---|---|---|
call addを呼んだ直後のスタック | …… | 100 | ret(c) | 100 | 10 | ret(add) |
という感じで。これをtail callに出来たら面白いかも。
calleeがスタックを解放する場合
簡単すぎて省略。
callerがスタックを解放する場合
call cを呼んだ直後のスタック | …… | 100 | ret(c) | |
---|---|---|---|---|
call addを呼んだ直後のスタック | …… | 100 | 10 | ret(add) |
call cから帰った直後のスタック | …… | x |
となるように手を加えればよい。
細工付きトランポリン
call cを呼んだ直後のスタック | …… | 100 | ret(c) | |
---|---|---|---|---|
call addを呼んだ直後のスタック | …… | 100 | 10 | ret(add) |
call addから帰った直後のスタック | …… | 100 | 10 | |
call cから帰る直前のスタック | …… | 100 | ret(c) | |
call cから帰った直後のスタック | …… | 100 |
トランポリン関数部分で細工を頑張る。でも、スタック消費がわずかに減っただけで処理自体は元のものよりも重くなっている。
bp, spに細工
call cを呼んだ直後のスタック | …… | 100 | ret(c) | |||
---|---|---|---|---|---|---|
call addを呼んだ直後のスタック | …… | 100 | ret(c) | 100 | 10 | ret(c) |
call addから帰った直後のスタック | …… | 100 |
call addを呼ぶ直前のebp, espをcall cを呼ぶ直前の値にし、一回のretで二つの関数呼び出しの分を返してしまうという。処理の流れはtail call、スタック消費は非tail callになっている。
〆。
C言語の呼び出し規約は良くも悪くも難しい。