我有一个可以正确构建和运行的编译器,但 PEVerify 在某个时候称它无法验证。仔细查看错误、相应的源代码和问题点的 ILDasm 输出后,我找不到问题,以至于我怀疑 PEVerify 中存在错误,除了 .NET 和 Mono 版本在同一个地方报告同样的错误。
有问题的方法如下:
internal static bool InAsyncMethod(Expression value)
{
INodeWithBody ancestor = value.GetAncestor<BlockExpression>() ?? (INodeWithBody) value.GetAncestor<Method>();
return ContextAnnotations.IsAsync(ancestor);
}
错误报告为:
[IL]:错误:[D:\SDL-1.3.0-4423\boo\build\Boo.Lang.Compiler.dll:Boo.Lang.Compiler.TypeSystem.AsyncHelper::InAsyncMethod][偏移量 0x00000011][找到参考'Boo.Lang.Compiler.Ast.Node'][expected ref Boo.Lang.Compiler.Ast.INodeWithBody'] 堆栈上的意外类型。
Offsest对应于表达式0x11
的后半部分。??
来自 ILDasm:
.method assembly hidebysig static bool InAsyncMethod(class Boo.Lang.Compiler.Ast.Expression 'value') cil managed
{
// Code size 29 (0x1d)
.maxstack 2
.locals init ([0] class Boo.Lang.Compiler.Ast.INodeWithBody ancestor,
[1] bool CS$1$0000)
IL_0000: nop
IL_0001: ldarg.0
IL_0002: callvirt instance !!0 Boo.Lang.Compiler.Ast.Node::GetAncestor<class Boo.Lang.Compiler.Ast.BlockExpression>()
IL_0007: dup
IL_0008: brtrue.s IL_0011
IL_000a: pop
IL_000b: ldarg.0
IL_000c: callvirt instance !!0 Boo.Lang.Compiler.Ast.Node::GetAncestor<class Boo.Lang.Compiler.Ast.Method>()
IL_0011: stloc.0
IL_0012: ldloc.0
IL_0013: call bool Boo.Lang.Compiler.Steps.ContextAnnotations::IsAsync(class Boo.Lang.Compiler.Ast.INodeWithBody)
IL_0018: stloc.1
IL_0019: br.s IL_001b
IL_001b: ldloc.1
IL_001c: ret
} // end of method AsyncHelper::InAsyncMethod
该类Boo.Lang.Compiler.Ast.Node
是所有 AST 节点的基类。 BlockExpression
和Method
分别是 lambda 和方法的节点类,它们都实现了INodeWithBody
接口。一切看起来都是正确的,无论是在 C#(如果存在类型问题,它将不会构建)和 IL(它说调用000c
的返回类型是GetAncestor<Method>
!!0
,方法调用的第一个类型参数。)
Node
当 PEVerify 显然具有type 值时,是什么导致它认为它在这里处理的是 type值Method
?有什么办法可以解决吗?