001/**
002 *
003 * Copyright (c) 2014, the Railo Company Ltd. All rights reserved.
004 *
005 * This library is free software; you can redistribute it and/or
006 * modify it under the terms of the GNU Lesser General Public
007 * License as published by the Free Software Foundation; either 
008 * version 2.1 of the License, or (at your option) any later version.
009 * 
010 * This library is distributed in the hope that it will be useful,
011 * but WITHOUT ANY WARRANTY; without even the implied warranty of
012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
013 * Lesser General Public License for more details.
014 * 
015 * You should have received a copy of the GNU Lesser General Public 
016 * License along with this library.  If not, see <http://www.gnu.org/licenses/>.
017 * 
018 **/
019package lucee.transformer.bytecode.statement;
020
021import lucee.transformer.bytecode.Body;
022import lucee.transformer.bytecode.BytecodeContext;
023import lucee.transformer.bytecode.BytecodeException;
024import lucee.transformer.bytecode.Position;
025import lucee.transformer.bytecode.cast.CastBoolean;
026import lucee.transformer.bytecode.expression.ExprBoolean;
027import lucee.transformer.bytecode.expression.Expression;
028import lucee.transformer.bytecode.literal.LitBoolean;
029
030import org.objectweb.asm.Label;
031import org.objectweb.asm.Opcodes;
032import org.objectweb.asm.commons.GeneratorAdapter;
033
034public final class While extends StatementBaseNoFinal implements FlowControlBreak,FlowControlContinue,HasBody {
035        
036        private ExprBoolean expr;
037        private Body body;
038        
039
040        private Label begin = new Label();
041        private Label end = new Label();
042        private String label;
043
044
045
046        /**
047         * Constructor of the class
048         * @param expr
049         * @param body
050         * @param line
051         */
052        public While(Expression expr,Body body,Position start,Position end, String label) {
053                super(start,end);
054                this.expr=CastBoolean.toExprBoolean(expr);
055                this.body=body;
056                body.setParent(this);
057                this.label=label;
058        }
059        
060        
061        /**
062         * Constructor of the class
063         * @param b
064         * @param body
065         * @param line
066         */
067        public While(boolean b, Body body,Position start,Position end, String label) {
068                this(LitBoolean.toExprBoolean(b),body,start, end, label);
069        }
070
071        @Override
072        public void _writeOut(BytecodeContext bc) throws BytecodeException {
073                GeneratorAdapter adapter = bc.getAdapter();
074                adapter.visitLabel(begin);
075                
076                expr.writeOut(bc, Expression.MODE_VALUE);
077                adapter.ifZCmp(Opcodes.IFEQ, end);
078                
079                body.writeOut(bc);
080                adapter.visitJumpInsn(Opcodes.GOTO, begin);
081                
082                adapter.visitLabel(end);
083        }
084
085        @Override
086        public Label getBreakLabel() {
087                return end;
088        }
089
090        @Override
091        public Label getContinueLabel() {
092                return begin;
093        }
094
095        @Override
096        public Body getBody() {
097                return body;
098        }
099
100        @Override
101        public String getLabel() {
102                return label;
103        }
104}