コード例 #1
0
ファイル: OptimizingVisitor.java プロジェクト: sba1/teavm
 @Override
 public void visit(VariableExpr expr) {
   int index = expr.getIndex();
   resultExpr = expr;
   if (readFrequencies[index] != 1 || preservedVars[index]) {
     return;
   }
   if (resultSequence.isEmpty()) {
     return;
   }
   Statement last = resultSequence.get(resultSequence.size() - 1);
   if (!(last instanceof AssignmentStatement)) {
     return;
   }
   AssignmentStatement assignment = (AssignmentStatement) last;
   if (assignment.isAsync()) {
     return;
   }
   if (!(assignment.getLeftValue() instanceof VariableExpr)) {
     return;
   }
   VariableExpr var = (VariableExpr) assignment.getLeftValue();
   if (var.getLocation() != null
       && assignment.getLocation() != null
       && !assignment.getLocation().equals(var.getLocation())) {
     return;
   }
   if (var.getIndex() == index) {
     resultSequence.remove(resultSequence.size() - 1);
     assignment.getRightValue().setLocation(assignment.getLocation());
     assignment.getRightValue().acceptVisitor(this);
   }
 }
コード例 #2
0
ファイル: OptimizingVisitor.java プロジェクト: sba1/teavm
 @Override
 public void visit(SequentialStatement statement) {
   List<Statement> statements = processSequence(statement.getSequence());
   if (statements.size() == 1) {
     resultStmt = statements.get(0);
   } else {
     statement.getSequence().clear();
     statement.getSequence().addAll(statements);
     resultStmt = statement;
   }
 }
コード例 #3
0
ファイル: StatementGenerator.java プロジェクト: sba1/teavm
 @Override
 public void visit(MonitorExitInstruction insn) {
   MonitorExitStatement stmt = new MonitorExitStatement();
   stmt.setLocation(currentLocation);
   stmt.setObjectRef(Expr.var(insn.getObjectRef().getIndex()));
   statements.add(stmt);
 }
コード例 #4
0
ファイル: StatementGenerator.java プロジェクト: sba1/teavm
 @Override
 public void visit(JumpInstruction insn) {
   Statement stmt = generateJumpStatement(insn.getTarget());
   if (stmt != null) {
     statements.add(stmt);
   }
 }
コード例 #5
0
ファイル: StatementGenerator.java プロジェクト: sba1/teavm
 @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);
 }
コード例 #6
0
ファイル: StatementGenerator.java プロジェクト: sba1/teavm
 @Override
 public void visit(RaiseInstruction insn) {
   ThrowStatement stmt = new ThrowStatement();
   stmt.setLocation(currentLocation);
   stmt.setException(Expr.var(insn.getException().getIndex()));
   statements.add(stmt);
 }
コード例 #7
0
ファイル: StatementGenerator.java プロジェクト: sba1/teavm
 @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);
   }
 }
コード例 #8
0
ファイル: StatementGenerator.java プロジェクト: sba1/teavm
 @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);
 }
コード例 #9
0
ファイル: StatementGenerator.java プロジェクト: sba1/teavm
 private void branch(Expr condition, BasicBlock consequentBlock, BasicBlock alternativeBlock) {
   Statement consequent = generateJumpStatement(consequentBlock);
   Statement alternative = generateJumpStatement(alternativeBlock);
   statements.add(
       Statement.cond(
           condition,
           consequent != null ? Arrays.asList(consequent) : Collections.emptyList(),
           alternative != null ? Arrays.asList(alternative) : Collections.emptyList()));
 }
コード例 #10
0
ファイル: StatementGenerator.java プロジェクト: sba1/teavm
 @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);
 }
コード例 #11
0
ファイル: OptimizingVisitor.java プロジェクト: sba1/teavm
 private List<Statement> processSequence(List<Statement> statements) {
   List<Statement> backup = resultSequence;
   resultSequence = new ArrayList<>();
   processSequenceImpl(statements);
   wieldTryCatch(resultSequence);
   List<Statement> result =
       resultSequence.stream().filter(part -> part != null).collect(Collectors.toList());
   resultSequence = backup;
   return result;
 }
コード例 #12
0
ファイル: StatementGenerator.java プロジェクト: sba1/teavm
 @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);
 }
