internal ITypeReference/*?*/ UnderlyingModuleTypeSpecReference( TypeSpecReference moduleTypeSpecReference ) //^ requires moduleTypeSpecReference.TypeSpecRowId >= 1; { uint typeSpecRowId = moduleTypeSpecReference.TypeSpecRowId; if (typeSpecRowId == 0 || typeSpecRowId > this.PEFileReader.TypeSpecTable.NumberOfRows) { // TODO: Error... return null; } uint signatureBlobOffset = this.PEFileReader.TypeSpecTable.GetSignature(typeSpecRowId); // TODO: error checking offset in range MemoryBlock signatureMemoryBlock = this.PEFileReader.BlobStream.GetMemoryBlockAt(signatureBlobOffset); // TODO: Error checking enough space in signature memoryBlock. MemoryReader memoryReader = new MemoryReader(signatureMemoryBlock); TypeSpecSignatureConverter typeSpecSignatureConverter = new TypeSpecSignatureConverter(this, moduleTypeSpecReference, memoryReader); return typeSpecSignatureConverter.TypeReference; }
//^ [NotDelayed] internal TypeSpecSignatureConverter( PEFileToObjectModel peFileToObjectModel, TypeSpecReference moduleTypeSpecReference, MemoryReader signatureMemoryReader ) : base(peFileToObjectModel, signatureMemoryReader, moduleTypeSpecReference.TypeSpecOwner) { //^ base; //^ this.SignatureMemoryReader = signatureMemoryReader; //TODO: Spec# bug. This assignment should not be necessary. byte firstByte = this.SignatureMemoryReader.ReadByte(); switch (firstByte) { case ElementType.GenericTypeInstance: this.TypeReference = this.GetModuleGenericTypeInstanceReference(TokenTypeIds.TypeSpec | moduleTypeSpecReference.TypeSpecRowId); break; case ElementType.ByReference: this.TypeReference = this.GetModuleManagedPointerType(TokenTypeIds.TypeSpec | moduleTypeSpecReference.TypeSpecRowId); break; case ElementType.Pointer: this.TypeReference = this.GetModulePointerType(TokenTypeIds.TypeSpec | moduleTypeSpecReference.TypeSpecRowId); break; case ElementType.Array: this.TypeReference = this.GetModuleMatrixType(TokenTypeIds.TypeSpec | moduleTypeSpecReference.TypeSpecRowId); break; case ElementType.SzArray: this.TypeReference = this.GetModuleVectorType(TokenTypeIds.TypeSpec | moduleTypeSpecReference.TypeSpecRowId); break; case ElementType.FunctionPointer: this.TypeReference = this.GetModuleFuntionPointer(TokenTypeIds.TypeSpec | moduleTypeSpecReference.TypeSpecRowId); break; case ElementType.Class: case ElementType.ValueType: { uint typeEncoded = (uint)this.SignatureMemoryReader.ReadCompressedUInt32(); uint typeToken = TypeDefOrRefTag.ConvertToToken(typeEncoded); this.TypeReference = this.PEFileToObjectModel.GetTypeReferenceForToken(this.MetadataOwnerObject, typeToken, firstByte == ElementType.ValueType); } break; case ElementType.GenericTypeParameter: { ushort ordinal = (ushort)this.SignatureMemoryReader.ReadCompressedUInt32(); if (this.ModuleGenericType == null) { // TODO: Error } else { this.TypeReference = this.ModuleGenericType.GetGenericTypeParameterFromOrdinal(ordinal); } break; } case ElementType.GenericMethodParameter: { ushort ordinal = (ushort)this.SignatureMemoryReader.ReadCompressedUInt32(); if (this.ModuleGenericMethod == null) { // TODO: Error } else { this.TypeReference = this.ModuleGenericMethod.GetGenericMethodParameterFromOrdinal(ordinal); } break; } case ElementType.RequiredModifier: case ElementType.OptionalModifier: { bool dummyPinned; this.SignatureMemoryReader.SkipBytes(-1); var customModifiers = this.GetCustomModifiers(out dummyPinned); ITypeReference/*?*/ typeReference = this.GetTypeReference(); if (typeReference == null) { // TODO: Error } else { this.TypeReference = new ModifiedTypeReference(this.PEFileToObjectModel, typeReference, customModifiers); } break; } case ElementType.Boolean: this.TypeReference = this.PEFileToObjectModel.PlatformType.SystemBoolean; break; case ElementType.Char: this.TypeReference = this.PEFileToObjectModel.PlatformType.SystemChar; break; case ElementType.Double: this.TypeReference = this.PEFileToObjectModel.PlatformType.SystemFloat64; break; case ElementType.Int16: this.TypeReference = this.PEFileToObjectModel.PlatformType.SystemInt16; break; case ElementType.Int32: this.TypeReference = this.PEFileToObjectModel.PlatformType.SystemInt32; break; case ElementType.Int64: this.TypeReference = this.PEFileToObjectModel.PlatformType.SystemInt64; break; case ElementType.Int8: this.TypeReference = this.PEFileToObjectModel.PlatformType.SystemInt8; break; case ElementType.IntPtr: this.TypeReference = this.PEFileToObjectModel.PlatformType.SystemIntPtr; break; case ElementType.Object: this.TypeReference = this.PEFileToObjectModel.PlatformType.SystemObject; break; case ElementType.Single: this.TypeReference = this.PEFileToObjectModel.PlatformType.SystemFloat32; break; case ElementType.String: this.TypeReference = this.PEFileToObjectModel.PlatformType.SystemString; break; case ElementType.UInt16: this.TypeReference = this.PEFileToObjectModel.PlatformType.SystemUInt16; break; case ElementType.UInt32: this.TypeReference = this.PEFileToObjectModel.PlatformType.SystemUInt32; break; case ElementType.UInt64: this.TypeReference = this.PEFileToObjectModel.PlatformType.SystemUInt64; break; case ElementType.UInt8: this.TypeReference = this.PEFileToObjectModel.PlatformType.SystemUInt8; break; case ElementType.UIntPtr: this.TypeReference = this.PEFileToObjectModel.PlatformType.SystemUIntPtr; break; case ElementType.Void: this.TypeReference = this.PEFileToObjectModel.PlatformType.SystemVoid; break; default: // Error... break; } }
internal TypeSpecReference/*?*/ GetTypeSpecReferenceAtRow( MetadataObject owningObject, uint typeSpecRowId ) //^ requires this.PEFileReader.TypeSpecTable.NumberOfRows >= 1; //^ requires typeSpecRowId >= 1 && typeSpecRowId <= this.PEFileReader.TypeSpecTable.NumberOfRows; { if (typeSpecRowId > this.PEFileReader.TypeSpecTable.NumberOfRows || typeSpecRowId == 0) { return null; } uint ownerId = owningObject.TokenValue; //^ assert this.ModuleTypeSpecHashtable != null; TypeSpecReference/*?*/ typeSpecReference = this.ModuleTypeSpecHashtable.Find(ownerId, typeSpecRowId); if (typeSpecReference == null) { lock (GlobalLock.LockingObject) { typeSpecReference = this.ModuleTypeSpecHashtable.Find(ownerId, typeSpecRowId); if (typeSpecReference == null) { typeSpecReference = new TypeSpecReference(this, typeSpecRowId, owningObject); } this.ModuleTypeSpecHashtable.Add(ownerId, typeSpecRowId, typeSpecReference); } } return typeSpecReference; }