Exemplo n.º 1
0
        public static VTable ConstructVTable(TypeDef typeDef, VTableStorage storage)
        {
            var ret = new VTable(typeDef);

            var slotDict = new Dictionary<VTableSignature, List<VTableSlot>>();

            // Partition II 12.2

            // Interfaces
            foreach (InterfaceImpl iface in typeDef.Interfaces) {
                VTable ifaceVTbl = storage.GetVTable(iface.Interface);
                if (ifaceVTbl != null)
                    ret.Inherit(ifaceVTbl, slotDict);
            }

            // Base type
            VTable baseVTbl = storage.GetVTable(typeDef.GetBaseTypeThrow());
            if (baseVTbl != null)
                ret.Inherit(baseVTbl, slotDict);

            List<MethodDef> virtualMethods = typeDef.Methods.Where(method => method.IsVirtual).ToList();
            var methodsProcessed = new HashSet<MethodDef>();

            // MethodImpls (Partition II 22.27)
            foreach (MethodDef method in virtualMethods)
                foreach (MethodOverride impl in method.Overrides) {
                    Debug.Assert(impl.MethodBody == method);

                    MethodDef targetMethod = impl.MethodDeclaration.ResolveThrow();
                    VTableSignature sig = VTableSignature.FromMethod(impl.MethodDeclaration);
                    Debug.Assert(slotDict.ContainsKey(sig));

                    var methodSlot = new VTableSlot(ret, method, method.DeclaringType.ToTypeSig(), VTableSignature.FromMethod(method));
                    ret.Override(slotDict, sig, methodSlot, targetMethod);
                    methodsProcessed.Add(method);
                }

            // Normal override
            foreach (MethodDef method in virtualMethods) {
                VTableSignature sig = VTableSignature.FromMethod(method);
                var methodSlot = new VTableSlot(ret, method, method.DeclaringType.ToTypeSig(), sig);
                if (slotDict.ContainsKey(sig) && slotDict[sig].Count > 0) {
                    ret.Override(slotDict, sig, methodSlot);
                    methodsProcessed.Add(method);
                }
            }

            // Remaining methods
            foreach (MethodDef method in typeDef.Methods.Where(method => method.IsVirtual).Except(methodsProcessed)) {
                var slot = new VTableSlot(ret, method, method.DeclaringType.ToTypeSig(), VTableSignature.FromMethod(method));
                if (method.IsFinal)
                    ret.Finals.Add(slot);
                else {
                    Debug.Assert(!ret.Slots.Any(s => s.MethodDef == method));
                    ret.Slots.Add(slot);
                }
            }

            return ret;
        }
Exemplo n.º 2
0
 internal VTableSlot(TypeSig defDeclType, MethodDef def, TypeSig decl, VTableSignature signature, VTableSlot overrides)
 {
     MethodDefDeclType = defDeclType;
     MethodDef         = def;
     DeclaringType     = decl;
     Signature         = signature;
     Overrides         = overrides;
 }
Exemplo n.º 3
0
        static VTableSlot ResolveSlot(TypeDef openType, VTableSlot slot, IList <TypeSig> genArgs)
        {
            MethodSig newSig  = GenericArgumentResolver.Resolve(slot.Signature.MethodSig, genArgs);
            TypeSig   newDecl = slot.MethodDefDeclType;

            newDecl = new SigComparer().Equals(newDecl, openType)
                ? new GenericInstSig((ClassOrValueTypeSig)openType.ToTypeSig(), genArgs.ToArray())
                : GenericArgumentResolver.Resolve(newDecl, genArgs);
            return(new VTableSlot(newDecl, slot.MethodDef, slot.DeclaringType, new VTableSignature(newSig, slot.Signature.Name), slot.Overrides));
        }
