internal unsafe SharpLangType ResolveTypeHandle(ISharpLangGenericContext context, Handle handle) { switch (handle.Kind) { case HandleKind.TypeDefinition: return(ResolveTypeDef(null, (TypeDefinitionHandle)handle)); case HandleKind.TypeReference: { var typeReference = MetadataReader.GetTypeReference((TypeReferenceHandle)handle); var module = ResolveModule(typeReference.ResolutionScope); if (module == null) { throw new InvalidOperationException("Could not resolve module"); } return(module.ResolveType(MetadataReader.GetString(typeReference.Namespace), MetadataReader.GetString(typeReference.Name))); } case HandleKind.TypeSpecification: { var typeSpecification = MetadataReader.GetTypeSpecification((TypeSpecificationHandle)handle); var signatureReader = MetadataReader.GetBlobReader(typeSpecification.Signature); return(ReadSignature(context, signatureReader)); } case HandleKind.GenericParameter: default: throw new NotImplementedException(); } }
unsafe internal SharpLangType ReadSignature(ISharpLangGenericContext context, BlobReader signatureReader) { var signatureTypeCode = signatureReader.ReadSignatureTypeCode(); switch (signatureTypeCode) { #region Primitive types case SignatureTypeCode.Void: return((SharpLangType)typeof(void)); case SignatureTypeCode.Boolean: return((SharpLangType)typeof(bool)); case SignatureTypeCode.Char: return((SharpLangType)typeof(char)); case SignatureTypeCode.Byte: return((SharpLangType)typeof(byte)); case SignatureTypeCode.SByte: return((SharpLangType)typeof(sbyte)); case SignatureTypeCode.UInt16: return((SharpLangType)typeof(ushort)); case SignatureTypeCode.Int16: return((SharpLangType)typeof(short)); case SignatureTypeCode.UInt32: return((SharpLangType)typeof(uint)); case SignatureTypeCode.Int32: return((SharpLangType)typeof(int)); case SignatureTypeCode.UInt64: return((SharpLangType)typeof(ulong)); case SignatureTypeCode.Int64: return((SharpLangType)typeof(long)); case SignatureTypeCode.Single: return((SharpLangType)typeof(float)); case SignatureTypeCode.Double: return((SharpLangType)typeof(double)); case SignatureTypeCode.UIntPtr: return((SharpLangType)typeof(UIntPtr)); case SignatureTypeCode.IntPtr: return((SharpLangType)typeof(IntPtr)); case SignatureTypeCode.Object: return((SharpLangType)typeof(object)); case SignatureTypeCode.String: return((SharpLangType)typeof(string)); case SignatureTypeCode.TypedReference: return((SharpLangType)typeof(TypedReference)); #endregion case SignatureTypeCode.TypeHandle: return(ResolveTypeHandle(context, signatureReader.ReadTypeHandle())); case SignatureTypeCode.Pointer: return(ResolveElementType(null, ReadSignature(context, signatureReader), SharpLangEEType.Kind.Pointer)); case SignatureTypeCode.ByReference: return(ResolveElementType(null, ReadSignature(context, signatureReader), SharpLangEEType.Kind.ByRef)); case SignatureTypeCode.SZArray: return(ResolveElementType(null, ReadSignature(context, signatureReader), SharpLangEEType.Kind.Array)); case SignatureTypeCode.Array: { var elementType = ReadSignature(context, signatureReader); // Read ArrayShape var rank = signatureReader.ReadCompressedInteger(); var numSizes = signatureReader.ReadCompressedInteger(); for (int i = 0; i < numSizes; ++i) { signatureReader.ReadCompressedInteger(); } var numLoBounds = signatureReader.ReadCompressedInteger(); for (int i = 0; i < numSizes; ++i) { signatureReader.ReadCompressedSignedInteger(); } return(ResolveElementType(null, elementType, SharpLangEEType.Kind.Array)); } case SignatureTypeCode.GenericTypeInstance: { var isValueType = signatureReader.ReadByte(); var genericTypeDefinition = (SharpLangTypeDefinition)ResolveTypeHandle(context, signatureReader.ReadTypeHandle()); var genericArgumentCount = signatureReader.ReadCompressedInteger(); var genericArguments = new SharpLangType[genericArgumentCount]; for (int i = 0; i < genericArgumentCount; ++i) { genericArguments[i] = ReadSignature(context, signatureReader); } return(ResolveGenericType(null, genericTypeDefinition, genericArguments)); } case SignatureTypeCode.GenericTypeParameter: { if (context == null) { throw new InvalidOperationException(); } var methodInfoContext = context as SharpLangMethodInfo; if (methodInfoContext != null) { context = (SharpLangType)((SharpLangMethodInfo)context).DeclaringType; } var index = signatureReader.ReadCompressedInteger(); var typeDefinitionContext = context as SharpLangTypeDefinition; if (typeDefinitionContext != null) { var genericParameters = typeDefinitionContext.InternalGetGenericParameters(); return(genericParameters[index]); } var typeGenericContext = context as SharpLangTypeGeneric; if (typeGenericContext != null) { var genericArguments = typeGenericContext.InternalArguments; return(genericArguments[index]); } // Not sure yet what other cases could happen here... throw new NotSupportedException(); } case SignatureTypeCode.GenericMethodParameter: { if (context == null) { throw new InvalidOperationException(); } var index = signatureReader.ReadCompressedInteger(); var methodInfoContext = context as SharpLangMethodInfo; if (methodInfoContext != null) { var genericParameters = methodInfoContext.InternalGetGenericParameters(); return(genericParameters[index]); } // Not sure yet what other cases could happen here... throw new NotSupportedException(); } case SignatureTypeCode.OptionalModifier: case SignatureTypeCode.RequiredModifier: case SignatureTypeCode.Pinned: case SignatureTypeCode.Sentinel: default: throw new NotImplementedException(); } }