Goのコンテキストレジスタ
This content is a draft and will not be included in production builds.
Goには一言で関数といっても複数の種類が存在する。
- トップレベル関数
- 値レシーバなメソッド
- ポインタレシーバなメソッド
- クロージャ(関数リテラル)
クロージャの場合、元々は都度コードを生成していたらしいのだが、それだと問題があるので可変のメモリ領域を参照するように変わった。
これによると、var f func() という関数ポインタは以下のような構造を持っている。
block-beta columns 5 f["var f func()"] space block:b columns 1 ref["code"] data1 data2 aux["..."] end space c["code"]
f --> b ref --> c関数を実行するときのアセンブリコードは次のように記述する。
MOVQ DI, DX // コンテキスト(黄色い部分の先頭ポインタ)をレジスタに格納MOVQ (DI), DI // codeの実アドレスを取り出すCALL DIこれで実行中の関数は DX レジスタを通してキャプチャした変数にアクセス可能となる。