Example #1
0
        public static void MethodDefNameKey(
            StringBuilder sb,
            MethodDef metDef,
            IGenericReplacer replacer)
        {
            if (replacer == null)
            {
                MethodNameKey(
                    sb,
                    metDef.Name,
                    metDef.GenericParameters.Count,
                    metDef.MethodSig.RetType,
                    metDef.MethodSig.Params,
                    metDef.MethodSig.CallingConvention);
            }
            else
            {
                TypeSig         retType    = Helper.ReplaceGenericSig(metDef.MethodSig.RetType, replacer);
                IList <TypeSig> paramTypes = Helper.ReplaceGenericSigList(metDef.MethodSig.Params, replacer);

                MethodNameKey(
                    sb,
                    metDef.Name,
                    metDef.GenericParameters.Count,
                    retType,
                    paramTypes,
                    metDef.MethodSig.CallingConvention);
            }
        }
Example #2
0
        // 替换类型中的泛型签名
        public static TypeSig ReplaceGenericSig(TypeSig tySig, IGenericReplacer replacer)
        {
            if (replacer == null || !IsReplaceNeeded(tySig))
            {
                return(tySig);
            }

            return(ReplaceGenericSigImpl(tySig, replacer));
        }
Example #3
0
 private string GetReplacedNameKey(IGenericReplacer replacer)
 {
     if (HasGenArgs)
     {
         var           repGenArgs = Helper.ReplaceGenericSigList(GenArgs, replacer);
         StringBuilder sb         = new StringBuilder();
         Helper.TypeNameKey(sb, Def, repGenArgs);
         return(sb.ToString());
     }
     return(GetNameKey());
 }
Example #4
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);
                }
            }
        }
