aiscript icon indicating copy to clipboard operation
aiscript copied to clipboard

専用仮想マシンへのコンパイル

Open marihachi opened this issue 1 year ago • 33 comments

AiScript専用のバイトコードを生成する

レジスタマシンにする? Luaもこの方式らしい

  • インタプリタよりパフォーマンス良さそう
  • むつかしそう

marihachi avatar Oct 18 '23 18:10 marihachi

実装する際、レジスタと変数をどう割り当てるのか難しそうですね レジスタは有限にしかないので、スコープとかが合わさってくるとより複雑になりそう・・・😵

luaはレジスタが256個あってそれを超える数の変数を定義しようとするとエラーになるらしいです それなら単純そうだし、luaのスコープ周りの挙動がわかれば意外と実装できそうな気もするかもしれない?:thinking:

ただ、変数をより多く作りたいケースもあるかもしれない・・・?:thinking:

ikasoba avatar Oct 19 '23 03:10 ikasoba

パーサー(コンパイラ?)がバイトコードを生成してインタープリタ?がそれを読み取って実行する感じですか?(今で言うASTをバイト列に置き換える感じ)

FineArchs avatar Oct 19 '23 05:10 FineArchs

そんな感じですね、単にASTをバイト列にシリアライズすれば良いわけではないのが難しい所です

ikasoba avatar Oct 19 '23 05:10 ikasoba

有限個のレジスタだけだと枯渇しますし、メモリモデルが必要かもですね ただjs環境前提ならレジスタ数無限でも良いかもしれません

marihachi avatar Oct 19 '23 06:10 marihachi

レジスタ割当については、各レジスタが使用フラグを持って、スコープを抜けたとかで解放していけばいいのかなと思いました

marihachi avatar Oct 19 '23 06:10 marihachi

レジスタ割当については、各レジスタが使用フラグを持って、スコープを抜けたとかで解放していけばいいのかなと思いました

eval {
  var a = 'hoge'
  @func(){ return a}
}
func()

みたいな状況だとaが解放されているのにfuncにアクセスされてしまうという問題が起きそう?

FineArchs avatar Oct 19 '23 08:10 FineArchs

evalでスコープが生成されるからそのスコープの外からはfuncは参照できないし大丈夫そう

ikasoba avatar Oct 19 '23 08:10 ikasoba

確かに

var func = null
eval {
  var a = 'hoge'
  func = @(){ return a }
}
func()

問題になるのはこういうケースですね

FineArchs avatar Oct 19 '23 08:10 FineArchs

あ~詰めが甘いとありそう 新しいブロックとかで参照される変数は開放するのを除外すれば行けそうかな:thinking:

ikasoba avatar Oct 19 '23 08:10 ikasoba

パーサー(コンパイラ?)がバイトコードを生成してインタープリタ?がそれを読み取って実行する感じですか?(今で言うASTをバイト列に置き換える感じ)

少し違います パーサーとインタプリタの間にコードジェネレーターが挟まるようになりますね

marihachi avatar Oct 19 '23 09:10 marihachi

確かにさすがにパーサーで直接バイト列を生成するのは厳しそうですね…

FineArchs avatar Oct 19 '23 09:10 FineArchs

新しいブロックとかで参照される変数は開放するのを除外すれば行けそうかな🤔

今のところ参照を保持するのは配列、オブジェクト、関数なのでその3つだけ対策すれば良さそう?

FineArchs avatar Oct 19 '23 09:10 FineArchs

うーん、配列やオブジェクトだと値を参照するので、レジスタからの読み取りは発生しないはずなので、関数のみで良さそう?(JavaScript上にランタイムを実装するのであれば) ただ、配列やオブジェクトの構造の中身も確認しないといけなさそうですね

ikasoba avatar Oct 19 '23 09:10 ikasoba

あー、確かに配列やオブジェクトの要素への代入に関しては値渡しだから関数と同じ問題は起こらないのか

FineArchs avatar Oct 19 '23 09:10 FineArchs

根本的にどういう設計・思想でVMを作るかを先に考えないと決められないと思います

salano-ym avatar Oct 19 '23 09:10 salano-ym

ややこしそう

marihachi avatar Oct 19 '23 09:10 marihachi

根本的にどういう設計・思想でVMを作るかを先に考えないと決められないと思います

といいますと

marihachi avatar Oct 19 '23 09:10 marihachi

結局何が可能なのかを確認する前に設計・思想を固めるのは現実的でないような気も…?

FineArchs avatar Oct 19 '23 09:10 FineArchs

js上に実装するのか、レジスタの実装方法(何を保持できる?)、値の表現方法、命令セット、メモリ表現だとかの方針がある程度無いと何が改善できるのか分かりません 何ができるかはvmの設計次第ですし 理屈で言えば今できてることは全部できるはずです

salano-ym avatar Oct 19 '23 09:10 salano-ym

式の評価を今はASTを再帰で見てるので、そこを平坦にするだけでもパフォーマンスは良くなるのかなと思っていますね

marihachi avatar Oct 19 '23 09:10 marihachi

そうなるとJavaScript上で実装する感じになるのかな

ikasoba avatar Oct 19 '23 10:10 ikasoba

メモリ表現についてはオブジェクトを架空のメモリ上(Uint8Arrayとか)で表現するより、 レジスタにAiScriptのオブジェクトをそのまま載せたほうが早くて実装しやすい気もする (じゃないとHashMapをイチから実装する羽目になる)

ikasoba avatar Oct 19 '23 10:10 ikasoba

楽しいと思うのでいろいろ作ってみるのも良いんじゃないでしょうか!

marihachi avatar Oct 20 '23 01:10 marihachi

中途半端にオリジナルの中間コード作るよりLLVMだとか既存の技術使う方が効率的にも将来性的にも良さそう

salano-ym avatar Oct 20 '23 08:10 salano-ym

LLVM、あまり詳しくないですがランタイム実行に耐える程度にコンパイル速いんですかね? そうであればそちらも試してみるのもいいと思います。

FineArchs avatar Oct 20 '23 09:10 FineArchs

技術者層がTypeScript使用者とあまり被らないと思うのでメンテナンスが大変そうですが…

FineArchs avatar Oct 20 '23 09:10 FineArchs

LLVMのコンパイラ自体をwasmで動かせるのか気になる

ikasoba avatar Oct 20 '23 10:10 ikasoba

安全に動くようにするのが大変そうかも

marihachi avatar Oct 20 '23 10:10 marihachi

既存の技術使う方が

wasmにコンパイルする動きはあったらしいですね。何故頓挫したのかは分かりませんが

FineArchs avatar Oct 20 '23 10:10 FineArchs

スタックマシンのほうが単純に実装できるかも そんなに知識もないのでまずスタックマシンとして作ってみるのがいいかも

marihachi avatar Oct 21 '23 02:10 marihachi