首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >.locals init上方括号的意义

.locals init上方括号的意义
EN

Stack Overflow用户
提问于 2013-09-23 17:36:11
回答 1查看 1.1K关注 0票数 1

我试图使用.NET中的反射和发射生成一个动态程序集。我得到了一个错误,“公共语言运行时检测到一个无效的程序。”我创建了另一个程序,它具有我希望使用硬编码类型的功能。我试图编写的功能最终将使用动态类型,但我可以使用ILDasm查看我需要生成的IL。我将生成的IL与编译器生成的IL进行比较。在我看到的一个方法的.locals init声明中,编译器生成的代码中有一个额外的项,

编译器生成的:

代码语言:javascript
复制
.locals init ([0] class [System.Core]System.Linq.Expressions.ParameterExpression CS$0$0000,
           [1] class [System.Core]System.Linq.Expressions.ParameterExpression[] CS$0$0001)

我的:

代码语言:javascript
复制
.locals init (class [System.Core]System.Linq.Expressions.ParameterExpression V_0,  
       class [System.Core]System.Linq.Expressions.ParameterExpression[] V_1)

我不明白编译器生成的代码中"1“和”1“的重要性。有人能告诉我这是什么意思吗?

作为一个更普遍的问题,我可以在没有太多麻烦的情况下跟踪大多数ILDasm输出。但我经常遇到一个有问题的表达。例如,在ILDasm中的这一行

代码语言:javascript
复制
callvirt   instance class [EntityFramework]System.Data.Entity.ModelConfiguration.EntityTypeConfiguration`1<!!0> [EntityFramework]System.Data.Entity.DbModelBuilder::Entity<class DynamicEdmxTrial.HardFooAsset>()

"!!0“可能指的是Entity<>的泛型类型,但我不确定,我不知道ILDasm输出是否有一个键可以向我解释其更模糊的输出。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2013-09-23 18:34:14

该规范是免费提供的这里。这需要一些习惯,但大多数细节是很容易找到的,一旦你知道了结构。

!!列在二.7.1类型中

键入::= \ Description \ Clause‘!’Int32 _Int32 _

换句话说,在C#将调用f<T, U>()的方法中,!!0T!!1U

然而,[0]是一个很好的问题。规范似乎没有解决这个问题。.locals指令在is .15.4.1.3中描述了.locals指令,该指令列出了如下语法

MethodBodyItem ::= .\x{e76f} .locals init‘(’LocalsSignature‘)’LocalsSignature ::= Local‘,’Local *Local::= Type Id‘

似乎没有任何东西允许[0]存在,除非它是Type的一部分,而且Type也不允许以[开头的任何东西。我的猜测是,这是Microsoft实现特有的一个无文档化的特性,目的是帮助人类读者了解位置0是局部变量CS$0$0000,以便生成的指令按索引访问局部变量。

对ILAsm的实验表明,这正是它的含义。使用一个简单的C#程序:

代码语言:javascript
复制
static class Program {
    static void Main() {
        int i = 0, j = 1;
    }
}

编译然后拆卸它(csc test.cs && ildasm /text test.exe >test.il)显示:

代码语言:javascript
复制
....
.locals init (int32 V_0,
         int32 V_1)
IL_0000:  nop
IL_0001:  ldc.i4.0
IL_0002:  stloc.0
IL_0003:  ldc.i4.1
IL_0004:  stloc.1
IL_0005:  ret
....

.locals修改为

代码语言:javascript
复制
.locals init ([0] int32 V_0, [0] int32 V_1)

给出一个有用的警告消息:

代码语言:javascript
复制
test.il(41) : warning : Local var slot 0 is in use

事实上,声明不同类型的变量,然后使用[2][1][0]对它们进行重新排序,组装并立即拆解结果,表明变量被重新排序了。

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

https://stackoverflow.com/questions/18965440

复制
相关文章

相似问题

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