Esempio n. 1
0
        private ClrType TryBuildType(ClrHeap heap)
        {
            ClrRuntime           runtime = heap.Runtime;
            IList <ClrAppDomain> domains = runtime.AppDomains;

            ClrType[] types = new ClrType[domains.Count];

            ClrElementType elType = ElementType;

            if (elType.IsPrimitive() || elType == ClrElementType.String)
            {
                return(((DesktopGCHeap)heap).GetBasicType(elType));
            }

            int count = 0;

            foreach (ClrAppDomain domain in domains)
            {
                object value = GetValue(domain);
                if (value != null && value is ulong && (ulong)value != 0)
                {
                    types[count++] = heap.GetObjectType((ulong)value);
                }
            }

            int     depth  = int.MaxValue;
            ClrType result = null;

            for (int i = 0; i < count; ++i)
            {
                ClrType curr = types[i];
                if (curr == result || curr == null)
                {
                    continue;
                }

                int nextDepth = GetDepth(curr);
                if (nextDepth < depth)
                {
                    result = curr;
                    depth  = nextDepth;
                }
            }

            return(result);
        }
Esempio n. 2
0
        internal static ClrType?GetTypeForFieldSig(ITypeFactory factory, SigParser sigParser, ClrHeap heap, ClrModule?module)
        {
            ClrType?result = null;
            bool    res;
            int     etype = 0;

            if (res = sigParser.GetCallingConvInfo(out int sigType))
            {
                DebugOnly.Assert(sigType == SigParser.IMAGE_CEE_CS_CALLCONV_FIELD);
            }

            res = res && sigParser.SkipCustomModifiers();
            res = res && sigParser.GetElemType(out etype);

            // Generic instantiation
            if (etype == 0x15)
            {
                res = res && sigParser.GetElemType(out etype);
            }

            if (res)
            {
                ClrElementType type = (ClrElementType)etype;

                if (type == ClrElementType.Array)
                {
                    res = sigParser.PeekElemType(out etype);
                    res = res && sigParser.SkipExactlyOne();

                    int ranks = 0;
                    res = res && sigParser.GetData(out ranks);

                    if (res)
                    {
                        ClrType inner = factory.GetOrCreateBasicType((ClrElementType)etype);
                        result = factory.GetOrCreateArrayType(inner, ranks);
                    }
                }
                else if (type == ClrElementType.SZArray)
                {
                    sigParser.PeekElemType(out etype);
                    type = (ClrElementType)etype;

                    if (type.IsObjectReference())
                    {
                        result = factory.GetOrCreateBasicType(ClrElementType.SZArray);
                    }
                    else
                    {
                        ClrType inner = factory.GetOrCreateBasicType((ClrElementType)etype);
                        result = factory.GetOrCreateArrayType(inner, 1);
                    }
                }
                else if (type == ClrElementType.Pointer)
                {
                    // Only deal with single pointers for now and types that have already been constructed
                    sigParser.GetElemType(out etype);
                    type = (ClrElementType)etype;

                    sigParser.GetToken(out int token);

                    if (module != null)
                    {
                        ClrType?innerType;
                        if (type.IsPrimitive())
                        {
                            innerType = factory.GetOrCreateBasicType(type);
                        }
                        else
                        {
                            innerType = factory.GetOrCreateTypeFromToken(module, token);

                            // Fallback just in case
                            if (innerType is null)
                            {
                                innerType = factory.GetOrCreateBasicType(type);
                            }
                        }


                        result = factory.GetOrCreatePointerType(innerType, 1);
                    }
                }
                else if (type == ClrElementType.Object || type == ClrElementType.Class)
                {
                    result = heap.ObjectType;
                }
                else
                {
                    // struct, then try to get the token
                    int token = 0;
                    if (etype == 0x11 || etype == 0x12)
                    {
                        sigParser.GetToken(out token);
                    }

                    if (token != 0 && module != null)
                    {
                        result = factory.GetOrCreateTypeFromToken(module, token);
                    }

                    if (result is null)
                    {
                        result = factory.GetOrCreateBasicType((ClrElementType)etype);
                    }
                }
            }

            if (result is null)
            {
                return(result);
            }

            if (result.IsArray && result.ComponentType is null && result is ClrmdArrayType clrmdType)
            {
                etype = 0;

                if (res = sigParser.GetCallingConvInfo(out sigType))
                {
                    DebugOnly.Assert(sigType == SigParser.IMAGE_CEE_CS_CALLCONV_FIELD);
                }

                res = res && sigParser.SkipCustomModifiers();
                res = res && sigParser.GetElemType(out etype);

                _ = res && sigParser.GetElemType(out etype);

                // Generic instantiation
                if (etype == 0x15)
                {
                    sigParser.GetElemType(out etype);
                }

                // If it's a class or struct, then try to get the token
                int token = 0;
                if (etype == 0x11 || etype == 0x12)
                {
                    sigParser.GetToken(out token);
                }

                if (token != 0 && module != null)
                {
                    clrmdType.SetComponentType(factory.GetOrCreateTypeFromToken(module, token));
                }
                else
                {
                    clrmdType.SetComponentType(factory.GetOrCreateBasicType((ClrElementType)etype));
                }
            }

            return(result);
        }