Example #1
0
 @Override
 public void visit(ConstructMultiArrayInstruction insn) {
   Expr[] dimensionExprs = new Expr[insn.getDimensions().size()];
   for (int i = 0; i < dimensionExprs.length; ++i) {
     dimensionExprs[i] = Expr.var(insn.getDimensions().get(i).getIndex());
   }
   assign(Expr.createArray(insn.getItemType(), dimensionExprs), insn.getReceiver());
 }
Example #2
0
 @Override
 public void visit(BinaryExpr expr) {
   switch (expr.getOperation()) {
     case AND:
     case OR:
       resultExpr = expr;
       return;
     default:
       break;
   }
   expr.getSecondOperand().acceptVisitor(this);
   Expr b = resultExpr;
   if (b instanceof ConstantExpr && expr.getOperation() == BinaryOperation.SUBTRACT) {
     if (tryMakePositive((ConstantExpr) b)) {
       expr.setOperation(BinaryOperation.ADD);
     }
   }
   expr.getFirstOperand().acceptVisitor(this);
   Expr a = resultExpr;
   Expr p = a;
   Expr q = b;
   boolean invert = false;
   if (isZero(p)) {
     Expr tmp = p;
     p = q;
     q = tmp;
     invert = true;
   }
   if (isComparison(p) && isZero(q)) {
     switch (expr.getOperation()) {
       case EQUALS:
       case NOT_EQUALS:
       case LESS:
       case LESS_OR_EQUALS:
       case GREATER:
       case GREATER_OR_EQUALS:
         {
           BinaryExpr comparison = (BinaryExpr) p;
           Expr result =
               BinaryExpr.binary(
                   expr.getOperation(),
                   comparison.getFirstOperand(),
                   comparison.getSecondOperand());
           result.setLocation(comparison.getLocation());
           if (invert) {
             result = ExprOptimizer.invert(result);
           }
           resultExpr = result;
           return;
         }
       default:
         break;
     }
   }
   expr.setFirstOperand(a);
   expr.setSecondOperand(b);
   resultExpr = expr;
 }
Example #3
0
 @Override
 public void visit(AssignInstruction insn) {
   AssignmentStatement stmt =
       Statement.assign(
           Expr.var(insn.getReceiver().getIndex()), Expr.var(insn.getAssignee().getIndex()));
   stmt.getDebugNames().addAll(insn.getReceiver().getDebugNames());
   stmt.setLocation(currentLocation);
   statements.add(stmt);
 }
Example #4
0
 @Override
 public void visit(NewMultiArrayExpr expr) {
   for (int i = 0; i < expr.getDimensions().size(); ++i) {
     Expr dimension = expr.getDimensions().get(i);
     dimension.acceptVisitor(this);
     expr.getDimensions().set(i, resultExpr);
   }
   resultExpr = expr;
 }
Example #5
0
 @Override
 public void visit(CloneArrayInstruction insn) {
   MethodDescriptor cloneMethodDesc =
       new MethodDescriptor("clone", ValueType.object("java.lang.Object"));
   MethodReference cloneMethod = new MethodReference("java.lang.Object", cloneMethodDesc);
   assign(
       Expr.invoke(cloneMethod, Expr.var(insn.getArray().getIndex()), new Expr[0]),
       insn.getReceiver());
 }
Example #6
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;
 }
Example #7
0
 @Override
 public void visit(PutElementInstruction insn) {
   AssignmentStatement stmt =
       Statement.assign(
           Expr.subscript(
               Expr.var(insn.getArray().getIndex()), Expr.var(insn.getIndex().getIndex())),
           Expr.var(insn.getValue().getIndex()));
   stmt.setLocation(currentLocation);
   statements.add(stmt);
 }
Example #8
0
 @Override
 public void visit(PutFieldInstruction insn) {
   Expr right = Expr.var(insn.getValue().getIndex());
   Expr left;
   if (insn.getInstance() != null) {
     left = Expr.qualify(Expr.var(insn.getInstance().getIndex()), insn.getField());
   } else {
     left = Expr.qualify(null, insn.getField());
   }
   AssignmentStatement stmt = Statement.assign(left, right);
   stmt.setLocation(currentLocation);
   statements.add(stmt);
 }
