Esempio n. 1
0
        (TypeMirror type, bool containsGenericParameters) Create(DmdType type)
        {
            if ((object)type == null)
            {
                throw new ArgumentNullException(nameof(type));
            }

            if (typeCache.TryGetType(type, out var cachedType))
            {
                return(cachedType, false);
            }

            if (recursionCounter++ > 100)
            {
                throw new InvalidOperationException();
            }

            (TypeMirror type, bool containsGenericParameters)result;
            bool addType = true;

            switch (type.TypeSignatureKind)
            {
            case DmdTypeSignatureKind.Type:
                if (!engine.TryGetMonoModule(type.Module.GetDebuggerModule() ?? throw new InvalidOperationException(), out var monoModule))
                {
                    throw new InvalidOperationException();
                }
                Debug.Assert((type.MetadataToken >> 24) == 0x02);
                //TODO: This can sometimes crash Unity's old mono fork
                //TODO: It's possible to resolve types, but it's an internal method and it requires a method in the module
                result = (monoModule.Assembly.GetType(type.FullName, false, false), false);
                if (result.type == null)
                {
                    throw new InvalidOperationException();
                }
                if (result.type.MetadataToken != type.MetadataToken)
                {
                    throw new InvalidOperationException();
                }
                break;

            case DmdTypeSignatureKind.Pointer:
                result = Create(type.GetElementType());
                result = (TryResolveType(result.type, type), result.containsGenericParameters);
                if (result.type == null)
                {
                    throw new InvalidOperationException();
                }
                if (!result.type.IsPointer)
                {
                    throw new InvalidOperationException();
                }
                break;

            case DmdTypeSignatureKind.ByRef:
                result = Create(type.GetElementType());
                result = (TryResolveType(result.type, type), result.containsGenericParameters);
                if (result.type == null)
                {
                    throw new InvalidOperationException();
                }
                // This currently always fails
                //TODO: We could func-eval MakeByRefType()
                if (!result.type.IsByRef)
                {
                    throw new InvalidOperationException();
                }
                break;

            case DmdTypeSignatureKind.TypeGenericParameter:
            case DmdTypeSignatureKind.MethodGenericParameter:
                result  = (Create(type.AppDomain.System_Object).type, true);
                addType = false;
                break;

            case DmdTypeSignatureKind.SZArray:
                result = Create(type.GetElementType());
                result = (TryResolveType(result.type, type), result.containsGenericParameters);
                if (result.type == null)
                {
                    throw new InvalidOperationException();
                }
                if (!result.type.IsArray || result.type.GetArrayRank() != 1 || !result.type.FullName.EndsWith("[]", StringComparison.Ordinal))
                {
                    throw new InvalidOperationException();
                }
                break;

            case DmdTypeSignatureKind.MDArray:
                result = Create(type.GetElementType());
                result = (TryResolveType(result.type, type), result.containsGenericParameters);
                if (result.type == null)
                {
                    throw new InvalidOperationException();
                }
                if (!result.type.IsArray || (result.type.GetArrayRank() == 1 && result.type.FullName.EndsWith("[]", StringComparison.Ordinal)))
                {
                    throw new InvalidOperationException();
                }
                break;

            case DmdTypeSignatureKind.GenericInstance:
                result = Create(type.GetGenericTypeDefinition());
                result = (TryResolveType(result.type, type), result.containsGenericParameters);
                if (result.type == null)
                {
                    throw new InvalidOperationException();
                }
                // This fails on Unity (version < 2.12), since it doesn't have that info available
                //if (!result.type.IsGenericType)
                //	throw new InvalidOperationException();
                break;

            case DmdTypeSignatureKind.FunctionPointer:
                // It's not possible to create function pointers, so use a pointer type instead
                result  = Create(type.AppDomain.System_Void.MakePointerType());
                addType = false;
                break;

            default:
                throw new InvalidOperationException();
            }

            if (result.type == null)
            {
                throw new InvalidOperationException();
            }
            if (addType && !result.containsGenericParameters)
            {
                typeCache.Add(result.type, type);
            }

            recursionCounter--;
            return(result);
        }
Esempio n. 2
0
 public EmitType(Type type)
 {
     Type = type;
     TypeCache.Add(type, this);
 }