Example #1
0
 public bool NeedCombine(ExHandlerInfo other)
 {
     return(TryStart == other.TryStart &&
            TryEnd == other.TryEnd &&
            (HandlerType == ExceptionHandlerType.Catch || HandlerType == ExceptionHandlerType.Filter) &&
            (other.HandlerType == ExceptionHandlerType.Catch || other.HandlerType == ExceptionHandlerType.Filter));
 }
Example #2
0
        private void BuildInstructions(MethodX metX)
        {
            Debug.Assert(metX.InstList == null);

            if (!metX.Def.HasBody || !metX.Def.Body.HasInstructions)
            {
                return;
            }

            IGenericReplacer replacer = new GenericReplacer(metX.DeclType, metX);

            var defInstList = metX.Def.Body.Instructions;
            int numInsts    = defInstList.Count;

            InstInfo[] instList = new InstInfo[numInsts];

            Dictionary <uint, int> offsetMap   = new Dictionary <uint, int>();
            List <InstInfo>        branchInsts = new List <InstInfo>();

            // 构建指令列表
            for (int ip = 0; ip < numInsts; ++ip)
            {
                var defInst = defInstList[ip];
                var inst    = instList[ip] = new InstInfo();
                inst.OpCode  = defInst.OpCode;
                inst.Operand = defInst.Operand;
                inst.Offset  = ip;

                offsetMap.Add(defInst.Offset, ip);
                switch (inst.OpCode.OperandType)
                {
                case OperandType.InlineBrTarget:
                case OperandType.ShortInlineBrTarget:
                case OperandType.InlineSwitch:
                    branchInsts.Add(inst);
                    break;

                default:
                    ResolveOperand(inst, replacer);
                    break;
                }
            }

            // 重定向跳转位置
            foreach (var inst in branchInsts)
            {
                if (inst.Operand is Instruction defInst)
                {
                    int target;
                    inst.Operand = target = offsetMap[defInst.Offset];
                    instList[target].IsBrTarget = true;
                }
                else if (inst.Operand is Instruction[] defInsts)
                {
                    int[] insts = new int[defInsts.Length];
                    for (int i = 0; i < defInsts.Length; ++i)
                    {
                        int target;
                        insts[i] = target = offsetMap[defInsts[i].Offset];
                        instList[target].IsBrTarget = true;
                    }
                    inst.Operand = insts;
                }
            }

            // 展开异常处理信息
            if (metX.Def.Body.HasExceptionHandlers)
            {
                List <Tuple <int, ExHandlerInfo> > sortedHandlers = new List <Tuple <int, ExHandlerInfo> >();
                int idx = 0;
                foreach (var eh in metX.Def.Body.ExceptionHandlers)
                {
                    ExHandlerInfo info = new ExHandlerInfo();
                    info.TryStart = offsetMap[eh.TryStart.Offset];
                    info.TryEnd   = offsetMap[eh.TryEnd.Offset];

                    if (eh.FilterStart != null)
                    {
                        info.FilterStart = offsetMap[eh.FilterStart.Offset];
                    }
                    else
                    {
                        info.FilterStart = -1;
                    }

                    info.HandlerStart = offsetMap[eh.HandlerStart.Offset];

                    if (eh.HandlerEnd != null)
                    {
                        info.HandlerEnd = offsetMap[eh.HandlerEnd.Offset];
                    }
                    else
                    {
                        info.HandlerEnd = instList.Length;
                    }

                    if (eh.CatchType != null)
                    {
                        info.CatchType = ResolveTypeDefOrRef(eh.CatchType, replacer);
                    }

                    info.HandlerType = eh.HandlerType;
                    sortedHandlers.Add(new Tuple <int, ExHandlerInfo>(idx++, info));
                }
                // 根据 try 位置排序, 如果相同则根据定义顺序排序
                sortedHandlers.Sort((lhs, rhs) =>
                {
                    int cmp = lhs.Item2.TryStart.CompareTo(rhs.Item2.TryStart);
                    if (cmp == 0)
                    {
                        cmp = rhs.Item2.TryEnd.CompareTo(lhs.Item2.TryEnd);
                        if (cmp == 0)
                        {
                            return(lhs.Item1.CompareTo(rhs.Item1));
                        }
                    }
                    return(cmp);
                });

                // 合并同范围的异常处理器
                List <ExHandlerInfo> handlers = new List <ExHandlerInfo>();

                ExHandlerInfo headInfo = null;
                int           count    = sortedHandlers.Count;
                for (int i = 0; i < count; ++i)
                {
                    ExHandlerInfo currInfo = sortedHandlers[i].Item2;
                    if (headInfo != null && headInfo.NeedCombine(currInfo))
                    {
                        headInfo.CombinedHandlers.Add(currInfo);
                    }
                    else
                    {
                        headInfo = currInfo;
                        Debug.Assert(headInfo.CombinedHandlers.Count == 0);
                        headInfo.CombinedHandlers.Add(headInfo);
                        handlers.Add(headInfo);
                    }

                    instList[currInfo.HandlerOrFilterStart].IsBrTarget = true;
                }

                metX.ExHandlerList = handlers;
            }

            metX.InstList = instList;
        }