可能な限りimportの実行を遅延したgoのインタプリタが作りたい
minigo
goのインタプリタが欲しい
理由
- go/packagesが遅い
- packageに対する操作(メソッド)が持てない
機能
- 遅くて全然良い
- channelとgoroutineの実装は要らない
- importを可能な限り遅延したい
- vm的なものをdumpしたい
- エントリーポイントを変えたい(main)
- docstringに対してmarkerを付けたい
more
- replみたいなものが欲しい
- 速くしたい
- FFI?
実験
利用方法が2種類あるかもしれない?
- 既存のgoのコードを実行する
- go generateで実行する変形として利用する
あと可能ならFFIも欲しい
既存のコードの実行
例えばwebAPIのルーティングの記述のコードを実行してOpenAPI docを生成する
📝 コードのコメントをメタデータとして取り出したい。実行時に利用したい。
//minigo:description 何かここに
router.Get("/xxx/{userId}", handler.GetUser)
実際のアプリケーションコードでもあり定義のコードでもある。
疑問
- go runではだめなの?
- 何でインタプリタにしたいの?
- mainを実行するなら結果は同じじゃないの?
- goでvalidなコードを要求するなら結局reflectと闘うことになるの?
go generateで実行する変形として利用する
パッケージをオブジェクトととして利用したい。関数を取り出してあれこれしたりenumの生成みたいなHaskellで言うderivingとかrustのderiveとかdartのマクロ的なことがしたい(rustやlispのマクロみたいなものはなくて良い)
こちらはインタプリタでしか実行しないコード。
(しかしgoとしてはvalidであってほしいしgopls経由でdiagnosticはでてきてほしい)
📝 マーカーコメントを付けた関数のbodyを書き換えたい
疑問
- go generateではだめなの?
- go/astを直接使うのではだめなの?
- パッケージオブジェクトにはどうやってアクセスするの?
- swaggoみたいなレベルではだめなの?
少しずれてるが参考になるもの
コードからコードを出力する例
jsx的なもの(パーサーは自作。jsのprismaのファイルと似たような感じかも?)
なんか手軽にgoのコードを出力したい
goに拘らず独自言語で定義したら(あるいはprotobufだとか)
go/astでやると辛いのはこちらの方が良いかも
FFI的なものを呼びたい?
とりあえず、Windowsは放置してpluginでいけないかな?と思ったりしてる。
実験はこの辺でしてた(途中)
(後で転記する)
go generateではなぜだめなの?
co-location的な話かも?
TODO: 真面目に書く
実行自体はgo generateでされるかも。
go runが嫌な理由は?
調査: FFIをgoの plugin で
[!NOTE]
優先度は低い
可能ならwrapperとかも書きたくない…
どうしてほしいのか?
TODO: 書く
structなどを返したい
mainとpluginの方でそれぞれimportしてあげると大丈夫みたい
⚠️ go:linknameみたいな機構を使って無理やりその場で定義した同じレイアウトのstructの値として利用するとかはできないみたい (plugin b)
initの回数
実験。以下のような別々のpluginから共通して依存してるxのinitは2回呼ばれてしまうんだろうか?
試してみたらinit()は一度きりになってくれるみたい
package x
import "fmt"
var V = 10
func init() {
V++
fmt.Println("on init, V is", V)
}
というxをplugin_aでもplugin_bでもimportしても一度きりみたい
TODO: goのビルドキャッシュとかオブジェクトレイアウトとか調べる(buildmodeとか)。
調査: ファイルの読み込みを減らしたい
[!NOTE]
優先度は低い
- structの定義場所が分からない
キャッシュする?シンボルとファイルの一覧を持っておければ減らせるかも?
実態を保持していれば関数から取り出すことは出来るかも?
(ビルドキャッシュ的なバイナリからとりだすこともできるかも?)
go.modで記述されてる依存は変更がない事が多いかも?
importを可能な限り遅延したいとは?
dynamic import的な感じに一部だけを読み込みたい。
TODO: 真面目に書く
インタプリタ
素直なインタプリタ。記憶が確かならgo modulesに対応していない