Example #1
0
    Symbol GetSymbol(System.Type type)
    {
        NameSpace ns   = GetNameSpace(type);
        string    name = GetName(type);
        Type      t    = ns.members[name] as Type;

        if (t != null)
        {
            return(t);
        }
        if (type.IsInterface)
        {
            t = GetInterface(type, ns.members);
        }
        else if (type.IsEnum)
        {
            t = GetEnum(type, ns.members);
        }
        else if (type.IsValueType)
        {
            t = GetStruct(type, ns.members);
        }
        else if (type.IsClass &&
                 (type.BaseType == typeof(System.Delegate) || type.BaseType == typeof(System.MulticastDelegate)))
        {
            t = GetDelegate(type, ns.members);
        }
        else if (type.IsArray)
        {
            t = new ArrayType(GetType(type.GetElementType()), type.GetArrayRank(), global.Types.Array);
        }
        else if (type.IsByRef)
        {
            t = new ManagedPointerType(GetType(type.GetElementType()));
        }
        else if (type.IsPointer)
        {
            t = new UnmanagedPointerType(GetType(type.GetElementType()));
        }
        else if (type.IsClass || type.IsAnsiClass)
        {
            t = GetClass(type, ns.members);
        }
        else
        {
            Debug.Fail("unknown type " + type.FullName);
        }
        t.module = type.Assembly.Location.ToLower();
        t.type   = type;
        return(t);
    }