Exemplo n.º 4
0
        static void Implements(VTableConstruction vTbl, Dictionary <VTableSignature, MethodDef> virtualMethods, VTable ifaceVTbl, TypeSig iface)
        {
            // This is the step 2 of 12.2 algorithm -- use virtual newslot methods for explicit implementation.

            Func <VTableSlot, VTableSlot> implLookup = slot => {
                if (virtualMethods.TryGetValue(slot.Signature, out MethodDef impl) &&
                    impl.IsNewSlot && !impl.DeclaringType.IsInterface)
                {
                    // Interface methods cannot implements base interface methods.
                    // The Overrides of interface slots should directly points to the root interface slot
                    VTableSlot targetSlot = slot;
                    while (targetSlot.Overrides != null && !targetSlot.MethodDef.DeclaringType.IsInterface)
                    {
                        targetSlot = targetSlot.Overrides;
                    }
                    Debug.Assert(targetSlot.MethodDef.DeclaringType.IsInterface);
                    return(targetSlot.OverridedBy(impl));
                }
                return(slot);
            };

            if (vTbl.InterfaceSlots.ContainsKey(iface))
            {
                vTbl.InterfaceSlots[iface] = vTbl.InterfaceSlots[iface].Values.ToDictionary(
                    slot => slot.Signature, implLookup);
            }
            else
            {
                vTbl.InterfaceSlots.Add(iface, ifaceVTbl.Slots.ToDictionary(
                                            slot => slot.Signature, implLookup));
            }

            foreach (KeyValuePair <TypeSig, IList <VTableSlot> > baseIface in ifaceVTbl.InterfaceSlots)
            {
                if (vTbl.InterfaceSlots.ContainsKey(baseIface.Key))
                {
                    vTbl.InterfaceSlots[baseIface.Key] = vTbl.InterfaceSlots[baseIface.Key].Values.ToDictionary(
                        slot => slot.Signature, implLookup);
                }
                else
                {
                    vTbl.InterfaceSlots.Add(baseIface.Key, baseIface.Value.ToDictionary(
                                                slot => slot.Signature, implLookup));
                }
            }
        }
Exemplo n.º 5
0
        private void Override(Dictionary <VTableSignature, List <VTableSlot> > slotDict, VTableSignature sig, VTableSlot slot, MethodDef target)
        {
            List <VTableSlot> slotList   = slotDict[sig];
            VTableSlot        targetSlot = slotList.Single(baseSlot => baseSlot.MethodDef == target);

            if (slot.MethodDef.IsReuseSlot || targetSlot.MethodDef.DeclaringType.IsInterface)
            {
                slot.Override(targetSlot);
            }
            slotList.Remove(targetSlot);

            if (!slot.MethodDef.IsFinal)
            {
                slotDict.AddListEntry(slot.Signature, slot);
                Slots.Add(slot);
            }
            else
            {
                Finals.Add(slot);
            }
        }
Exemplo n.º 6
0
 public VTableSlot Override(VTableSlot slot)
 {
     Overrides.Add(slot);
     return this;
 }
Exemplo n.º 7
0
        private void Override(Dictionary<VTableSignature, List<VTableSlot>> slotDict, VTableSignature sig, VTableSlot slot, MethodDef target)
        {
            List<VTableSlot> slotList = slotDict[sig];
            VTableSlot targetSlot = slotList.Single(baseSlot => baseSlot.MethodDef == target);

            if (slot.MethodDef.IsReuseSlot || targetSlot.MethodDef.DeclaringType.IsInterface)
                slot.Override(targetSlot);
            slotList.Remove(targetSlot);

            if (!slot.MethodDef.IsFinal) {
                slotDict.AddListEntry(slot.Signature, slot);
                Slots.Add(slot);
            }
            else
                Finals.Add(slot);
        }
Exemplo n.º 8
0
        private void Override(Dictionary<VTableSignature, List<VTableSlot>> slotDict, VTableSignature sig, VTableSlot slot)
        {
            List<VTableSlot> slotList = slotDict[sig];

            foreach (VTableSlot baseSlot in slotList) {
                if (slot.MethodDef.IsReuseSlot || baseSlot.MethodDef.DeclaringType.IsInterface)
                    slot.Override(baseSlot);
                bool k = Slots.Remove(baseSlot);
                Debug.Assert(k);
            }
            slotList.Clear();
            if (!slot.MethodDef.IsFinal) {
                slotList.Add(slot);
                Slots.Add(slot);
            }
            else
                Finals.Add(slot);
        }
