001    package railo.transformer.bytecode.statement;
002    
003    import java.util.Stack;
004    
005    import org.objectweb.asm.Opcodes;
006    import org.objectweb.asm.commons.GeneratorAdapter;
007    
008    import railo.transformer.bytecode.BytecodeContext;
009    import railo.transformer.bytecode.BytecodeException;
010    import railo.transformer.bytecode.Position;
011    import railo.transformer.bytecode.Statement;
012    import railo.transformer.bytecode.expression.Expression;
013    import railo.transformer.bytecode.util.ASMConstants;
014    import railo.transformer.bytecode.util.Types;
015    import railo.transformer.bytecode.visitor.OnFinally;
016    
017    /**
018     * Return Statement
019     */
020    public final class Return extends StatementBaseNoFinal {
021    
022            Expression expr;
023    
024            /**
025             * Constructor of the class
026             * @param line
027             */
028            public Return(Position start,Position end) {
029                    super(start,end);
030                    setHasFlowController(true);
031                    //expr=LitString.toExprString("", line);
032            }
033            
034            /**
035             * Constructor of the class
036             * @param expr
037             * @param line
038             */
039            public Return(Expression expr, Position start,Position end) {
040                    super(start,end);
041                    this.expr=expr;
042                    setHasFlowController(true);
043                    //if(expr==null)expr=LitString.toExprString("", line);
044            }
045    
046            public void _writeOut(BytecodeContext bc) throws BytecodeException {
047                    GeneratorAdapter adapter = bc.getAdapter();
048                    
049                    Stack<OnFinally> finallies = bc.getOnFinallyStack();
050                    int len=finallies.size();
051                    OnFinally onFinally;
052                    
053                    if(expr==null)ASMConstants.NULL(adapter);
054                    else expr.writeOut(bc, Expression.MODE_REF);
055                    if(len>0) {
056                            int rtn = adapter.newLocal(Types.OBJECT);
057                            adapter.storeLocal(rtn, Types.OBJECT);
058                            for(int i=len-1;i>=0;i--) {
059                                    
060                                    onFinally=finallies.get(i);
061                                    onFinally.writeOut(bc);
062                            }
063                            adapter.loadLocal(rtn, Types.OBJECT);
064                    }
065                    if(bc.getMethod().getReturnType().equals(Types.VOID)) {
066                            adapter.pop();
067                            adapter.visitInsn(Opcodes.RETURN);
068                    }
069                    else adapter.visitInsn(Opcodes.ARETURN);
070            }
071            
072    
073            /**
074             *
075             * @see railo.transformer.bytecode.statement.StatementBase#setParent(railo.transformer.bytecode.Statement)
076             */
077            public void setParent(Statement parent) {
078                    super.setParent(parent);
079                    parent.setHasFlowController(true);
080            }
081    }