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.expression.Expression; 011 import railo.transformer.bytecode.literal.LitBoolean; 012 import railo.transformer.bytecode.util.ASMUtil; 013 import railo.transformer.bytecode.util.ExpressionUtil; 014 015 public final class For extends StatementBase implements FlowControl,HasBody { 016 017 private Expression init; 018 private Expression condition; 019 private Expression update; 020 private Body body; 021 022 //private static final int I=1; 023 024 Label beforeUpdate = new Label(); 025 Label end = new Label(); 026 027 028 029 /** 030 * Constructor of the class 031 * @param init 032 * @param condition 033 * @param update 034 * @param body 035 * @param line 036 */ 037 public For(Expression init,Expression condition,Expression update,Body body,int startline,int endline) { 038 super(startline,endline); 039 this.init=init; 040 this.condition=condition; 041 this.update=update; 042 this.body=body; 043 body.setParent(this); 044 045 } 046 047 /** 048 * 049 * @see railo.transformer.bytecode.statement.StatementBase#_writeOut(org.objectweb.asm.commons.GeneratorAdapter) 050 */ 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, getStartLine()); 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 /** 086 * 087 * @see railo.transformer.bytecode.statement.FlowControl#getBreakLabel() 088 */ 089 public Label getBreakLabel() { 090 return end; 091 } 092 093 /** 094 * 095 * @see railo.transformer.bytecode.statement.FlowControl#getContinueLabel() 096 */ 097 public Label getContinueLabel() { 098 return beforeUpdate; 099 } 100 101 /** 102 * @see railo.transformer.bytecode.statement.HasBody#getBody() 103 */ 104 public Body getBody() { 105 return body; 106 } 107 108 }