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); } }
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)); } } } }
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++; } } }
// 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); } }
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."); }
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); } }
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); } }
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); } }
// [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)); }
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)); } }
public MethodFilter(string name, int genericParameterCount, int parameterCount, CorCallingConvention callingConvention) { this.Name = name; this.GenericParameterCount = genericParameterCount; this.ParameterCount = parameterCount; this.CallingConvention = callingConvention; }
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)); }