コード例 #13
0
ファイル: StatementGenerator.java プロジェクト: sba1/teavm
 @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);
 }
コード例 #14
0
ファイル: OptimizingVisitor.java プロジェクト: sba1/teavm
 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;
 }
コード例 #15
0
ファイル: OptimizingVisitor.java プロジェクト: sba1/teavm
 @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;
 }
コード例 #16
0
ファイル: OptimizingVisitor.java プロジェクト: sba1/teavm
 private boolean briefStatementComparison(List<Statement> firstSeq, List<Statement> secondSeq) {
   if (firstSeq.isEmpty() && secondSeq.isEmpty()) {
     return true;
   }
   if (firstSeq.size() != 1 || secondSeq.size() != 1) {
     return false;
   }
   Statement first = firstSeq.get(0);
   Statement second = secondSeq.get(0);
   if (first instanceof BreakStatement && second instanceof BreakStatement) {
     BreakStatement firstBreak = (BreakStatement) first;
     BreakStatement secondBreak = (BreakStatement) second;
     return firstBreak.getTarget() == secondBreak.getTarget();
   }
   return false;
 }
コード例 #17
0
ファイル: OptimizingVisitor.java プロジェクト: sba1/teavm
 private void wieldTryCatch(List<Statement> statements) {
   for (int i = 0; i < statements.size() - 1; ++i) {
     if (statements.get(i) instanceof TryCatchStatement
         && statements.get(i + 1) instanceof TryCatchStatement) {
       TryCatchStatement first = (TryCatchStatement) statements.get(i);
       TryCatchStatement second = (TryCatchStatement) statements.get(i + 1);
       if (Objects.equals(first.getExceptionType(), second.getExceptionType())
           && Objects.equals(first.getExceptionVariable(), second.getExceptionVariable())
           && briefStatementComparison(first.getHandler(), second.getHandler())) {
         first.getProtectedBody().addAll(second.getProtectedBody());
         statements.remove(i + 1);
         wieldTryCatch(first.getProtectedBody());
         --i;
       }
     }
   }
 }
コード例 #18
0
ファイル: OptimizingVisitor.java プロジェクト: sba1/teavm
 private boolean processSequenceImpl(List<Statement> statements) {
   for (Statement part : statements) {
     if (part instanceof SequentialStatement) {
       if (!processSequenceImpl(((SequentialStatement) part).getSequence())) {
         return false;
       }
       continue;
     }
     part.acceptVisitor(this);
     part = resultStmt;
     if (part instanceof SequentialStatement) {
       if (!processSequenceImpl(((SequentialStatement) part).getSequence())) {
         return false;
       }
       continue;
     }
     resultSequence.add(part);
     if (part instanceof BreakStatement) {
       return false;
     }
   }
   return true;
 }
コード例 #19
0
ファイル: StatementGenerator.java プロジェクト: sba1/teavm
 @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);
 }
コード例 #20
0
ファイル: OptimizingVisitor.java プロジェクト: sba1/teavm
 @Override
 public void visit(ConditionalStatement statement) {
   statement.getCondition().acceptVisitor(this);
   statement.setCondition(resultExpr);
   List<Statement> consequent = processSequence(statement.getConsequent());
   List<Statement> alternative = processSequence(statement.getAlternative());
   if (consequent.isEmpty()) {
     consequent.addAll(alternative);
     alternative.clear();
     statement.setCondition(ExprOptimizer.invert(statement.getCondition()));
   }
   if (consequent.isEmpty()) {
     resultStmt = Statement.empty();
     return;
   }
   statement.getConsequent().clear();
   statement.getConsequent().addAll(consequent);
   statement.getAlternative().clear();
   statement.getAlternative().addAll(alternative);
   resultStmt = statement;
 }
コード例 #21
0
ファイル: StatementGenerator.java プロジェクト: sba1/teavm
 @Override
 public void visit(InitClassInstruction insn) {
   InitClassStatement stmt = Statement.initClass(insn.getClassName());
   stmt.setLocation(currentLocation);
   statements.add(stmt);
 }
コード例 #22
0
ファイル: OptimizingVisitor.java プロジェクト: sba1/teavm
 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);
     }
   }
 }
コード例 #23
0
ファイル: StatementGenerator.java プロジェクト: sba1/teavm
 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);
 }