internal static unsafe SharpLangTypeGeneric ResolveGenericType(SharpLangEEType *eeType, SharpLangTypeDefinition genericTypeDefinition, SharpLangType[] genericArguments) { var genericTypeKey = new GenericKey(genericTypeDefinition, genericArguments); lock (SystemTypeLock) { SharpLangTypeGeneric sharpLangType; if (genericTypes.TryGetValue(genericTypeKey, out sharpLangType)) { return(sharpLangType); } if (eeType == null) { var sharpLangTypeSearchKey = new SharpLangEETypeComparer.SharpLangTypeSearchKey { Kind = SharpLangEEType.Kind.TypeDef, TypeDefinition = new SharpLangEETypeDefinition { Module = genericTypeDefinition.InternalModule, Handle = genericTypeDefinition.InternalHandle, }, GenericArguments = genericArguments, }; var typeIndex = SharpLangEETypeComparer.BinarySearch(types, ref sharpLangTypeSearchKey); if (typeIndex >= 0) { eeType = types[typeIndex]; } } sharpLangType = new SharpLangTypeGeneric(eeType, genericTypeDefinition, genericArguments); genericTypes.Add(genericTypeKey, sharpLangType); if (eeType != null) { eeType->CachedTypeField = (IntPtr)SharpLangHelper.GetObjectPointer(sharpLangType); } return(sharpLangType); } }
internal unsafe SharpLangTypeDefinition ResolveTypeDef(SharpLangEEType *eeType, TypeDefinitionHandle typeDefHandle) { var typeDef = new SharpLangEETypeDefinition(this, typeDefHandle); lock (SystemTypeLock) { // Check if type has already been instantiated SharpLangTypeDefinition sharpLangType; if (typeDefinitions.TryGetValue(typeDef, out sharpLangType)) { return(sharpLangType); } if (eeType == null) { var sharpLangTypeSearchKey = new SharpLangEETypeComparer.SharpLangTypeSearchKey { Kind = SharpLangEEType.Kind.TypeDef, TypeDefinition = typeDef, }; var typeIndex = SharpLangEETypeComparer.BinarySearch(types, ref sharpLangTypeSearchKey); if (typeIndex >= 0) { eeType = types[typeIndex]; } } sharpLangType = new SharpLangTypeDefinition(eeType, typeDef.Module, typeDef.Handle); typeDefinitions.Add(typeDef, sharpLangType); if (eeType != null) { eeType->CachedTypeField = (IntPtr)SharpLangHelper.GetObjectPointer(sharpLangType); } return(sharpLangType); } }
unsafe internal static SharpLangType ResolveType(SharpLangEEType *eeType) { // Check if already created var cachedTypeField = eeType->CachedTypeField; if (cachedTypeField != IntPtr.Zero) { return((SharpLangType)SharpLangHelper.GetObjectFromPointer((void *)cachedTypeField)); } lock (SystemTypeLock) { // Check again inside the lock to avoid creation conflicts cachedTypeField = eeType->CachedTypeField; if (cachedTypeField != IntPtr.Zero) { return((SharpLangType)SharpLangHelper.GetObjectFromPointer((void *)cachedTypeField)); } // Create SharpLangType var kind = eeType->GetKind(); if (kind == SharpLangEEType.Kind.Array || kind == SharpLangEEType.Kind.Pointer || kind == SharpLangEEType.Kind.ByRef) { // Types with elements (ByRef, Pointer, Array) var elementType = ResolveType((SharpLangEEType *)(eeType->ExtraTypeInfo - (int)kind)); return(ResolveElementType(eeType, elementType, kind)); } var typeDef = &eeType->TypeDefinition; if (kind == SharpLangEEType.Kind.TypeDef) { // Normal type definition return(typeDef->Module.ResolveTypeDef(eeType, typeDef->Handle)); } if (kind == SharpLangEEType.Kind.Generics) { // Find generic arguments var genericVTable = (SharpLangEEType **)eeType->ExtraTypeInfo; int genericVTableCount = 0; // First count them for (var genericVTableIt = genericVTable; *genericVTableIt != null; ++genericVTableIt) { genericVTableCount++; } // Then build the array var genericArguments = new SharpLangType[genericVTableCount]; for (int i = 0; i < genericVTableCount; ++i) { genericArguments[i] = ResolveType(*genericVTable++); } // TODO: Build dependent types (generic type def + generic arguments) lazily could make initialization faster return(ResolveGenericType(eeType, typeDef->Module.ResolveTypeDef(null, typeDef->Handle), genericArguments)); } throw new InvalidOperationException(string.Format("Unknown type kind: {0}", kind)); } }
internal unsafe static SharpLangTypeElement ResolveElementType(SharpLangEEType *eeType, SharpLangType elementType, SharpLangEEType.Kind kind) { Dictionary <SharpLangType, SharpLangTypeElement> elementTypes; switch (kind) { case SharpLangEEType.Kind.Array: elementTypes = arrayTypes; break; case SharpLangEEType.Kind.Pointer: elementTypes = pointerTypes; break; case SharpLangEEType.Kind.ByRef: elementTypes = byRefTypes; break; default: throw new ArgumentOutOfRangeException(); } lock (SystemTypeLock) { // Check if type has already been instantiated SharpLangTypeElement sharpLangType; if (elementTypes.TryGetValue(elementType, out sharpLangType)) { return(sharpLangType); } if (eeType == null) { var sharpLangTypeSearchKey = new SharpLangEETypeComparer.SharpLangTypeSearchKey { Kind = kind, ElementType = elementType, }; var typeIndex = SharpLangEETypeComparer.BinarySearch(types, ref sharpLangTypeSearchKey); if (typeIndex >= 0) { eeType = types[typeIndex]; } } switch (kind) { case SharpLangEEType.Kind.Array: sharpLangType = new SharpLangTypeArray(eeType, elementType, 1); break; case SharpLangEEType.Kind.Pointer: sharpLangType = new SharpLangTypePointer(eeType, elementType); break; case SharpLangEEType.Kind.ByRef: sharpLangType = new SharpLangTypeByRef(eeType, elementType); break; default: throw new ArgumentOutOfRangeException(); } elementTypes.Add(elementType, sharpLangType); if (eeType != null) { eeType->CachedTypeField = (IntPtr)SharpLangHelper.GetObjectPointer(sharpLangType); } return(sharpLangType); } }