スレッド化コードの場合は、 すべての VM 命令のラベルを含んだテーブルを作成する必要もあります。 これは VM コード生成(see VM code generation)に必要であり、 ラベルは外部から見えないため、 エンジン関数内で実行する必要があります。 次に、 VM コード生成関数で使用できるように、 関数の外に渡す(そして ‘vm_prim’ に割り当てする)必要があります。
これは、 VM 命令テーブルを生成するために最初にエンジン関数を呼び出す必要があり、 その後 VM コードを生成した後、 生成された VM コードを実行するためにエンジン関数を再度呼び出す必要があることを意味します(はい、これは醜いです)。 我々のプログラム例では、 エンジン関数を呼び出すこれら 2 つのモードは、 パラメーター ip0 の値によって区別されます(0 に等しい場合はテーブルが渡され、 それ以外の場合は VM コードが実行されます)。 我々の例では、 テーブルを ‘vm_prim’ に割り当て、 それを ‘engine’ から返すことによってテーブルを渡します。
我々の例 (vmgen-ex/engine.c) では、スイッチ・ディスパッチ用のテーブルも構築します。 これは主に均一性を目的として行われます。
スイッチ・ディスパッチの場合、 enum
で case ラベルとして使用される VM 命令オペコードも定義する必要があります。
両方の目的 (VM 命令テーブルと enum )のために、 ファイル name-labels.i が Vmgen によって生成されます。 あなたはこのファイルで使用される以下のマクロを定義する必要があります:
INST_ADDR(inst_name)
¶スイッチ・ディスパッチの場合、 これは name-labels.i のどちらの使用法でもスイッチ・ラベルの名前にすぎません(‘LABEL(inst_name)’ で使用されているのと同一の名前です)。 スレッド化コード・ディスパッチの場合、 これは ‘LABEL(inst_name)’ で定義されたラベルのアドレスです。 アドレスは ‘&&’ で取得されます(see Labels as Values in GNU C Manual)。