예제 #1
0
        public static void ReadMethodSignature(IMetadataImport importer, ref IntPtr pData, out CorCallingConvention cconv, out Type retType, out List <Type> argTypes)
        {
            cconv = MetadataHelperFunctions.CorSigUncompressCallingConv(ref pData);
            uint numArgs = MetadataHelperFunctions.CorSigUncompressData(ref pData);

            retType  = MetadataHelperFunctions.ReadType(importer, ref pData);
            argTypes = new List <Type> ();
            for (int n = 0; n < numArgs; n++)
            {
                argTypes.Add(MetadataHelperFunctions.ReadType(importer, ref pData));
            }
        }
예제 #2
0
        private static CorElementType GetEnumUnderlyingType(IMetadataImport importer, int tk)
        {
            IntPtr hEnum = IntPtr.Zero;
            int    mdFieldDef;
            uint   numFieldDefs;
            int    fieldAttributes;
            int    nameSize;
            int    cPlusTypeFlab;
            IntPtr ppValue;
            int    pcchValue;
            IntPtr ppvSig;
            int    size;
            int    classToken;

            importer.EnumFields(ref hEnum, tk, out mdFieldDef, 1, out numFieldDefs);
            while (numFieldDefs != 0)
            {
                importer.GetFieldProps(mdFieldDef, out classToken, null, 0, out nameSize, out fieldAttributes,
                                       out ppvSig, out size, out cPlusTypeFlab, out ppValue, out pcchValue);
                Debug.Assert(tk == classToken);

                // Enums should have one instance field that indicates the underlying type
                if ((((FieldAttributes)fieldAttributes) & FieldAttributes.Static) == 0)
                {
                    Debug.Assert(size == 2); // Primitive type field sigs should be two bytes long

                    IntPtr ppvSigTemp = ppvSig;
                    CorCallingConvention callingConv =
                        MetadataHelperFunctions.CorSigUncompressCallingConv(ref ppvSigTemp);
                    Debug.Assert(callingConv == CorCallingConvention.Field);

                    return(MetadataHelperFunctions.CorSigUncompressElementType(ref ppvSigTemp));
                }

                importer.EnumFields(ref hEnum, tk, out mdFieldDef, 1, out numFieldDefs);
            }

            Debug.Fail("Should never get here.");
            throw new ArgumentException("Non-enum passed to GetEnumUnderlyingType.");
        }
예제 #3
0
        // [Xamarin] Expression evaluator.
        public static void ReadMethodSignature(IMetadataImport importer, ref IntPtr pData, out CorCallingConvention cconv, out Type retType, out List <Type> argTypes)
        {
            cconv = MetadataHelperFunctions.CorSigUncompressCallingConv(ref pData);
            uint numArgs = 0;
            // FIXME: Use number of <T>s.
            uint types = 0;

            if ((cconv & CorCallingConvention.Generic) == CorCallingConvention.Generic)
            {
                types = MetadataHelperFunctions.CorSigUncompressData(ref pData);
            }

            if (cconv != CorCallingConvention.Field)
            {
                numArgs = MetadataHelperFunctions.CorSigUncompressData(ref pData);
            }

            retType  = MetadataHelperFunctions.ReadType(importer, ref pData);
            argTypes = new List <Type> ();
            for (int n = 0; n < numArgs; n++)
            {
                argTypes.Add(MetadataHelperFunctions.ReadType(importer, ref pData));
            }
        }
