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 void MergeInterfaces(string metNameKey, HashSet <TableMethodPair> entrySet) { if (!SlotMap.TryGetValue(metNameKey, out var vslot)) { vslot = new VirtualSlot(null); SlotMap.Add(metNameKey, vslot); } vslot.Entries.UnionWith(entrySet); }
private void MergeInterface(string metNameKey, TableMethodPair entry) { Debug.Assert(entry.Item1.Def.IsInterface); if (!SlotMap.TryGetValue(metNameKey, out var vslot)) { vslot = new VirtualSlot(null); SlotMap.Add(metNameKey, vslot); } vslot.Entries.Add(entry); }
private void NewSlot(string expSigName, MethodDef metDef) { VirtualSlot vslot = new VirtualSlot(); VSlotMap[expSigName] = vslot; vslot.AddEntry(this, metDef); vslot.SetImpl(this, metDef); NewSlotMap[expSigName] = new Tuple <MethodTable, MethodDef>(this, metDef); }
private void ApplyVirtualSlot(VirtualSlot vslot) { Debug.Assert(vslot != null); var impl = vslot.Implemented; foreach (TableMethodPair entry in vslot.Entries) { SetEntryMap(entry, impl); } }
public VirtualSlot(VirtualSlot other, TableMethodPair newEntry) { Entries.UnionWith(other.Entries); NewSlotEntry = other.NewSlotEntry; Implemented = other.Implemented; if (NewSlotEntry == null) { NewSlotEntry = newEntry; } }
public VirtualSlot(VirtualSlot other) { foreach (var kv in other.Entries) { Entries.Add(kv.Key, new HashSet <MethodDef>(kv.Value)); } if (other.Entries.Count > 0) { Impl = other.Impl; } }
private VirtualSlot ExpandVirtualSlot(VirtualSlot vslot, MethodTable expMetTable, IGenericReplacer replacer) { VirtualSlot expVSlot = new VirtualSlot(ExpandMethodPair(vslot.NewSlotEntry, expMetTable, replacer)); foreach (var entry in vslot.Entries) { expVSlot.Entries.Add(ExpandMethodPair(entry, expMetTable, replacer)); } expVSlot.Implemented = ExpandMethodPair(vslot.Implemented, expMetTable, replacer); return(expVSlot); }
private VirtualSlot MergeSlot(string expSigName, MethodTable entryTable, MethodDef entryDef) { // 合并之前需要删除现有的入口 RemoveEntry(entryTable, entryDef); if (!VSlotMap.TryGetValue(expSigName, out var vslot)) { vslot = new VirtualSlot(); VSlotMap.Add(expSigName, vslot); } vslot.AddEntry(entryTable, entryDef); return(vslot); }
private VirtualSlot ProcessMethod( string metNameKey, MethodDef metDef, MethodTable baseTable, List <Tuple <string, MethodDef> > expOverrides) { Debug.Assert(metDef.IsVirtual); // 记录显式重写方法 if (metDef.HasOverrides) { expOverrides.Add(new Tuple <string, MethodDef>(metNameKey, metDef)); } var entry = new TableMethodPair(this, metDef); var impl = Def.IsInterface ? null : entry; VirtualSlot vslot; if (metDef.IsReuseSlot) { // 对于重写槽方法, 如果不存在可重写的槽则转换为新建槽方法 if (baseTable == null) { metDef.IsNewSlot = true; } else if (!baseTable.SlotMap.TryGetValue(metNameKey, out vslot)) { metDef.IsNewSlot = true; } else { vslot = new VirtualSlot(vslot, impl); vslot.Entries.Add(entry); vslot.Implemented = impl; SlotMap[metNameKey] = vslot; ApplyVirtualSlot(vslot); return(vslot); } } Debug.Assert(metDef.IsNewSlot); vslot = new VirtualSlot(impl); vslot.Entries.Add(entry); vslot.Implemented = impl; SlotMap[metNameKey] = vslot; ApplyVirtualSlot(vslot); return(vslot); }
public void ResolveTable() { Debug.Assert(InstGenArgs == null); var metDefList = new List <Tuple <string, MethodDef> >(); var conflictMap = new Dictionary <string, ConflictPair>(); var nameSet = new HashSet <string>(); bool thisIsInterface = Def.IsInterface; bool thisIsAbstract = Def.IsAbstract; StringBuilder sb = new StringBuilder(); uint lastRid = 0; foreach (MethodDef metDef in Def.Methods) { // 跳过非虚方法 if (!metDef.IsVirtual) { // 非虚方法如果存在显式重写则视为错误 if (metDef.HasOverrides) { throw new TypeLoadException( string.Format("Explicit overridden method must be virtual in type {0}: {1}", GetNameKey(), metDef.FullName)); } continue; } Debug.Assert(lastRid == 0 || lastRid < metDef.Rid); lastRid = metDef.Rid; // 获得方法签名 Helper.MethodDefNameKey(sb, metDef, null); string metNameKey = sb.ToString(); sb.Clear(); nameSet.Add(metNameKey); if (thisIsInterface) { Debug.Assert(metDef.IsAbstract && metDef.IsNewSlot); metDefList.Add(new Tuple <string, MethodDef>(metNameKey, metDef)); } else { // 特殊处理签名冲突的方法 if (!conflictMap.TryGetValue(metNameKey, out var confPair)) { confPair = new ConflictPair(); conflictMap.Add(metNameKey, confPair); metDefList.Add(new Tuple <string, MethodDef>(metNameKey, metDef)); } if (metDef.IsNewSlot) { confPair.NewSlots.Add(metDef); } else { confPair.ReuseSlots.Add(metDef); } } } if (!thisIsInterface) { foreach (var item in conflictMap.Where(kvp => !kvp.Value.ContainsConflicts()).ToList()) { conflictMap.Remove(item.Key); } } // 解析基类方法表 MethodTable baseTable = null; if (Def.BaseType != null) { baseTable = TypeMgr.ResolveMethodTable(Def.BaseType); // 继承基类数据 DerivedTable(baseTable); } var expOverrides = new List <Tuple <string, MethodDef> >(); // 解析隐式重写 foreach (var metItem in metDefList) { string metNameKey = metItem.Item1; if (thisIsInterface) { // 接口需要合并相同签名的方法 MethodDef metDef = metItem.Item2; var entry = new TableMethodPair(this, metDef); MergeInterface(metNameKey, entry); } else if (conflictMap.TryGetValue(metNameKey, out var confPair)) { Debug.Assert(confPair.ContainsConflicts()); // 冲突签名的方法需要先处理重写槽方法, 再处理新建槽方法 VirtualSlot lastVSlot = null; foreach (var metDef in confPair.ReuseSlots) { lastVSlot = ProcessMethod(metNameKey, metDef, baseTable, expOverrides); } // 应用重写信息到入口映射 ApplyVirtualSlot(lastVSlot); foreach (var metDef in confPair.NewSlots) { ProcessMethod(metNameKey, metDef, baseTable, expOverrides); } } else { MethodDef metDef = metItem.Item2; ProcessMethod(metNameKey, metDef, baseTable, expOverrides); } } metDefList = null; conflictMap = null; baseTable = null; // 关联抽象基类未实现的接口 if (NotImplInterfaces.IsCollectionValid()) { List <string> removedKeys = new List <string>(); foreach (var kv in NotImplInterfaces) { string metNameKey = kv.Key; var notImplEntries = kv.Value; if (SlotMap.TryGetValue(metNameKey, out var vslot)) { vslot.Entries.UnionWith(notImplEntries); removedKeys.Add(metNameKey); ApplyVirtualSlot(vslot); } } foreach (var key in removedKeys) { NotImplInterfaces.Remove(key); } } // 关联接口 if (Def.HasInterfaces) { foreach (var inf in Def.Interfaces) { MethodTable infTable = TypeMgr.ResolveMethodTable(inf.Interface); foreach (var kv in infTable.SlotMap) { string metNameKey = kv.Key; var infEntries = kv.Value.Entries; if (thisIsInterface) { MergeInterfaces(metNameKey, infEntries); } else if (nameSet.Contains(metNameKey) && SlotMap.TryGetValue(metNameKey, out var vslot)) { // 关联当前类型内签名相同的方法 vslot.Entries.UnionWith(infEntries); ApplyVirtualSlot(vslot); } else { foreach (var entry in infEntries) { if (!EntryMap.ContainsKey(entry)) { if (SlotMap.TryGetValue(metNameKey, out vslot)) { // 关联继承链上签名相同的方法 vslot.Entries.Add(entry); ApplyVirtualSlot(vslot); } else if (thisIsAbstract) { AddNotImplInterface(metNameKey, entry); } else { // 暂时未实现的接口入口 SetEntryMap(entry, null); } } } } } } } // 记录显式重写目标以便查重 var expOverTargets = new HashSet <TableMethodPair>(); // 解析显式重写 foreach (var expItem in expOverrides) { string metNameKey = expItem.Item1; MethodDef metDef = expItem.Item2; foreach (MethodOverride metOver in metDef.Overrides) { var overTarget = metOver.MethodDeclaration; var overImpl = metOver.MethodBody; MethodTable targetTable = TypeMgr.ResolveMethodTable(overTarget.DeclaringType); MethodDef targetDef = overTarget.ResolveMethodDef(); // 验证显式重写目标的正确性 if (targetDef == null || targetDef.DeclaringType != targetTable.Def) { throw new TypeLoadException( string.Format("Illegal explicit overriding target in type {0}: {1}", GetNameKey(), overTarget.FullName)); } if (!targetDef.IsVirtual) { throw new TypeLoadException( string.Format("Explicit overriding target must be virtual in type {0}: {1}", GetNameKey(), overTarget.FullName)); } var targetEntry = new TableMethodPair(targetTable, targetDef); MethodDef implDef = overImpl.ResolveMethodDef(); Debug.Assert(metDef == implDef); // 同一个类内重复的显式重写, 以及重写存在重写的方法, 视为错误 if ((targetTable == this && targetDef.HasOverrides) || expOverTargets.Contains(targetEntry)) { throw new TypeLoadException( string.Format("Explicit overriding target has been overridden in type {0}: {1}", GetNameKey(), overTarget.FullName)); } expOverTargets.Add(targetEntry); if (targetTable.Def.IsInterface) { // 接口方法显式重写 ExplicitOverride(targetEntry, metNameKey); } else { // 相同类型的需要添加到替换映射, 以便非虚调用时处理替换 if (targetTable == this) { SameTypeReplaceMap[targetDef] = new TableMethodPair(this, implDef); } else { var vslot = SlotMap[metNameKey]; Debug.Assert(vslot != null); SetEntryMap(targetEntry, vslot.Implemented); } } } } expOverTargets = null; // 接口不需要展开入口 if (thisIsInterface) { return; } // 展开新建槽位映射 foreach (var kv in SlotMap) { var entries = kv.Value.Entries; var newSlotEntry = kv.Value.NewSlotEntry; Debug.Assert(newSlotEntry.Item2.IsNewSlot); foreach (TableMethodPair entry in entries) { var entryDef = entry.Item2; if (entryDef.IsReuseSlot && entryDef != newSlotEntry.Item2) { NewSlotEntryMap[entryDef] = newSlotEntry; } } } // 对于非抽象类需要检查是否存在实现 if (!thisIsAbstract) { foreach (var kv in EntryMap) { if (kv.Value == null) { throw new TypeLoadException( string.Format("Interface/abstract method not implemented in type {0}: {1} -> {2}", GetNameKey(), kv.Key.Item1.GetNameKey(), kv.Key.Item2.FullName)); } } } }
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); } } } }