我在业余时间用reflection.emit构建了一个编译器,我遇到了一个我不理解的问题。
简单介绍一下,我有一个运行时,有几个类型,其中一个是Float2,它是一个更简单的向量结构,有两个浮点值(X和Y)。我已经创建了几个属性,它们允许我调整值(就像hlsl一样)。例如,如果我有一个新的Float2(1.0f,2.0f),如果我编写了类似(new Float2(1.0f,2.0f)).YX的代码,我会得到一个Float2(2.0f,1.0f),我正在我的语言中使用这个类型,并且目前正在测试这个例子(省略了语言的次要细节):
float2 a = float2(1.0, 2.0).yx;
return a;我在一个新的调用中转换float2(1.0,2.0),并在.yx中访问我的Float2类型的属性YX。
问题是我得到了一个"System.AccessViolationException :试图读取或写入受保护的内存。这通常表示其他内存已损坏。“我不明白为什么,因为如果我做这样的东西:
float2 a = float2(1.0, 2.0);
return a;万事如意。
我生成的IL代码如下(我认为问题出现在"L_0014: stloc.0“中,但我不知道为什么会这样):
.method public virtual final instance valuetype
[Bifrost.Psl]Bifrost.Psl.Compiler.Runtime.Float2 Main() cil managed
{
.maxstack 3
.locals init (
[0] valuetype [Bifrost.Psl]Bifrost.Psl.Compiler.Runtime.Float2 num)
L_0000: ldc.r4 1
L_0005: ldc.r4 2
L_000a: newobj instance void [Bifrost.Psl]Bifrost.Psl.Compiler.Runtime.Float2::.ctor(float32, float32)
L_000f: call instance valuetype [Bifrost.Psl]Bifrost.Psl.Compiler.Runtime.Float2 [Bifrost.Psl]Bifrost.Psl.Compiler.Runtime.Float2::get_XY()
L_0014: stloc.0
L_0015: ldloc.0
L_0016: ret
}peverify的结果:
IL:错误:偏移量0x0000000F堆栈上出现意外类型的值'Bifrost.Psl.Compiler.Runtime.Float2‘的预期地址。
发布于 2010-07-06 00:01:54
虽然我不知道你的Float2是什么样子,但IL看起来没问题。
我发现最好的调试方法是将程序集保存到磁盘,然后运行peverify。任何生成AccessViolationException的代码都会在peverify中导致错误。
编辑: newobj doc on MSDN谈到了将对象引用推到堆栈上,我认为它是一个指向值类型的指针。如果你从peverify得到这个错误,那么我认为你需要
指向临时variable
ldloca的newobjstloc,以获取存储在临时variablecall中的值类型的地址
考虑到这一点,如果您直接调用像4.ToString();这样的值类型,C#编译器就会这样做。
https://stackoverflow.com/questions/3180800
复制相似问题