今の所の問題点として
-
マシンが一つの結合されたコンパイル済みバイトコードしか受け付けていない
- これを配列として複数保持する必要あり
-
外部関数の参照インデックスのテーブルはVM上に載っているが、内部関数は一つのプログラム上の絶対位置しか参照できない
-
プログラム上で定義した内部関数を、他のプログラムでも参照できるようにする、シンボルテーブルがいる
-
またグローバル環境の評価も同様に、シンボル-(GlobalPos,型)変換のテーブルをコンパイラが持っていないとだめ
-
マシンをオーディオドライバ立ち上げとともにオーディオスレッドにMoveしてしまっているので、メインスレッドで新たにコンパイルしたプログラムを何かの方法でオーディオスレッドに送ってやらないといけない
- しかもできればロックフリーで
- GitHub - hawkw/sharded-slab: a lock-free concurrent slab (experimental) これかな
- それか普通にDashMapか
- しかもできればロックフリーで
-
シンボルテーブルもDashMapで作ってればなんとかなるのかな
-
VMの中にControllerみたいなDashMap系をArcで包んだものを用意しておいて、メインのマシンはオーディオスレッドに送ってしまい、Arcでコントローラーだけをメインスレッドに残しておく
-
ExecContextはRepl起動から終了まで次の情報を持ち続ける
- グローバル変数のシンボルテーブル(型情報含む)
- 内部関数のシンボルテーブル(型情報含む)
- 外部関数のシンボルテーブル(型情報含む)
ExecContextは、起動時VMのインスタンスを作る。この時VMConrollerのArc参照がVM内に渡される。
ExecContextは、ソースコードを受け取るたびにコンパイラのインスタンスを作ってはプログラムを出力し、終了する。
出力されたプログラムはVMControllerのPrograms(DashMap)に非同期でインサートされ、シンボルテーブルも更新される
Replで送られた新しいプログラム(一行だけ)のプログラムをどのスレッドで、いつ実行するかが問題
DSPの頭でReplで溜まった処理(無名関数のキュー)を順番に消化する?あるいは、
dsp = |l,r| ->(float,float){ ( new_process )}
こんな感じでREPLに送ると、実際には
fn repl_001(){
| | {
dsp = |l,r| ->(float,float){ ( new_process )}
}@now
}
みたいなのを実行したことになるとか
これだとスケジューラープラグイン実装されてることが前提にはなるし、スケジューラーにタスクを登録するのをController越しに行える必要がある
というか、メインスレッドに相当するものを別途作る方がやっぱり良さそう