예제 #4
0
        private static object ParseDefaultValue(MetadataType declaringType, IntPtr ppvSigBlob, IntPtr ppvRawValue)
        {
            IntPtr ppvSigTemp = ppvSigBlob;
            CorCallingConvention callingConv = MetadataHelperFunctions.CorSigUncompressCallingConv(ref ppvSigTemp);

            Debug.Assert(callingConv == CorCallingConvention.Field);

            CorElementType elementType = MetadataHelperFunctions.CorSigUncompressElementType(ref ppvSigTemp);

            if (elementType == CorElementType.ELEMENT_TYPE_END || elementType == CorElementType.ELEMENT_TYPE_VALUETYPE)
            {
                uint token = MetadataHelperFunctions.CorSigUncompressToken(ref ppvSigTemp);

                if (token == declaringType.MetadataToken)
                {
                    // Static literal field of the same type as the enclosing type
                    // may be one of the value fields of an enum
                    if (declaringType.ReallyIsEnum)
                    {
                        // If so, the value will be of the enum's underlying type,
                        // so we change it from VALUETYPE to be that type so that
                        // the following code will get the value
                        elementType = declaringType.EnumUnderlyingType;
                    }
                }
            }

            switch (elementType)
            {
            case CorElementType.ELEMENT_TYPE_CHAR:
                return((char)Marshal.ReadByte(ppvRawValue));

            case CorElementType.ELEMENT_TYPE_I1:
                return((sbyte)Marshal.ReadByte(ppvRawValue));

            case CorElementType.ELEMENT_TYPE_U1:
                return(Marshal.ReadByte(ppvRawValue));

            case CorElementType.ELEMENT_TYPE_I2:
                return(Marshal.ReadInt16(ppvRawValue));

            case CorElementType.ELEMENT_TYPE_U2:
                return((ushort)Marshal.ReadInt16(ppvRawValue));

            case CorElementType.ELEMENT_TYPE_I4:
                return(Marshal.ReadInt32(ppvRawValue));

            case CorElementType.ELEMENT_TYPE_U4:
                return((uint)Marshal.ReadInt32(ppvRawValue));

            case CorElementType.ELEMENT_TYPE_I8:
                return(Marshal.ReadInt64(ppvRawValue));

            case CorElementType.ELEMENT_TYPE_U8:
                return((ulong)Marshal.ReadInt64(ppvRawValue));

            case CorElementType.ELEMENT_TYPE_I:
                return(Marshal.ReadIntPtr(ppvRawValue));

            case CorElementType.ELEMENT_TYPE_U:
            case CorElementType.ELEMENT_TYPE_R4:
            case CorElementType.ELEMENT_TYPE_R8:
            // Technically U and the floating-point ones are options in the CLI, but not in the CLS or C#, so these are NYI
            default:
                return(null);
            }
        }
        private static object ParseDefaultValue(MetadataType declaringType, IntPtr ppvSigBlob, IntPtr ppvRawValue, int rawValueSize)
        {
            IntPtr ppvSigTemp = ppvSigBlob;
            CorCallingConvention callingConv = MetadataHelperFunctions.CorSigUncompressCallingConv(ref ppvSigTemp);

            Debug.Assert(callingConv == CorCallingConvention.Field);

            CorApi.Portable.CorElementType elementType = MetadataHelperFunctions.CorSigUncompressElementType(ref ppvSigTemp);
            if (elementType == CorApi.Portable.CorElementType.ElementTypeValuetype)
            {
                uint token = MetadataHelperFunctions.CorSigUncompressToken(ref ppvSigTemp);

                if (token == declaringType.MetadataToken)
                {
                    // Static literal field of the same type as the enclosing type
                    // may be one of the value fields of an enum
                    if (declaringType.ReallyIsEnum)
                    {
                        // If so, the value will be of the enum's underlying type,
                        // so we change it from VALUETYPE to be that type so that
                        // the following code will get the value
                        elementType = declaringType.EnumUnderlyingType;
                    }
                }
            }

            switch (elementType)
            {
            case CorApi.Portable.CorElementType.ElementTypeChar:
                return((char)Marshal.ReadByte(ppvRawValue));

            case CorApi.Portable.CorElementType.ElementTypeI1:
                return((sbyte)Marshal.ReadByte(ppvRawValue));

            case CorApi.Portable.CorElementType.ElementTypeU1:
                return(Marshal.ReadByte(ppvRawValue));

            case CorApi.Portable.CorElementType.ElementTypeI2:
                return(Marshal.ReadInt16(ppvRawValue));

            case CorApi.Portable.CorElementType.ElementTypeU2:
                return((ushort)Marshal.ReadInt16(ppvRawValue));

            case CorApi.Portable.CorElementType.ElementTypeI4:
                return(Marshal.ReadInt32(ppvRawValue));

            case CorApi.Portable.CorElementType.ElementTypeU4:
                return((uint)Marshal.ReadInt32(ppvRawValue));

            case CorApi.Portable.CorElementType.ElementTypeI8:
                return(Marshal.ReadInt64(ppvRawValue));

            case CorApi.Portable.CorElementType.ElementTypeU8:
                return((ulong)Marshal.ReadInt64(ppvRawValue));

            case CorApi.Portable.CorElementType.ElementTypeI:
                return(Marshal.ReadIntPtr(ppvRawValue));

            case CorApi.Portable.CorElementType.ElementTypeString:
                return(Marshal.PtrToStringAuto(ppvRawValue, rawValueSize));

            case CorApi.Portable.CorElementType.ElementTypeR4:
                unsafe {
                    return(*(float *)ppvRawValue.ToPointer());
                }

            case CorApi.Portable.CorElementType.ElementTypeR8:
                unsafe {
                    return(*(double *)ppvRawValue.ToPointer());
                }

            case CorApi.Portable.CorElementType.ElementTypeBoolean:
                unsafe {
                    return(*(bool *)ppvRawValue.ToPointer());
                }

            default:
                return(null);
            }
        }