Example #5
0
        private void ResolveOperand(InstInfo inst, IGenericReplacer replacer)
        {
            // 重定向数组指令
            switch (inst.OpCode.Code)
            {
            case Code.Newarr:
            {
                // newobj T[]::.ctor(int)
                TypeSig elemSig = ((ITypeDefOrRef)inst.Operand).ToTypeSig();
                inst.OpCode  = OpCodes.Newobj;
                inst.Operand = new MemberRefUser(
                    Context.CorLibModule,
                    ".ctor",
                    MethodSig.CreateInstance(Context.CorLibTypes.Void, Context.CorLibTypes.Int32),
                    new TypeSpecUser(new SZArraySig(elemSig)));
                break;
            }

            case Code.Ldlen:
            {
                // call int Array::get_Length()
                inst.OpCode  = OpCodes.Call;
                inst.Operand = new MemberRefUser(
                    Context.CorLibModule,
                    "get_Length",
                    MethodSig.CreateInstance(Context.CorLibTypes.Int32),
                    Context.CorLibTypes.GetTypeRef("System", "Array"));
                break;
            }

            case Code.Ldelema:
            {
                // call T& T[]::Address(int)
                TypeSig elemSig = ((ITypeDefOrRef)inst.Operand).ToTypeSig();
                inst.OpCode  = OpCodes.Call;
                inst.Operand = new MemberRefUser(
                    Context.CorLibModule,
                    "Address",
                    MethodSig.CreateInstance(new ByRefSig(elemSig), Context.CorLibTypes.Int32),
                    new TypeSpecUser(new SZArraySig(elemSig)));
                break;
            }

            case Code.Ldelem_I1:
            case Code.Ldelem_U1:
            case Code.Ldelem_I2:
            case Code.Ldelem_U2:
            case Code.Ldelem_I4:
            case Code.Ldelem_U4:
            case Code.Ldelem_I8:
            case Code.Ldelem_I:
            case Code.Ldelem_R4:
            case Code.Ldelem_R8:
            case Code.Ldelem_Ref:
            case Code.Ldelem:
            {
                TypeSig elemSig = null;
                switch (inst.OpCode.Code)
                {
                case Code.Ldelem_I1:
                    elemSig = Context.CorLibTypes.SByte;
                    break;

                case Code.Ldelem_U1:
                    elemSig = Context.CorLibTypes.Byte;
                    break;

                case Code.Ldelem_I2:
                    elemSig = Context.CorLibTypes.Int16;
                    break;

                case Code.Ldelem_U2:
                    elemSig = Context.CorLibTypes.UInt16;
                    break;

                case Code.Ldelem_I4:
                    elemSig = Context.CorLibTypes.Int32;
                    break;

                case Code.Ldelem_U4:
                    elemSig = Context.CorLibTypes.UInt32;
                    break;

                case Code.Ldelem_I8:
                    elemSig = Context.CorLibTypes.Int64;
                    break;

                case Code.Ldelem_I:
                    elemSig = Context.CorLibTypes.IntPtr;
                    break;

                case Code.Ldelem_R4:
                    elemSig = Context.CorLibTypes.Single;
                    break;

                case Code.Ldelem_R8:
                    elemSig = Context.CorLibTypes.Double;
                    break;

                case Code.Ldelem_Ref:
                    elemSig = Context.CorLibTypes.Object;
                    break;

                case Code.Ldelem:
                    elemSig = ((ITypeDefOrRef)inst.Operand).ToTypeSig();
                    break;
                }
                // call T T[]::Get(int)
                inst.OpCode  = OpCodes.Call;
                inst.Operand = new MemberRefUser(
                    Context.CorLibModule,
                    "Get",
                    MethodSig.CreateInstance(elemSig, Context.CorLibTypes.Int32),
                    new TypeSpecUser(new SZArraySig(elemSig)));
                break;
            }

            case Code.Stelem_I1:
            case Code.Stelem_I2:
            case Code.Stelem_I4:
            case Code.Stelem_I8:
            case Code.Stelem_I:
            case Code.Stelem_R4:
            case Code.Stelem_R8:
            case Code.Stelem_Ref:
            case Code.Stelem:
            {
                TypeSig elemSig = null;
                switch (inst.OpCode.Code)
                {
                case Code.Stelem_I1:
                    elemSig = Context.CorLibTypes.SByte;
                    break;

                case Code.Stelem_I2:
                    elemSig = Context.CorLibTypes.Int16;
                    break;

                case Code.Stelem_I4:
                    elemSig = Context.CorLibTypes.Int32;
                    break;

                case Code.Stelem_I8:
                    elemSig = Context.CorLibTypes.Int64;
                    break;

                case Code.Stelem_I:
                    elemSig = Context.CorLibTypes.IntPtr;
                    break;

                case Code.Stelem_R4:
                    elemSig = Context.CorLibTypes.Single;
                    break;

                case Code.Stelem_R8:
                    elemSig = Context.CorLibTypes.Double;
                    break;

                case Code.Stelem_Ref:
                    elemSig = Context.CorLibTypes.Object;
                    break;

                case Code.Stelem:
                    elemSig = ((ITypeDefOrRef)inst.Operand).ToTypeSig();
                    break;
                }
                // call void T[]::Set(int,T)
                inst.OpCode  = OpCodes.Call;
                inst.Operand = new MemberRefUser(
                    Context.CorLibModule,
                    "Set",
                    MethodSig.CreateInstance(Context.CorLibTypes.Void, Context.CorLibTypes.Int32, elemSig),
                    new TypeSpecUser(new SZArraySig(elemSig)));
                break;
            }
            }

            switch (inst.OpCode.OperandType)
            {
            case OperandType.InlineMethod:
            {
                MethodX resMetX;
                switch (inst.Operand)
                {
                case MethodDef metDef:
                    resMetX = ResolveMethodDef(metDef);
                    break;

                case MemberRef memRef:
                    resMetX = ResolveMethodRef(memRef, replacer);
                    break;

                case MethodSpec metSpec:
                    resMetX = ResolveMethodSpec(metSpec, replacer);
                    break;

                default:
                    throw new ArgumentOutOfRangeException();
                }

                bool isReAddMethod = false;

                if (inst.OpCode.Code == Code.Newobj)
                {
                    Debug.Assert(!resMetX.Def.IsStatic);
                    Debug.Assert(resMetX.Def.IsConstructor);
                    // 设置实例化标记
                    resMetX.DeclType.IsInstantiated = true;
                    // 生成静态构造和终结器
                    GenStaticCctor(resMetX.DeclType);
                    GenFinalizer(resMetX.DeclType);
                }
                else if (inst.OpCode.Code == Code.Callvirt ||
                         inst.OpCode.Code == Code.Ldvirtftn)
                {
                    if (resMetX.IsVirtual)
                    {
                        AddVCallEntry(resMetX);
                    }
                    else
                    {
                        // 非虚方法重定向指令
                        inst.OpCode = inst.OpCode.Code == Code.Callvirt ?
                                      OpCodes.Call : OpCodes.Ldftn;
                    }
                }
                else if (resMetX.IsVirtual &&
                         (inst.OpCode.Code == Code.Call ||
                          inst.OpCode.Code == Code.Ldftn))
                {
                    // 处理方法替换
                    if (resMetX.DeclType.QueryCallReplace(this, resMetX.Def, out TypeX implTyX, out var implDef))
                    {
                        resMetX.IsSkipProcessing = true;

                        Debug.Assert(implTyX != null);
                        MethodX implMetX = MakeMethodX(implTyX, implDef, resMetX.GenArgs);

                        resMetX = implMetX;
                    }
                    else
                    {
                        isReAddMethod = true;
                    }
                }
                else
                {
                    isReAddMethod = true;
                }

                if (isReAddMethod)
                {
                    // 尝试重新加入处理队列
                    AddPendingMethod(resMetX);
                }

                if (resMetX.IsStatic)
                {
                    // 生成静态构造
                    GenStaticCctor(resMetX.DeclType);
                }

                inst.Operand = resMetX;
                return;
            }
Example #6
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);
        }
