hlsl
ピクセルシェーダーと非常によく似ていますが、サポートする小さな言語を作成しています。この言語はreflection.emit
、同じ機能を実装する.NETアセンブリを構築するために使用します。私は現在、分岐命令の実装をテストしていますif
が、ユニットテストの1つ(if
内部が大きいif/else
)で次のエラーメッセージが表示されて失敗しました。
System.NotSupportedException:位置:32の不正な1バイトブランチ。要求されたブランチは:132でした。
私の場合、短い形式の指示を使用することで問題を追跡しましたOpCodes.Br_S
。解決策は単純でしたが、私は置き換えましたOpCodes.Br_S
がOpCodes.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