Browse Source

Fix assertion with fields declared in an unresolved class type.

pull/1213/head
Daniel Grunwald 7 years ago
parent
commit
367b396b35
  1. 38
      ICSharpCode.Decompiler/IL/ILReader.cs
  2. 15
      ICSharpCode.Decompiler/IL/Instructions/LdFlda.cs

38
ICSharpCode.Decompiler/IL/ILReader.cs

@ -1093,21 +1093,47 @@ namespace ICSharpCode.Decompiler.IL @@ -1093,21 +1093,47 @@ namespace ICSharpCode.Decompiler.IL
return inst;
default:
Warn("Expected native int or pointer, but got " + inst.ResultType);
return inst;
return new Conv(inst, PrimitiveType.I, false, Sign.None);
}
}
ILInstruction PopFieldTarget(IField field)
{
return field.DeclaringType.IsReferenceType == true ? Pop(StackType.O) : PopPointer();
switch (field.DeclaringType.IsReferenceType) {
case true:
return Pop(StackType.O);
case false:
return PopPointer();
default:
// field in unresolved type
if (PeekStackType() == StackType.O)
return Pop();
else
return PopPointer();
}
}
/// <summary>
/// Like PopFieldTarget, but supports ldfld's special behavior for fields of temporary value types.
/// </summary>
ILInstruction PopLdFldTarget(IField field)
{
if (field.DeclaringType.IsReferenceType == true)
return Pop(StackType.O);
return PeekStackType() == StackType.O ? new AddressOf(Pop()) : PopPointer();
switch (field.DeclaringType.IsReferenceType) {
case true:
return Pop(StackType.O);
case false:
// field of value type: ldfld can handle temporaries
if (PeekStackType() == StackType.O)
return new AddressOf(Pop());
else
return PopPointer();
default:
// field in unresolved type
if (PeekStackType() == StackType.O)
return Pop(StackType.O);
else
return PopPointer();
}
}
private ILInstruction Return()

15
ICSharpCode.Decompiler/IL/Instructions/LdFlda.cs

@ -25,7 +25,20 @@ namespace ICSharpCode.Decompiler.IL @@ -25,7 +25,20 @@ namespace ICSharpCode.Decompiler.IL
internal override void CheckInvariant(ILPhase phase)
{
base.CheckInvariant(phase);
Debug.Assert(field.DeclaringType.IsReferenceType == true ? (target.ResultType == StackType.O) : (target.ResultType == StackType.I || target.ResultType == StackType.Ref));
switch (field.DeclaringType.IsReferenceType) {
case true:
Debug.Assert(target.ResultType == StackType.O,
"Class fields can only be accessed with an object on the stack");
break;
case false:
Debug.Assert(target.ResultType == StackType.I || target.ResultType == StackType.Ref,
"Struct fields can only be accessed with a pointer on the stack");
break;
case null:
// field of unresolved type
Debug.Assert(target.ResultType == StackType.O || target.ResultType == StackType.I || target.ResultType == StackType.Ref);
break;
}
}
}
}

Loading…
Cancel
Save