Пример #1
0
        public Field(uint token)
            : base(token)
        {
            char[] szName = new char[1024];
            uint   outNameSize;
            uint   tokclass, attr, sigBlobSize, constValueType, constValueSize;
            IntPtr sigBlob, constValue;

            Context.importIntf.GetFieldProps
                (token, out tokclass, szName, 1024, out outNameSize, out attr,
                out sigBlob, out sigBlobSize,
                out constValueType, out constValue, out constValueSize);

            this.name          = Decoder.ReadString(szName, (int)outNameSize);
            this.flags         = (CorFieldAttr)attr;
            this.declaringType = Type.Get(tokclass, null);

            int idx = 0;
            CorCallingConvention b = (CorCallingConvention)Decoder.ReadValue(sigBlob, ref idx);

            if (b != CorCallingConvention.FIELD)
            {
                throw new ArgumentException("Not a field signature");
            }
            CustomMod.ReadCustomMods(sigBlob, ref idx);
            this.type = new Type(sigBlob, ref idx, this.declaringType);

            if (this.IsLiteral)
            {
                this.constValue = new ConstValue(constValueType, constValue, constValueSize);
            }
        }
Пример #2
0
        public override void ReadSignature()
        {
            uint data;
            int  dataLength = Convert.ToInt32(NuGenSignatureCompression.CorSigUncompressData(signatureBlob, out data));

            CorCallingConvention callingConvention = (CorCallingConvention)data;

            NuGenHelperFunctions.StepIntPtr(ref signatureBlob, dataLength);
            Type = ReadSignatureItem(ref signatureBlob);

            if (signatureBlob.ToInt32() < SignatureEnd)
            {
                uint genericParamCount;
                NuGenHelperFunctions.StepIntPtr(ref signatureBlob, NuGenSignatureCompression.CorSigUncompressData(signatureBlob, out genericParamCount));

                if (genericParamCount > 0)
                {
                    GenericParameters = new List <NuGenBaseSignatureItem>();

                    for (int genericParamIndex = 0; genericParamIndex < genericParamCount; genericParamIndex++)
                    {
                        GenericParameters.Add(ReadSignatureItem(ref signatureBlob));
                    }
                }
            }
        }
Пример #3
0
        private void ReadStandAloneMethodSignature(ref IntPtr signatureBlob)
        {
            uint paramCount = 0;

            if (CallingConvention == CorCallingConvention.IMAGE_CEE_CS_CALLCONV_HASTHIS)
            {
                uint data;
                NuGenHelperFunctions.StepIntPtr(ref signatureBlob, NuGenSignatureCompression.CorSigUncompressData(signatureBlob, out data));
                CorCallingConvention explicitThis = (CorCallingConvention)data;

                if (explicitThis == CorCallingConvention.IMAGE_CEE_CS_CALLCONV_EXPLICITTHIS)
                {
                    CallingConvention |= CorCallingConvention.IMAGE_CEE_CS_CALLCONV_EXPLICITTHIS;
                }
                else
                {
                    paramCount = data;
                }
            }
            else
            {
                NuGenHelperFunctions.StepIntPtr(ref signatureBlob, NuGenSignatureCompression.CorSigUncompressData(signatureBlob, out paramCount));
            }

            ReturnType = ReadSignatureItem(ref signatureBlob);

            if (paramCount > 0)
            {
                Parameters = new List <NuGenBaseSignatureItem>();

                int paramIndex = 0;
                while (paramIndex < paramCount)
                {
                    uint data;
                    NuGenSignatureCompression.CorSigUncompressData(signatureBlob, out data);
                    CorElementType elementType = (CorElementType)data;

                    if (elementType == CorElementType.ELEMENT_TYPE_SENTINEL)
                    {
                        throw new NotImplementedException("Sentinel found.");
                    }

                    if (SentinelFound)
                    {
                        if (VarargParameters == null)
                        {
                            VarargParameters = new List <NuGenBaseSignatureItem>();
                        }

                        VarargParameters.Add(ReadSignatureItem(ref signatureBlob));
                    }
                    else
                    {
                        Parameters.Add(ReadSignatureItem(ref signatureBlob));
                    }
                    paramIndex++;
                }
            }
        }
Пример #4
0
// Function translated directly from cor.h but never tested; included here in case someone wants to use it in future

/*        internal static uint CorSigUncompressToken(     // return number of bytes of that compressed data occupied in pData
 *          IntPtr pData,              // [IN] compressed data
 *          out uint     pToken)                // [OUT] the expanded *pData
 *      {
 *          uint       cb;
 *          uint     tk;
 *          uint     tkType;
 *
 *          cb = CorSigUncompressData(pData, out tk);
 *          tkType = g_tkCorEncodeToken[tk & 0x3];
 *          tk = TokenFromRid(tk >> 2, tkType);
 *          pToken = tk;
 *          return cb;
 *      }*/

        internal static CorCallingConvention CorSigUncompressCallingConv(
            ref IntPtr pData)             // [IN,OUT] compressed data
        {
            unsafe
            {
                byte *pBytes = (byte *)pData;
                CorCallingConvention retval = (CorCallingConvention)(*pBytes++);
                pData = (IntPtr)pBytes;
                return(retval);
            }
        }
Пример #5
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.");
        }
Пример #6
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);
            }
        }