Example #9
0
 @Override
 public void visit(MonitorExitInstruction insn) {
   MonitorExitStatement stmt = new MonitorExitStatement();
   stmt.setLocation(currentLocation);
   stmt.setObjectRef(Expr.var(insn.getObjectRef().getIndex()));
   statements.add(stmt);
 }
Example #10
0
 @Override
 public void visit(RaiseInstruction insn) {
   ThrowStatement stmt = new ThrowStatement();
   stmt.setLocation(currentLocation);
   stmt.setException(Expr.var(insn.getException().getIndex()));
   statements.add(stmt);
 }
Example #11
0
 @Override
 public void visit(ExitInstruction insn) {
   ReturnStatement stmt =
       Statement.exitFunction(
           insn.getValueToReturn() != null ? Expr.var(insn.getValueToReturn().getIndex()) : null);
   stmt.setLocation(currentLocation);
   statements.add(stmt);
 }
Example #12
0
 @Override
 public void visit(GetFieldInstruction insn) {
   if (insn.getInstance() != null) {
     AssignmentStatement stmt =
         Statement.assign(
             Expr.var(insn.getReceiver().getIndex()),
             Expr.qualify(Expr.var(insn.getInstance().getIndex()), insn.getField()));
     stmt.setLocation(currentLocation);
     statements.add(stmt);
   } else {
     Expr fieldExpr = Expr.qualify(null, insn.getField());
     AssignmentStatement stmt =
         Statement.assign(Expr.var(insn.getReceiver().getIndex()), fieldExpr);
     stmt.setLocation(currentLocation);
     statements.add(stmt);
   }
 }
Example #13
0
 @Override
 public void visit(InvokeInstruction insn) {
   Expr[] exprArgs = new Expr[insn.getMethod().getParameterTypes().length];
   for (int i = 0; i < insn.getArguments().size(); ++i) {
     exprArgs[i] = Expr.var(insn.getArguments().get(i).getIndex());
   }
   InvocationExpr invocationExpr;
   if (insn.getInstance() != null) {
     if (insn.getType() == InvocationType.VIRTUAL) {
       invocationExpr =
           Expr.invoke(insn.getMethod(), Expr.var(insn.getInstance().getIndex()), exprArgs);
     } else {
       invocationExpr =
           Expr.invokeSpecial(insn.getMethod(), Expr.var(insn.getInstance().getIndex()), exprArgs);
     }
   } else {
     invocationExpr = Expr.invokeStatic(insn.getMethod(), exprArgs);
   }
   AssignmentStatement stmt;
   if (insn.getReceiver() != null) {
     stmt = Statement.assign(Expr.var(insn.getReceiver().getIndex()), invocationExpr);
     stmt.getDebugNames().addAll(insn.getReceiver().getDebugNames());
   } else {
     stmt = Statement.assign(null, invocationExpr);
   }
   stmt.setLocation(currentLocation);
   stmt.setAsync(async);
   async = false;
   statements.add(stmt);
 }
Example #14
0
 @Override
 public void visit(CastIntegerInstruction insn) {
   Expr value = Expr.var(insn.getValue().getIndex());
   switch (insn.getDirection()) {
     case FROM_INTEGER:
       switch (insn.getTargetType()) {
         case BYTE:
           value = Expr.unary(UnaryOperation.INT_TO_BYTE, value);
           break;
         case SHORT:
           value = Expr.unary(UnaryOperation.INT_TO_SHORT, value);
           break;
         case CHARACTER:
           value = Expr.unary(UnaryOperation.INT_TO_CHAR, value);
           break;
       }
       break;
     case TO_INTEGER:
       break;
   }
   assign(value, insn.getReceiver());
 }
Example #15
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;
   }
 }
Example #16
0
 @Override
 public void visit(CastNumberInstruction insn) {
   Expr value = Expr.var(insn.getValue().getIndex());
   switch (insn.getTargetType()) {
     case INT:
       switch (insn.getSourceType()) {
         case DOUBLE:
         case FLOAT:
           value = castToInteger(value);
           break;
         case LONG:
           value = castLongToInt(value);
           break;
         default:
           break;
       }
       break;
     case LONG:
       switch (insn.getSourceType()) {
         case INT:
           value = castIntToLong(value);
           break;
         case FLOAT:
         case DOUBLE:
           value = castToLong(value);
           break;
         default:
           break;
       }
       break;
     case FLOAT:
     case DOUBLE:
       if (insn.getSourceType() == NumericOperandType.LONG) {
         value = castFromLong(value);
       }
       break;
     default:
       break;
   }
   assign(value, insn.getReceiver());
 }
