Compiler construction 关于字段引用的MSIL问题
我有一个类,它有一个类型为generic Stack的私有变量。Compiler construction 关于字段引用的MSIL问题,compiler-construction,cil,Compiler Construction,Cil,我有一个类,它有一个类型为generic Stack的私有变量。 在类中,我声明了一个Foo方法。 在检查了IL之后,我注意到方法推送的目标实际上是方法调用集\u Property2,而不是类的字段。 编译器实际上是如何在两者之间建立连接的 public class A { public int Property1 { get; set; } public int Property2 { get; set; } } public class ShortDemo { p
在类中,我声明了一个Foo方法。
在检查了IL之后,我注意到方法推送的目标实际上是方法调用集\u Property2,而不是类的字段。
编译器实际上是如何在两者之间建立连接的
public class A
{
public int Property1 { get; set; }
public int Property2 { get; set; }
}
public class ShortDemo
{
private Stack<A> _stack = new Stack<A>();
private void Foo()
{
_stack.Push(new A()
{
Property1 = 1,
Property2 = 2
});
}
}
我看没问题。以下是选项:
A a = new A() { ... };
_stack.Push(args)
翻译为:
- 在本地0中创建对象和存储引用
- 加载堆栈字段
- 加载本地0
- 呼叫推送
_stack.Push(new A() { ... });
翻译为:
- 加载堆栈字段
- 在本地0中创建对象并存储
- 加载本地0
- 呼叫推送
在这两种情况下,堆栈都以字段和参数结束。只是在“嵌入式”对象初始值设定项版本中,在加载字段和调用方法之间有更多的工作要做。根据reflector
L_0001:“此”参考位于顶部。
L_0002:从堆栈中弹出值后,字段引用位于顶部。
L_0007:新控制台应用程序1。对象位于顶部。
L_000c:从堆栈中弹出值后,赋值表达式位于顶部。
(现在我们有两个表达式分配在顶部和字段引用)。
L_000d:顶部的可变参考。
L_000e:顶部的文字整数值。
L_000f:在弹出文本值以用作参数并将变量引用用作目标后,在顶部设置_Property1方法调用。
(现在我们有3个表达式方法调用来设置_Property1,分配表达式,然后是字段
引用)。
L_0017:与L_000f相同,以添加到堆栈的方法调用结尾 (设置属性2,设置属性1,分配,字段引用)。
L_001d:可变参考 (变量引用,集合属性2,集合属性1…) L_001e:push方法需要一个目标和一个参数。如果我假设这一行与L_000f行的工作方式相同,则位于堆栈顶部的目标设置为_Property2
我不明白你为什么写堆栈以字段和参数结束。你的字段在L_0024加载,然后方法的参数被放置在堆栈上,然后在L_0052调用
Push
。问题是什么?这里的事情太多了,很难分析。请提供一个简短但完整的程序来演示这一点,并尽可能使用简短的方法。我注意到,只有在使用对象初始值设定项时才会出现这种情况。当我创建A的新实例并将其推送到堆栈时,ldfld行从L_0002中省略并插入到L_001a,这对我来说是有意义的。这不是一个真正的答案。作为一个问题编辑会更好。
_stack.Push(new A() { ... });