internal override ClrType GetTypeByMethodTable(ulong mt, ulong cmt, ulong obj) { if (mt == 0) { return(null); } ClrType componentType = null; if (mt == DesktopRuntime.ArrayMethodTable) { if (cmt != 0) { componentType = GetTypeByMethodTable(cmt, 0); if (componentType != null) { cmt = componentType.MethodTable; } else if (obj != 0) { componentType = TryGetComponentType(obj, cmt); if (componentType != null) { cmt = componentType.MethodTable; } } } else { componentType = ObjectType; cmt = ObjectType.MethodTable; } } else { cmt = 0; } TypeHandle hnd = new TypeHandle(mt, cmt); ClrType ret = null; // See if we already have the type. if (_indices.TryGetValue(hnd, out int index)) { ret = _types[index]; } else if (mt == DesktopRuntime.ArrayMethodTable && cmt == 0) { // Handle the case where the methodtable is an array, but the component method table // was not specified. (This happens with fields.) In this case, return System.Object[], // with an ArrayComponentType set to System.Object. uint token = DesktopRuntime.GetMetadataToken(mt); if (token == 0xffffffff) { return(null); } ModuleEntry modEnt = new ModuleEntry(ArrayType.Module, token); ret = ArrayType; index = _types.Count; _indices[hnd] = index; _typeEntry[modEnt] = index; _types.Add(ret); Debug.Assert(_types[index] == ret); } else { // No, so we'll have to construct it. ulong moduleAddr = DesktopRuntime.GetModuleForMT(hnd.MethodTable); DesktopModule module = DesktopRuntime.GetModule(moduleAddr); uint token = DesktopRuntime.GetMetadataToken(mt); bool isFree = mt == DesktopRuntime.FreeMethodTable; if (token == 0xffffffff && !isFree) { return(null); } // Dynamic functions/modules uint tokenEnt = token; if (!isFree && (module == null || module.IsDynamic)) { tokenEnt = (uint)mt; } ModuleEntry modEnt = new ModuleEntry(module, tokenEnt); if (ret == null) { IMethodTableData mtData = DesktopRuntime.GetMethodTableData(mt); if (mtData == null) { return(null); } ret = new DesktopHeapType(() => GetTypeName(hnd, module, token), module, token, mt, mtData, this) { ComponentType = componentType }; index = _types.Count; ((DesktopHeapType)ret).SetIndex(index); _indices[hnd] = index; _typeEntry[modEnt] = index; _types.Add(ret); Debug.Assert(_types[index] == ret); } } if (obj != 0 && ret.ComponentType == null && ret.IsArray) { ret.ComponentType = TryGetComponentType(obj, cmt); } return(ret); }
internal override ClrType GetTypeByMethodTable(ulong mt, ulong _, ulong obj) { if (mt == 0) { return(null); } ClrType ret = null; // See if we already have the type. if (_indices.TryGetValue(mt, out int index)) { ret = _types[index]; } else { // No, so we'll have to construct it. ulong moduleAddr = DesktopRuntime.GetModuleForMT(mt); DesktopModule module = DesktopRuntime.GetModule(moduleAddr); uint token = DesktopRuntime.GetMetadataToken(mt); bool isFree = mt == DesktopRuntime.FreeMethodTable; if (token == 0xffffffff && !isFree) { return(null); } // Dynamic functions/modules uint tokenEnt = token; if (!isFree && (module == null || module.IsDynamic)) { tokenEnt = unchecked ((uint)mt); } ModuleEntry modEnt = new ModuleEntry(module, tokenEnt); if (ret == null) { IMethodTableData mtData = DesktopRuntime.GetMethodTableData(mt); if (mtData == null) { return(null); } IMethodTableCollectibleData mtCollectibleData = DesktopRuntime.GetMethodTableCollectibleData(mt); ret = new DesktopHeapType(() => GetTypeName(mt, module, token), module, token, mt, mtData, this, mtCollectibleData); index = _types.Count; _indices[mt] = index; // Arrays share a common token, so it's not helpful to look them up here. if (!ret.IsArray) { _typeEntry[modEnt] = index; } _types.Add(ret); Debug.Assert(_types[index] == ret); } } if (obj != 0 && ret.ComponentType == null && ret.IsArray) { ret.ComponentType = TryGetComponentType(obj, 0); } return(ret); }