Example #2
0
        private void InferTypeAndUpdateStack(Instruction instruction)
        {
            Contract.Requires(instruction != null);
            switch (instruction.Operation.OperationCode)
            {
            case OperationCode.Add:
            case OperationCode.Add_Ovf:
            case OperationCode.Div:
            case OperationCode.Mul:
            case OperationCode.Mul_Ovf:
            case OperationCode.Rem:
            case OperationCode.Sub:
            case OperationCode.Sub_Ovf:
                this.stack.Pop();
                this.stack.Pop();
                instruction.Type = this.GetBinaryNumericOperationType(instruction);
                this.stack.Push(instruction);
                break;

            case OperationCode.And:
            case OperationCode.Or:
            case OperationCode.Xor:
                Contract.Assume(instruction.Operand1 != null);
                Contract.Assume(instruction.Operand2 is Instruction);
                if (instruction.Operand1.Type.TypeCode == PrimitiveTypeCode.Boolean && ((Instruction)instruction.Operand2).Type.TypeCode == PrimitiveTypeCode.Boolean)
                {
                    this.stack.Pop();
                    this.stack.Pop();
                    instruction.Type = this.platformType.SystemBoolean;
                    this.stack.Push(instruction);
                    break;
                }
                goto case OperationCode.Add;

            case OperationCode.Add_Ovf_Un:
            case OperationCode.Div_Un:
            case OperationCode.Mul_Ovf_Un:
            case OperationCode.Rem_Un:
            case OperationCode.Sub_Ovf_Un:
                this.stack.Pop();
                this.stack.Pop();
                instruction.Type = this.GetUnsignedBinaryNumericOperationType(instruction);
                this.stack.Push(instruction);
                break;

            case OperationCode.Arglist:
                instruction.Type = this.platformType.SystemRuntimeArgumentHandle;
                this.stack.Push(instruction);
                break;

            case OperationCode.Array_Addr:
                var arrayType = instruction.Operation.Value as IArrayTypeReference;
                Contract.Assume(arrayType != null); //This is an informally specified property of the Metadata model.
                for (var i = arrayType.Rank; i > 0; i--)
                {
                    this.stack.Pop();
                }
                this.stack.Pop();
                instruction.Type = ManagedPointerType.GetManagedPointerType(arrayType.ElementType, this.internFactory);
                this.stack.Push(instruction);
                break;

            case OperationCode.Array_Create:
                arrayType = instruction.Operation.Value as IArrayTypeReference;
                Contract.Assume(arrayType != null); //This is an informally specified property of the Metadata model.
                for (var i = arrayType.Rank; i > 0; i--)
                {
                    this.stack.Pop();
                }
                instruction.Type = arrayType;
                this.stack.Push(instruction);
                break;

            case OperationCode.Array_Create_WithLowerBound:
                arrayType = instruction.Operation.Value as IArrayTypeReference;
                Contract.Assume(arrayType != null); //This is an informally specified property of the Metadata model.
                for (var i = arrayType.Rank * 2; i > 0; i--)
                {
                    this.stack.Pop();
                }
                instruction.Type = arrayType;
                this.stack.Push(instruction);
                break;

            case OperationCode.Array_Get:
                arrayType = instruction.Operation.Value as IArrayTypeReference;
                Contract.Assume(arrayType != null); //This is an informally specified property of the Metadata model.
                for (var i = arrayType.Rank; i > 0; i--)
                {
                    this.stack.Pop();
                }
                this.stack.Pop();
                instruction.Type = arrayType.ElementType;
                this.stack.Push(instruction);
                break;

            case OperationCode.Array_Set:
                arrayType = instruction.Operation.Value as IArrayTypeReference;
                Contract.Assume(arrayType != null); //This is an informally specified property of the Metadata model.
                this.stack.Pop();                   //The value to set
                for (var i = arrayType.Rank; i > 0; i--)
                {
                    this.stack.Pop();
                }
                this.stack.Pop();
                instruction.Type = this.platformType.SystemVoid;
                break;

            case OperationCode.Beq:
            case OperationCode.Beq_S:
            case OperationCode.Bge:
            case OperationCode.Bge_S:
            case OperationCode.Bge_Un:
            case OperationCode.Bge_Un_S:
            case OperationCode.Bgt:
            case OperationCode.Bgt_S:
            case OperationCode.Bgt_Un:
            case OperationCode.Bgt_Un_S:
            case OperationCode.Ble:
            case OperationCode.Ble_S:
            case OperationCode.Ble_Un:
            case OperationCode.Ble_Un_S:
            case OperationCode.Blt:
            case OperationCode.Blt_S:
            case OperationCode.Blt_Un:
            case OperationCode.Blt_Un_S:
            case OperationCode.Bne_Un:
            case OperationCode.Bne_Un_S:
            case OperationCode.Cpobj:
            case OperationCode.Stfld:
            case OperationCode.Stind_I:
            case OperationCode.Stind_I1:
            case OperationCode.Stind_I2:
            case OperationCode.Stind_I4:
            case OperationCode.Stind_I8:
            case OperationCode.Stind_R4:
            case OperationCode.Stind_R8:
            case OperationCode.Stind_Ref:
            case OperationCode.Stobj:
                this.stack.Pop();
                this.stack.Pop();
                instruction.Type = this.platformType.SystemVoid;
                break;

            case OperationCode.Box:
                this.stack.Pop();
                instruction.Type = this.platformType.SystemObject;
                this.stack.Push(instruction);
                break;

            case OperationCode.Brfalse:
            case OperationCode.Brfalse_S:
            case OperationCode.Brtrue:
            case OperationCode.Brtrue_S:
            case OperationCode.Endfilter:
            case OperationCode.Initobj:
            case OperationCode.Pop:
            case OperationCode.Starg:
            case OperationCode.Starg_S:
            case OperationCode.Stloc:
            case OperationCode.Stloc_0:
            case OperationCode.Stloc_1:
            case OperationCode.Stloc_2:
            case OperationCode.Stloc_3:
            case OperationCode.Stloc_S:
            case OperationCode.Stsfld:
            case OperationCode.Throw:
            case OperationCode.Switch:
                this.stack.Pop();
                instruction.Type = this.platformType.SystemVoid;
                break;

            case OperationCode.Call:
            case OperationCode.Callvirt:
                var signature = instruction.Operation.Value as ISignature;
                Contract.Assume(signature != null); //This is an informally specified property of the Metadata model.
                var numArguments = IteratorHelper.EnumerableCount(signature.Parameters);
                for (var i = numArguments; i > 0; i--)
                {
                    this.stack.Pop();
                }
                if (!signature.IsStatic)
                {
                    this.stack.Pop();
                }
                instruction.Type = signature.Type;
                if (signature.Type.TypeCode != PrimitiveTypeCode.Void)
                {
                    this.stack.Push(instruction);
                }
                break;

            case OperationCode.Calli:
                var funcPointer = instruction.Operation.Value as IFunctionPointerTypeReference;
                Contract.Assume(funcPointer != null); //This is an informally specified property of the Metadata model.
                this.stack.Pop();                     //The function pointer
                numArguments = IteratorHelper.EnumerableCount(funcPointer.Parameters);
                for (var i = numArguments; i > 0; i--)
                {
                    this.stack.Pop();
                }
                if (!funcPointer.IsStatic)
                {
                    this.stack.Pop();
                }
                instruction.Type = funcPointer.Type;
                if (funcPointer.Type.TypeCode != PrimitiveTypeCode.Void)
                {
                    this.stack.Push(instruction);
                }
                break;

            case OperationCode.Castclass:
            case OperationCode.Isinst:
                this.stack.Pop();
                Contract.Assume(instruction.Operation.Value is ITypeReference); //This is an informally specified property of the Metadata model.
                instruction.Type = (ITypeReference)instruction.Operation.Value;
                this.stack.Push(instruction);
                break;

            case OperationCode.Ceq:
            case OperationCode.Cgt:
            case OperationCode.Cgt_Un:
            case OperationCode.Clt:
            case OperationCode.Clt_Un:
                this.stack.Pop();
                this.stack.Pop();
                instruction.Type = this.platformType.SystemBoolean;
                this.stack.Push(instruction);
                break;

            case OperationCode.Ckfinite:
            case OperationCode.Neg:
            case OperationCode.Not:
                this.stack.Pop();
                Contract.Assume(instruction.Operand1 != null); //Assumed because of the informal specification of the DataFlowInferencer
                instruction.Type = instruction.Operand1.Type;
                this.stack.Push(instruction);
                break;

            case OperationCode.Conv_I:
            case OperationCode.Conv_Ovf_I:
            case OperationCode.Conv_Ovf_I_Un:
            case OperationCode.Ldind_I:
            case OperationCode.Localloc:
                this.stack.Pop();
                instruction.Type = this.platformType.SystemIntPtr;
                this.stack.Push(instruction);
                break;

            case OperationCode.Conv_I1:
            case OperationCode.Conv_Ovf_I1:
            case OperationCode.Conv_Ovf_I1_Un:
            case OperationCode.Ldind_I1:
                this.stack.Pop();
                instruction.Type = this.platformType.SystemInt8;
                this.stack.Push(instruction);
                break;

            case OperationCode.Conv_I2:
            case OperationCode.Conv_Ovf_I2:
            case OperationCode.Conv_Ovf_I2_Un:
            case OperationCode.Ldind_I2:
                this.stack.Pop();
                instruction.Type = this.platformType.SystemInt16;
                this.stack.Push(instruction);
                break;

            case OperationCode.Conv_I4:
            case OperationCode.Conv_Ovf_I4:
            case OperationCode.Conv_Ovf_I4_Un:
            case OperationCode.Ldind_I4:
                this.stack.Pop();
                instruction.Type = this.platformType.SystemInt32;
                this.stack.Push(instruction);
                break;

            case OperationCode.Conv_I8:
            case OperationCode.Conv_Ovf_I8:
            case OperationCode.Conv_Ovf_I8_Un:
            case OperationCode.Ldind_I8:
                this.stack.Pop();
                instruction.Type = this.platformType.SystemInt64;
                this.stack.Push(instruction);
                break;

            case OperationCode.Conv_Ovf_U:
            case OperationCode.Conv_Ovf_U_Un:
            case OperationCode.Conv_U:
            case OperationCode.Ldlen:
                this.stack.Pop();
                instruction.Type = this.platformType.SystemUIntPtr;
                this.stack.Push(instruction);
                break;

            case OperationCode.Conv_Ovf_U1:
            case OperationCode.Conv_Ovf_U1_Un:
            case OperationCode.Conv_U1:
            case OperationCode.Ldind_U1:
                this.stack.Pop();
                instruction.Type = this.platformType.SystemUInt8;
                this.stack.Push(instruction);
                break;

            case OperationCode.Conv_Ovf_U2:
            case OperationCode.Conv_Ovf_U2_Un:
            case OperationCode.Conv_U2:
            case OperationCode.Ldind_U2:
                this.stack.Pop();
                instruction.Type = this.platformType.SystemUInt16;
                this.stack.Push(instruction);
                break;

            case OperationCode.Conv_Ovf_U4:
            case OperationCode.Conv_Ovf_U4_Un:
            case OperationCode.Conv_U4:
            case OperationCode.Ldind_U4:
                this.stack.Pop();
                instruction.Type = this.platformType.SystemUInt32;
                this.stack.Push(instruction);
                break;

            case OperationCode.Conv_Ovf_U8:
            case OperationCode.Conv_Ovf_U8_Un:
            case OperationCode.Conv_U8:
                this.stack.Pop();
                instruction.Type = this.platformType.SystemUInt64;
                this.stack.Push(instruction);
                break;

            case OperationCode.Conv_R_Un:
                this.stack.Pop();
                Contract.Assume(instruction.Operand1 != null); //Assumed because of the informal specification of the DataFlowInferencer
                if (TypeHelper.SizeOfType(instruction.Operand1.Type) < 4)
                {
                    instruction.Type = this.platformType.SystemFloat32;
                }
                else
                {
                    instruction.Type = this.platformType.SystemFloat64;
                }
                this.stack.Push(instruction);
                break;

            case OperationCode.Conv_R4:
            case OperationCode.Ldind_R4:
                this.stack.Pop();
                instruction.Type = this.platformType.SystemFloat32;
                this.stack.Push(instruction);
                break;

            case OperationCode.Conv_R8:
            case OperationCode.Ldind_R8:
                this.stack.Pop();
                instruction.Type = this.platformType.SystemFloat64;
                this.stack.Push(instruction);
                break;

            case OperationCode.Cpblk:
            case OperationCode.Initblk:
            case OperationCode.Stelem:
            case OperationCode.Stelem_I:
            case OperationCode.Stelem_I1:
            case OperationCode.Stelem_I2:
            case OperationCode.Stelem_I4:
            case OperationCode.Stelem_I8:
            case OperationCode.Stelem_R4:
            case OperationCode.Stelem_R8:
            case OperationCode.Stelem_Ref:
                this.stack.Pop();
                this.stack.Pop();
                this.stack.Pop();
                instruction.Type = this.platformType.SystemVoid;
                break;

            case OperationCode.Dup:
                Contract.Assume(instruction.Operand1 != null); //Assumed because of the informal specification of the DataFlowInferencer
                instruction.Type = instruction.Operand1.Type;
                this.stack.Push(instruction);
                break;

            case OperationCode.Ldarg:
            case OperationCode.Ldarg_0:
            case OperationCode.Ldarg_1:
            case OperationCode.Ldarg_2:
            case OperationCode.Ldarg_3:
            case OperationCode.Ldarg_S:
                var parameter = instruction.Operation.Value as IParameterDefinition;
                if (parameter == null) //this arg
                {
                    instruction.Type = this.cfg.MethodBody.MethodDefinition.ContainingType;
                    if (instruction.Type.IsValueType)
                    {
                        instruction.Type = ManagedPointerType.GetManagedPointerType(instruction.Type, this.internFactory);
                    }
                }
                else
                {
                    instruction.Type = parameter.Type;
                    if (parameter.IsByReference)
                    {
                        instruction.Type = ManagedPointerType.GetManagedPointerType(instruction.Type, this.internFactory);
                    }
                }
                this.stack.Push(instruction);
                break;

            case OperationCode.Ldarga:
            case OperationCode.Ldarga_S:
                parameter = instruction.Operation.Value as IParameterDefinition;
                if (parameter == null) //this arg
                {
                    instruction.Type = ManagedPointerType.GetManagedPointerType(this.cfg.MethodBody.MethodDefinition.ContainingType, this.internFactory);
                }
                else
                {
                    instruction.Type = ManagedPointerType.GetManagedPointerType(parameter.Type, this.internFactory);
                    if (parameter.IsByReference)
                    {
                        instruction.Type = ManagedPointerType.GetManagedPointerType(instruction.Type, this.internFactory);
                    }
                }
                this.stack.Push(instruction);
                break;

            case OperationCode.Ldc_I4:
            case OperationCode.Ldc_I4_0:
            case OperationCode.Ldc_I4_1:
            case OperationCode.Ldc_I4_2:
            case OperationCode.Ldc_I4_3:
            case OperationCode.Ldc_I4_4:
            case OperationCode.Ldc_I4_5:
            case OperationCode.Ldc_I4_6:
            case OperationCode.Ldc_I4_7:
            case OperationCode.Ldc_I4_8:
            case OperationCode.Ldc_I4_M1:
            case OperationCode.Ldc_I4_S:
                instruction.Type = this.platformType.SystemInt32;
                this.stack.Push(instruction);
                break;

            case OperationCode.Ldc_I8:
                instruction.Type = this.platformType.SystemInt64;
                this.stack.Push(instruction);
                break;

            case OperationCode.Ldc_R4:
                instruction.Type = this.platformType.SystemFloat32;
                this.stack.Push(instruction);
                break;

            case OperationCode.Ldc_R8:
                instruction.Type = this.platformType.SystemFloat64;
                this.stack.Push(instruction);
                break;

            case OperationCode.Ldelem:
                this.stack.Pop();
                this.stack.Pop();
                Contract.Assume(instruction.Operation.Value is ITypeReference); //This is an informally specified property of the Metadata model.
                instruction.Type = (ITypeReference)instruction.Operation.Value;
                this.stack.Push(instruction);
                break;

            case OperationCode.Ldobj:
            case OperationCode.Unbox_Any:
                this.stack.Pop();
                Contract.Assume(instruction.Operation.Value is ITypeReference); //This is an informally specified property of the Metadata model.
                instruction.Type = (ITypeReference)instruction.Operation.Value;
                this.stack.Push(instruction);
                break;

            case OperationCode.Ldelem_I:
                this.stack.Pop();
                this.stack.Pop();
                instruction.Type = this.platformType.SystemIntPtr;
                this.stack.Push(instruction);
                break;

            case OperationCode.Ldelem_I1:
                this.stack.Pop();
                this.stack.Pop();
                instruction.Type = this.platformType.SystemInt8;
                this.stack.Push(instruction);
                break;

            case OperationCode.Ldelem_I2:
                this.stack.Pop();
                this.stack.Pop();
                instruction.Type = this.platformType.SystemInt16;
                this.stack.Push(instruction);
                break;

            case OperationCode.Ldelem_I4:
                this.stack.Pop();
                this.stack.Pop();
                instruction.Type = this.platformType.SystemInt32;
                this.stack.Push(instruction);
                break;

            case OperationCode.Ldelem_I8:
                this.stack.Pop();
                this.stack.Pop();
                instruction.Type = this.platformType.SystemInt64;
                this.stack.Push(instruction);
                break;

            case OperationCode.Ldelem_Ref:
                this.stack.Pop();
                this.stack.Pop();
                Contract.Assume(instruction.Operand1 != null); //Assumed because of the informal specification of the DataFlowInferencer
                arrayType = instruction.Operand1.Type as IArrayTypeReference;
                if (arrayType != null)
                {
                    instruction.Type = arrayType.ElementType;
                }
                else //Should only get here if the IL is bad.
                {
                    instruction.Type = this.platformType.SystemObject;
                }
                this.stack.Push(instruction);
                break;

            case OperationCode.Ldelem_R4:
                this.stack.Pop();
                this.stack.Pop();
                instruction.Type = this.platformType.SystemFloat32;
                this.stack.Push(instruction);
                break;

            case OperationCode.Ldelem_R8:
                this.stack.Pop();
                this.stack.Pop();
                instruction.Type = this.platformType.SystemFloat64;
                this.stack.Push(instruction);
                break;

            case OperationCode.Ldelem_U1:
                this.stack.Pop();
                this.stack.Pop();
                instruction.Type = this.platformType.SystemUInt8;
                this.stack.Push(instruction);
                break;

            case OperationCode.Ldelem_U2:
                this.stack.Pop();
                this.stack.Pop();
                instruction.Type = this.platformType.SystemUInt16;
                this.stack.Push(instruction);
                break;

            case OperationCode.Ldelem_U4:
                this.stack.Pop();
                this.stack.Pop();
                instruction.Type = this.platformType.SystemUInt32;
                this.stack.Push(instruction);
                break;

            case OperationCode.Ldelema:
                this.stack.Pop();
                this.stack.Pop();
                Contract.Assume(instruction.Operation.Value is ITypeReference); //This is an informally specified property of the Metadata model.
                instruction.Type = ManagedPointerType.GetManagedPointerType((ITypeReference)instruction.Operation.Value, this.internFactory);
                this.stack.Push(instruction);
                break;

            case OperationCode.Ldfld:
                this.stack.Pop();
                Contract.Assume(instruction.Operation.Value is IFieldReference); //This is an informally specified property of the Metadata model.
                instruction.Type = ((IFieldReference)instruction.Operation.Value).Type;
                this.stack.Push(instruction);
                break;

            case OperationCode.Ldsfld:
                Contract.Assume(instruction.Operation.Value is IFieldReference); //This is an informally specified property of the Metadata model.
                instruction.Type = ((IFieldReference)instruction.Operation.Value).Type;
                this.stack.Push(instruction);
                break;

            case OperationCode.Ldflda:
                this.stack.Pop();
                Contract.Assume(instruction.Operation.Value is IFieldReference); //This is an informally specified property of the Metadata model.
                instruction.Type = ManagedPointerType.GetManagedPointerType(((IFieldReference)instruction.Operation.Value).Type, this.internFactory);
                this.stack.Push(instruction);
                break;

            case OperationCode.Ldsflda:
                Contract.Assume(instruction.Operation.Value is IFieldReference); //This is an informally specified property of the Metadata model.
                instruction.Type = ManagedPointerType.GetManagedPointerType(((IFieldReference)instruction.Operation.Value).Type, this.internFactory);
                this.stack.Push(instruction);
                break;

            case OperationCode.Ldftn:
                Contract.Assume(instruction.Operation.Value is IMethodReference); //This is an informally specified property of the Metadata model.
                instruction.Type = new FunctionPointerType((IMethodReference)instruction.Operation.Value, this.internFactory);
                this.stack.Push(instruction);
                break;

            case OperationCode.Ldvirtftn:
                this.stack.Pop();
                Contract.Assume(instruction.Operation.Value is IMethodReference); //This is an informally specified property of the Metadata model.
                instruction.Type = new FunctionPointerType((IMethodReference)instruction.Operation.Value, this.internFactory);
                this.stack.Push(instruction);
                break;

            case OperationCode.Ldind_Ref:
                this.stack.Pop();
                Contract.Assume(instruction.Operand1 != null); //Assumed because of the informal specification of the DataFlowInferencer
                var ptr = instruction.Operand1.Type as IPointerTypeReference;
                if (ptr != null)
                {
                    instruction.Type = ptr.TargetType;
                }
                else
                {
                    Contract.Assume(instruction.Operand1.Type is IManagedPointerTypeReference); //This is an informally specified property of the Metadata model.
                    instruction.Type = ((IManagedPointerTypeReference)instruction.Operand1.Type).TargetType;
                }
                this.stack.Push(instruction);
                break;

            case OperationCode.Ldloc:
            case OperationCode.Ldloc_0:
            case OperationCode.Ldloc_1:
            case OperationCode.Ldloc_2:
            case OperationCode.Ldloc_3:
            case OperationCode.Ldloc_S:
                var local = instruction.Operation.Value as ILocalDefinition;
                Contract.Assume(local != null); //This is an informally specified property of the Metadata model.
                instruction.Type = local.Type;
                if (local.IsReference)
                {
                    instruction.Type = ManagedPointerType.GetManagedPointerType(instruction.Type, this.internFactory);
                }
                this.stack.Push(instruction);
                break;

            case OperationCode.Ldloca:
            case OperationCode.Ldloca_S:
                local = instruction.Operation.Value as ILocalDefinition;
                Contract.Assume(local != null); //This is an informally specified property of the Metadata model.
                instruction.Type = ManagedPointerType.GetManagedPointerType(local.Type, this.internFactory);
                if (local.IsReference)
                {
                    instruction.Type = ManagedPointerType.GetManagedPointerType(instruction.Type, this.internFactory);
                }
                this.stack.Push(instruction);
                break;

            case OperationCode.Ldnull:
                instruction.Type = this.platformType.SystemObject;
                this.stack.Push(instruction);
                break;

            case OperationCode.Ldstr:
                instruction.Type = this.platformType.SystemString;
                this.stack.Push(instruction);
                break;

            case OperationCode.Ldtoken:
                if (instruction.Operation.Value is IMethodReference)
                {
                    instruction.Type = this.platformType.SystemRuntimeMethodHandle;
                }
                else if (instruction.Operation.Value is ITypeReference)
                {
                    instruction.Type = this.platformType.SystemRuntimeTypeHandle;
                }
                else if (instruction.Operation.Value is IFieldReference)
                {
                    instruction.Type = this.platformType.SystemRuntimeFieldHandle;
                }
                else
                {
                    //this should never happen in well formed IL.
                    instruction.Type = this.platformType.SystemVoid;
                }
                this.stack.Push(instruction);
                break;

            case OperationCode.Leave:
            case OperationCode.Leave_S:
                this.stack.Clear();
                break;

            case OperationCode.Mkrefany:
                this.stack.Pop();
                instruction.Type = this.platformType.SystemTypedReference;
                this.stack.Push(instruction);
                break;

            case OperationCode.Newarr:
                this.stack.Pop();
                Contract.Assume(instruction.Operation.Value is ITypeReference); //This is an informally specified property of the Metadata model.
                instruction.Type = (ITypeReference)instruction.Operation.Value;
                this.stack.Push(instruction);
                break;

            case OperationCode.Newobj:
                var constructorReference = instruction.Operation.Value as IMethodReference;
                Contract.Assume(constructorReference != null); //This is an informally specified property of the Metadata model.
                for (var i = constructorReference.ParameterCount; i > 0; i--)
                {
                    this.stack.Pop();
                }
                instruction.Type = constructorReference.ContainingType;
                this.stack.Push(instruction);
                break;

            case OperationCode.Refanytype:
                this.stack.Pop();
                instruction.Type = this.platformType.SystemRuntimeTypeHandle;
                this.stack.Push(instruction);
                break;

            case OperationCode.Refanyval:
                this.stack.Pop();
                Contract.Assume(instruction.Operation.Value is ITypeReference); //This is an informally specified property of the Metadata model.
                instruction.Type = ManagedPointerType.GetManagedPointerType((ITypeReference)instruction.Operation.Value, this.internFactory);
                this.stack.Push(instruction);
                break;

            case OperationCode.Ret:
                if (this.cfg.MethodBody.MethodDefinition.Type.TypeCode != PrimitiveTypeCode.Void)
                {
                    instruction.Operand1 = this.stack.Pop();
                }
                instruction.Type = this.platformType.SystemVoid;
                break;

            case OperationCode.Shl:
            case OperationCode.Shr:
            case OperationCode.Shr_Un:
                this.stack.Pop();
                this.stack.Pop();
                Contract.Assume(instruction.Operand1 != null); //Assumed because of the informal specification of the DataFlowInferencer
                instruction.Type = instruction.Operand1.Type;
                this.stack.Push(instruction);
                break;

            case OperationCode.Sizeof:
                instruction.Type = this.platformType.SystemUInt32;
                this.stack.Push(instruction);
                break;

            case OperationCode.Unbox:
                this.stack.Pop();
                Contract.Assume(instruction.Operation.Value is ITypeReference); //This is an informally specified property of the Metadata model.
                instruction.Type = ManagedPointerType.GetManagedPointerType((ITypeReference)instruction.Operation.Value, this.internFactory);
                this.stack.Push(instruction);
                break;

            default:
                instruction.Type = this.platformType.SystemVoid;
                break;
            }
        }
