// elementType is FNPTR internal Type(ElementTypes elementType, SignatureMethod methodSignature) { this.elementType = elementType; this.methodSignature = methodSignature; }
private Type parseSignatureType(MetaDataLoader mdLoader) { ElementTypes elementType = (ElementTypes)this.buffer[this.offset]; this.offset++; switch (elementType) { case ElementTypes.VOID: case ElementTypes.BOOLEAN: case ElementTypes.CHAR: case ElementTypes.I1: case ElementTypes.U1: case ElementTypes.I2: case ElementTypes.U2: case ElementTypes.I4: case ElementTypes.U4: case ElementTypes.I8: case ElementTypes.U8: case ElementTypes.R4: case ElementTypes.R8: case ElementTypes.U: case ElementTypes.I: case ElementTypes.OBJECT: case ElementTypes.STRING: case ElementTypes.TYPEDBYREF: { return(new Type(elementType)); } case ElementTypes.VALUETYPE: case ElementTypes.CLASS: { // Followed by: TypeDefOrRefEncoded MetaDataObject classObject = uncompressToken(mdLoader); return(new Type(elementType, classObject)); } case ElementTypes.SZARRAY: { // Followed by: CustomMod* Type Modifier modifierList = this.parseSignatureModifiers(mdLoader); Type type = this.parseSignatureType(mdLoader); return(new Type(elementType, type, modifierList)); } case ElementTypes.ARRAY: { // Followed by: Type ArrayShape Type type = this.parseSignatureType(mdLoader); uint rank = uncompressInt(this.buffer, ref this.offset); if (rank == 0) { throw new MetaDataLoader.IllegalMetaDataFormatException("ARRAY with rank 0"); } uint[] upperBounds = new uint[rank]; uint[] lowerBounds = new uint[rank]; uint numUpperBounds = uncompressInt(this.buffer, ref this.offset); if (numUpperBounds > rank) { throw new MetaDataLoader.IllegalMetaDataFormatException("ARRAY with upper bounds > rank"); } for (int i = 0; i < numUpperBounds; i++) { upperBounds[i] = uncompressInt(this.buffer, ref this.offset); } uint numLowerBounds = uncompressInt(this.buffer, ref this.offset); if (numLowerBounds > rank) { throw new MetaDataLoader.IllegalMetaDataFormatException("ARRAY with lower bounds > rank"); } for (int i = 0; i < numLowerBounds; i++) { lowerBounds[i] = uncompressInt(this.buffer, ref this.offset); } return(new Type(elementType, type, lowerBounds, upperBounds)); } case ElementTypes.FNPTR: { // Followed by: MethodDefSig or MethodRefSig uint unmaskedCallingConvention = uncompressInt(this.buffer, ref this.offset); CallingConventions callingConvention = (CallingConventions) (unmaskedCallingConvention & (uint)CallingConventions.Mask); if (callingConvention == CallingConventions.Field || callingConvention == CallingConventions.LocalVar || callingConvention == CallingConventions.Property) { throw new MetaDataLoader.IllegalMetaDataFormatException("FNPTR surprised by calling convention " + callingConvention); } if ((unmaskedCallingConvention & (uint)CallingConventions.Generic) != 0) { throw new MetaDataLoader.IllegalMetaDataFormatException("FNPTR generic unimplemented - check to see if legal"); } uint paramCount = uncompressInt(this.buffer, ref this.offset); Type returnType = this.parseSignatureType(mdLoader); int sentinelLocation = -1; Param[] parameters = new Param[paramCount]; for (int i = 0; i < paramCount; i++) { byte first = this.buffer[this.offset]; if (first == (byte)ElementTypes.SENTINEL) { sentinelLocation = i; this.offset++; } parameters[i] = this.parseSignatureParam(mdLoader); } SignatureMethod signature = new SignatureMethod(callingConvention, 0, returnType, parameters, sentinelLocation); return(new Type(elementType, signature)); } case ElementTypes.VAR: case ElementTypes.MVAR: { // Generic type variables uint number = uncompressInt(this.buffer, ref this.offset); return(new Type(elementType, number)); } case ElementTypes.GENERICINST: { // Generic type instantiation Type type = this.parseSignatureType(mdLoader); uint typeCount = uncompressInt(this.buffer, ref this.offset); Type[] typeParams = new Type[typeCount]; for (int i = 0; i < typeCount; i++) { Type paramType = this.parseSignatureType(mdLoader); typeParams[i] = paramType; } return(new Type(elementType, type, typeParams)); } case ElementTypes.CMOD_OPT: case ElementTypes.CMOD_REQD: { // Modifiers this.offset--; Modifier modifierList = this.parseSignatureModifiers(mdLoader); Type type = this.parseSignatureType(mdLoader); return(new Type(elementType, type, modifierList)); } case ElementTypes.PINNED: case ElementTypes.PTR: case ElementTypes.BYREF: { // Modifiers Type type = this.parseSignatureType(mdLoader); return(new Type(elementType, type, (Modifier)null)); } default: { throw new MetaDataLoader.IllegalMetaDataFormatException("Unknown signature type: 0x" + ((byte)elementType).ToString("x2") + " at " + this.offset + " in " + this); } } }