コード例 #1
0
ファイル: MethodTable.cs プロジェクト: azureidea/il2cpp
        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);
        }