正しくビルドして実行するコンパイラがありますが、PEVerify は特定の時点でそれを検証不能と呼んでいます。問題のエラー、対応するソース コード、および ILDasm の出力を注意深く調べた後、.NET および Mono バージョンを除いて、PEVerify のバグを疑うところまで問題を見つけることができませんでした。同じ場所で同じエラーを報告します。
問題のあるメソッドは次のようになります。
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'] スタックに予期しない型があります。
Offsest0x11
は式の後半に対応し??
ます。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
は、それぞれラムダとメソッドのノード クラスであり、どちらもINodeWithBody
インターフェースを実装します。C# (型に問題があるとビルドされない) と IL (メソッド呼び出しの最初の型パラメーターが呼び出し000c
の戻り値の型であると記述されている) の両方で、すべてが正しく表示されます。GetAncestor<Method>
!!0
Node
明らかに type の値を持っているのに、ここで type の値を扱っていると PEVerify が考える原因は何Method
ですか? そして、それを修正する方法はありますか?