protected override void DoInitStackAnalysis(MethodBase aMethod) { base.DoInitStackAnalysis(aMethod); switch (OpCode) { case Code.Ldsfld: StackPushTypes[0] = Value.FieldType; if (StackPushTypes[0].IsEnum) { StackPushTypes[0] = StackPushTypes[0].GetEnumUnderlyingType(); } return; case Code.Ldsflda: StackPushTypes[0] = typeof(IntPtr); return; case Code.Ldfld: StackPushTypes[0] = Value.FieldType; if (StackPushTypes[0].IsEnum) { StackPushTypes[0] = StackPushTypes[0].GetEnumUnderlyingType(); } if (!Value.DeclaringType.IsValueType) { StackPopTypes[0] = Value.DeclaringType; } return; case Code.Ldflda: StackPopTypes[0] = Value.DeclaringType; if (StackPopTypes[0].IsEnum) { StackPopTypes[0] = StackPopTypes[0].GetEnumUnderlyingType(); } if (StackPopTypes[0].IsValueType) { StackPopTypes[0] = StackPopTypes[0].MakeByRefType(); } StackPushTypes[0] = ILOp.IsPointer(StackPopTypes[0]) ? StackPopTypes[0] : Value.FieldType.MakeByRefType(); return; } }
public override void DoInterpretStackTypes() { switch (OpCode) { case Code.Stfld: // pop type 0 is value and pop type 1 is object var expectedType = Value.FieldType; if (expectedType.IsEnum) { expectedType = expectedType.GetEnumUnderlyingType(); } if (StackPopTypes[1] == typeof(void *)) { return; } if (StackPopTypes[1] == expectedType || StackPopTypes[1] == Value.FieldType) { return; } if ((ILOp.IsPointer(Value.FieldType) || ILOp.IsIntegerBasedType(Value.FieldType)) && (ILOp.IsIntegerBasedType(StackPopTypes[1]) || ILOp.IsPointer(StackPopTypes[1]))) { return; } if (expectedType == typeof(bool)) { if (StackPopTypes[1] == typeof(int)) { return; } } if (StackPopTypes[1] == typeof(NullRef)) { return; } if (expectedType.IsAssignableFrom(StackPopTypes[1])) { return; } if (StackPopTypes[0] == null) { return; } if (expectedType.IsAssignableFrom(StackPopTypes[0])) { return; } if (ILOp.IsObject(expectedType) && ILOp.IsObject(StackPopTypes[0])) { return; } if (ILOp.IsPointer(expectedType) && ILOp.IsPointer(StackPopTypes[0])) { return; } if (ILOp.IsIntegerBasedType(expectedType) && ILOp.IsIntegerBasedType(StackPopTypes[0])) { return; } throw new Exception($"Wrong Poptype encountered! (Field Type = {StackPopTypes[0].FullName} expected = {expectedType.FullName})"); case Code.Stsfld: if (StackPopTypes[0] == null) { return; } if (StackPopTypes[0] == typeof(void *)) { return; } expectedType = Value.FieldType; if (expectedType.IsEnum) { expectedType = expectedType.GetEnumUnderlyingType(); } if (StackPopTypes[0] == expectedType || StackPopTypes[0] == Value.FieldType) { return; } if (ILOp.IsIntegerBasedType(expectedType) && ILOp.IsIntegerBasedType(StackPopTypes[0])) { return; } if (ILOp.IsLongBasedType(expectedType) && ILOp.IsLongBasedType(StackPopTypes[0])) { return; } if (expectedType == typeof(bool)) { if (StackPopTypes[0] == typeof(int)) { return; } } if (expectedType.IsAssignableFrom(StackPopTypes[0])) { return; } if (StackPopTypes[0] == typeof(NullRef)) { return; } if ((StackPopTypes[0] == typeof(IntPtr) || StackPopTypes[0] == typeof(UIntPtr)) & expectedType.IsPointer) { return; } throw new Exception("Wrong Poptype encountered! (Type = " + StackPopTypes[0].FullName + ", expected = " + expectedType.FullName + ")"); case Code.Ldfld: if (StackPopTypes[0] == null) { return; } if (!Value.DeclaringType.IsValueType) { return; } if (StackPopTypes[0] == Value.DeclaringType.MakePointerType() || StackPopTypes[0] == Value.DeclaringType.MakeByRefType() || StackPopTypes[0] == typeof(void *) || StackPopTypes[0] == typeof(IntPtr)) { return; } if (StackPopTypes[0] == Value.DeclaringType) { return; } throw new Exception("Wrong Poptype encountered! (Type = " + StackPopTypes[0].FullName + ", expected = " + Value.DeclaringType.FullName + ")"); } }
public override void DoInterpretStackTypes() { switch (OpCode) { case Code.Add: case Code.Add_Ovf: case Code.Add_Ovf_Un: case Code.Mul: case Code.Mul_Ovf: case Code.Mul_Ovf_Un: case Code.Div: case Code.Div_Un: case Code.Sub: case Code.Sub_Ovf: case Code.Sub_Ovf_Un: case Code.Rem: case Code.Rem_Un: case Code.Xor: case Code.And: case Code.Or: if (StackPushTypes[0] != null) { return; } if (!StackPopTypes.Contains(null)) { // PopTypes set, but PushType not yet, so fill it. if (StackPopTypes[0] == StackPopTypes[1]) { StackPushTypes[0] = StackPopTypes[0]; return; } if (ILOp.IsIntegerBasedType(StackPopTypes[0]) && ILOp.IsIntegerBasedType(StackPopTypes[1])) { StackPushTypes[0] = typeof(int); return; } if (ILOp.IsLongBasedType(StackPopTypes[0]) && ILOp.IsLongBasedType(StackPopTypes[1])) { StackPushTypes[0] = typeof(long); return; } if (ILOp.IsPointer(StackPopTypes[0]) && ILOp.IsPointer(StackPopTypes[1])) { StackPushTypes[0] = typeof(uint *); return; } if ((ILOp.IsPointer(StackPopTypes[0]) && ILOp.IsIntegerBasedType(StackPopTypes[1])) || (ILOp.IsIntegerBasedType(StackPopTypes[0]) && ILOp.IsPointer(StackPopTypes[1]))) { StackPushTypes[0] = typeof(uint *); return; } throw new NotImplementedException(string.Format("{0} on types '{1}' and '{2}' {3} not yet implemented!", OpCode, StackPopTypes[0], StackPopTypes[1], StackPopTypes[1].IsByRef)); } break; case Code.Localloc: StackPushTypes[0] = typeof(void *); return; case Code.Stelem_I2: var xTypeValue = StackPopTypes[0]; if (xTypeValue == null) { return; } if (xTypeValue == typeof(byte) || xTypeValue == typeof(char) || xTypeValue == typeof(short) || xTypeValue == typeof(ushort) || xTypeValue == typeof(int)) { return; } throw new NotImplementedException(String.Format("Stelem_I2 storing type '{0}' is not implemented!", xTypeValue)); case Code.Shl: case Code.Shr: case Code.Shr_Un: xTypeValue = StackPopTypes[1]; var xTypeShift = StackPopTypes[0]; if (xTypeValue == null || xTypeShift == null) { return; } if (xTypeValue == typeof(int) && xTypeShift == typeof(int)) { StackPushTypes[0] = typeof(int); return; } if (xTypeValue == typeof(byte) && xTypeShift == typeof(int)) { StackPushTypes[0] = typeof(int); return; } if (xTypeValue == typeof(long) && xTypeShift == typeof(int)) { StackPushTypes[0] = typeof(long); return; } if (xTypeValue == typeof(IntPtr) && xTypeShift == typeof(int)) { StackPushTypes[0] = typeof(int); return; } if (xTypeValue == typeof(int) && xTypeShift == typeof(IntPtr)) { StackPushTypes[0] = typeof(int); return; } if (xTypeValue == typeof(ushort) && xTypeShift == typeof(int)) { StackPushTypes[0] = typeof(int); return; } if (xTypeValue == typeof(char) && xTypeShift == typeof(int)) { StackPushTypes[0] = typeof(int); return; } if (xTypeValue == typeof(uint) && xTypeShift == typeof(int)) { StackPushTypes[0] = typeof(int); return; } if (xTypeValue == typeof(long) && xTypeShift == typeof(IntPtr)) { StackPushTypes[0] = typeof(long); return; } if (xTypeValue == typeof(IntPtr) && xTypeShift == typeof(IntPtr)) { StackPushTypes[0] = typeof(IntPtr); return; } if (xTypeValue == typeof(IntPtr) && xTypeShift == typeof(IntPtr)) { StackPushTypes[0] = typeof(IntPtr); return; } if (xTypeValue == typeof(ulong) && xTypeShift == typeof(int)) { StackPushTypes[0] = typeof(ulong); return; } if (xTypeValue == typeof(sbyte) && xTypeShift == typeof(int)) { StackPushTypes[0] = typeof(int); return; } if (xTypeValue == typeof(short) && xTypeShift == typeof(int)) { StackPushTypes[0] = typeof(int); return; } if (xTypeValue == typeof(UIntPtr) && xTypeShift == typeof(int)) { StackPushTypes[0] = typeof(UIntPtr); return; } if (xTypeValue == typeof(char *) && xTypeShift == typeof(int)) { StackPushTypes[0] = typeof(char *); return; } throw new NotImplementedException(String.Format("{0} with types {1} and {2} is not implemented!", OpCode, xTypeValue.FullName, xTypeShift.FullName)); case Code.Ldelem_Ref: if (StackPushTypes[0] != null) { return; } var xTypeArray = StackPopTypes[1]; if (xTypeArray == null) { return; } if (!xTypeArray.IsArray) { throw new Exception("Ldelem Array type is not an array (Actual = " + xTypeArray.FullName + ")"); } StackPushTypes[0] = xTypeArray.GetElementType(); break; case Code.Not: case Code.Neg: if (StackPushTypes[0] != null) { return; } if (StackPopTypes[0] != null) { StackPushTypes[0] = StackPopTypes[0]; return; } break; case Code.Dup: if (StackPopTypes[0] != null) { StackPushTypes[0] = StackPopTypes[0]; StackPushTypes[1] = StackPopTypes[0]; return; } return; case Code.Stind_I1: if (!ILOp.IsIntegerBasedType(StackPopTypes[0])) { throw new Exception("Wrong value type: " + StackPopTypes[0].FullName); } if (!ILOp.IsPointer(StackPopTypes[1]) && StackPopTypes[1] != typeof(int)) // can either be pointer or native int { throw new Exception("Wrong Pointer type: " + StackPopTypes[1].FullName); } break; case Code.Stind_I2: if (!ILOp.IsIntegerBasedType(StackPopTypes[0])) { throw new Exception("Wrong value type: " + StackPopTypes[0].FullName); } if (!ILOp.IsPointer(StackPopTypes[1]) && StackPopTypes[1] != typeof(int)) { throw new Exception("Wrong Pointer type: " + StackPopTypes[1].FullName); } break; case Code.Stind_I4: if (!ILOp.IsIntegerBasedType(StackPopTypes[0])) { throw new Exception("Wrong value type: " + StackPopTypes[0].FullName); } if (!ILOp.IsPointer(StackPopTypes[1]) && StackPopTypes[1] != typeof(int)) { throw new Exception("Wrong Pointer type: " + StackPopTypes[1].FullName); } break; case Code.Stind_I8: if (!ILOp.IsLongBasedType(StackPopTypes[0])) { throw new Exception("Wrong value type: " + StackPopTypes[0].FullName); } if (!ILOp.IsPointer(StackPopTypes[1]) && StackPopTypes[1] != typeof(int)) { throw new Exception("Wrong Pointer type: " + StackPopTypes[1].FullName); } break; case Code.Stind_I: if (!ILOp.IsIntegralTypeOrPointer(StackPopTypes[0])) { throw new Exception("Wrong value type: " + StackPopTypes[0].FullName); } if (!ILOp.IsPointer(StackPopTypes[1]) && StackPopTypes[1] != typeof(int)) { throw new Exception("Wrong Pointer type: " + StackPopTypes[1].FullName); } break; case Code.Ldind_Ref: if (StackPushTypes[0] != null) { return; } if (StackPopTypes[0] == null) { return; } if (!StackPopTypes[0].IsByRef && !StackPopTypes[0].IsPointer) { throw new Exception("Invalid ref type: " + StackPopTypes[0].FullName); } if (StackPopTypes[0].IsPointer) { StackPushTypes[0] = typeof(object); } else { StackPushTypes[0] = StackPopTypes[0].GetElementType(); } break; } }
protected override void DoInterpretStackTypes(ref bool aSituationChanged) { base.DoInterpretStackTypes(ref aSituationChanged); switch (OpCode) { case Code.Add: case Code.Add_Ovf: case Code.Add_Ovf_Un: case Code.Mul: case Code.Mul_Ovf: case Code.Mul_Ovf_Un: case Code.Div: case Code.Div_Un: case Code.Sub: case Code.Sub_Ovf: case Code.Sub_Ovf_Un: case Code.Rem: case Code.Rem_Un: case Code.Xor: case Code.And: case Code.Or: if (StackPushTypes[0] != null) { return; } if (!StackPopTypes.Contains(null)) { // PopTypes set, but PushType not yet, so fill it. if (StackPopTypes[0] == typeof(bool) && StackPopTypes[1] == typeof(bool)) { StackPushTypes[0] = typeof(bool); aSituationChanged = true; return; } if ((StackPopTypes[0] == typeof(bool) && StackPopTypes[1] == typeof(Int32)) || (StackPopTypes[0] == typeof(Int32) && StackPopTypes[1] == typeof(bool))) { StackPushTypes[0] = typeof(Int32); aSituationChanged = true; return; } if ((StackPopTypes[0] == typeof(IntPtr) && StackPopTypes[1] == typeof(uint *)) || (StackPopTypes[0] == typeof(uint *) && StackPopTypes[1] == typeof(IntPtr))) { StackPushTypes[0] = typeof(uint *); aSituationChanged = true; return; } if ((StackPopTypes[0] == typeof(UIntPtr) && StackPopTypes[1] == typeof(uint *)) || (StackPopTypes[0] == typeof(uint *) && StackPopTypes[1] == typeof(UIntPtr))) { StackPushTypes[0] = typeof(uint *); aSituationChanged = true; return; } if ((StackPopTypes[0] == typeof(uint) && StackPopTypes[1] == typeof(byte *)) || (StackPopTypes[0] == typeof(byte *) && StackPopTypes[1] == typeof(uint))) { StackPushTypes[0] = typeof(byte *); aSituationChanged = true; return; } if ((StackPopTypes[0] == typeof(int) && StackPopTypes[1] == typeof(byte *)) || (StackPopTypes[0] == typeof(byte *) && StackPopTypes[1] == typeof(int))) { StackPushTypes[0] = typeof(byte *); aSituationChanged = true; return; } if ((StackPopTypes[0] == typeof(IntPtr) && StackPopTypes[1] == typeof(byte *)) || (StackPopTypes[0] == typeof(byte *) && StackPopTypes[1] == typeof(IntPtr))) { StackPushTypes[0] = typeof(byte *); aSituationChanged = true; return; } if ((StackPopTypes[0] == typeof(IntPtr) && StackPopTypes[1] == typeof(char *)) || (StackPopTypes[0] == typeof(char *) && StackPopTypes[1] == typeof(IntPtr))) { StackPushTypes[0] = typeof(char *); aSituationChanged = true; return; } if ((StackPopTypes[0] == typeof(UIntPtr) && StackPopTypes[1] == typeof(char *)) || (StackPopTypes[0] == typeof(char *) && StackPopTypes[1] == typeof(UIntPtr))) { StackPushTypes[0] = typeof(char *); aSituationChanged = true; return; } if ((StackPopTypes[0] == typeof(IntPtr) && StackPopTypes[1] == typeof(uint)) || (StackPopTypes[0] == typeof(uint) && StackPopTypes[1] == typeof(IntPtr))) { StackPushTypes[0] = typeof(UIntPtr); aSituationChanged = true; return; } if ((StackPopTypes[0] == typeof(int) && StackPopTypes[1] == typeof(UIntPtr)) || (StackPopTypes[0] == typeof(UIntPtr) && StackPopTypes[1] == typeof(int))) { StackPushTypes[0] = typeof(UIntPtr); aSituationChanged = true; return; } if ((StackPopTypes[0] == typeof(int) && StackPopTypes[1] == typeof(IntPtr)) || (StackPopTypes[0] == typeof(IntPtr) && StackPopTypes[1] == typeof(int))) { StackPushTypes[0] = typeof(IntPtr); aSituationChanged = true; return; } if ((StackPopTypes[0] == typeof(int) && StackPopTypes[1] == typeof(uint)) || (StackPopTypes[0] == typeof(uint) && StackPopTypes[1] == typeof(int))) { StackPushTypes[0] = typeof(int); aSituationChanged = true; return; } if ((StackPopTypes[0] == typeof(short) && StackPopTypes[1] == typeof(ushort)) || (StackPopTypes[0] == typeof(ushort) && StackPopTypes[1] == typeof(short))) { StackPushTypes[0] = typeof(short); aSituationChanged = true; return; } if ((StackPopTypes[0] == typeof(int) && StackPopTypes[1] == typeof(byte)) || (StackPopTypes[0] == typeof(byte) && StackPopTypes[1] == typeof(int))) { StackPushTypes[0] = typeof(int); aSituationChanged = true; return; } if ((StackPopTypes[0] == typeof(int) && StackPopTypes[1] == typeof(short)) || (StackPopTypes[0] == typeof(short) && StackPopTypes[1] == typeof(int))) { StackPushTypes[0] = typeof(int); aSituationChanged = true; return; } if ((StackPopTypes[0] == typeof(long) && StackPopTypes[1] == typeof(ulong)) || (StackPopTypes[0] == typeof(ulong) && StackPopTypes[1] == typeof(long))) { StackPushTypes[0] = typeof(long); aSituationChanged = true; return; } if ((StackPopTypes[0] == typeof(int) && StackPopTypes[1] == typeof(ushort)) || (StackPopTypes[0] == typeof(ushort) && StackPopTypes[1] == typeof(int))) { StackPushTypes[0] = typeof(int); aSituationChanged = true; return; } if ((StackPopTypes[0] == typeof(byte) && StackPopTypes[1] == typeof(uint)) || (StackPopTypes[0] == typeof(uint) && StackPopTypes[1] == typeof(byte))) { StackPushTypes[0] = typeof(int); aSituationChanged = true; return; } if ((StackPopTypes[0] == typeof(ushort) && StackPopTypes[1] == typeof(uint)) || (StackPopTypes[0] == typeof(uint) && StackPopTypes[1] == typeof(ushort))) { StackPushTypes[0] = typeof(uint); aSituationChanged = true; return; } if ((StackPopTypes[0] == typeof(int) && StackPopTypes[1] == typeof(char)) || (StackPopTypes[0] == typeof(char) && StackPopTypes[1] == typeof(int))) { StackPushTypes[0] = typeof(int); aSituationChanged = true; return; } if ((StackPopTypes[0] == typeof(IntPtr) && StackPopTypes[1] == typeof(UIntPtr)) || (StackPopTypes[0] == typeof(UIntPtr) && StackPopTypes[1] == typeof(IntPtr))) { StackPushTypes[0] = typeof(UIntPtr); aSituationChanged = true; return; } if (StackPopTypes[0] == typeof(IntPtr) && StackPopTypes[1] == typeof(IntPtr)) { StackPushTypes[0] = typeof(IntPtr); aSituationChanged = true; return; } if (StackPopTypes[0] == typeof(uint) && StackPopTypes[1] == typeof(uint)) { StackPushTypes[0] = typeof(uint); aSituationChanged = true; return; } if (StackPopTypes[0] == typeof(uint) && StackPopTypes[1] == typeof(char)) { StackPushTypes[0] = typeof(uint); aSituationChanged = true; return; } if (StackPopTypes[0] == typeof(byte) && StackPopTypes[1] == typeof(byte)) { StackPushTypes[0] = typeof(byte); aSituationChanged = true; return; } if (StackPopTypes[0] == typeof(byte) && StackPopTypes[1] == typeof(ushort) || StackPopTypes[0] == typeof(ushort) && StackPopTypes[1] == typeof(byte)) { StackPushTypes[0] = typeof(ushort); aSituationChanged = true; return; } if (StackPopTypes[0] == typeof(int) && StackPopTypes[1] == typeof(int)) { StackPushTypes[0] = typeof(int); aSituationChanged = true; return; } if ((StackPopTypes[0] == typeof(int) && StackPopTypes[1] == typeof(bool)) || (StackPopTypes[0] == typeof(bool) && StackPopTypes[1] == typeof(int))) { StackPushTypes[0] = typeof(int); aSituationChanged = true; return; } if (StackPopTypes[0] == typeof(ushort) && StackPopTypes[1] == typeof(ushort)) { StackPushTypes[0] = typeof(ushort); aSituationChanged = true; return; } //Changed if (StackPopTypes[0] == typeof(short) && StackPopTypes[1] == typeof(short)) { StackPushTypes[0] = typeof(short); aSituationChanged = true; return; } if (StackPopTypes[0] == typeof(long) && StackPopTypes[1] == typeof(long)) { StackPushTypes[0] = typeof(long); aSituationChanged = true; return; } if (StackPopTypes[0] == typeof(ulong) && StackPopTypes[1] == typeof(ulong)) { StackPushTypes[0] = typeof(ulong); aSituationChanged = true; return; } if (StackPopTypes[0] == typeof(Double) && StackPopTypes[1] == typeof(Double)) { StackPushTypes[0] = typeof(Double); aSituationChanged = true; return; } if (StackPopTypes[0] == typeof(Single) && StackPopTypes[1] == typeof(Single)) { StackPushTypes[0] = typeof(Single); aSituationChanged = true; return; } if (StackPopTypes[0] == typeof(Char) && StackPopTypes[1] == typeof(Char)) { StackPushTypes[0] = typeof(Char); aSituationChanged = true; return; } if ((StackPopTypes[0] == typeof(int) && StackPopTypes[1] == typeof(sbyte)) || (StackPopTypes[0] == typeof(sbyte) && StackPopTypes[1] == typeof(int))) { StackPushTypes[0] = typeof(int); aSituationChanged = true; return; } if (StackPopTypes[0] == StackPopTypes[1] && StackPopTypes[0].IsPointer) { StackPushTypes[0] = StackPopTypes[0]; aSituationChanged = true; return; } if (StackPopTypes[0] == typeof(int) && StackPopTypes[1].IsPointer) { StackPushTypes[0] = StackPopTypes[1]; aSituationChanged = true; return; } if ((StackPopTypes[0] == typeof(IntPtr) || StackPopTypes[0] == typeof(UIntPtr)) && StackPopTypes[1].IsPointer) { StackPushTypes[0] = StackPopTypes[1]; aSituationChanged = true; return; } if (OpCode == Code.Add && ((StackPopTypes[0] == typeof(IntPtr) && (StackPopTypes[1].IsPointer || StackPopTypes[1].IsByRef)) || ((StackPopTypes[0].IsPointer || StackPopTypes[0].IsByRef) && StackPopTypes[1] == typeof(IntPtr)))) { if (StackPopTypes[0] == typeof(IntPtr)) { StackPushTypes[0] = StackPopTypes[1]; } else { StackPushTypes[0] = StackPopTypes[0]; } aSituationChanged = true; return; } throw new NotImplementedException(string.Format("{0} on types '{1}' and '{2}' not yet implemented!", OpCode, StackPopTypes[0], StackPopTypes[1])); } break; case Code.Localloc: StackPushTypes[0] = typeof(void *); aSituationChanged = true; return; case Code.Stelem_I2: var xTypeValue = StackPopTypes[0]; if (xTypeValue == null) { return; } if (xTypeValue == typeof(byte) || xTypeValue == typeof(char) || xTypeValue == typeof(short) || xTypeValue == typeof(ushort) || xTypeValue == typeof(int)) { return; } throw new NotImplementedException(String.Format("Stelem_I2 storing type '{0}' is not implemented!", xTypeValue)); case Code.Shl: case Code.Shr: case Code.Shr_Un: xTypeValue = StackPopTypes[1]; var xTypeShift = StackPopTypes[0]; if (xTypeValue == null || xTypeShift == null) { return; } if (xTypeValue == typeof(int) && xTypeShift == typeof(int)) { StackPushTypes[0] = typeof(int); aSituationChanged = true; return; } if (xTypeValue == typeof(byte) && xTypeShift == typeof(int)) { StackPushTypes[0] = typeof(int); aSituationChanged = true; return; } if (xTypeValue == typeof(long) && xTypeShift == typeof(int)) { StackPushTypes[0] = typeof(long); aSituationChanged = true; return; } if (xTypeValue == typeof(IntPtr) && xTypeShift == typeof(int)) { StackPushTypes[0] = typeof(int); aSituationChanged = true; return; } if (xTypeValue == typeof(int) && xTypeShift == typeof(IntPtr)) { StackPushTypes[0] = typeof(int); aSituationChanged = true; return; } if (xTypeValue == typeof(ushort) && xTypeShift == typeof(int)) { StackPushTypes[0] = typeof(int); aSituationChanged = true; return; } if (xTypeValue == typeof(char) && xTypeShift == typeof(int)) { StackPushTypes[0] = typeof(int); aSituationChanged = true; return; } if (xTypeValue == typeof(uint) && xTypeShift == typeof(int)) { StackPushTypes[0] = typeof(int); aSituationChanged = true; return; } if (xTypeValue == typeof(long) && xTypeShift == typeof(IntPtr)) { StackPushTypes[0] = typeof(long); aSituationChanged = true; return; } if (xTypeValue == typeof(IntPtr) && xTypeShift == typeof(IntPtr)) { StackPushTypes[0] = typeof(IntPtr); aSituationChanged = true; return; } if (xTypeValue == typeof(IntPtr) && xTypeShift == typeof(IntPtr)) { StackPushTypes[0] = typeof(IntPtr); aSituationChanged = true; return; } if (xTypeValue == typeof(ulong) && xTypeShift == typeof(int)) { StackPushTypes[0] = typeof(ulong); aSituationChanged = true; return; } if (xTypeValue == typeof(sbyte) && xTypeShift == typeof(int)) { StackPushTypes[0] = typeof(int); aSituationChanged = true; return; } if (xTypeValue == typeof(short) && xTypeShift == typeof(int)) { StackPushTypes[0] = typeof(int); aSituationChanged = true; return; } throw new NotImplementedException(String.Format("{0} with types {1} and {2} is not implemented!", OpCode, xTypeValue.FullName, xTypeShift.FullName)); case Code.Ldelem_Ref: if (StackPushTypes[0] != null) { return; } var xTypeArray = StackPopTypes[1]; if (xTypeArray == null) { return; } if (!xTypeArray.IsArray) { throw new Exception("Ldelem Array type is not an array (Actual = " + xTypeArray.FullName + ")"); } StackPushTypes[0] = xTypeArray.GetElementType(); aSituationChanged = true; break; case Code.Not: case Code.Neg: if (StackPushTypes[0] != null) { return; } if (StackPopTypes[0] != null) { StackPushTypes[0] = StackPopTypes[0]; aSituationChanged = true; return; } break; case Code.Dup: if (StackPushTypes[0] != null && StackPushTypes[1] != null) { return; } if (StackPopTypes[0] != null) { StackPushTypes[0] = StackPopTypes[0]; StackPushTypes[1] = StackPopTypes[0]; aSituationChanged = true; return; } return; case Code.Stind_I1: if (StackPopTypes[1] == null || StackPopTypes[0] == null) { return; } if (!ILOp.IsIntegralType(StackPopTypes[0])) { throw new Exception("Wrong value type: " + StackPopTypes[0].FullName); } if (!ILOp.IsPointer(StackPopTypes[1])) { throw new Exception("Wrong Pointer type: " + StackPopTypes[1].FullName); } break; case Code.Stind_I2: if (StackPopTypes[1] == null || StackPopTypes[0] == null) { return; } if (!ILOp.IsIntegralType(StackPopTypes[0])) { throw new Exception("Wrong value type: " + StackPopTypes[0].FullName); } if (!ILOp.IsPointer(StackPopTypes[1])) { throw new Exception("Wrong Pointer type: " + StackPopTypes[1].FullName); } break; case Code.Stind_I4: if (StackPopTypes[1] == null || StackPopTypes[0] == null) { return; } if (!ILOp.IsIntegralType(StackPopTypes[0])) { throw new Exception("Wrong value type: " + StackPopTypes[0].FullName); } if (!ILOp.IsPointer(StackPopTypes[1])) { throw new Exception("Wrong Pointer type: " + StackPopTypes[1].FullName); } break; case Code.Stind_I8: if (StackPopTypes[1] == null || StackPopTypes[0] == null) { return; } if (!ILOp.IsIntegralType(StackPopTypes[0])) { throw new Exception("Wrong value type: " + StackPopTypes[0].FullName); } if (!ILOp.IsPointer(StackPopTypes[1])) { throw new Exception("Wrong Pointer type: " + StackPopTypes[1].FullName); } break; case Code.Stind_I: if (StackPopTypes[1] == null || StackPopTypes[0] == null) { return; } if (!ILOp.IsIntegralTypeOrPointer(StackPopTypes[0])) { throw new Exception("Wrong value type: " + StackPopTypes[0].FullName); } if (!ILOp.IsPointer(StackPopTypes[1])) { throw new Exception("Wrong Pointer type: " + StackPopTypes[1].FullName); } break; case Code.Ldind_Ref: if (StackPushTypes[0] != null) { return; } if (StackPopTypes[0] == null) { return; } if (!StackPopTypes[0].IsByRef && !StackPopTypes[0].IsPointer) { throw new Exception("Invalid ref type: " + StackPopTypes[0].FullName); } if (StackPopTypes[0].IsPointer) { StackPushTypes[0] = typeof(object); } else { StackPushTypes[0] = StackPopTypes[0].GetElementType(); } aSituationChanged = true; break; } }
protected override void DoInterpretStackTypes(ref bool aSituationChanged) { base.DoInterpretStackTypes(ref aSituationChanged); switch (OpCode) { case Code.Stfld: if (StackPopTypes[1] == null) { return; } var expectedType = Value.FieldType; if (expectedType.IsEnum) { expectedType = expectedType.GetEnumUnderlyingType(); } else if (Value.DeclaringType.IsValueType && !Value.DeclaringType.IsPrimitive) { expectedType = typeof(void *); } if (StackPopTypes[1] == expectedType || StackPopTypes[1] == Value.FieldType) { return; } if (ILOp.IsIntegralType(expectedType) && ILOp.IsIntegralType(StackPopTypes[1])) { return; } if (expectedType == typeof(bool)) { if (StackPopTypes[1] == typeof(int)) { return; } } if (StackPopTypes[1] == typeof(NullRef)) { return; } if (expectedType.IsAssignableFrom(StackPopTypes[1])) { return; } if (StackPopTypes[0] == null) { return; } if (Value.FieldType.IsAssignableFrom(StackPopTypes[0])) { return; } if (ILOp.IsIntegralType(Value.FieldType) && ILOp.IsIntegralType(StackPopTypes[0])) { return; } if (Value.FieldType == typeof(bool) && ILOp.IsIntegralType(StackPopTypes[0])) { return; } if (Value.FieldType.IsEnum) { if (ILOp.IsIntegralType(StackPopTypes[0])) { return; } } if (ILOp.IsPointer(Value.FieldType) && ILOp.IsPointer(StackPopTypes[0])) { return; } if (Value.FieldType.IsClass && StackPopTypes[0] == typeof(NullRef)) { return; } throw new Exception("Wrong Poptype encountered! (Type = " + StackPopTypes[0].FullName + ", expected = " + expectedType.FullName + ")"); // throw new Exception("Wrong Poptype encountered!"); case Code.Stsfld: if (StackPopTypes[0] == null) { return; } expectedType = Value.FieldType; if (expectedType.IsEnum) { expectedType = expectedType.GetEnumUnderlyingType(); } if (StackPopTypes[0] == expectedType || StackPopTypes[0] == Value.FieldType) { return; } if (ILOp.IsIntegralType(expectedType) && ILOp.IsIntegralType(StackPopTypes[0])) { return; } if (expectedType == typeof(bool)) { if (StackPopTypes[0] == typeof(int)) { return; } } if (expectedType.IsAssignableFrom(StackPopTypes[0])) { return; } if (StackPopTypes[0] == typeof(NullRef)) { return; } if ((StackPopTypes[0] == typeof(IntPtr) || StackPopTypes[0] == typeof(UIntPtr)) & expectedType.IsPointer) { return; } throw new Exception("Wrong Poptype encountered! (Type = " + StackPopTypes[0].FullName + ", expected = " + expectedType.FullName + ")"); case Code.Ldfld: if (StackPopTypes[0] == null) { return; } if (!Value.DeclaringType.IsValueType) { return; } if (StackPopTypes[0] == Value.DeclaringType.MakePointerType() || StackPopTypes[0] == Value.DeclaringType.MakeByRefType() || StackPopTypes[0] == typeof(void *) || StackPopTypes[0] == typeof(IntPtr)) { return; } if (StackPopTypes[0] == Value.DeclaringType) { return; } throw new Exception("Wrong Poptype encountered! (Type = " + StackPopTypes[0].FullName + ", expected = " + Value.DeclaringType.FullName + ")"); } }