OSC2019東京・春での展示の予告
(1) 厳密ではないけどわかりやすい概要
- 現在予定通りプログラミング言語を作っています(開発ペースはいまいちですが)。今のところ名前はEssen2019-Aとなっています。1月に決めた「機械語を使わなくてよくなる言語」をもちろん目指していますが、それは少し後回しにすることにして、今はもっと基盤になる部分から書いています。
- Essenでは、(シリーズで一貫して)言語処理系内で疑似マルチタスクを実現することが理想とされています。これは プログラムA を実行中に、その変数の中身を別の プログラムB が覗き見してもよい、みたいなことをどうしてもやりたくて、そのために必要なことなのです。
- 別のプログラムから参照するだけではなく、プログラム実行中にコマンドプロンプトから print prog1.i; とかやれば、実行中のprog1のグローバル変数のiが見えちゃうとか、そういうのを想定しています。これでプログラムの実行中に不信な挙動を示したとき、プログラムを止めずに変数の値を確認できるので、デバッグがはかどるのです(デバッガがなくても)。もちろん実行中のプログラムを一時停止したり、また再開したりもできるので、ちょっと怪しいからよく調べたいときは、一時停止にしてじっくり調べることもできます。
- 一方、この考えを発展させて、プログラムを一時停止させて、それをファイルに保存し、後日ファイルからロードして再開することもできます。これもデバッグには超便利です。だって危ないところに差し掛かりそうになったら直前に保存して、そこから何度でも再開できるからです。でもこれを実現しようとすると、次回起動時に変数などのオブジェクトを同じアドレスに展開できる保証が無くなるので、生ポインタはそのままでは使えなくなってしまいます(まあ要するに内部で疑似セグメンテーションをやります)。
- でも生ポインタが使えないとなると、今度は大半の処理で速度がダウンします。EssenはJITコンパイラで速度を上げるわけですが、でもこの制約のせいでC言語にボロ負けするようになると、この言語を使う気が失せてしまうかもしれません。・・・ということでプログラム内では数ミリ秒の間は生ポインタを自由に使えることにしました。プログラムは定期的に「ここで生ポインタを全部破棄して、再取得したほうがいいですか?」と言語処理系に問い合わせます。そのタイミングで処理系はプログラムを一時停止するかどうかを決めることにしたので、ほとんど性能低下することなく、私の望みどおりの動作ができるようになりました。
- ただし、数ミリ秒ごとにこの問い合わせ処理を入れるのはそれなりに面倒ですし、ポインタ計算も(特に再取得が)いろいろめんどくさいです。ということで、それは言語側で隠ぺいして、「ソースコードは自然に書いているのに、でもこれらのメリットを享受できる」という、そんな言語を目指しています。・・・なんかもう微妙にOSっぽいです(笑)。
- それで、これのデモと説明をOSCでやりたいと思っています。
(2) より正確な記述
- Essen2019-Aにおけるアプリケーションは、関数の集合として記述します。関数にはそれぞれ番号がついています。番号ゼロは関数番号には使えないので、関数番号は1から始まります。関数番号1がアプリの実行に際して、一番最初に呼ばれます。
- 関数は必ずオブジェクトの生ポインタを受け取ります。このオブジェクトは、システムとやり取りするためのハンドルなどが入っています。そのほか、アプリが必要なデータもすべてここに格納します。だからここを書き換えながら実行が進むことになります。
- この関数は数ミリ秒以内に終了してシステムにreturnしなければいけません。そしてreturn時に整数を1つ返すことになっており、それが次に呼んでほしい関数番号になります。・・・これを繰り返すことで、アプリの処理は進んでいきます。関数が0を返したらアプリは終了です。
- 関数は割込みなどによって処理が妨げられることはありません。つまり関数の実行中はすべてのリソースに対してロックをかけていると思っていいです。だからほとんど排他処理に気を付けることなく、疑似マルチスレッドプログラミングができます。関数の中では生ポインタも自由に使えますが、そのポインタをオブジェクト内の変数などを使って次の関数へそのまま渡すことはできません(原則としては)。疑似セグメンテーションを利用して抽象的な方法で記録しておき、次の関数内でまた生ポインタに戻して使うことになります。
- なお関数は、任意の時点から今の時点まで、生ポインタを再計算しなければいけないようなイベントがあったかどうかを知ることはできます。これを使えば再計算を最小限にして高速化することができます。これのためにオブジェクト内に生ポインタを保存しておくことは許されます。
- このシステムにおいての肝は、関数が数ミリ秒以内に確実にreturnしてくれることです。ここが守られないと、システムは容易にハングアップしてしまいます。これを守らないアプリはEssen2019-Aにおいて「バグのあるアプリ」であり、直さなければいけないものです。システムは各関数の実行時間の最大値を常にモニターしており、長かったものをいつでも調べることができます。こうしてユーザはダメなアプリを早期に発見することができます。
- プログラムをこのような関数の集合で記述するというスタイルは一般的なものとはいいがたく、だからこれを隠ぺいするために(もしくは支援するために)言語処理系があり、JITコンパイルによって実行するというわけです。
- [Q] なぜ関数の番号なんですか?素直に次に実行する関数ポインタを返せばいいのに。
- [A] 関数はアプリが終了する前に書き換えられるかもしれません(そういうことをEssen2019-Aは許すのです)。そしたら関数のアドレスは変わるかもしれません(JITコンパイルを部分的にやり直すので)。もしくはオブジェクトをセーブして後日再開して、だから関数のアドレスは変わっているかもしれません。そういうことがありうるので、関数のポインタはあてにならないのです。ということで関数番号を返します。
こめんと欄