Skip to content

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 レジスタを通してキャプチャした変数にアクセス可能となる。