Example #7
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);
        }
Example #8
0
 private static IList <TypeSig> ReplaceGenericSigListImpl(IList <TypeSig> tySigList, IGenericReplacer replacer)
 {
     return(tySigList?.Select(tySig => ReplaceGenericSigImpl(tySig, replacer)).ToList());
 }
Example #9
0
 // 替换类型签名列表
 public static IList <TypeSig> ReplaceGenericSigList(IList <TypeSig> tySigList, IGenericReplacer replacer)
 {
     return(tySigList?.Select(tySig => ReplaceGenericSig(tySig, replacer)).ToList());
 }
Example #10
0
        private static TypeSig ReplaceGenericSigImpl(TypeSig tySig, IGenericReplacer replacer)
        {
            if (tySig == null)
            {
                return(null);
            }

            switch (tySig.ElementType)
            {
            case ElementType.Class:
            case ElementType.ValueType:
            case ElementType.TypedByRef:
                return(tySig);

            case ElementType.Ptr:
                return(new PtrSig(ReplaceGenericSigImpl(tySig.Next, replacer)));

            case ElementType.ByRef:
                return(new ByRefSig(ReplaceGenericSigImpl(tySig.Next, replacer)));

            case ElementType.Pinned:
                return(new PinnedSig(ReplaceGenericSigImpl(tySig.Next, replacer)));

            case ElementType.SZArray:
                return(new SZArraySig(ReplaceGenericSigImpl(tySig.Next, replacer)));

            case ElementType.Array:
            {
                ArraySig arySig = (ArraySig)tySig;
                return(new ArraySig(ReplaceGenericSigImpl(arySig.Next, replacer),
                                    arySig.Rank,
                                    arySig.Sizes,
                                    arySig.LowerBounds));
            }

            case ElementType.CModReqd:
            {
                CModReqdSig modreqdSig = (CModReqdSig)tySig;
                return(new CModReqdSig(modreqdSig.Modifier, ReplaceGenericSigImpl(modreqdSig.Next, replacer)));
            }

            case ElementType.CModOpt:
            {
                CModOptSig modoptSig = (CModOptSig)tySig;
                return(new CModOptSig(modoptSig.Modifier, ReplaceGenericSigImpl(modoptSig.Next, replacer)));
            }

            case ElementType.GenericInst:
            {
                GenericInstSig genInstSig = (GenericInstSig)tySig;
                return(new GenericInstSig(genInstSig.GenericType, ReplaceGenericSigListImpl(genInstSig.GenericArguments, replacer)));
            }

            case ElementType.Var:
            {
                GenericVar genVarSig = (GenericVar)tySig;
                TypeSig    result    = replacer.Replace(genVarSig);
                if (result != null)
                {
                    return(result);
                }
                return(genVarSig);
            }

            case ElementType.MVar:
            {
                GenericMVar genMVarSig = (GenericMVar)tySig;
                TypeSig     result     = replacer.Replace(genMVarSig);
                if (result != null)
                {
                    return(result);
                }
                return(genMVarSig);
            }

            default:
                if (tySig is CorLibTypeSig)
                {
                    return(tySig);
                }

                throw new NotSupportedException();
            }
        }
