Пример #1
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;
            }
        }
Пример #2
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;
            }
        }
Пример #3
0
        protected override void DoInterpretStackTypes(ref bool aSituationChanged)
        {
            base.DoInterpretStackTypes(ref aSituationChanged);
            // this method is supposed to deduct push types from pop types. Branch ops don't push, but we want to do checks here,
            // to help verify other code is right
            switch (OpCode)
            {
            case Code.Brtrue:
            case Code.Brfalse:
                // check pop types according to ECMA 335
                var xPopType = StackPopTypes[0];
                if (xPopType == null)
                {
                    return;
                }
                if (ILOp.IsIntegralType(xPopType))
                {
                    return;
                }
                if (xPopType.IsClass)
                {
                    return;
                }
                if (xPopType.IsInterface)
                {
                    return;
                }
                // ECMA apparently sees a boolean on the stack as a native int. We push as boolean, so acccept that as well
                if (xPopType == typeof(bool))
                {
                    return;
                }

                throw new Exception("Invalid type in PopTypes! (Type = '" + xPopType.AssemblyQualifiedName + "')");

            case Code.Br:
            case Code.Leave:
                return;

            case Code.Blt:
            case Code.Ble:
            case Code.Beq:
            case Code.Bge:
            case Code.Bgt:
            case Code.Bge_Un:
            case Code.Blt_Un:
            case Code.Ble_Un:
            case Code.Bne_Un:
            case Code.Bgt_Un:
                var xValue1 = StackPopTypes[0];
                var xValue2 = StackPopTypes[1];
                if (xValue1 == null || xValue2 == null)
                {
                    return;
                }
                if (ILOp.IsIntegralTypeOrPointer(xValue1) && ILOp.IsIntegralTypeOrPointer(xValue2))
                {
                    return;
                }
                if (xValue1 == typeof(float) && xValue2 == typeof(float))
                {
                    return;
                }
                if (xValue1 == typeof(double) && xValue2 == typeof(double))
                {
                    return;
                }
                if (xValue1 == typeof(IntPtr) && xValue2 == typeof(IntPtr))
                {
                    return;
                }
                if (xValue1 == typeof(bool) && xValue2 == typeof(bool))
                {
                    return;
                }
                if ((xValue1 == typeof(int) && xValue2 == typeof(IntPtr)) ||
                    (xValue1 == typeof(IntPtr) && xValue2 == typeof(int)))
                {
                    return;
                }
                if ((xValue1 == typeof(UIntPtr) && xValue2 == typeof(byte *)) ||
                    (xValue1 == typeof(byte *) && xValue2 == typeof(UIntPtr)))
                {
                    return;
                }

                if ((xValue1 == typeof(long) && xValue2 == typeof(ulong)) ||
                    (xValue1 == typeof(ulong) && xValue2 == typeof(long)))
                {
                    return;
                }

                if ((xValue1 == typeof(int) && xValue2 == typeof(bool)) ||
                    (xValue1 == typeof(bool) && xValue2 == typeof(int)))
                {
                    return;
                }

                if ((xValue1.IsClass || xValue1.IsInterface) &&
                    (xValue2.IsClass || xValue2.IsInterface))
                {
                    return;
                }

                throw new Exception(String.Format("Comparing types '{0}' and '{1}' not supported!", xValue1.AssemblyQualifiedName, xValue2.AssemblyQualifiedName));

            default:
                throw new NotImplementedException("Checks for opcode " + OpCode + " not implemented!");
            }
        }