Beispiel #1
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);
        }
Beispiel #2
0
 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);
 }
Beispiel #3
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);
 }
Beispiel #4
0
        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);
        }
Beispiel #5
0
        private void ApplyVirtualSlot(VirtualSlot vslot)
        {
            Debug.Assert(vslot != null);

            var impl = vslot.Implemented;

            foreach (TableMethodPair entry in vslot.Entries)
            {
                SetEntryMap(entry, impl);
            }
        }
Beispiel #6
0
        public VirtualSlot(VirtualSlot other, TableMethodPair newEntry)
        {
            Entries.UnionWith(other.Entries);
            NewSlotEntry = other.NewSlotEntry;
            Implemented  = other.Implemented;

            if (NewSlotEntry == null)
            {
                NewSlotEntry = newEntry;
            }
        }
Beispiel #7
0
        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;
            }
        }
Beispiel #8
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);
        }
Beispiel #9
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);
        }
Beispiel #10
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);
        }
Beispiel #11
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));
                    }
                }
            }
        }
Beispiel #12
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);
                    }
                }
            }
        }