Example #11
0
        private void ResolveOperand(InstInfo inst, IGenericReplacer replacer)
        {
            switch (inst.OpCode.OperandType)
            {
            case OperandType.InlineMethod:
            {
                MethodX resMetX;
                switch (inst.Operand)
                {
                case MethodDef metDef:
                    resMetX = ResolveMethodDef(metDef);
                    break;

                case MemberRef memRef:
                    resMetX = ResolveMethodRef(memRef, replacer);
                    break;

                case MethodSpec metSpec:
                    resMetX = ResolveMethodSpec(metSpec, replacer);
                    break;

                default:
                    throw new ArgumentOutOfRangeException();
                }

                bool isReAddMethod = false;

                if (inst.OpCode.Code == Code.Newobj)
                {
                    Debug.Assert(!resMetX.Def.IsStatic);
                    Debug.Assert(resMetX.Def.IsConstructor);
                    // 设置实例化标记
                    resMetX.DeclType.IsInstantiated = true;
                    // 生成静态构造和终结器
                    GenStaticCctor(resMetX.DeclType);
                    GenFinalizer(resMetX.DeclType);

                    // 解析虚表
                    resMetX.DeclType.ResolveVTable();
                }
                else if (resMetX.IsVirtual &&
                         (inst.OpCode.Code == Code.Callvirt ||
                          inst.OpCode.Code == Code.Ldvirtftn))
                {
                    // 处理非入口虚调用重定向
                    if (!resMetX.Def.IsNewSlot)
                    {
                        if (GetNewSlotMethodChecked(resMetX.DeclType, resMetX.Def, out var slotTypeName, out var slotMetDef))
                        {
                            resMetX.IsSkipProcessing = true;

                            TypeX slotTyX = GetTypeByName(slotTypeName);
                            Debug.Assert(slotTyX != null);

                            MethodX slotMetX = MakeMethodX(slotTyX, slotMetDef, resMetX.GenArgs);

                            resMetX = slotMetX;
                        }
                    }
                    AddVCallEntry(resMetX);
                }
                else if (resMetX.IsVirtual &&
                         (inst.OpCode.Code == Code.Call ||
                          inst.OpCode.Code == Code.Ldftn))
                {
                    // 处理方法替换
                    if (resMetX.DeclType.IsMethodReplaced(resMetX.Def, out var repTypeName, out var repMetDef))
                    {
                        resMetX.IsSkipProcessing = true;

                        TypeX repTyX = GetTypeByName(repTypeName);
                        Debug.Assert(repTyX != null);

                        MethodX repMetX = MakeMethodX(repTyX, repMetDef, resMetX.GenArgs);

                        resMetX = repMetX;
                    }
                    else
                    {
                        isReAddMethod = true;
                    }
                }
                else
                {
                    isReAddMethod = true;
                }

                if (isReAddMethod)
                {
                    // 尝试重新加入处理队列
                    AddPendingMethod(resMetX);
                }

                if (resMetX.IsStatic)
                {
                    // 生成静态构造
                    GenStaticCctor(resMetX.DeclType);
                }

                inst.Operand = resMetX;
                return;
            }
Example #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);
                    }
                }
            }
        }
Example #13
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);
        }