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    }