Reflection.Emit中的短格式操作码出错

时间:2010-08-12 16:12:03

标签: c# reflection.emit hlsl opcode

我正在制作一种与hlsl非常相似但只支持像素着色器的小语言。此语言使用reflection.emit构建实现相同功能的点网络程序集。我目前正在测试我的分支指令“if”的实现,并且在我的一个单元测试中(一个大的if if inner if else)失败并出现以下错误消息:

System.NotSupportedException:位置处的非法单字节分支:32。请求的分支是:132。

我已经在我的案例OpCodes.Br_S中使用短格式指令来追踪问题。解决方案很简单,我用OpCodes.Br替换了OpCodes.Br_S但是我对这个解决方案有几个问题:

此解决方案是否会影响生成代码的性能? 如果我想为单个字节正确生成Br_S而对于其他情况需要Br,我该怎么做?这里的问题是我正在使用访问者模式和像“if”这样的分支指令我必须首先输出Br或Br_s,此时我无法知道剩下的代码是否需要多个单字节跳到标签。为了更好地说明我的问题,这是我为以下语句生成的代码:

我的语言:

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 

.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

在这种情况下,我使用两个简短的格式说明ble.s和br.s来实现ifs,就像.net编译器那样。但是.NET编译器能够根据具体情况选择br.s或br,我的问题是我该如何做类似的事情?

TNKS

1 个答案:

答案 0 :(得分:6)

如果要执行此操作,则需要在生成分支本身之前计算分支目标的偏移量,然后确定偏移量是否足够小以使短格式指令达到。我不认为使用Reflection.Emit库有一种特别简单的方法。