Error with short form codes in Reflection.Emit

I am making a small language that is very similar to hlsl, but only supports pixel shaders. This language uses reflection.emit to create point network assemblies that implement the same functionality. I am currently testing my implementation of the instructions of the "if" branch in one of my unit tests (large, if with an internal if else), with an error message:

System.NotSupportedException: Illegal single-byte branch at position: 32. The requested branch was: 132.

I traced the problem using short form instructions in my OpCodes.Br_S case. The solution was simple, I replaced OpCodes.Br_S with OpCodes.Br, however I have a few questions about this solution:

Does this decision affect the performance of the generated code? If I want to correctly generate Br_S for one byte and Br for other cases, how can I do this? The problem here is that I use the visitor pattern and for the branch instruction, such as "if", I need to output Br or Br_s first, and at that moment I do not know if there will be more than one byte in the rest of the code to go to the label. To better illustrate my question, this is the code that I generate for the following statements:

My language:

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 

} Code>

In this case, I use the two short form commands ble.s and br.s to implement ifs in exactly the same way the .net compiler does. However, the .NET compiler can choose br.s or br according to the cases, my problem is how can I do something like this?

Tnks

+3
1

, , , , . , , Reflection.Emit.

+6

Source: https://habr.com/ru/post/1759369/


All Articles