Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/ant/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# If/else和while在Mono.Cecil中分支_C#_.net_Code Generation_Reflection.emit_Mono.cecil - Fatal编程技术网

C# If/else和while在Mono.Cecil中分支

C# If/else和while在Mono.Cecil中分支,c#,.net,code-generation,reflection.emit,mono.cecil,C#,.net,Code Generation,Reflection.emit,Mono.cecil,另外,Cecil不支持DefineLabel和MarkLabel。在使用if-else和while分支时,可以使用哪些替代方法(例如生成Nopopcode)来替换标签 例如: public void Run(bool someParam) { int someInt = 0; while (someParam) { someInt = someInt + 1; if (someInt == 10) someParam = false;

另外,Cecil不支持
DefineLabel
MarkLabel
。在使用if-else和while分支时,可以使用哪些替代方法(例如生成
Nop
opcode)来替换标签

例如:

public void Run(bool someParam)
{
    int someInt = 0;
    while (someParam)
    {
        someInt = someInt + 1;
        if (someInt == 10) someParam = false;
        System.Console.WriteLine(someInt);
    }
}
将具有以下反编译反射。发出代码:

Label whileLabel = gen.DefineLabel();
Label label1 = gen.DefineLabel();
Label label2 = gen.DefineLabel();
gen.Emit(OpCodes.Ldc_I4_0);
gen.Emit(OpCodes.Stloc_0);
gen.Emit(OpCodes.Br_S,label1);
gen.MarkLabel(whileLabel);
gen.Emit(OpCodes.Ldloc_0);
gen.Emit(OpCodes.Ldc_I4_1);
gen.Emit(OpCodes.Add);
gen.Emit(OpCodes.Stloc_0);
gen.Emit(OpCodes.Ldloc_0);
gen.Emit(OpCodes.Ldc_I4_S,10);
gen.Emit(OpCodes.Ceq);
gen.Emit(OpCodes.Stloc_1);
gen.Emit(OpCodes.Ldloc_1);
gen.Emit(OpCodes.Brfalse_S,label2);
gen.Emit(OpCodes.Ldc_I4_0);
gen.Emit(OpCodes.Starg_S,1);
gen.MarkLabel(label2);
gen.Emit(OpCodes.Ldloc_0);
gen.Emit(OpCodes.Call,writeLineMethod);
gen.MarkLabel(label1);
gen.Emit(OpCodes.Ldarg_1);
gen.Emit(OpCodes.Stloc_2);
gen.Emit(OpCodes.Ldloc_2);
gen.Emit(OpCodes.Brtrue_S,whileLabel);
gen.Emit(OpCodes.Ret);

如何在Cecil中“标记”标签?

基本上,在创建跳转时传递目标指令,例如:

using Mono.Cecil;
using Mono.Cecil.Cil;
using Mono.Cecil.Rocks;
using System; 
using System.Linq;
using BindingFlags = System.Reflection.BindingFlags;

using Cecilifier.Runtime;