Example #17
0
 private boolean tryApplyConstructor(InvocationExpr expr) {
   if (!expr.getMethod().getName().equals("<init>")) {
     return false;
   }
   if (resultSequence == null || resultSequence.isEmpty()) {
     return false;
   }
   Statement last = resultSequence.get(resultSequence.size() - 1);
   if (!(last instanceof AssignmentStatement)) {
     return false;
   }
   AssignmentStatement assignment = (AssignmentStatement) last;
   if (!(assignment.getLeftValue() instanceof VariableExpr)) {
     return false;
   }
   VariableExpr var = (VariableExpr) assignment.getLeftValue();
   if (!(expr.getArguments().get(0) instanceof VariableExpr)) {
     return false;
   }
   VariableExpr target = (VariableExpr) expr.getArguments().get(0);
   if (target.getIndex() != var.getIndex()) {
     return false;
   }
   if (!(assignment.getRightValue() instanceof NewExpr)) {
     return false;
   }
   NewExpr constructed = (NewExpr) assignment.getRightValue();
   if (!constructed.getConstructedClass().equals(expr.getMethod().getClassName())) {
     return false;
   }
   Expr[] args = expr.getArguments().toArray(new Expr[0]);
   args = Arrays.copyOfRange(args, 1, args.length);
   InvocationExpr constructrExpr = Expr.constructObject(expr.getMethod(), args);
   constructrExpr.setLocation(expr.getLocation());
   assignment.setRightValue(constructrExpr);
   readFrequencies[var.getIndex()]--;
   return true;
 }
Example #18
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);
 }
Example #19
0
 @Override
 public void visit(NegateInstruction insn) {
   switch (insn.getOperandType()) {
     case INT:
       assign(
           castToInteger(
               Expr.unary(UnaryOperation.NEGATE, Expr.var(insn.getOperand().getIndex()))),
           insn.getReceiver());
       break;
     case LONG:
       assign(
           Expr.unary(UnaryOperation.NEGATE_LONG, Expr.var(insn.getOperand().getIndex())),
           insn.getReceiver());
       break;
     default:
       assign(
           Expr.unary(UnaryOperation.NEGATE, Expr.var(insn.getOperand().getIndex())),
           insn.getReceiver());
       break;
   }
 }
Example #20
0
 @Override
 public void visit(IsInstanceInstruction insn) {
   assign(
       Expr.instanceOf(Expr.var(insn.getValue().getIndex()), insn.getType()), insn.getReceiver());
 }
Example #21
0
 private void assign(Expr source, Variable target) {
   AssignmentStatement stmt = Statement.assign(Expr.var(target.getIndex()), source);
   stmt.setLocation(currentLocation);
   stmt.getDebugNames().addAll(target.getDebugNames());
   statements.add(stmt);
 }
Example #22
0
 private Expr castToInteger(Expr value) {
   return Expr.binary(BinaryOperation.BITWISE_OR, value, Expr.constant(0));
 }
Example #23
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);
     }
   }
 }
Example #24
0
 @Override
 public void visit(StringConstantInstruction insn) {
   assign(Expr.constant(insn.getConstant()), insn.getReceiver());
 }
Example #25
0
 private Expr castLongToInt(Expr value) {
   return Expr.unary(UnaryOperation.LONG_TO_INT, value);
 }
Example #26
0
 private Expr castIntToLong(Expr value) {
   return Expr.unary(UnaryOperation.INT_TO_LONG, value);
 }
Example #27
0
 @Override
 public void visit(NullCheckInstruction insn) {
   assign(
       Expr.unary(UnaryOperation.NULL_CHECK, Expr.var(insn.getValue().getIndex())),
       insn.getReceiver());
 }
Example #28
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;
 }
Example #29
0
 private void intBinary(int first, int second, Variable result, BinaryOperation op) {
   assign(castToInteger(Expr.binary(op, Expr.var(first), Expr.var(second))), result);
 }
Example #30
0
 private Expr castFromLong(Expr value) {
   return Expr.unary(UnaryOperation.LONG_TO_NUM, value);
 }