001 package railo.transformer.bytecode.statement; 002 003 import org.objectweb.asm.Label; 004 import org.objectweb.asm.Opcodes; 005 import org.objectweb.asm.commons.GeneratorAdapter; 006 007 import railo.transformer.bytecode.Body; 008 import railo.transformer.bytecode.BytecodeContext; 009 import railo.transformer.bytecode.BytecodeException; 010 import railo.transformer.bytecode.Position; 011 import railo.transformer.bytecode.expression.Expression; 012 import railo.transformer.bytecode.literal.LitBoolean; 013 import railo.transformer.bytecode.util.ASMUtil; 014 import railo.transformer.bytecode.util.ExpressionUtil; 015 016 public final class For extends StatementBaseNoFinal implements FlowControlBreak,FlowControlContinue,HasBody { 017 018 private Expression init; 019 private Expression condition; 020 private Expression update; 021 private Body body; 022 023 //private static final int I=1; 024 025 Label beforeUpdate = new Label(); 026 Label end = new Label(); 027 private String label; 028 029 030 031 /** 032 * Constructor of the class 033 * @param init 034 * @param condition 035 * @param update 036 * @param body 037 * @param line 038 */ 039 public For(Expression init,Expression condition,Expression update,Body body,Position start, Position end, String label) { 040 super(start,end); 041 this.init=init; 042 this.condition=condition; 043 this.update=update; 044 this.body=body; 045 this.label=label; 046 body.setParent(this); 047 048 } 049 050 @Override 051 public void _writeOut(BytecodeContext bc) throws BytecodeException { 052 GeneratorAdapter adapter = bc.getAdapter(); 053 Label beforeInit = new Label(); 054 Label afterInit = new Label(); 055 Label afterUpdate = new Label(); 056 057 ExpressionUtil.visitLine(bc, getStart()); 058 adapter.visitLabel(beforeInit); 059 if(init!=null) { 060 init.writeOut(bc, Expression.MODE_VALUE); 061 adapter.pop(); 062 } 063 adapter.visitJumpInsn(Opcodes.GOTO, afterUpdate); 064 adapter.visitLabel(afterInit); 065 066 body.writeOut(bc); 067 068 adapter.visitLabel(beforeUpdate); 069 //ExpressionUtil.visitLine(bc, getStartLine()); 070 if(update!=null) { 071 update.writeOut(bc, Expression.MODE_VALUE); 072 ASMUtil.pop(adapter,update, Expression.MODE_VALUE); 073 } 074 //ExpressionUtil.visitLine(bc, getStartLine()); 075 adapter.visitLabel(afterUpdate); 076 077 if(condition!=null)condition.writeOut(bc, Expression.MODE_VALUE); 078 else LitBoolean.TRUE.writeOut(bc, Expression.MODE_VALUE); 079 adapter.visitJumpInsn(Opcodes.IFNE, afterInit); 080 //ExpressionUtil.visitLine(bc, getEndLine()); 081 adapter.visitLabel(end); 082 083 } 084 085 @Override 086 public Label getBreakLabel() { 087 return end; 088 } 089 090 @Override 091 public Label getContinueLabel() { 092 return beforeUpdate; 093 } 094 095 @Override 096 public Body getBody() { 097 return body; 098 } 099 100 @Override 101 public String getLabel() { 102 return label; 103 } 104 }