Esempio n. 1
0
        private TableMethodPair ExpandMethodPair(TableMethodPair metPair, MethodTable expMetTable, IGenericReplacer replacer)
        {
            if (metPair == null)
            {
                return(null);
            }

            MethodTable mtable = metPair.Item1;

            if (mtable == this)
            {
                return(new TableMethodPair(expMetTable, metPair.Item2));
            }

            if (mtable.InstGenArgs.IsCollectionValid())
            {
                var genArgs = Helper.ReplaceGenericSigList(mtable.InstGenArgs, replacer);
                mtable = TypeMgr.ResolveMethodTableSpec(mtable.Def, genArgs);

                Debug.Assert(mtable != this);
                return(new TableMethodPair(mtable, metPair.Item2));
            }

            return(metPair);
        }
Esempio n. 2
0
        private void DerivedTable(MethodTable baseTable)
        {
            DerivedLevel = baseTable.DerivedLevel + 1;

            foreach (var kv in baseTable.SlotMap)
            {
                SlotMap.Add(kv.Key, new VirtualSlot(kv.Value, null));
            }

            foreach (var kv in baseTable.EntryMap)
            {
                EntryMap.Add(kv.Key, kv.Value);
            }

            foreach (var kv in baseTable.SameTypeReplaceMap)
            {
                SameTypeReplaceMap.Add(kv.Key, kv.Value);
            }

            foreach (var kv in baseTable.NewSlotEntryMap)
            {
                NewSlotEntryMap.Add(kv.Key, kv.Value);
            }

            if (baseTable.NotImplInterfaces.IsCollectionValid())
            {
                Debug.Assert(baseTable.Def.IsAbstract);
                NotImplInterfaces = new Dictionary <string, HashSet <TableMethodPair> >();
                foreach (var kv in baseTable.NotImplInterfaces)
                {
                    NotImplInterfaces.Add(kv.Key, new HashSet <TableMethodPair>(kv.Value));
                }
            }
        }
Esempio n. 3
0
        public VirtualTable(MethodTable mtable)
        {
            Name = mtable.GetNameKey();

            foreach (var kv in mtable.EntryMap)
            {
                EntryMap.Add(
                    new TypeMethodPair(kv.Key.Item1.GetTypeX(), kv.Key.Item2),
                    new TypeMethodImpl(kv.Value));
            }

            foreach (var kv in mtable.SameTypeReplaceMap)
            {
                SameTypeReplaceMap.Add(
                    kv.Key,
                    new TypeMethodPair(kv.Value.Item1.GetTypeX(), kv.Value.Item2));
            }

            foreach (var kv in mtable.NewSlotEntryMap)
            {
                NewSlotEntryMap.Add(
                    kv.Key,
                    new TypeMethodPair(kv.Value.Item1.GetTypeX(), kv.Value.Item2));
            }
        }
Esempio n. 4
0
        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);
        }
Esempio n. 5
0
 public void ResolveVTable()
 {
     if (VTable == null)
     {
         MethodTable mtable = Context.TypeMgr.ResolveMethodTable(Def, null);
         VTable = mtable.ExpandVTable(GenArgs);
     }
 }
Esempio n. 6
0
 private void SetExpandedVSlotMap(MethodTable entryTable, MethodDef entryDef, ref VirtualImpl impl)
 {
     if (!ExpandedVSlotMap.TryGetValue(entryTable, out var defMap))
     {
         defMap = new Dictionary <MethodDef, VirtualImpl>();
         ExpandedVSlotMap.Add(entryTable, defMap);
     }
     defMap[entryDef] = impl;
 }
Esempio n. 7
0
 public void AddEntry(MethodTable entryTable, MethodDef entryDef)
 {
     if (!Entries.TryGetValue(entryTable, out var defSet))
     {
         defSet = new HashSet <MethodDef>();
         Entries.Add(entryTable, defSet);
     }
     defSet.Add(entryDef);
 }
Esempio n. 8
0
        public void SetImpl(MethodTable mtable, MethodDef metDef)
        {
            // 抽象方法不作为实现
            if (metDef.IsAbstract)
            {
                return;
            }

            Impl.ImplTable  = mtable;
            Impl.ImplMethod = metDef;
        }
Esempio n. 9
0
        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);
        }
Esempio n. 10
0
        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);
        }
Esempio n. 11
0
        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);
                }
            }
        }
Esempio n. 12
0
        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);
        }
Esempio n. 13
0
        private void DerivedFrom(MethodTable other)
        {
            foreach (var kv in other.VSlotMap)
            {
                if (kv.Value.Entries.Count > 0)
                {
                    VSlotMap.Add(kv.Key, new VirtualSlot(kv.Value));
                }
            }

            foreach (var kv in other.ExpandedVSlotMap)
            {
                ExpandedVSlotMap.Add(kv.Key, new Dictionary <MethodDef, VirtualImpl>(kv.Value));
            }

            foreach (var kv in other.NewSlotMap)
            {
                NewSlotMap.Add(kv.Key, kv.Value);
            }

            foreach (var kv in other.MethodReplaceMap)
            {
                MethodReplaceMap.Add(kv.Key, kv.Value);
            }

            if (Helper.IsCollectionValid(other.AbsNoImplSlotMap))
            {
                AbsNoImplSlotMap = new Dictionary <string, Dictionary <MethodTable, HashSet <MethodDef> > >();
                foreach (var kv in other.AbsNoImplSlotMap)
                {
                    var defMap = new Dictionary <MethodTable, HashSet <MethodDef> >();
                    AbsNoImplSlotMap.Add(kv.Key, defMap);

                    foreach (var kv2 in kv.Value)
                    {
                        defMap.Add(kv2.Key, new HashSet <MethodDef>(kv2.Value));
                    }
                }
            }

            if (Helper.IsCollectionValid(other.SameSigResolvedMap))
            {
                SameSigResolvedMap = new Dictionary <string, Tuple <MethodTable, MethodDef> >();
                foreach (var kv in other.SameSigResolvedMap)
                {
                    SameSigResolvedMap.Add(kv.Key, kv.Value);
                }
            }
        }
Esempio n. 14
0
 private void RemoveEntry(MethodTable entryTable, MethodDef entryDef)
 {
     // 在所有方法槽内查找, 找到匹配的入口则删除
     foreach (VirtualSlot vslot in VSlotMap.Values)
     {
         if (vslot.Entries.TryGetValue(entryTable, out var defSet))
         {
             if (defSet.Contains(entryDef))
             {
                 defSet.Remove(entryDef);
                 if (defSet.Count == 0)
                 {
                     vslot.Entries.Remove(entryTable);
                 }
             }
         }
     }
 }
Esempio n. 15
0
        private bool NeedMergeInterface(string expSigName, MethodTable entryTable, MethodDef entryDef)
        {
            // 当前方法表内存在该接口签名, 则需要合并接口
            foreach (string sigName in ExpandedSigList)
            {
                if (sigName == expSigName)
                {
                    return(true);
                }
            }

            // 当前方法不存在该接口签名, 但是展平的方法槽内已经有该签名了, 则无需合并接口
            if (ExpandedVSlotMap.TryGetValue(entryTable, out var defMap))
            {
                if (defMap.ContainsKey(entryDef))
                {
                    return(false);
                }
            }

            // 其他情况需要合并接口
            return(true);
        }
Esempio n. 16
0
        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);
        }
Esempio n. 17
0
        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));
                    }
                }
            }
        }
Esempio n. 18
0
        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);
                    }
                }
            }
        }