Example #3
0
        [ContractVerification(false)] //Times out
        private void Inline(IMethodBody methodBody)
        {
            Contract.Requires(methodBody != null);

            var savedCombinedMaxStack = this.combinedMaxStack;

            this.combinedMaxStack += methodBody.MaxStack;
            if (this.combinedMaxStack > this.maxStack)
            {
                this.maxStack = this.combinedMaxStack;
            }

            var savedLocalForThis = this.localForThis;
            var nametable         = this.Host.NameTable;
            var method            = methodBody.MethodDefinition;
            var n = method.ParameterCount;

            if (!method.IsStatic)
            {
                n++;
            }
            var temps = new GeneratorLocal[n];

            for (ushort i = 0; i < n; i++)
            {
                temps[i] = new GeneratorLocal()
                {
                    MethodDefinition = method
                }
            }
            ;
            var j = 0;

            if (!method.IsStatic)
            {
                var temp0 = temps[0];
                Contract.Assume(temp0 != null);
                temp0.Name = nametable.GetNameFor("this");
                temp0.Type = method.ContainingTypeDefinition;
                if (method.ContainingTypeDefinition.IsValueType)
                {
                    temp0.Type = ManagedPointerType.GetManagedPointerType(temp0.Type, this.Host.InternFactory);
                }
                j = 1;
                this.localForThis = temp0;
            }
            foreach (var par in methodBody.MethodDefinition.Parameters)
            {
                Contract.Assume(par != null);
                Contract.Assume(j < n);
                var tempj = temps[j++];
                Contract.Assume(tempj != null);
                this.localFor[par] = tempj;
                tempj.Name         = par.Name;
                tempj.Type         = par.Type;
                if (par.IsByReference)
                {
                    tempj.Type = ManagedPointerType.GetManagedPointerType(tempj.Type, this.Host.InternFactory);
                }
            }
            this.Generator.BeginScope();
            for (int i = n - 1; i >= 0; i--)
            {
                var temp = temps[i];
                Contract.Assume(temp != null);
                this.Generator.Emit(OperationCode.Stloc, temp);
                this.TrackLocal(temp);
                this.Generator.AddVariableToCurrentScope(temp);
            }

            var savedReturnLabel = this.returnLabel;
            var returnLabel      = this.returnLabel = new ILGeneratorLabel();

            this.EmitMethodBody(methodBody);
            this.Generator.MarkLabel(returnLabel);
            this.returnLabel  = savedReturnLabel;
            this.localForThis = savedLocalForThis;
            this.Generator.EndScope();
            this.combinedMaxStack = savedCombinedMaxStack;
        }
    }
Example #4
0
        public ITypeReference PointerType(ITypeReference targetType)
        {
            var type = ManagedPointerType.GetManagedPointerType(targetType, host.InternFactory);

            return(type);
        }