public class SnippetRunner
{
    public static void Main(string[] args)
    {
        var assembly = AssemblyDefinition.CreateAssembly(new AssemblyNameDefinition("name", Version.Parse("1.0.0.0")), "moduleName", ModuleKind.Dll);
        var t1 = new TypeDefinition("", "Foo", TypeAttributes.AnsiClass | TypeAttributes.BeforeFieldInit | TypeAttributes.NotPublic, assembly.MainModule.TypeSystem.Object);
        assembly.MainModule.Types.Add(t1);
        t1.BaseType = assembly.MainModule.TypeSystem.Object;
        var Foo_ctor_ = new MethodDefinition(".ctor", MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.RTSpecialName | MethodAttributes.SpecialName, assembly.MainModule.TypeSystem.Void);
        t1.Methods.Add(Foo_ctor_);
        var il1 = Foo_ctor_.Body.GetILProcessor();
        var Ldarg_02 = il1.Create(OpCodes.Ldarg_0);
        il1.Append(Ldarg_02);
        var Call3 = il1.Create(OpCodes.Call, assembly.MainModule.ImportReference(TypeHelpers.DefaultCtorFor(t1.BaseType)));
        il1.Append(Call3);
        var Ret4 = il1.Create(OpCodes.Ret);
        il1.Append(Ret4);

        var Foo_F_int32 = new MethodDefinition("F", MethodAttributes.Private | MethodAttributes.HideBySig, assembly.MainModule.TypeSystem.Void);
        t1.Methods.Add(Foo_F_int32);
        var il_Foo_F_int32 = Foo_F_int32.Body.GetILProcessor();
        var x5 = new ParameterDefinition("x", ParameterAttributes.None, assembly.MainModule.TypeSystem.Int32);
        Foo_F_int32.Parameters.Add(x5);
        // if (x < 10)
        var Ldarg_16 = il_Foo_F_int32.Create(OpCodes.Ldarg_1);
        il_Foo_F_int32.Append(Ldarg_16);
        var Ldc_I47 = il_Foo_F_int32.Create(OpCodes.Ldc_I4, 10);
        il_Foo_F_int32.Append(Ldc_I47);
        il_Foo_F_int32.Append(il_Foo_F_int32.Create(OpCodes.Clt));
        var esp8 = il_Foo_F_int32.Create(OpCodes.Nop);
        il_Foo_F_int32.Append(il_Foo_F_int32.Create(OpCodes.Brfalse, esp8));
        //if body

// x = x + 1;
        var Ldarg_19 = il_Foo_F_int32.Create(OpCodes.Ldarg_1);
        il_Foo_F_int32.Append(Ldarg_19);
        var Ldc_I410 = il_Foo_F_int32.Create(OpCodes.Ldc_I4, 1);
        il_Foo_F_int32.Append(Ldc_I410);
        il_Foo_F_int32.Append(il_Foo_F_int32.Create(OpCodes.Add));
        var Starg_S11 = il_Foo_F_int32.Create(OpCodes.Starg_S, x5);
        il_Foo_F_int32.Append(Starg_S11);
        var ese12 = il_Foo_F_int32.Create(OpCodes.Nop);
        il_Foo_F_int32.Append(esp8);
        il_Foo_F_int32.Append(ese12);
        Foo_F_int32.Body.OptimizeMacros();
        var Ret13 = il_Foo_F_int32.Create(OpCodes.Ret);
        il_Foo_F_int32.Append(Ret13);

        assembly.Write(args[0]);
    }
}
使用Mono.Cecil;
使用Mono.Cecil.Cil;
使用Mono.Cecil.Rocks;
使用制度;
使用System.Linq;
使用BindingFlags=System.Reflection.BindingFlags;
使用Cecilifier.Runtime;
公共类代码段管理器
{
公共静态void Main(字符串[]args)
{
var assembly=AssemblyDefinition.CreateAssembly(新的AssemblyNameDefinition(“name”,Version.Parse(“1.0.0.0”),“moduleName”,ModuleKind.Dll);
var t1=新的类型定义(“,”Foo“,TypeAttributes.AnsiClass | TypeAttributes.BeforeFieldInit | TypeAttributes.NotPublic,assembly.MainModule.TypeSystem.Object);
汇编.MainModule.Types.Add(t1);
t1.BaseType=assembly.MainModule.TypeSystem.Object;
var Foo_ctor_=new MethodDefinition(“.ctor”,MethodAttributes.Public | MethodAttributes.hidebysing | MethodAttributes.RTSpecialName | MethodAttributes.SpecialName,assembly.MainModule.TypeSystem.Void);
t1.方法。添加(Foo_-ctor_);
var il1=Foo_ctor_.Body.GetILProcessor();
var Ldarg_02=il1.Create(操作码.Ldarg_0);
il1.追加(Ldarg_02);
var Call3=il1.Create(OpCodes.Call,assembly.MainModule.ImportReference(TypeHelpers.DefaultCtorFor(t1.BaseType));
il1.追加(Call3);
var Ret4=il1.Create(操作码.Ret);
il1.追加(Ret4);
var Foo_F_int32=新方法定义(“F”,MethodAttributes.Private | MethodAttributes.HideBySig,assembly.MainModule.TypeSystem.Void);
t1.方法。添加(Foo_F_int32);
var il_Foo_F_int32=Foo_F_int32.Body.GetILProcessor();
var x5=新参数定义(“x”,ParameterAttributes.None,assembly.MainModule.TypeSystem.Int32);
Foo_F_int32.Parameters.Add(x5);
//if(x<10)
var Ldarg_16=il_Foo_F_int32.Create(操作码.Ldarg_1);
il_Foo_F_int32.Append(Ldarg_16);
var Ldc_I47=il_Foo_F_int32.Create(opcode.Ldc_I4,10);
il_Foo_F_int32.Append(Ldc_I47);
il_Foo_F_int32.Append(il_Foo_F_int32.Create(OpCodes.Clt));
var esp8=il_Foo_F_int32.Create(opcode.Nop);
il_Foo_F_int32.Append(il_Foo_F_int32.Create(OpCodes.Brfalse,esp8));
//如果主体
//x=x+1;
var Ldarg_19=il_Foo_F_int32.Create(操作码.Ldarg_1);
il_Foo_F_int32.Append(Ldarg_19);
var Ldc_I410=il_Foo_F_int32.Create(opcode.Ldc_I4,1);
il_Foo_F_int32.Append(Ldc_I410);
il_Foo_F_int32.Append(il_Foo_F_int32.Create(opcode.Add));
var Starg_S11=il_Foo_F_int32.Create(opcode.Starg_S,x5);
il_Foo_F_int32.Append(Starg_S11);
var ese12=il_Foo_F_int32.Create(opcode.Nop);
il_Foo_F_int32.Append(esp8);
il_Foo_F_int32.附加(ese12);
Foo_F_int32.Body.OptimizeMacros();
var Ret13=il_Foo_F_int32.Create(opcode.Ret);
il_Foo_F_int32.追加(Ret13);
汇编.Write(args[0]);
}
}
顺便说一下,上面的代码是由这个工具()生成的(它可以帮助您了解Mono.Cecil),代码如下:

class Foo
{
   void F(int x)
   {
     if (x < 10)
     {
         x = x + 1;
     }
   }
}
class-Foo
{
空F(整数x)
{
if(x<10)
{
x=x+1;
}
}
}

IIRC mono中的分支
指令
。cecil以相应的
指令
对象的形式将分支的目标直接保存为操作数。。