Exemplo n.º 9
0
        public static VTable ConstructVTable(TypeDef typeDef, VTableStorage storage)
        {
            var ret = new VTable(typeDef);

            var slotDict = new Dictionary<VTableSignature, List<VTableSlot>>();

            // Partition II 12.2

            // Interfaces
            foreach (InterfaceImpl iface in typeDef.Interfaces) {
                VTable ifaceVTbl = storage.GetVTable(iface.Interface);
                if (ifaceVTbl != null)
                    ret.Inherit(ifaceVTbl, slotDict);
            }

            // Base type
            VTable baseVTbl = storage.GetVTable(typeDef.GetBaseTypeThrow());
            if (baseVTbl != null)
                ret.Inherit(baseVTbl, slotDict);

            List<MethodDef> virtualMethods = typeDef.Methods.Where(method => method.IsVirtual).ToList();
            var methodsProcessed = new HashSet<MethodDef>();

            // MethodImpls (Partition II 22.27)
            foreach (MethodDef method in virtualMethods)
                foreach (MethodOverride impl in method.Overrides) {
                    Debug.Assert(impl.MethodBody == method);

                    MethodDef targetMethod = impl.MethodDeclaration.ResolveThrow();
                    VTableSignature sig = VTableSignature.FromMethod(impl.MethodDeclaration);
                    Debug.Assert(slotDict.ContainsKey(sig));

                    var methodSlot = new VTableSlot(ret, method, method.DeclaringType.ToTypeSig(), VTableSignature.FromMethod(method));
                    if (slotDict.ContainsKey(sig) && slotDict[sig].Count > 0) {
                        ret.Override(slotDict, sig, methodSlot, targetMethod);
                        methodsProcessed.Add(method);
                    }
                }

            // Normal override
            foreach (MethodDef method in virtualMethods) {
                VTableSignature sig = VTableSignature.FromMethod(method);
                var methodSlot = new VTableSlot(ret, method, method.DeclaringType.ToTypeSig(), sig);
                if (slotDict.ContainsKey(sig) && slotDict[sig].Count > 0) {
                    ret.Override(slotDict, sig, methodSlot);
                    methodsProcessed.Add(method);
                }
            }

            // Remaining methods
            foreach (MethodDef method in typeDef.Methods.Where(method => method.IsVirtual).Except(methodsProcessed)) {
                foreach (var remainingSlot in slotDict.Keys.Where(key => key.InterfaceType != null)) {
                    // If there is a remaining slot for an interface method which has the same name and signature as an unprocessed method,
                    // allow the method to override the slot.
                    // This is necessary because public methods which implement interface methods do not have an InterfaceType in their signature,
                    // but the keys of "slotDict" which were added for interface methods *do* have InterfaceType in their signature.  Therefore,
                    // these slots are not filled by the "Normal override" loop above.
                    if (new SigComparer().Equals(remainingSlot.MethodSig, method.MethodSig) && remainingSlot.Name.Equals(method.Name, StringComparison.Ordinal)) {
                        var methodSlot = new VTableSlot(ret, method, method.DeclaringType.ToTypeSig(), remainingSlot);
                        ret.Override(slotDict, remainingSlot, methodSlot);
                        methodsProcessed.Add(method);
                        goto next;
                    }
                }
                var slot = new VTableSlot(ret, method, method.DeclaringType.ToTypeSig(), VTableSignature.FromMethod(method));
                if (method.IsFinal)
                    ret.Finals.Add(slot);
                else {
                    Debug.Assert(!ret.Slots.Any(s => s.MethodDef == method));
                    ret.Slots.Add(slot);
                }
                next:
                continue;
            }

            return ret;
        }
