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