コード例 #1
0
ファイル: OpNone.cs プロジェクト: aura-systems/IL2CPU
        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
ファイル: OpField.cs プロジェクト: aura-systems/IL2CPU
        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
ファイル: OpBranch.cs プロジェクト: aura-systems/IL2CPU
        public override void DoInterpretStackTypes()
        {
            // 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.IsIntegerBasedType(xPopType) || ILOp.IsLongBasedType(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 (ILOp.IsSameValueType(xValue1, xValue2))
                {
                    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!");
            }
        }