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