public void AddEHClause(string opcode) { lastLabelValue++; IlIns il = new IlIns(); il.Opcode = opcode; il.LabelValue = lastLabelValue; ilLines.Add(lastLabelValue, il); IlOpcode op = IlOpcodes.GetEH(opcode); switch (op) { case IlOpcode.TRY: { curEHBlock = curEHNode.AddNewBlock(); curEHNode = curEHBlock.TryNode; curEHNode.ScopeStart = lastLabelValue; } break; case IlOpcode.FINALLY: { curEHNode = curEHBlock.AddNewFinally(); curEHNode.ScopeStart = lastLabelValue; } break; case IlOpcode.FAULT: { curEHNode = curEHBlock.AddNewFault(); curEHNode.ScopeStart = lastLabelValue; } break; case IlOpcode.FILTER: { curEHNode = curEHBlock.AddNewFilter(); curEHNode.ScopeStart = lastLabelValue; } break; case IlOpcode.ENDTRY: case IlOpcode.ENDCATCH: case IlOpcode.ENDFINALLY: case IlOpcode.ENDFAULT: case IlOpcode.ENDFILTER: { curEHNode.ScopeEnd = lastLabelValue; curEHBlock = curEHNode.EncloseBlock; curEHNode = curEHBlock.EncloseNode; } break; } }
private void IlToCsharps() { foreach (long lv in switches) { FlowGraphNode n = flowGraph.Find(lv); if (n != null) { switchBlocks[n.LabelValue] = n; } } flowGraph.Reset(); for (; flowGraph.CurNode != null; flowGraph.Next()) { FlowGraphNode node = flowGraph.CurNode; int i = ilLines.Keys.IndexOf(node.LabelValue); for (; i < ilLines.Values.Count; i++) { IlIns il = ilLines.Values[i]; if (il.LabelValue == node.LabelValue) { BeginGraphNode(node); } else if (il.LabelValue != node.LabelValue && flowGraph.IsNode(il.LabelValue)) { EndGraphNode(node, true); break; } IlOpcode op0 = IlOpcodes.GetEH(il.Opcode); if (op0 != IlOpcode.Prefixref) { EvaluateEH(op0, il, true); } else { OpCode op = IlOpcodes.Get(il.Opcode); int type = EvaluateIl(op, il, true); } } } }
private void AdjustFlowGraph() { flowGraph.Reset(); for (; flowGraph.CurNode != null; flowGraph.Next()) { FlowGraphNode node = flowGraph.CurNode; int i = ilLines.Keys.IndexOf(node.LabelValue); for (; i < ilLines.Values.Count; i++) { IlIns il = ilLines.Values[i]; if (il.LabelValue == node.LabelValue) { BeginGraphNode(node); } else if (il.LabelValue != node.LabelValue && flowGraph.IsNode(il.LabelValue)) { //行进到块的开始语句才发现新开始块是异常构造块或跳转目标倒致的块 EndGraphNode(node, false); break; } IlOpcode op0 = IlOpcodes.GetEH(il.Opcode); if (op0 != IlOpcode.Prefixref) { EvaluateEH(op0, il, false); } else { OpCode op = IlOpcodes.Get(il.Opcode); int type = EvaluateIl(op, il, false); switch (type) { case -2: //永不成立的条件跳转,当前结点与分支目标块断开 { long target = IlIns.LabelToValue(il.Value); if (flowGraph.IsNode(target)) { FlowGraphNode n = flowGraph[target]; node.DelNext(n); } EndGraphNode(node, false); } break; case -1: //永成立的条件跳转,当前结点与下一条指令开始的块断开 { if (i + 1 < ilLines.Values.Count) { if (flowGraph.IsNode(ilLines.Values[i + 1].LabelValue)) { FlowGraphNode n = flowGraph[ilLines.Values[i + 1].LabelValue]; node.DelNext(n); } } EndGraphNode(node, false); } break; case 0: //正常指令流 { } break; case 1: //无条件跳转 case 2: //条件跳转 case 3: //switch分支 { EndGraphNode(node, false); } break; case 4: //结束类语句 { EndGraphNode(node, false); } break; } if (type != 0) { break; } } } } //合并无分支的顺序块 flowGraph.Reset(); for (; flowGraph.CurNode != null; flowGraph.Next()) { FlowGraphNode node = flowGraph.CurNode; while (node.NextNodes.Count == 1 && node.NextNodes[0].PrevNodes.Count == 1) { FlowGraphNode n = node.NextNodes[0]; int i = ilLines.Keys.IndexOf(node.EndLabelValue); int j = ilLines.Keys.IndexOf(n.LabelValue); if (i + 1 == j) { flowGraph.Combine(node, n); } else { break; } } } }
private void BuildFlowGraph() { flowGraph = new FlowGraph(); FlowGraphNode curNode = null; FlowGraphNode prevNode = null; bool nextIsBlock = true; for (int i = 0; i < ilLines.Count; i++) { IlIns il = ilLines.Values[i]; if (nextIsBlock) { nextIsBlock = false; FlowGraphNode node = flowGraph.NewNode(il.LabelValue); curNode = node; if (prevNode != null) { prevNode.AddNext(node); } } else { if (flowGraph.IsNode(il.LabelValue)) { FlowGraphNode node = flowGraph[il.LabelValue]; curNode.EndLabelValue = GetPrevIlLabelValue(il.LabelValue); curNode.AddNext(node); curNode = node; } } IlOpcode op0 = IlOpcodes.GetEH(il.Opcode); if (op0 != IlOpcode.Prefixref) { switch (op0) { case IlOpcode.TRY: { FlowGraphNode node = flowGraph.NewNode(il.LabelValue); if (curNode != null) { curNode.AddNext(node); } curNode = node; } break; case IlOpcode.CATCH: { FlowGraphNode node = flowGraph.NewNode(il.LabelValue); curNode = node; } break; case IlOpcode.FINALLY: { FlowGraphNode node = flowGraph.NewNode(il.LabelValue); curNode = node; } break; case IlOpcode.FILTER: { FlowGraphNode node = flowGraph.NewNode(il.LabelValue); curNode = node; } break; case IlOpcode.FAULT: { FlowGraphNode node = flowGraph.NewNode(il.LabelValue); curNode = node; } break; case IlOpcode.ENDTRY: case IlOpcode.ENDCATCH: case IlOpcode.ENDFINALLY: case IlOpcode.ENDFILTER: case IlOpcode.ENDFAULT: { curNode.EndLabelValue = il.LabelValue; prevNode = null; nextIsBlock = true; } break; } } else { OpCode op = IlOpcodes.Get(il.Opcode); switch ((IlOpcode)op.Value) { case IlOpcode.Br: case IlOpcode.Br_S: { long val = IlIns.LabelToValue(il.Value); FlowGraphNode node = null; if (val > il.LabelValue) { node = flowGraph.NewNode(val); curNode.AddNext(node); } else { long prevVal = GetPrevIlLabelValue(val); FlowGraphNode d = flowGraph.Find(val); node = flowGraph.Split(val, prevVal); if (curNode != d) { curNode.AddNext(node); } else { node.AddNext(node); curNode = node; } } curNode.EndLabelValue = il.LabelValue; prevNode = null; nextIsBlock = true; } break; case IlOpcode.Brtrue: case IlOpcode.Brfalse: case IlOpcode.Brtrue_S: case IlOpcode.Brfalse_S: case IlOpcode.Beq_S: case IlOpcode.Bge_S: case IlOpcode.Bgt_S: case IlOpcode.Ble_S: case IlOpcode.Blt_S: case IlOpcode.Bne_Un_S: case IlOpcode.Bge_Un_S: case IlOpcode.Bgt_Un_S: case IlOpcode.Ble_Un_S: case IlOpcode.Blt_Un_S: case IlOpcode.Beq: case IlOpcode.Bge: case IlOpcode.Bgt: case IlOpcode.Ble: case IlOpcode.Blt: case IlOpcode.Bne_Un: case IlOpcode.Bge_Un: case IlOpcode.Bgt_Un: case IlOpcode.Ble_Un: case IlOpcode.Blt_Un: { long val = IlIns.LabelToValue(il.Value); FlowGraphNode node = null; if (val > il.LabelValue) { node = flowGraph.NewNode(val); curNode.AddNext(node); } else { long prevVal = GetPrevIlLabelValue(val); FlowGraphNode d = flowGraph.Find(val); node = flowGraph.Split(val, prevVal); if (curNode != d) { curNode.AddNext(node); } else { node.AddNext(node); curNode = node; } } curNode.EndLabelValue = il.LabelValue; prevNode = curNode; nextIsBlock = true; } break; case IlOpcode.Switch: { SwitchOperand opVal = il.Operand as SwitchOperand; foreach (string label in opVal.Labels) { long val = IlIns.LabelToValue(label); FlowGraphNode node = null; if (val > il.LabelValue) { node = flowGraph.NewNode(val); curNode.AddNext(node); } else { long prevVal = GetPrevIlLabelValue(val); FlowGraphNode d = flowGraph.Find(val); node = flowGraph.Split(val, prevVal); if (curNode != d) { curNode.AddNext(node); } else { node.AddNext(node); curNode = node; } } } curNode.EndLabelValue = il.LabelValue; prevNode = curNode; nextIsBlock = true; } break; case IlOpcode.Ret: case IlOpcode.Break: case IlOpcode.Throw: case IlOpcode.Rethrow: case IlOpcode.Leave: case IlOpcode.Leave_S: case IlOpcode.Endfilter: case IlOpcode.Endfinally: { curNode.EndLabelValue = il.LabelValue; prevNode = null; nextIsBlock = true; } break; } } } }