public void generate(RangedForStatement rangedForStatement) { Scope newScope = rangedForStatement.getScope(); StatementGenerator scopeGeneratorWithNewScope = new StatementGenerator(methodVisitor, newScope); ExpressionGenrator exprGeneratorWithNewScope = new ExpressionGenrator(methodVisitor, newScope); Statement iterator = rangedForStatement.getIteratorVariableStatement(); Label incrementationSection = new Label(); Label decrementationSection = new Label(); Label endLoopSection = new Label(); String iteratorVarName = rangedForStatement.getIteratorVarName(); Expression endExpression = rangedForStatement.getEndExpression(); Expression iteratorVariable = new VarReference(iteratorVarName, rangedForStatement.getType()); ConditionalExpression iteratorGreaterThanEndConditional = new ConditionalExpression(iteratorVariable, endExpression, CompareSign.GREATER); ConditionalExpression iteratorLessThanEndConditional = new ConditionalExpression(iteratorVariable, endExpression, CompareSign.LESS);
//generates varaible declaration or variable reference (istore) iterator.accept(scopeGeneratorWithNewScope);
//Section below checks whether the loop should be iterating or decrementing //If the range start is smaller than range end (i from 0 to 5) then iterate (++) //If the range start is greater than range end (i from 5 to 0) then decrement (--)
//Pushes 0 or 1 onto the stack iteratorLessThanEndConditional.accept(exprGeneratorWithNewScope); //IFNE - is value on the stack (result of conditional) different than 0 (success)? methodVisitor.visitJumpInsn(Opcodes.IFNE,incrementationSection);
//Incrementation section methodVisitor.visitLabel(incrementationSection); rangedForStatement.getStatement().accept(scopeGeneratorWithNewScope); //execute the body methodVisitor.visitIincInsn(newScope.getLocalVariableIndex(iteratorVarName),1); //increment iterator iteratorGreaterThanEndConditional.accept(exprGeneratorWithNewScope); //is iterator greater than range end? methodVisitor.visitJumpInsn(Opcodes.IFEQ,incrementationSection); //if it is not go back loop again //the iterator is greater than end range. Break out of the loop, skipping decrementation section methodVisitor.visitJumpInsn(Opcodes.GOTO,endLoopSection);
Loops { main(string[] args) { for i from 1 to 5 { print i } } }
生成后的字节码反编译后的 Java 代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
public class Loops { public static void main(String[] var0) { int var1 = 1; if(var1 >= 5 ) { //should it be decremented? do { System.out.println(var1); --var1; } while(var1 >= 5); } else { //should it be incremented? do { System.out.println(var1); ++var1; } while(var1 <= 5); }