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    }