예제 #1
0
        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 + ")");
            }
        }