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)); }
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; }