예제 #1
0
 @Override
 public void visit(BinaryBranchingInstruction insn) {
   int a = insn.getFirstOperand().getIndex();
   int b = insn.getSecondOperand().getIndex();
   BasicBlock consequent = insn.getConsequent();
   BasicBlock alternative = insn.getAlternative();
   switch (insn.getCondition()) {
     case EQUAL:
       branch(
           withLocation(Expr.binary(BinaryOperation.EQUALS, Expr.var(a), Expr.var(b))),
           consequent,
           alternative);
       break;
     case REFERENCE_EQUAL:
       branch(
           withLocation(Expr.binary(BinaryOperation.STRICT_EQUALS, Expr.var(a), Expr.var(b))),
           consequent,
           alternative);
       break;
     case NOT_EQUAL:
       branch(
           withLocation(Expr.binary(BinaryOperation.NOT_EQUALS, Expr.var(a), Expr.var(b))),
           consequent,
           alternative);
       break;
     case REFERENCE_NOT_EQUAL:
       branch(
           withLocation(Expr.binary(BinaryOperation.STRICT_NOT_EQUALS, Expr.var(a), Expr.var(b))),
           consequent,
           alternative);
       break;
   }
 }
예제 #2
0
 @Override
 public void visit(BranchingInstruction insn) {
   switch (insn.getCondition()) {
     case EQUAL:
       branch(
           compare(BinaryOperation.EQUALS, insn.getOperand()),
           insn.getConsequent(),
           insn.getAlternative());
       break;
     case NOT_EQUAL:
       branch(
           compare(BinaryOperation.NOT_EQUALS, insn.getOperand()),
           insn.getConsequent(),
           insn.getAlternative());
       break;
     case GREATER:
       branch(
           compare(BinaryOperation.GREATER, insn.getOperand()),
           insn.getConsequent(),
           insn.getAlternative());
       break;
     case GREATER_OR_EQUAL:
       branch(
           compare(BinaryOperation.GREATER_OR_EQUALS, insn.getOperand()),
           insn.getConsequent(),
           insn.getAlternative());
       break;
     case LESS:
       branch(
           compare(BinaryOperation.LESS, insn.getOperand()),
           insn.getConsequent(),
           insn.getAlternative());
       break;
     case LESS_OR_EQUAL:
       branch(
           compare(BinaryOperation.LESS_OR_EQUALS, insn.getOperand()),
           insn.getConsequent(),
           insn.getAlternative());
       break;
     case NOT_NULL:
       branch(
           Expr.binary(
               BinaryOperation.STRICT_NOT_EQUALS,
               Expr.var(insn.getOperand().getIndex()),
               Expr.constant(null)),
           insn.getConsequent(),
           insn.getAlternative());
       break;
     case NULL:
       branch(
           Expr.binary(
               BinaryOperation.STRICT_EQUALS,
               Expr.var(insn.getOperand().getIndex()),
               Expr.constant(null)),
           insn.getConsequent(),
           insn.getAlternative());
       break;
   }
 }
예제 #3
0
 @Override
 public void visit(WhileStatement statement) {
   if (statement.getBody().size() == 1 && statement.getBody().get(0) instanceof WhileStatement) {
     WhileStatement innerLoop = (WhileStatement) statement.getBody().get(0);
     BreakToContinueReplacer replacer = new BreakToContinueReplacer(innerLoop, statement);
     replacer.visitSequence(innerLoop.getBody());
     statement.getBody().clear();
     statement.getBody().addAll(innerLoop.getBody());
   }
   List<Statement> statements = processSequence(statement.getBody());
   for (int i = 0; i < statements.size(); ++i) {
     if (statements.get(i) instanceof ContinueStatement) {
       ContinueStatement continueStmt = (ContinueStatement) statements.get(i);
       if (continueStmt.getTarget() == statement) {
         statements.subList(i, statements.size()).clear();
         break;
       }
     }
   }
   statement.getBody().clear();
   statement.getBody().addAll(statements);
   if (statement.getCondition() != null) {
     List<Statement> sequenceBackup = resultSequence;
     resultSequence = new ArrayList<>();
     statement.getCondition().acceptVisitor(this);
     statement.setCondition(resultExpr);
     resultSequence = sequenceBackup;
   }
   while (true) {
     if (!statement.getBody().isEmpty()
         && statement.getBody().get(0) instanceof ConditionalStatement) {
       ConditionalStatement cond = (ConditionalStatement) statement.getBody().get(0);
       if (cond.getConsequent().size() == 1
           && cond.getConsequent().get(0) instanceof BreakStatement) {
         BreakStatement breakStmt = (BreakStatement) cond.getConsequent().get(0);
         if (breakStmt.getTarget() == statement) {
           statement.getBody().remove(0);
           if (statement.getCondition() != null) {
             Expr newCondition =
                 Expr.binary(
                     BinaryOperation.AND,
                     statement.getCondition(),
                     ExprOptimizer.invert(cond.getCondition()));
             newCondition.setLocation(statement.getCondition().getLocation());
             statement.setCondition(newCondition);
           } else {
             statement.setCondition(ExprOptimizer.invert(cond.getCondition()));
           }
           continue;
         }
       }
     }
     break;
   }
   resultStmt = statement;
 }
예제 #4
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);
     }
   }
 }
예제 #5
0
 private Expr compare(BinaryOperation op, Variable value) {
   Expr expr = Expr.binary(op, Expr.var(value.getIndex()), Expr.constant(0));
   expr.setLocation(currentLocation);
   return expr;
 }
예제 #6
0
 private void intBinary(int first, int second, Variable result, BinaryOperation op) {
   assign(castToInteger(Expr.binary(op, Expr.var(first), Expr.var(second))), result);
 }
예제 #7
0
 private Expr castToInteger(Expr value) {
   return Expr.binary(BinaryOperation.BITWISE_OR, value, Expr.constant(0));
 }