Ejemplo n.º 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);
        }
Ejemplo n.º 2
0
        private string GetExpandedMethodNameKey(StringBuilder sb, MethodDef metDef)
        {
            IGenericReplacer replacer = new TypeDefGenReplacer(Def, InstGenArgs);

            Helper.MethodDefNameKey(sb, metDef, replacer);
            string metNameKey = sb.ToString();

            sb.Clear();
            return(metNameKey);
        }
Ejemplo n.º 3
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);
                }
            }
        }
Ejemplo n.º 4
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);
                    }
                }
            }
        }
Ejemplo n.º 5
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);
        }