* 仮想マシン [#c5820a88] #contents 実装のためのメモやら設計方針やらを書いておくページ。 * 構成 [#ke3cf9b5] - 1つのScriptVM - 1つ以上のScriptContext ** ScriptVM [#bb572835] - 仮想マシン。 - コンパイル済みの命令コード,ユーザー定義型の初期化データ(.init)を持つ。 - staticなデータはこいつが持ち,複数のContextで共有することになる。 ** ScriptContext [#uc0127e1] - コンテキスト。スレッド。 - スタック,レジスタは各ScriptContextがそれぞれ持つ。 * ScriptVM [#hae3d592] ** 手順 [#i4dc4609] - セットアップ前準備(ユーザーがやる) -- コンパイル済みのスクリプトコードの追加。 -- 関数,クラス類,変数類のC++とのバインド。 - セットアップ -- 1) リンク&未解決シンボルのチェック。 -- 2) staticデータに.initデータをコピー。 -- 3) 各クラスのstaticコンストラクタ&statinc invariant()を実行。 - ファイナライズ -- 1) 全ScriptContextが終了していることを確認。 -- 2) ガベージコレクトを実行。 -- 3) 各クラスのstatic invariant()&staticデストラクタを実行。 -- 4) ガベージコレクトを実行。 -- 5) ゴミが残っていないかチェック。 * ScriptContext [#q24e9b98] ** 実行開始手順 [#xe3c6b37] - (ユーザーがやる) - エントリーポイントとなる関数とその引数を設定。 ** インスタンスの生成手順 [#e0c3e509] - メモリ領域は確保済みとする。 - 1) .initデータを領域にコピー。 - 2) コンストラクタがあれば実行。 - 3) invariantがあれば実行。 - 4) scopeなclassもしくはstructなオブジェクトならデストラクタスタックに自身を追加 ** 関数に入るときの手順 [#v722abbb] - 1) 関数スタックにプッシュ ** 関数から抜けるときの手順 [#saac6cfb] - 1) 関数スタックの情報を元に,デストラクタスタックに積まれているオブジェクトを必要なだけポップ&実行 - 2) 関数スタックからポップ ** メンバ関数に入るときの手順 [#e65b2f19] - 1) publicなメンバ関数の呼び出しならinvariantがあれば実行。 - 2) 『関数に入るときの手順』を実行 ** メンバ関数から抜けるときの手順 [#yf66bb06] - 1) 『関数から抜けるときの手順』を実行 - 2) publicな関数の呼び出しならinvariantがあれば実行。 ** コンストラクタの手順 [#e7a580bf] - 1) 『関数に入るときの手順』を実行 - 2) structメンバ変数をデストラクタスタックにプッシュ - 3) 関数本体を実行 - 4) invariantがあれば実行 - 5) コンストラクトが正常に終了したと判断したので,デストラクタスタックに追加済みのstructメンバ変数をポップ。 - 6) 『関数から抜けるときの手順』を実行 ** デストラクタの手順 [#m98537bc] - 1) 『関数に入るときの手順』を実行 - 2) invariantがあれば実行 - 3) 関数本体を実行 - 4) 『関数から抜けるときの手順』を実行 |