필자는 올바르게 빌드하고 실행되는 컴파일러를 가지고 있지만 PEVerify는 특정 시점에서이를 확인할 수 없다고합니다. 문제의 지점에 대한 오류, 해당 소스 코드 및 ILDasm 출력을주의 깊게 살펴본 후 .NET 및 Mono 버전을 제외하고 PEVerify의 버그를 의심할만한 지점에서 문제를 찾을 수 없습니다. 같은 장소에서 같은 오류를보고합니다. 다음이 코드가 확인되지 않는 이유는 무엇입니까?
The problematic method 읽 0x11
Offsest
[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.
가 ??
식의 후반부에 해당로서
internal static bool InAsyncMethod(Expression value)
{
INodeWithBody ancestor = value.GetAncestor<BlockExpression>() ?? (INodeWithBody) value.GetAncestor<Method>();
return ContextAnnotations.IsAsync(ancestor);
}
오류가보고된다. 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>
호출의 반환 형식이 메서드 호출의 첫 번째 형식 매개 변수 인 경우)에 나타납니다.
PEVerify가 정확히 Method
값을 가지고있을 때 Node
유형의 값을 처리한다고 생각하게하는 원인은 무엇입니까? 그리고 그것을 고칠 수있는 방법이 있습니까?
몇 년 동안 나 자신을 여러 번 디버깅 한 결과, 거의 항상 '? :'조건부 연산자. 검증자는 수년에 걸쳐 조건을 처리하기위한 전략을 변경했으며 매우 혼란 스러울 수 있습니다. –
@EricLippert 이번에는 '??'연산자였습니다. 자세한 내용은 대답을 참조하십시오. 코드를 고정 된 두 개의 별도 문으로 다시 작성하면 코드가 정확히 같아야하므로 약간 이상합니다. 나는'csc'가 검증 할 수없는 일리노이를 생성하는 것을보고 깜짝 놀랐습니다! –
'?? '연산자는 그냥 멋진 드레스에서'? :'연산자입니다. ('&&'와'||'및'? .')'csc'가 이것을 생성하면 (1) 여러분의 csc 버전이 검증 자의 다른 버전에 대해 테스트되었습니다. (2) csc는 조건부 코드 경로에서 또 다른 사기성 버그를 겪었습니다. 보고 해주십시오. 이번에 고칠 필요가 없기 때문에 기쁩니다. 또는 (3) 둘 다. –