1

我在业余时间用reflection.emit 构建一个编译器,我遇到了一个我不理解的问题。

一点上下文,我有一个包含几种类型的运行时,其中之一是 Float2,一个更简单的向量结构,具有两个浮点值(X 和 Y)。我已经制作了几个属性,可以让我调整值(a la 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]:错误:[offset 0x0000000F] [found value 'Bifrost.Psl.Compiler.Runtime.Float2'][expected address of value 'Bifrost.Psl.Compiler.Runtime.Float2'] 堆栈上的意外类型。

4

1 回答 1

4

IL 看起来不错,虽然我不知道你的Float2样子。

我发现调试它的最佳方法是将程序集保存到磁盘,然后运行​​peverify。任何生成 的代码AccessViolationException都会导致peverify 出错

编辑:newobjMSDN 上的文档谈到将对象引用推入堆栈,我认为它是指向值类型的指针。如果您从peverify收到此错误,那么我认为您需要

  1. newobj
  2. stloc到一个临时变量
  3. ldloca获取存储在临时变量中的值类型的地址
  4. call

现在我想了想,如果你直接调用像4.ToString();.

于 2010-07-05T16:01:54.230 回答