1 19 20 package jode.flow; 21 import java.util.Vector ; 22 import jode.expr.*; 23 import jode.type.Type; 24 25 public class CombineIfGotoExpressions { 26 27 public static boolean transform(ConditionalBlock cb, 28 StructuredBlock last) { 29 if (cb.jump == null 30 || !(last.outer instanceof SequentialBlock)) 31 return false; 32 33 SequentialBlock sequBlock = (SequentialBlock) cb.outer; 34 Expression firstCond, secondCond; 35 36 secondCond = cb.getInstruction(); 37 Expression lastCombined = secondCond; 38 39 while (sequBlock.subBlocks[0] instanceof InstructionBlock) { 40 InstructionBlock ib = 41 (InstructionBlock) sequBlock.subBlocks[0]; 42 43 if (!(sequBlock.outer instanceof SequentialBlock)) 44 return false; 45 46 Expression expr = ib.getInstruction(); 47 if (!(expr instanceof CombineableOperator) 48 || (lastCombined.canCombine((CombineableOperator)expr) 49 + secondCond.canCombine((CombineableOperator)expr) <= 0)) 50 52 return false; 53 54 lastCombined = expr; 55 56 sequBlock = (SequentialBlock) sequBlock.outer; 57 } 58 59 if (sequBlock.subBlocks[0] instanceof ConditionalBlock) { 60 61 ConditionalBlock cbprev = 62 (ConditionalBlock) sequBlock.subBlocks[0]; 63 64 Jump prevJump = cbprev.trueBlock.jump; 65 66 int operator; 67 if (prevJump.destination == cb.jump.destination) { 68 operator = BinaryOperator.LOG_AND_OP; 69 firstCond = cbprev.getInstruction().negate(); 70 } else if (prevJump.destination == cb.trueBlock.jump.destination) { 71 operator = BinaryOperator.LOG_OR_OP; 72 firstCond = cbprev.getInstruction(); 73 } else 74 return false; 75 76 79 80 sequBlock = (SequentialBlock) cb.outer; 81 while (sequBlock.subBlocks[0] instanceof InstructionBlock) { 82 84 InstructionBlock ib = 85 (InstructionBlock) sequBlock.subBlocks[0]; 86 87 Expression expr = ib.getInstruction(); 88 89 secondCond = secondCond.combine((CombineableOperator) expr); 90 sequBlock = (SequentialBlock) sequBlock.outer; 91 } 92 93 cb.flowBlock.removeSuccessor(prevJump); 94 prevJump.prev.removeJump(); 95 Expression cond = new BinaryOperator(Type.tBoolean, operator) 96 .addOperand(secondCond).addOperand(firstCond); 97 cb.setInstruction(cond); 98 cb.moveDefinitions(sequBlock, last); 99 last.replace(sequBlock); 100 return true; 101 } 102 return false; 103 } 104 } 105 | Popular Tags |