Exemple #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);
        }
Exemple #2
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);
        }
Exemple #3
0
        private void ExplicitOverride(TableMethodPair targetEntry, string overriddenMet)
        {
            RemoveSlotEntry(targetEntry);
            var vslot = SlotMap[overriddenMet];

            Debug.Assert(vslot != null);
            vslot.Entries.Add(targetEntry);
            ApplyVirtualSlot(vslot);
        }
Exemple #4
0
 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);
 }
Exemple #5
0
 private void SetEntryMap(TableMethodPair entry, TableMethodPair impl)
 {
     if (impl != null)
     {
         EntryMap[entry] = new TableMethodImpl(impl, DerivedLevel);
     }
     else
     {
         EntryMap[entry] = null;
     }
 }
Exemple #6
0
        public VirtualSlot(VirtualSlot other, TableMethodPair newEntry)
        {
            Entries.UnionWith(other.Entries);
            NewSlotEntry = other.NewSlotEntry;
            Implemented  = other.Implemented;

            if (NewSlotEntry == null)
            {
                NewSlotEntry = newEntry;
            }
        }
Exemple #7
0
        private void AddNotImplInterface(string metNameKey, TableMethodPair notImplPair)
        {
            if (NotImplInterfaces == null)
            {
                NotImplInterfaces = new Dictionary <string, HashSet <TableMethodPair> >();
            }

            if (!NotImplInterfaces.TryGetValue(metNameKey, out var entries))
            {
                entries = new HashSet <TableMethodPair>();
                NotImplInterfaces.Add(metNameKey, entries);
            }
            entries.Add(notImplPair);
        }
Exemple #8
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);
        }
Exemple #9
0
 private void MergeExpandedEntry(
     Dictionary <TableMethodPair, TableMethodImpl> expEntryMap,
     TableMethodPair entry,
     TableMethodPair impl,
     uint level)
 {
     if (expEntryMap.TryGetValue(entry, out var oval))
     {
         // 不覆盖同一个类内的相同签名, 对于不同的类则子类方法优先
         if (oval.Level >= level)
         {
             return;
         }
     }
     expEntryMap[entry] = new TableMethodImpl(impl, level);
 }
Exemple #10
0
        private void RemoveSlotEntry(TableMethodPair entry)
        {
            List <string> removedKeys = new List <string>();

            foreach (var kv in SlotMap)
            {
                string metNameKey = kv.Key;
                var    vslot      = kv.Value;

                vslot.Entries.Remove(entry);

                if (vslot.Entries.Count == 0)
                {
                    removedKeys.Add(metNameKey);
                }
            }
            foreach (var key in removedKeys)
            {
                SlotMap.Remove(key);
            }

            if (NotImplInterfaces.IsCollectionValid())
            {
                removedKeys.Clear();
                foreach (var kv in NotImplInterfaces)
                {
                    string metNameKey     = kv.Key;
                    var    notImplEntries = kv.Value;

                    notImplEntries.Remove(entry);

                    if (notImplEntries.Count == 0)
                    {
                        removedKeys.Add(metNameKey);
                    }
                }
                foreach (var key in removedKeys)
                {
                    NotImplInterfaces.Remove(key);
                }
            }
        }
Exemple #11
0
 public VirtualSlot(TableMethodPair newEntry)
 {
     NewSlotEntry = newEntry;
 }
Exemple #12
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));
                    }
                }
            }
        }
Exemple #13
0
 public TableMethodImpl(TableMethodPair methodPair, uint level)
 {
     MethodPair = methodPair;
     Level      = level;
 }