首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Reflection.Emit.ILGenerator异常处理“离开”指令

Reflection.Emit.ILGenerator异常处理“离开”指令
EN

Stack Overflow用户
提问于 2012-03-10 07:49:33
回答 1查看 1.1K关注 0票数 10

首先,一些背景信息:

我正在为一个学校项目做一个编译器。它已经在工作了,我正在花费大量的精力来修复和/或优化它。我最近遇到了一个关于is的问题,我发现当您调用以下任何成员方法时,ILGenerator对象会生成额外的leave指令:

代码语言:javascript
复制
BeginCatchBlock()
BeginExceptFilterBlock()
BeginFaultBlock()
BeginFinallyBlock()
EndExceptionBlock()

因此,您以调用BeginExceptionBlock()开始一个try语句,使用BeginCatchBlock()添加两个catch子句,可能使用BeginFinallyBlock()添加一个finally子句,然后使用EndExceptionBlock()结束受保护的代码区域。

我列出的方法会自动生成一条leave指令,分支到try语句之后的第一条指令。我不想要这些,有两个原因。其一,因为它总是生成未优化的leave指令,而不是leave.s指令,即使它只是在两个字节之外进行分支。第二,因为你不能控制leave指令的去向。

因此,如果您希望在代码中分支到其他位置,则必须添加一个编译器生成的本地变量,根据您希望在try语句中的位置设置它,让EndExceptionBlock()自动生成leave指令,然后在try块下面生成一个switch语句。或者,在调用前面的方法之前,您可以自己发出一条leaveleave.s指令,从而导致难看且无法访问的额外5个字节,如下所示:

代码语言:javascript
复制
L_00ca: leave.s L_00e5
L_00cc: leave L_00d1

这两个选项对我来说都是不可接受的。有没有办法阻止leave指令的自动生成,或者用其他方式来指定受保护的区域,而不是使用这些方法(这些方法非常烦人,而且实际上没有文档)?

编辑注意: C#编译器本身就是这样做的,所以似乎没有一个很好的理由强制我们使用它。例如,如果你有.NET 4.5测试版,反汇编下面的代码并检查它们的实现:(内部添加了异常块)

代码语言:javascript
复制
public static async Task<bool> TestAsync(int ms)
{
    var local = ms / 1000;
    Console.WriteLine("In async call, before await " + local.ToString() + "-second delay.");
    await System.Threading.Tasks.Task.Delay(ms);
    Console.WriteLine("In async call, after await " + local.ToString() + "-second delay.");

    Console.WriteLine();
    Console.WriteLine("Press any key to continue.");
    Console.ReadKey(false);
    return true;
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2012-03-10 21:59:01

据我所知,在.NET 4.0中不能做到这一点。在不使用ILGenerator的情况下创建方法体的唯一方法是使用MethodBuilder.CreateMethodBody,但这不允许您设置异常处理信息。ILGenerator会强制执行您所询问的leave指令。

但是,如果你可以选择.NET 4.5 (看起来是这样),那就看看MethodBuilder.SetMethodBody吧。这允许您自己创建IL,但仍然可以传递异常处理信息。您可以将其封装在您自己的自定义ILGenerator-like类中,使用Emit方法接受OpCode参数,并读取OpCode.SizeOpCode.Value以获取相应的字节。

当然,Mono.Cecil总是存在的,但这可能需要对您已经编写的代码进行更广泛的更改。

编辑you appear to have already figured this out yourself,但是您没有回答这个问题。你可以发布你自己问题的答案并接受它们,如果你自己想出来的话。这会让我知道我不应该浪费时间在搜索上,也会让其他有同样问题的人知道该怎么做。

票数 7
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/9642512

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档