Exemplo n.º 10
0
        public static VTable ConstructVTable(TypeDef typeDef, VTableStorage storage)
        {
            var ret = new VTable(typeDef.ToTypeSig());

            var virtualMethods = typeDef.Methods
                                 .Where(method => method.IsVirtual)
                                 .ToDictionary(
                method => VTableSignature.FromMethod(method),
                method => method
                );

            // See Partition II 12.2 for implementation algorithm
            var vTbl = new VTableConstruction();

            // Inherits base type's slots
            VTable baseVTbl = storage.GetVTable(typeDef.GetBaseTypeThrow());

            if (baseVTbl != null)
            {
                Inherits(vTbl, baseVTbl);
            }

            // Explicit interface implementation
            foreach (InterfaceImpl iface in typeDef.Interfaces)
            {
                VTable ifaceVTbl = storage.GetVTable(iface.Interface);
                if (ifaceVTbl != null)
                {
                    Implements(vTbl, virtualMethods, ifaceVTbl, iface.Interface.ToTypeSig());
                }
            }

            // Normal interface implementation
            if (!typeDef.IsInterface)
            {
                // Interface methods cannot implements base interface methods.
                foreach (Dictionary <VTableSignature, VTableSlot> iface in vTbl.InterfaceSlots.Values)
                {
                    foreach (KeyValuePair <VTableSignature, VTableSlot> entry in iface.ToList())
                    {
                        if (!entry.Value.MethodDef.DeclaringType.IsInterface)
                        {
                            continue;
                        }
                        if (virtualMethods.TryGetValue(entry.Key, out MethodDef impl))
                        {
                            iface[entry.Key] = entry.Value.OverridedBy(impl);
                        }
                        else if (vTbl.SlotsMap.TryGetValue(entry.Key, out VTableSlot implSlot))
                        {
                            iface[entry.Key] = entry.Value.OverridedBy(implSlot.MethodDef);
                        }
                    }
                }
            }

            // Normal overrides
            foreach (KeyValuePair <VTableSignature, MethodDef> method in virtualMethods)
            {
                VTableSlot slot;
                if (method.Value.IsNewSlot)
                {
                    slot = new VTableSlot(method.Value, typeDef.ToTypeSig(), method.Key);
                }
                else
                {
                    if (vTbl.SlotsMap.TryGetValue(method.Key, out slot))
                    {
                        Debug.Assert(!slot.MethodDef.IsFinal);
                        slot = slot.OverridedBy(method.Value);
                    }
                    else
                    {
                        slot = new VTableSlot(method.Value, typeDef.ToTypeSig(), method.Key);
                    }
                }
                vTbl.SlotsMap[method.Key] = slot;
                vTbl.AllSlots.Add(slot);
            }

            // MethodImpls
            foreach (KeyValuePair <VTableSignature, MethodDef> method in virtualMethods)
            {
                foreach (MethodOverride impl in method.Value.Overrides)
                {
                    Debug.Assert(impl.MethodBody == method.Value);

                    MethodDef targetMethod = impl.MethodDeclaration.ResolveThrow();
                    if (targetMethod.DeclaringType.IsInterface)
                    {
                        var iface = impl.MethodDeclaration.DeclaringType.ToTypeSig();
                        CheckKeyExist(storage, vTbl.InterfaceSlots, iface, "MethodImpl Iface");
                        Dictionary <VTableSignature, VTableSlot> ifaceVTbl = vTbl.InterfaceSlots[iface];

                        var signature = VTableSignature.FromMethod(impl.MethodDeclaration);
                        CheckKeyExist(storage, ifaceVTbl, signature, "MethodImpl Iface Sig");
                        VTableSlot targetSlot = ifaceVTbl[signature];

                        // The Overrides of interface slots should directly points to the root interface slot
                        while (targetSlot.Overrides != null)
                        {
                            targetSlot = targetSlot.Overrides;
                        }
                        Debug.Assert(targetSlot.MethodDef.DeclaringType.IsInterface);
                        ifaceVTbl[targetSlot.Signature] = targetSlot.OverridedBy(method.Value);
                    }
                    else
                    {
                        VTableSlot targetSlot = vTbl.AllSlots.Single(slot => slot.MethodDef == targetMethod);
                        CheckKeyExist(storage, vTbl.SlotsMap, targetSlot.Signature, "MethodImpl Normal Sig");
                        targetSlot = vTbl.SlotsMap[targetSlot.Signature];                         // Use the most derived slot
                        // Maybe implemented by above processes --- this process should take priority
                        while (targetSlot.MethodDef.DeclaringType == typeDef)
                        {
                            targetSlot = targetSlot.Overrides;
                        }
                        vTbl.SlotsMap[targetSlot.Signature] = targetSlot.OverridedBy(method.Value);
                    }
                }
            }

            // Populate result V-table
            ret.InterfaceSlots = vTbl.InterfaceSlots.ToDictionary(
                kvp => kvp.Key, kvp => (IList <VTableSlot>)kvp.Value.Values.ToList());

            foreach (VTableSlot slot in vTbl.AllSlots)
            {
                ret.Slots.Add(slot);
            }

            return(ret);
        }
