Example #1
0
        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);
            }
        }
Example #2
0
        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);
            }
        }
Example #3
0
        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));
            }
        }
Example #4
0
        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);
            }
        }