Пример #1
0
        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;
            }
        }
Пример #2
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 + ")");
            }
        }
Пример #3
0
        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;
            }
        }
Пример #4
0
        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;
            }
        }
Пример #5
0
        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 + ")");
            }
        }