4

hlslピクセルシェーダーと非常によく似ていますが、サポートする小さな言語を作成しています。この言語はreflection.emit、同じ機能を実装する.NETアセンブリを構築するために使用します。私は現在、分岐命令の実装をテストしていますifが、ユニットテストの1つ(if内部が大きいif/else)で次のエラーメッセージが表示されて失敗しました。

System.NotSupportedException:位置:32の不正な1バイトブランチ。要求されたブランチは:132でした。

私の場合、短い形式の指示を使用することで問題を追跡しましたOpCodes.Br_S。解決策は単純でしたが、私は置き換えましたOpCodes.Br_SOpCodes.Br、この解決策についていくつか質問があります。

このソリューションは、生成されたコードのパフォーマンスに影響を与えますか?

Br_Sシングルバイトを正しく生成したい場合、およびBrその他の場合はどうすればよいですか?ここでの問題は、ビジターパターンを使用してifいて、出力する必要があるような分岐命令の場合、BrまたはBr_s最初に、残りのコードがジャンプするのに1バイト以上必要かどうかを知る方法がないことです。ラベル。私の質問をよりよく説明するために、これは次のステートメントに対して生成するコードです。

私の言語:

int a = -1; if (1>1) { a=1; } else if (2>2) { a=2; }

IL:

.method public virtual final instance int32 Main() cil managed
{

    .maxstack 4
    .locals init (
        [0] int32 num)
    L_0000: ldc.i4.m1 
    L_0001: stloc.0 
    L_0002: ldc.i4.1 
    L_0003: ldc.i4.1 
    L_0004: ble.s L_000a
    L_0006: ldc.i4.1 
    L_0007: stloc.0 
    L_0008: br.s L_0010
    L_000a: ldc.i4.2 
    L_000b: ldc.i4.2 
    L_000c: ble.s L_0010
    L_000e: ldc.i4.2 
    L_000f: stloc.0 
    L_0010: ldloc.0 
    L_0011: ret 
}

この場合、私は2つの短い形式の命令を使用しble.sており、.NETコンパイラと同じようbr.sにを実装しています。ifただし、.NETコンパイラは選択することができますが、br.s場合brによっては、私の問題は、どのようにして同様のことを実行できるかということです。

Tnks

4

1 に答える 1

7

これを行う場合は、分岐自体を生成する前に分岐ターゲットへのオフセットを計算してから、オフセットが短い形式の命令で到達できるほど小さいかどうかを判断する必要があります。Reflection.Emitライブラリを使用してこれを行うための特に簡単な方法はないと思います。

于 2010-08-12T17:27:37.083 に答える