Open22

range over functionをもう少し真面目に追う

podhmopodhmo

実装周りや諸々

podhmopodhmo

直接使う例は面白い。つまるところrangeのときにコンパイラが頑張ってくれる

func PrintAllElements[E comparable](s *Set[E]) {
    s.All()(func(v E) bool {
        fmt.Println(v)
        return true
    })
}

なるほど range over function だ

podhmopodhmo

実装

実装から把握したい

https://zenn.dev/link/comments/5e9bb6749d5b88

フロントエンドでparseしてIRを作ってバックエンドで最適化をしてバイナリを吐くイメージ

podhmopodhmo

💭 たぶんインライン展開含めた最適化自体はヒューリスティック的なコストの換算でやってる気がする。一旦そちらは無視する。

podhmopodhmo

range over integerも一緒に挙げられてるけれどコミット自体には見るところが無いような気がする

podhmopodhmo

noderが確かastをwalkしてirを作る君だった気がする

podhmopodhmo

irgenの手前でRewriteしてるのかな?
(最適化自体はたぶん特別にはしてなくて後々のoptimizer任せになってるとおもう)

正解はnoderの中のLoadPackage()の中の...checkFiles()の中でrangefunc.Rewrite()を呼んでいた。

podhmopodhmo

たぶん、以下のような感じで呼ばれてる

package cmd/compile/internal/gc

func gc.Main(archInit func(*ssagen.ArchInfo))
  func noder.LoadPackage(filenames []string)
    func noder.unified(m noder.posMap, noders []*noder.noder)
      func noder.writePkgStub(m noder.posMap, noders []*noder.noder) string
        func noder.checkFiles(m noder.posMap, noders []*noder.noder) (*types2.Package, *types2.Info, map[*syntax.FuncLit]bool)
          func rangefunc.Rewrite(pkg *types2.Package, info *types2.Info, files []*syntax.File) map[*syntax.FuncLit]bool
podhmopodhmo

わりとrangefunc.Rewriteのコメントに色々書いてある。

雑に言うとインライン化可能なクロージャの呼び出しへの変換になっていて細々とした注意事項がある感じ(ところでネストした時の変換の話を真面目に追えていない)。

インライン展開自体は別の箇所で行われている。

podhmopodhmo

💭panic時のcall stackというか位置の表示はどうしているんだろうな?(おそらくsetpos()的な命令(?)が存在しているか消えてなくなってる)

podhmopodhmo

コミット自体はテストがめちゃくちゃ生成されていると言うこととrangefunc.Rewrite()が本体と言うことがわかれば十分そう。あとは普通にコードを読むだけになる。

podhmopodhmo

go/astとほとんど変わんないので何故かなんとなく読めるな。。

Hidden comment