예제 #1
0
 @Override
 public void visit(SwitchStatement statement) {
   statement.getValue().acceptVisitor(this);
   statement.setValue(resultExpr);
   for (SwitchClause clause : statement.getClauses()) {
     List<Statement> newBody = processSequence(clause.getBody());
     clause.getBody().clear();
     clause.getBody().addAll(newBody);
   }
   List<Statement> newDefault = processSequence(statement.getDefaultClause());
   statement.getDefaultClause().clear();
   statement.getDefaultClause().addAll(newDefault);
   resultStmt = statement;
 }
예제 #2
0
 @Override
 public void visit(SwitchInstruction insn) {
   SwitchStatement stmt = new SwitchStatement();
   stmt.setId("sblock" + (lastSwitchId++));
   stmt.setValue(Expr.var(insn.getCondition().getIndex()));
   Map<Integer, List<Integer>> switchMap = new HashMap<>();
   for (int i = 0; i < insn.getEntries().size(); ++i) {
     SwitchTableEntry entry = insn.getEntries().get(i);
     List<Integer> conditions = switchMap.get(entry.getTarget().getIndex());
     if (conditions == null) {
       conditions = new ArrayList<>();
       switchMap.put(entry.getTarget().getIndex(), conditions);
     }
     conditions.add(entry.getCondition());
   }
   List<Integer> targets = new ArrayList<>(switchMap.keySet());
   Collections.sort(targets);
   for (int target : targets) {
     SwitchClause clause = new SwitchClause();
     List<Integer> conditionList = switchMap.get(target);
     int[] conditions = new int[conditionList.size()];
     for (int i = 0; i < conditionList.size(); ++i) {
       conditions[i] = conditionList.get(i);
     }
     clause.setConditions(conditions);
     Statement jumpStmt = generateJumpStatement(stmt, target);
     if (jumpStmt != null) {
       clause.getBody().add(jumpStmt);
     }
     stmt.getClauses().add(clause);
   }
   Statement breakStmt = generateJumpStatement(insn.getDefaultTarget());
   if (breakStmt != null) {
     stmt.getDefaultClause().add(breakStmt);
   }
   statements.add(stmt);
 }
예제 #3
0
 private void eliminateRedundantBreaks(List<Statement> statements, IdentifiedStatement exit) {
   if (statements.isEmpty()) {
     return;
   }
   Statement last = statements.get(statements.size() - 1);
   if (last instanceof BreakStatement && exit != null) {
     IdentifiedStatement target = ((BreakStatement) last).getTarget();
     if (exit == target) {
       statements.remove(statements.size() - 1);
     }
   }
   if (statements.isEmpty()) {
     return;
   }
   for (int i = 0; i < statements.size(); ++i) {
     Statement stmt = statements.get(i);
     if (stmt instanceof ConditionalStatement) {
       ConditionalStatement cond = (ConditionalStatement) stmt;
       check_conditional:
       {
         last =
             cond.getConsequent().isEmpty()
                 ? null
                 : cond.getConsequent().get(cond.getConsequent().size() - 1);
         if (last instanceof BreakStatement) {
           BreakStatement breakStmt = (BreakStatement) last;
           if (exit != null && exit == breakStmt.getTarget()) {
             cond.getConsequent().remove(cond.getConsequent().size() - 1);
             List<Statement> remaining = statements.subList(i + 1, statements.size());
             cond.getAlternative().addAll(remaining);
             remaining.clear();
             break check_conditional;
           }
         }
         last =
             cond.getAlternative().isEmpty()
                 ? null
                 : cond.getAlternative().get(cond.getAlternative().size() - 1);
         if (last instanceof BreakStatement) {
           BreakStatement breakStmt = (BreakStatement) last;
           if (exit != null && exit == breakStmt.getTarget()) {
             cond.getAlternative().remove(cond.getAlternative().size() - 1);
             List<Statement> remaining = statements.subList(i + 1, statements.size());
             cond.getConsequent().addAll(remaining);
             remaining.clear();
           }
         }
       }
       if (i == statements.size() - 1) {
         eliminateRedundantBreaks(cond.getConsequent(), exit);
         eliminateRedundantBreaks(cond.getAlternative(), exit);
       }
       normalizeConditional(cond);
       if (cond.getConsequent().size() == 1
           && cond.getConsequent().get(0) instanceof ConditionalStatement) {
         ConditionalStatement innerCond = (ConditionalStatement) cond.getConsequent().get(0);
         if (innerCond.getAlternative().isEmpty()) {
           if (cond.getAlternative().isEmpty()) {
             cond.getConsequent().clear();
             cond.getConsequent().addAll(innerCond.getConsequent());
             cond.setCondition(
                 Expr.binary(
                     BinaryOperation.AND,
                     cond.getCondition(),
                     innerCond.getCondition(),
                     cond.getCondition().getLocation()));
             --i;
           } else if (cond.getAlternative().size() != 1
               || !(cond.getAlternative().get(0) instanceof ConditionalStatement)) {
             cond.setCondition(ExprOptimizer.invert(cond.getCondition()));
             cond.getConsequent().clear();
             cond.getConsequent().addAll(cond.getAlternative());
             cond.getAlternative().clear();
             cond.getAlternative().add(innerCond);
             --i;
           }
         }
       }
     } else if (stmt instanceof BlockStatement) {
       BlockStatement nestedBlock = (BlockStatement) stmt;
       eliminateRedundantBreaks(nestedBlock.getBody(), nestedBlock);
     } else if (stmt instanceof WhileStatement) {
       WhileStatement whileStmt = (WhileStatement) stmt;
       eliminateRedundantBreaks(whileStmt.getBody(), null);
     } else if (stmt instanceof SwitchStatement) {
       SwitchStatement switchStmt = (SwitchStatement) stmt;
       for (SwitchClause clause : switchStmt.getClauses()) {
         eliminateRedundantBreaks(clause.getBody(), null);
       }
       eliminateRedundantBreaks(switchStmt.getDefaultClause(), null);
     }
   }
 }