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