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.cast.CastBoolean;
012    import railo.transformer.bytecode.expression.ExprBoolean;
013    import railo.transformer.bytecode.expression.Expression;
014    import railo.transformer.bytecode.literal.LitBoolean;
015    
016    public final class While extends StatementBaseNoFinal implements FlowControlBreak,FlowControlContinue,HasBody {
017            
018            private ExprBoolean expr;
019            private Body body;
020            
021    
022            private Label begin = new Label();
023            private Label end = new Label();
024            private String label;
025    
026    
027    
028            /**
029             * Constructor of the class
030             * @param expr
031             * @param body
032             * @param line
033             */
034            public While(Expression expr,Body body,Position start,Position end, String label) {
035                    super(start,end);
036                    this.expr=CastBoolean.toExprBoolean(expr);
037                    this.body=body;
038                    body.setParent(this);
039                    this.label=label;
040            }
041            
042            
043            /**
044             * Constructor of the class
045             * @param b
046             * @param body
047             * @param line
048             */
049            public While(boolean b, Body body,Position start,Position end, String label) {
050                    this(LitBoolean.toExprBoolean(b),body,start, end, label);
051            }
052    
053            @Override
054            public void _writeOut(BytecodeContext bc) throws BytecodeException {
055                    GeneratorAdapter adapter = bc.getAdapter();
056                    adapter.visitLabel(begin);
057                    
058                    expr.writeOut(bc, Expression.MODE_VALUE);
059                    adapter.ifZCmp(Opcodes.IFEQ, end);
060                    
061                    body.writeOut(bc);
062                    adapter.visitJumpInsn(Opcodes.GOTO, begin);
063                    
064                    adapter.visitLabel(end);
065            }
066    
067            @Override
068            public Label getBreakLabel() {
069                    return end;
070            }
071    
072            @Override
073            public Label getContinueLabel() {
074                    return begin;
075            }
076    
077            @Override
078            public Body getBody() {
079                    return body;
080            }
081    
082            @Override
083            public String getLabel() {
084                    return label;
085            }
086    }