或曰

木曜日, 6月 21, 2007

スクリプト D&I (15) システム関数登録処理 - 2

スクリプト言語からC++側の関数 (システム関数) を呼び出す際のフローと、それをサポートする C++ コード自動生成ルーチンの設計/実装が一段落。

インタプリタ型のスクリプト言語から C++ 側のコードを呼び出す場合 (a) 呼び出されたシステム関数の種別によって処理を分岐し、 (b) 仮想マシン側のメモリから引数を取出し然るべき型に変換した上で、(c) 実際の処理を行い、(d) 結果を戻り値として仮想マシンに受け渡す必要がある。

実現に際しては、システム関数の識別子をどのように保持するか(文字列で関数名を持つのか、それとも整数値を振ってID管理にするのか)、また識別子から C++ 側の対応する処理を決定する(ディスパッチ処理)方法、スクリプト側のデータ型とC++側のデータ型の対応の取り方(スクリプトのコンパイル時に確定させるか仮想マシンの記憶域にデータ型情報を付加して動的に対処するか)など考慮すべきポイントが幾つかある。

今回は軽量型の組込型言語なので、次のような利用シーンを想定している。
  • システム関数の追加/変更は頻繁に発生しえる
  • システム関数の数は数十~多くても数千程度
  • 実行時の柔軟性よりも、コスト(メモリ/CPUリソース消費量)を抑えたい
そこでスクリプト言語からのシステム関数呼び出しは、スクリプトコンパイラで中間コードに翻訳すると、仮想マシンのスタックに実引数を積むコードと、 syscall 命令 (オペランド部の整数値 - システム関数番号で呼び出す C+ 側関数を区別) の組み合わせとなるようにした。

またプログラマは本質的な処理 (c) に集中できるよう、(a), (b), (d) に関しては極力 C++ コードを自動生成し、またコンパイル時に型の不整合などが検出できるようにしてある。

大まかな処理の流れは、次の通り。
  1. システム関数を定義したヘッダファイル (ファイル名 *.sch) を用意。
  2. スクリプト言語でプログラミングする場合には *.sch を #include して、スクリプトコンパイラで解析/利用。
  3. C++コード自動作成する場合には、*.sch のみを解析できるミニスクリプトコンパイラで解析/C++コード自動生成。なお自動生成されるコードには一切手を加えず、それを #include するなどして利用できる形にしてある。
図は仮想機械の内部動作に関わるシステム関数についてのコード生成フロー図。ユーザ定義のシステム関数に関しても文書化中。

p.s.

今回初めて Boost Multi-index containers library を使ったけど、これは便利。C++ プログラマなら使い方を学んでおくべき。

ラベル:

3 件のコメント:

  • これ、ソースのアーカイブを取得する方法はあるのでしょうか?

    Anonymous mumurik さんのコメント, 11:57 午後 に投稿  

  • 分散リポジトリ管理ツール darcs をインストールしてあれば、次のコマンドでダウンロードできます。

    darcs get http://gameobj.issei.org/darcs/

    また更新頻度は1日1回ですが、下記 URL から最新版のソースコード一式がダウンロードできるように設定しました。

    http://gameobj.issei.org/GameObj-current.tar.gz

    CScript 関連のソース/ドキュメント一式は tool/src/cscript 以下にあります。

    Blogger issei さんのコメント, 12:19 午前 に投稿  

  • ありがとうございます。darcs持ってないのですが、無事落とせました。

    Anonymous mumurik さんのコメント, 1:00 午後 に投稿  

コメントを投稿



この投稿へのリンク:

リンクを作成

<< ホーム