Пример #7
0
        public Method(uint token, Type declaringType)
            : base(token)
        {
            char[] szName = new char[1024];
            uint   outNameSize;
            uint   tokclass, attr, sigBlobSize, codeRVA, implFlags;
            IntPtr sigBlob;

            Context.importIntf.GetMethodProps
                (this.token, out tokclass, szName, 1024, out outNameSize, out attr,
                out sigBlob, out sigBlobSize,
                out codeRVA, out implFlags);

            if ((int)outNameSize <= 1)
            {
                throw new ArgumentException
                          ("Method without names unsupported: token is 0x" + token.ToString("x"));
            }
            else
            {
                this.name = Decoder.ReadString(szName, (int)outNameSize);
            }

            int idx = 0;

            this.flags         = (CorMethodAttr)attr;
            this.declaringType = declaringType;

            // start reading the signature of this method
            int nParams, nGenericParams;
            CorCallingConvention b = (CorCallingConvention)Decoder.ReadValue(sigBlob, ref idx);

            // first byte contains the flags for HASTHIS, EXPLICITTHIS AND Default/Vararg/Generic calling conventions.

            if ((b & CorCallingConvention.UPMASK) == CorCallingConvention.HASTHIS)
            {
                this.hasThis = true;
                if ((b & CorCallingConvention.UPMASK) == CorCallingConvention.EXPLICITTHIS)
                {
                    this.explicitThis = true;
                }
            }

            nGenericParams = 0;
            if ((b & CorCallingConvention.VARARG) != 0)
            {
                throw new System.ArgumentException(this.name + ": Vararg methods not supported");
            }
            else if ((b & CorCallingConvention.GENERIC) != 0)
            {
                this.callconv  = CallingConvention.Generic;
                nGenericParams = (int)Decoder.ReadCompressed(sigBlob, ref idx);
            }

            // Retrieve first the generic parameters, as the regular ones might reverence those

            if (nGenericParams > 0)
            {
                IntPtr hHandle     = IntPtr.Zero;
                int    countTokens = 0;
                uint[] tokenRef    = new uint[1];

                Context.importIntf.EnumGenericParams(ref hHandle, this.token, tokenRef, 1, out countTokens);
                this.genParameters = new List <GenericParam>();
                while (countTokens > 0)
                {
                    try
                    {
                        this.genParameters.Add(new GenericParam(tokenRef[0]));
                    }
                    catch (System.ArgumentException e)
                    {
                        // better message formating
                        throw new System.ArgumentException(string.Format("Unsupported generic argument in method {0} : {1}", e.Message, this.name));
                    }
                    Context.importIntf.EnumGenericParams(ref hHandle, this.token, tokenRef, 1, out countTokens);
                }
                Context.importIntf.CloseEnum(hHandle);
            }

            // Now read the parameters
            nParams      = Decoder.ReadCompressed(sigBlob, ref idx);
            this.retType = new Param(sigBlob, ref idx, this);

            {
                this.parameters = new List <Param>();

                IntPtr hHandle     = IntPtr.Zero;
                int    countTokens = 0;
                uint[] tokenRef    = new uint[1];
                Context.importIntf.EnumParams(ref hHandle, this.token, tokenRef, 1, out countTokens);
                while (countTokens > 0)
                {
                    // create the corresponding object
                    Param p = null;
                    // some parameters returned by the enumerator are useless informative token
                    // this raises an exception that we ignore here.
                    try
                    {
                        p = new Param(tokenRef[0], this);
                    }
                    catch
                    {
                        p = null;
                    }
                    if (p != null)
                    {
                        try
                        {
                            p.SetSig(sigBlob, ref idx, this);
                            this.parameters.Add(p);
                        }
                        catch (System.ArgumentException e)
                        {
                            throw new System.ArgumentException
                                      ("Unsupported parameter " + p.Name + " in method " + this.Name + ": " + e.Message);
                        }
                    }
                    Context.importIntf.EnumParams(ref hHandle, this.token, tokenRef, 1, out countTokens);
                }
                Context.importIntf.CloseEnum(hHandle);
            }
        }
Пример #8
0
        internal static void ReadMethodSignature(IMetadataImport importer, Instantiation instantiation, ref IntPtr pData, out CorCallingConvention cconv, out Type retType, out List <Type> argTypes, out int sentinelIndex)
        {
            cconv = MetadataHelperFunctions.CorSigUncompressCallingConv(ref pData);
            uint numArgs = 0;
            // FIXME: Use number of <T>s.
            uint types = 0;

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

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

            retType  = ReadType(importer, instantiation, ref pData);
            argTypes = new List <Type> ();
            for (int n = 0; n < numArgs; n++)
            {
                CorElementType elemType;
                unsafe {
                    var pByte = (byte *)pData;
                    var b     = *pByte;
                    elemType = (CorElementType)b;

                    if (elemType == CorElementType.ELEMENT_TYPE_SENTINEL)
                    {
                        // the case when SENTINEL is presented in a separate position, so we have to increment the pointer
                        sentinelIndex = n;
                        pData         = (IntPtr)(pByte + 1);
                    }
                    else if ((elemType & CorElementType.ELEMENT_TYPE_SENTINEL) == CorElementType.ELEMENT_TYPE_SENTINEL)
                    {
                        // SENTINEL is just a flag on element type, so we haven't to promote the pointer
                        sentinelIndex = n;
                    }
                }
                argTypes.Add(ReadType(importer, instantiation, ref pData));
            }
        }
        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);
            }
        }
Пример #10
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));
		}
Пример #11
0
        internal 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  = ReadType(importer, ref pData);
            argTypes = new List <Type> ();
            for (int n = 0; n < numArgs; n++)
            {
                argTypes.Add(ReadType(importer, ref pData));
            }
        }
Пример #12
0
 public MethodFilter(string name, int genericParameterCount, int parameterCount, CorCallingConvention callingConvention)
 {
     this.Name = name;
     this.GenericParameterCount = genericParameterCount;
     this.ParameterCount        = parameterCount;
     this.CallingConvention     = callingConvention;
 }
Пример #13
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));
            }
        }
		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));
		}