Exemplo n.º 11
0
        public static VTable ConstructVTable(TypeDef typeDef, VTableStorage storage)
        {
            var ret = new VTable(typeDef);

            var slotDict = new Dictionary <VTableSignature, List <VTableSlot> >();

            // Partition II 12.2

            // Interfaces
            foreach (InterfaceImpl iface in typeDef.Interfaces)
            {
                VTable ifaceVTbl = storage.GetVTable(iface.Interface);
                if (ifaceVTbl != null)
                {
                    ret.Inherit(ifaceVTbl, slotDict);
                }
            }

            // Base type
            VTable baseVTbl = storage.GetVTable(typeDef.GetBaseTypeThrow());

            if (baseVTbl != null)
            {
                ret.Inherit(baseVTbl, slotDict);
            }

            List <MethodDef> virtualMethods = typeDef.Methods.Where(method => method.IsVirtual).ToList();
            var methodsProcessed            = new HashSet <MethodDef>();


            // MethodImpls (Partition II 22.27)
            foreach (MethodDef method in virtualMethods)
            {
                foreach (MethodOverride impl in method.Overrides)
                {
                    Debug.Assert(impl.MethodBody == method);

                    MethodDef       targetMethod = impl.MethodDeclaration.ResolveThrow();
                    VTableSignature sig          = VTableSignature.FromMethod(impl.MethodDeclaration);
                    Debug.Assert(slotDict.ContainsKey(sig));

                    var methodSlot = new VTableSlot(ret, method, method.DeclaringType.ToTypeSig(), VTableSignature.FromMethod(method));
                    if (slotDict.ContainsKey(sig) && slotDict[sig].Count > 0)
                    {
                        ret.Override(slotDict, sig, methodSlot, targetMethod);
                        methodsProcessed.Add(method);
                    }
                }
            }

            // Normal override
            foreach (MethodDef method in virtualMethods)
            {
                VTableSignature sig        = VTableSignature.FromMethod(method);
                var             methodSlot = new VTableSlot(ret, method, method.DeclaringType.ToTypeSig(), sig);
                if (slotDict.ContainsKey(sig) && slotDict[sig].Count > 0)
                {
                    ret.Override(slotDict, sig, methodSlot);
                    methodsProcessed.Add(method);
                }
            }

            // Remaining methods
            foreach (MethodDef method in typeDef.Methods.Where(method => method.IsVirtual).Except(methodsProcessed))
            {
                foreach (var remainingSlot in slotDict.Keys.Where(key => key.InterfaceType != null))
                {
                    // If there is a remaining slot for an interface method which has the same name and signature as an unprocessed method,
                    // allow the method to override the slot.
                    // This is necessary because public methods which implement interface methods do not have an InterfaceType in their signature,
                    // but the keys of "slotDict" which were added for interface methods *do* have InterfaceType in their signature.  Therefore,
                    // these slots are not filled by the "Normal override" loop above.
                    if (new SigComparer().Equals(remainingSlot.MethodSig, method.MethodSig) && remainingSlot.Name.Equals(method.Name, StringComparison.Ordinal))
                    {
                        var methodSlot = new VTableSlot(ret, method, method.DeclaringType.ToTypeSig(), remainingSlot);
                        ret.Override(slotDict, remainingSlot, methodSlot);
                        methodsProcessed.Add(method);
                        goto next;
                    }
                }
                var slot = new VTableSlot(ret, method, method.DeclaringType.ToTypeSig(), VTableSignature.FromMethod(method));
                if (method.IsFinal)
                {
                    ret.Finals.Add(slot);
                }
                else
                {
                    Debug.Assert(!ret.Slots.Any(s => s.MethodDef == method));
                    ret.Slots.Add(slot);
                }
next:
                continue;
            }

            return(ret);
        }
