I have a compiler that builds and works correctly, but PEVerify calls it unverifiable at some point. After carefully examining the error, the corresponding source code and ILDasm output for the point in question, I cannot find the problem to the extent that I could suspect the error in PEVerify, except that the versions of .NET and Mono report the same error in same place.
The problematic method reads as follows:
internal static bool InAsyncMethod(Expression value)
{
INodeWithBody ancestor = value.GetAncestor<BlockExpression>() ?? (INodeWithBody) value.GetAncestor<Method>();
return ContextAnnotations.IsAsync(ancestor);
}
The error is reported as:
[IL]: Error: [D: \ SDL-1.3.0-4423 \ boo \ build \ Boo.Lang.Compiler.dll: Boo.Lang.Compiler.TypeSystem.AsyncHelper :: InAsyncMethod] [offset 0x00000011] [found ref 'Boo.Lang.Compiler.Ast.Node'] [expected ref Boo.Lang.Compiler.Ast.INodeWithBody '] Unexpected type on the stack.
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 node lambdas , , INodeWithBody. , # ( , ), IL ( 000c, GetAncestor<Method> !!0), .)
PEVerify , Node , Method? ?