public MethodTable ExpandTable(IList <TypeSig> genArgs) { Debug.Assert(genArgs.IsCollectionValid()); Debug.Assert(!InstGenArgs.IsCollectionValid()); Debug.Assert(Def.GenericParameters.Count == genArgs.Count); bool isInterface = Def.IsInterface; MethodTable expMetTable = new MethodTable(TypeMgr, Def); expMetTable.DerivedLevel = DerivedLevel; expMetTable.InstGenArgs = genArgs; expMetTable.GetNameKey(); IGenericReplacer replacer = new TypeDefGenReplacer(Def, genArgs); StringBuilder sb = new StringBuilder(); foreach (var kv in SlotMap) { Debug.Assert(kv.Value.Entries.Count != 0); VirtualSlot vslot = ExpandVirtualSlot(kv.Value, expMetTable, replacer); TableMethodPair metPair = vslot.Entries.First(); string metNameKey = metPair.Item1.GetExpandedMethodNameKey(sb, metPair.Item2); // 接口合并相同签名的方法 if (isInterface) { expMetTable.MergeInterfaces(metNameKey, vslot.Entries); } else { expMetTable.SlotMap[metNameKey] = vslot; } } var expEntryMap = expMetTable.EntryMap; foreach (var kv in EntryMap) { var entry = ExpandMethodPair(kv.Key, expMetTable, replacer); var impl = ExpandMethodPair(kv.Value.MethodPair, expMetTable, replacer); MergeExpandedEntry(expEntryMap, entry, impl, kv.Value.Level); } foreach (var kv in SameTypeReplaceMap) { expMetTable.SameTypeReplaceMap[kv.Key] = ExpandMethodPair(kv.Value, expMetTable, replacer); } foreach (var kv in NewSlotEntryMap) { expMetTable.NewSlotEntryMap[kv.Key] = ExpandMethodPair(kv.Value, expMetTable, replacer); } return(expMetTable); }
private string GetExpandedMethodNameKey(StringBuilder sb, MethodDef metDef) { IGenericReplacer replacer = new TypeDefGenReplacer(Def, InstGenArgs); Helper.MethodDefNameKey(sb, metDef, replacer); string metNameKey = sb.ToString(); sb.Clear(); return(metNameKey); }
private void ExplicitOverride(MethodDef ownerMetDef, int ownerMetIdx) { IGenericReplacer replacer = null; if (HasGenArgs) { replacer = new TypeDefGenReplacer(Def, GenArgs); } foreach (var overItem in ownerMetDef.Overrides) { var target = overItem.MethodDeclaration; var impl = overItem.MethodBody; MethodTable targetTable = Context.TypeMgr.ResolveMethodTable(target.DeclaringType, replacer); MethodDef targetDef = target.ResolveMethodDef(); if (targetDef == null) { throw new TypeLoadException("Cannot find overriding signature: " + target.FullName); } if (targetDef.HasOverrides) { throw new TypeLoadException("Method already has overrides: " + targetDef.FullName); } MethodDef implDef = impl.ResolveMethodDef(); if (targetTable == this) { // 处理显式重写当前类型方法的情况 MethodReplaceMap.Add(targetDef, new Tuple <MethodTable, MethodDef>(this, implDef)); } else { string expSigName; if (implDef == ownerMetDef) { expSigName = ExpandedSigList[ownerMetIdx]; } else { throw new NotSupportedException(); } // 合并目标入口到实现方法的方法槽内 MergeSlot(expSigName, targetTable, targetDef); } } }
public void ResolveTable() { StringBuilder sb = new StringBuilder(); IGenericReplacer replacer = null; if (HasGenArgs) { replacer = new TypeDefGenReplacer(Def, GenArgs); } Dictionary <string, MethodDef> sameSigDefs = new Dictionary <string, MethodDef>(); // 解析不展开类型泛型的方法签名, 和展开的方法签名 uint lastRid = 0; foreach (var metDef in Def.Methods) { if (metDef.IsStatic || metDef.IsConstructor) { continue; } Debug.Assert(lastRid < metDef.Rid); lastRid = metDef.Rid; MethodDefList.Add(metDef); Helper.MethodDefNameKey(sb, metDef, replacer); string expSigName = sb.ToString(); sb.Clear(); ExpandedSigList.Add(expSigName); if (sameSigDefs.TryGetValue(expSigName, out var osameDef)) { // 遇到相同签名的方法 //if (!Def.HasGenericParameters) // throw new TypeLoadException("Conflicted method signature"); if (SameSigResolvedMap == null) { SameSigResolvedMap = new Dictionary <string, Tuple <MethodTable, MethodDef> >(); } SameSigResolvedMap.Add(expSigName, new Tuple <MethodTable, MethodDef>(this, osameDef)); } else { sameSigDefs.Add(expSigName, metDef); } } // 解析并继承基类方法表 if (Def.BaseType != null) { MethodTable baseTable = Context.TypeMgr.ResolveMethodTable(Def.BaseType, replacer); DerivedFrom(baseTable); } List <int> explicitOverrides = new List <int>(); // 处理当前类型的重写 for (int i = 0; i < MethodDefList.Count; ++i) { MethodDef metDef = MethodDefList[i]; string expSigName = ExpandedSigList[i]; if (metDef.HasOverrides) { // 记录存在显式重写的方法 explicitOverrides.Add(i); } if (Def.IsInterface) { // 特殊处理接口方法, 用于解决泛型接口内签名相同的情况 Debug.Assert(metDef.IsVirtual && metDef.IsNewSlot && metDef.IsAbstract); MergeSlot(expSigName, this, metDef); } else if (metDef.IsVirtual) { if (metDef.IsNewSlot) { NewSlot(expSigName, metDef); } else { Debug.Assert(metDef.IsReuseSlot); ReuseSlot(expSigName, metDef); } } else { NewSlot(expSigName, metDef); } } HashSet <string> absNoImplSlots = null; if (Def.IsAbstract) { absNoImplSlots = new HashSet <string>(); } // 合并接口的方法槽到当前方法槽 if (Def.HasInterfaces) { foreach (var inf in Def.Interfaces) { MethodTable infTable = Context.TypeMgr.ResolveMethodTable(inf.Interface, replacer); foreach (var kv in infTable.VSlotMap) { string expSigName = kv.Key; VirtualSlot vslot = kv.Value; foreach (var kv2 in vslot.Entries) { MethodTable entryTable = kv2.Key; foreach (MethodDef entryDef in kv2.Value) { if (NeedMergeInterface(expSigName, entryTable, entryDef)) { // 合并 var mergedVSlot = MergeSlot(expSigName, entryTable, entryDef); // 记录虚类型未实现的接口签名 if (absNoImplSlots != null && !mergedVSlot.Impl.IsValid()) { absNoImplSlots.Add(expSigName); } } } } } } } // 合并抽象基类未实现的接口 if (Helper.IsCollectionValid(AbsNoImplSlotMap)) { foreach (var kv in AbsNoImplSlotMap) { string expSigName = kv.Key; foreach (var kv2 in kv.Value) { MethodTable entryTable = kv2.Key; foreach (MethodDef entryDef in kv2.Value) { if (NeedMergeInterface(expSigName, entryTable, entryDef)) { // 合并 var mergedVSlot = MergeSlot(expSigName, entryTable, entryDef); } } } } } // 处理显式重写 foreach (int idx in explicitOverrides) { MethodDef overDef = MethodDefList[idx]; ExplicitOverride(overDef, idx); } if (!Def.IsInterface) { foreach (var kv in VSlotMap) { string expSigName = kv.Key; VirtualSlot vslot = kv.Value; if (vslot.Entries.Count > 0) { if (!Def.IsAbstract && !vslot.Impl.IsValid()) { // 遇到非抽象类且存在空的绑定实现则报错 StringBuilder sb2 = new StringBuilder(); sb2.AppendFormat("Slot has no implementation. Class: {0}, Slot: {1}, ", this, expSigName); foreach (var item in vslot.Entries) { sb2.AppendFormat("{0} -> [", item.Key); foreach (var entryDef in item.Value) { sb2.AppendFormat("{0} ", entryDef); } sb2.Append(']'); } // 检查是否存在未实现的接口 throw new TypeLoadException(sb2.ToString()); } else { // 删除存在实现的接口入口 if (absNoImplSlots != null && vslot.Impl.IsValid()) { absNoImplSlots.Remove(expSigName); if (AbsNoImplSlotMap != null) { AbsNoImplSlotMap.Remove(expSigName); } } // 展平方法槽 foreach (var kv2 in vslot.Entries) { MethodTable entryTable = kv2.Key; foreach (MethodDef entryDef in kv2.Value) { SetExpandedVSlotMap(entryTable, entryDef, ref vslot.Impl); } } } } } } if (Helper.IsCollectionValid(absNoImplSlots)) { if (AbsNoImplSlotMap == null) { AbsNoImplSlotMap = new Dictionary <string, Dictionary <MethodTable, HashSet <MethodDef> > >(); } foreach (var expSigName in absNoImplSlots) { var vslot = VSlotMap[expSigName]; Debug.Assert(!vslot.Impl.IsValid()); if (!AbsNoImplSlotMap.TryGetValue(expSigName, out var defMap)) { defMap = new Dictionary <MethodTable, HashSet <MethodDef> >(); AbsNoImplSlotMap.Add(expSigName, defMap); } foreach (var entry in vslot.Entries) { if (!defMap.TryGetValue(entry.Key, out var defSet)) { defSet = new HashSet <MethodDef>(); defMap.Add(entry.Key, defSet); } defSet.UnionWith(entry.Value); } } } }
public VirtualTable ExpandVTable(IList <TypeSig> tyGenArgs) { Debug.Assert(!HasGenArgs); Debug.Assert(tyGenArgs == null || Def.GenericParameters.Count == tyGenArgs.Count); // 展开当前类型名 StringBuilder sb = new StringBuilder(); Helper.TypeNameKey(sb, Def, tyGenArgs); string thisNameKey = sb.ToString(); sb = null; // 构建泛型替换器 IGenericReplacer replacer = null; if (Helper.IsCollectionValid(tyGenArgs)) { replacer = new TypeDefGenReplacer(Def, tyGenArgs); } // 替换类型名称 var newSlotMap = new Dictionary <string, Tuple <string, MethodDef> >(); foreach (var kv in NewSlotMap) { MethodTable slotTable = kv.Value.Item1; string slotType = slotTable == this ? thisNameKey : slotTable.GetReplacedNameKey(replacer); newSlotMap.Add(kv.Key, new Tuple <string, MethodDef>(slotType, kv.Value.Item2)); } var metReplaceMap = new Dictionary <MethodDef, Tuple <string, MethodDef> >(); foreach (var kv in MethodReplaceMap) { MethodTable repTable = kv.Value.Item1; string repType = repTable == this ? thisNameKey : repTable.GetReplacedNameKey(replacer); metReplaceMap.Add(kv.Key, new Tuple <string, MethodDef>(repType, kv.Value.Item2)); } var fallbackTable = new Dictionary <string, MethodDef>(); if (Helper.IsCollectionValid(SameSigResolvedMap)) { foreach (var kv in SameSigResolvedMap) { MethodTable resTable = kv.Value.Item1; string resType = resTable == this ? thisNameKey : resTable.GetReplacedNameKey(replacer); fallbackTable.Add(resType, kv.Value.Item2); } } VirtualTable vtable = new VirtualTable(newSlotMap, metReplaceMap, fallbackTable); // 不可实例化的类型不展开虚表 if (Def.IsAbstract || Def.IsInterface) { return(vtable); } foreach (var kv in ExpandedVSlotMap) { MethodTable entryTable = kv.Key; Debug.Assert(entryTable != null); foreach (var item in kv.Value) { MethodDef entryDef = item.Key; Debug.Assert(entryDef != null); MethodTable implTable = item.Value.ImplTable; MethodDef implDef = item.Value.ImplMethod; Debug.Assert(implTable != null); string entryTypeName = entryTable == this ? thisNameKey : entryTable.GetReplacedNameKey(replacer); string implTypeName = implTable == this ? thisNameKey : implTable.GetReplacedNameKey(replacer); vtable.Set(entryTypeName, entryDef, implTypeName, implDef); } } return(vtable); }