static private ConditionStatementBlock Detect(Instruction first, Instruction last) { Instruction current = null; for (var instruction = first; instruction != last.Next && instruction != null; instruction = instruction.Next) { if (ConditionalBranch_OpCodes.Contains(instruction.OpCode) && (instruction.Operand as Instruction).Offset > instruction.Offset) { current = instruction; break; } } if (current == null) { return(null); } Instruction next = current.Operand as Instruction; var lastOffset = last.Offset; if (lastOffset < current.Offset || lastOffset < current.Next.Offset || lastOffset < next.Previous.Offset) { return(null); } return(new ConditionStatementBlock( new CodeBlock(first, current), new CodeBlock(current.Next, next.Previous) )); }
static public bool Detect(CodeBlock block, out StatementStructure statementStructure) { List <OpCode> brs = new List <OpCode> { OpCodes.Br_S, OpCodes.Br }; statementStructure = null; if (!ConditionalBranch_OpCodes.Contains(block.first.OpCode)) { return(false); } var conditionStatementBlock = Detect(block.first, block.last); if (conditionStatementBlock == null) { return(false); } List <ConditionStatementBlock> blocks = new List <ConditionStatementBlock>(); blocks.Add(conditionStatementBlock); while (true) { var next = conditionStatementBlock.body.last.Next; if (!brs.Contains(next.Previous.OpCode)) { break; } var br = next.Previous as Instruction; var target = br.Operand as Instruction; if (target.OpCode == OpCodes.Ret) { break; } conditionStatementBlock = Detect(next, target.Previous); if (conditionStatementBlock == null) { conditionStatementBlock = new ConditionStatementBlock(null, new CodeBlock(next, target.Previous)); blocks.Add(conditionStatementBlock); break; } var current = blocks[blocks.Count - 1]; blocks[blocks.Count - 1] = new ConditionStatementBlock( current.condition, new CodeBlock(current.body.first, current.body.last.Previous) ); blocks.Add(conditionStatementBlock); } CodeBlock all = new CodeBlock(block.first, blocks[blocks.Count - 1].body.last); statementStructure = new ConditionStatementStructure(all, blocks); return(true); }
static public bool Detect(CodeBlock block, out StatementStructure statementStructure) { statementStructure = null; var opCode = block.first.OpCode; if (opCode != OpCodes.Br && opCode != OpCodes.Br_S) { return(false); } // maybe loop condition var target = block.first.Operand as Instruction; // find next branch instruction (Brtrue, Brtrue_S), which may be a loop tag and an end Instruction last = null; { var tmp = target; while (tmp != null && !ConditionalBranch_OpCodes.Contains(tmp.OpCode)) { tmp = tmp.Next; } if (tmp == null) { return(false); } last = tmp; } // loop body if ((last.Operand as Instruction).Previous != block.first) { return(false); } CodeBlock all = new CodeBlock(block.first, last); CodeBlock init = null; CodeBlock condition = new CodeBlock(target, last); CodeBlock step = null; CodeBlock body = new CodeBlock(block.first.Next, target.Previous); statementStructure = new LoopStatementStructure(all, init, condition, step, body); return(true); }