示例#1
0
        private void QueryCallVirtImpl(
            TypeMethodPair entryPair,
            out TypeMethodPair implPair)
        {
            for (; ;)
            {
                // 尝试重定向入口到新建槽方法
                if (NewSlotEntryMap.TryGetValue(entryPair.Item2, out var newSlotPair))
                {
                    entryPair = newSlotPair;
                }

                QueryEntryMap(entryPair, out implPair);

                if (NewSlotEntryMap.TryGetValue(implPair.Item2, out newSlotPair) &&
                    !entryPair.Equals(newSlotPair))
                {
                    entryPair = newSlotPair;
                    continue;
                }

                if (SameTypeReplaceMap.TryGetValue(implPair.Item2, out var repPair))
                {
                    entryPair = repPair;
                }
                else
                {
                    break;
                }
            }
        }
示例#2
0
        private void QueryEntryMap(
            TypeMethodPair entryPair,
            out TypeMethodPair implPair)
        {
            // 查询直接绑定
            if (EntryMap.TryGetValue(entryPair, out var impl))
            {
                implPair = impl.MethodPair;
                return;
            }

            // 遍历查询协逆变绑定
            TypeX entryTyX = entryPair.Item1;

            if (entryTyX.HasVariances)
            {
                MethodDef entryMetDef = entryPair.Item2;

                TypeMethodPair lastImpl  = null;
                uint           lastLevel = 0;

                foreach (var kv in EntryMap)
                {
                    TypeX     keyTyX    = kv.Key.Item1;
                    MethodDef keyMetDef = kv.Key.Item2;

                    if (keyMetDef == entryMetDef &&
                        keyTyX.HasVariances &&
                        entryTyX.IsDerivedType(keyTyX))
                    {
                        TypeMethodPair currImpl  = kv.Value.MethodPair;
                        uint           currLevel = kv.Value.Level;

                        if (lastImpl == null || lastLevel < currLevel)
                        {
                            lastImpl  = currImpl;
                            lastLevel = currLevel;
                        }
                    }
                }

                if (lastImpl != null)
                {
                    implPair = lastImpl;
                    return;
                }
            }

            throw new TypeLoadException(
                      string.Format("Virtual method can't resolve in type {0}: {1} -> {2}",
                                    Name,
                                    entryPair.Item1,
                                    entryPair.Item2.FullName));
        }
示例#3
0
        public void QueryCallVirt(
            TypeX entryTyX,
            MethodDef entryDef,
            out TypeX implTyX,
            out MethodDef implDef)
        {
            var entryPair = new TypeMethodPair(entryTyX, entryDef);

            if (!CachedMap.TryGetValue(entryPair, out var implPair))
            {
                QueryCallVirtImpl(entryPair, out implPair);
                CachedMap[entryPair] = implPair;
            }
            implTyX = implPair.Item1;
            implDef = implPair.Item2;
        }
示例#4
0
 public TypeMethodImpl(TableMethodImpl tbImpl)
 {
     MethodPair = new TypeMethodPair(tbImpl.MethodPair.Item1.GetTypeX(), tbImpl.MethodPair.Item2);
     Level      = tbImpl.Level;
 }
示例#5
0
        private void QueryEntryMap(
            TypeManager typeMgr,
            TypeMethodPair entryPair,
            out TypeMethodPair implPair)
        {
            // 查询直接绑定
            if (EntryMap.TryGetValue(entryPair, out var impl))
            {
                implPair = impl.MethodPair;
                return;
            }

            // 遍历查询协逆变绑定
            TypeX entryTyX = entryPair.Item1;

            if (entryTyX.HasVariances)
            {
                MethodDef entryMetDef = entryPair.Item2;

                TypeMethodPair lastImpl  = null;
                uint           lastLevel = 0;

                foreach (var kv in EntryMap)
                {
                    TypeX     keyTyX    = kv.Key.Item1;
                    MethodDef keyMetDef = kv.Key.Item2;

                    if (keyMetDef == entryMetDef &&
                        keyTyX.HasVariances &&
                        entryTyX.IsDerivedType(keyTyX))
                    {
                        TypeMethodPair currImpl  = kv.Value.MethodPair;
                        uint           currLevel = kv.Value.Level;

                        if (lastImpl == null || lastLevel < currLevel)
                        {
                            lastImpl  = currImpl;
                            lastLevel = currLevel;
                        }
                    }
                }

                if (lastImpl != null)
                {
                    implPair = lastImpl;
                    return;
                }
            }

            // IList<T> 和 T[] 的赋值
            if (IsSZArray)
            {
                string fullName = entryTyX.Def.FullName;
                Debug.Assert(
                    fullName == "System.Collections.Generic.IList`1" ||
                    fullName == "System.Collections.Generic.ICollection`1");

                MethodDef entryMetDef = entryPair.Item2;

                TypeMethodPair lastImpl  = null;
                uint           lastLevel = 0;

                foreach (var kv in EntryMap)
                {
                    TypeX     keyTyX    = kv.Key.Item1;
                    MethodDef keyMetDef = kv.Key.Item2;

                    if (keyMetDef == entryMetDef)
                    {
                        Debug.Assert(entryTyX.GenArgs.Count == keyTyX.GenArgs.Count);
                        var baseSig    = entryTyX.GenArgs[0];
                        var derivedSig = keyTyX.GenArgs[0];

                        if (typeMgr.IsDerivedType(baseSig, derivedSig))
                        {
                            TypeMethodPair currImpl  = kv.Value.MethodPair;
                            uint           currLevel = kv.Value.Level;

                            if (lastImpl == null || lastLevel < currLevel)
                            {
                                lastImpl  = currImpl;
                                lastLevel = currLevel;
                            }
                        }
                    }
                }

                if (lastImpl != null)
                {
                    implPair = lastImpl;
                    return;
                }
            }

            throw new TypeLoadException(
                      string.Format("Virtual method can't resolve in type {0}: {1} -> {2}",
                                    Name,
                                    entryPair.Item1,
                                    entryPair.Item2.FullName));
        }