Exemplo n.º 12
0
        private void Override(Dictionary <VTableSignature, List <VTableSlot> > slotDict, VTableSignature sig, VTableSlot slot)
        {
            List <VTableSlot> slotList = slotDict[sig];

            foreach (VTableSlot baseSlot in slotList)
            {
                if (slot.MethodDef.IsReuseSlot || baseSlot.MethodDef.DeclaringType.IsInterface)
                {
                    slot.Override(baseSlot);
                }
                bool k = Slots.Remove(baseSlot);
                Debug.Assert(k);
            }
            slotList.Clear();
            if (!slot.MethodDef.IsFinal)
            {
                slotList.Add(slot);
                Slots.Add(slot);
            }
            else
            {
                Finals.Add(slot);
            }
        }
Exemplo n.º 13
0
 public VTableSlot Override(VTableSlot slot)
 {
     Overrides.Add(slot);
     return(this);
 }
Exemplo n.º 14
0
        public static VTable ConstructVTable(TypeDef typeDef, VTableStorage storage)
        {
            var ret = new VTable(typeDef.ToTypeSig());

            var virtualMethods = typeDef.Methods
                                 .Where(method => method.IsVirtual)
                                 .ToDictionary(
                method => VTableSignature.FromMethod(method),
                method => method
                );

            // See Partition II 12.2 for implementation algorithm
            VTableConstruction vTbl = new VTableConstruction();

            // Inherits base type's slots
            VTable baseVTbl = storage.GetVTable(typeDef.GetBaseTypeThrow());

            if (baseVTbl != null)
            {
                Inherits(vTbl, baseVTbl);
            }

            // Explicit interface implementation
            foreach (InterfaceImpl iface in typeDef.Interfaces)
            {
                VTable ifaceVTbl = storage.GetVTable(iface.Interface);
                if (ifaceVTbl != null)
                {
                    Implements(vTbl, virtualMethods, ifaceVTbl, iface.Interface.ToTypeSig());
                }
            }

            // Normal interface implementation
            if (!typeDef.IsInterface)
            {
                // Interface methods cannot implements base interface methods.

                foreach (var interfaceTypeSig in vTbl.InterfaceSlots.Keys.ToList())
                {
                    var slots = vTbl.InterfaceSlots[interfaceTypeSig];
                    if (slots.Select(g => g.Key)
                        .Any(sig => virtualMethods.ContainsKey(sig) || vTbl.SlotsMap.ContainsKey(sig)))
                    {
                        // Something has a new signature. We need to rewrite the whole thing.

                        // This is the step 1 of 12.2 algorithm -- find implementation for still empty slots.
                        // Note that it seems we should include newslot methods as well, despite what the standard said.
                        slots = slots
                                .SelectMany(g => g.Select(slot => (g.Key, Slot: slot)))
                                .ToLookup(t => t.Key, t => {
                            if (!t.Slot.MethodDef.DeclaringType.IsInterface)
                            {
                                return(t.Slot);
                            }

                            if (virtualMethods.TryGetValue(t.Key, out var impl))
                            {
                                return(t.Slot.OverridedBy(impl));
                            }

                            if (vTbl.SlotsMap.TryGetValue(t.Key, out var implSlot))
                            {
                                return(t.Slot.OverridedBy(implSlot.MethodDef));
                            }

                            return(t.Slot);
                        });

                        vTbl.InterfaceSlots[interfaceTypeSig] = slots;
                    }
                }
            }

            // Normal overrides
            foreach (var method in virtualMethods)
            {
                VTableSlot slot;
                if (method.Value.IsNewSlot)
                {
                    slot = new VTableSlot(method.Value, typeDef.ToTypeSig(), method.Key);
                }
                else
                {
                    if (vTbl.SlotsMap.TryGetValue(method.Key, out slot))
                    {
                        Debug.Assert(!slot.MethodDef.IsFinal);
                        slot = slot.OverridedBy(method.Value);
                    }
                    else
                    {
                        slot = new VTableSlot(method.Value, typeDef.ToTypeSig(), method.Key);
                    }
                }
                vTbl.SlotsMap[method.Key] = slot;
                vTbl.AllSlots.Add(slot);
            }

            // MethodImpls
            foreach (var method in virtualMethods)
            {
                foreach (var impl in method.Value.Overrides)
                {
                    Debug.Assert(impl.MethodBody == method.Value);

                    MethodDef targetMethod = impl.MethodDeclaration.ResolveThrow();
                    if (targetMethod.DeclaringType.IsInterface)
                    {
                        var iface = impl.MethodDeclaration.DeclaringType.ToTypeSig();
                        CheckKeyExist(storage, vTbl.InterfaceSlots, iface, "MethodImpl Iface");
                        var ifaceVTbl = vTbl.InterfaceSlots[iface];

                        var signature = VTableSignature.FromMethod(impl.MethodDeclaration);
                        CheckKeyExist(storage, ifaceVTbl, signature, "MethodImpl Iface Sig");

                        vTbl.InterfaceSlots[iface] = ifaceVTbl
                                                     .SelectMany(g => g.Select(slot => (g.Key, Slot: slot)))
                                                     .ToLookup(t => t.Key, t => {
                            if (!t.Key.Equals(signature))
                            {
                                return(t.Slot);
                            }

                            var targetSlot = t.Slot;
                            while (targetSlot.Overrides != null)
                            {
                                targetSlot = targetSlot.Overrides;
                            }
                            Debug.Assert(targetSlot.MethodDef.DeclaringType.IsInterface);
                            Debug.Assert(targetSlot.Signature.Equals(t.Slot.Signature));

                            return(targetSlot.OverridedBy(method.Value));
                        });
                    }
                    else
                    {
                        var targetSlot = vTbl.AllSlots.Single(slot => slot.MethodDef == targetMethod);
                        CheckKeyExist(storage, vTbl.SlotsMap, targetSlot.Signature, "MethodImpl Normal Sig");
                        targetSlot = vTbl.SlotsMap[targetSlot.Signature];                         // Use the most derived slot
                        // Maybe implemented by above processes --- this process should take priority
                        while (targetSlot.MethodDef.DeclaringType == typeDef)
                        {
                            targetSlot = targetSlot.Overrides;
                        }
                        vTbl.SlotsMap[targetSlot.Signature] = targetSlot.OverridedBy(method.Value);
                    }
                }
            }

            // Populate result V-table
            ret.InterfaceSlots = vTbl.InterfaceSlots.ToDictionary(
                kvp => kvp.Key, kvp => (IList <VTableSlot>)kvp.Value.SelectMany(g => g).ToList(), TypeEqualityComparer.Instance);

            foreach (var slot in vTbl.AllSlots)
            {
                ret.Slots.Add(slot);
            }

            return(ret);
        }