001 package railo.transformer.bytecode.visitor; 002 003 import org.objectweb.asm.Label; 004 import org.objectweb.asm.Opcodes; 005 import org.objectweb.asm.Type; 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.FlowControlFinal; 011 import railo.transformer.bytecode.util.ASMUtil; 012 import railo.transformer.bytecode.util.Types; 013 014 public class TryCatchFinallyVisitor implements Opcodes { 015 private OnFinally onFinally; 016 private Label beginTry; 017 private Label endTry; 018 private Label endTry2; 019 private Label l3; 020 private Label l4; 021 private Label l5; 022 private Label l6; 023 private Type type=Types.THROWABLE; 024 private FlowControlFinal fcf; 025 026 027 public TryCatchFinallyVisitor(OnFinally onFinally, FlowControlFinal fcf){ 028 this.onFinally=onFinally; 029 this.fcf=fcf; 030 } 031 032 public void visitTryBegin(BytecodeContext bc) { 033 GeneratorAdapter ga = bc.getAdapter(); 034 beginTry = new Label(); 035 endTry = new Label(); 036 endTry2 = new Label(); 037 l3 = new Label(); 038 l4 = new Label(); 039 bc.pushOnFinally(onFinally); 040 ga.visitLabel(beginTry); 041 } 042 043 public int visitTryEndCatchBeging(BytecodeContext bc) { 044 GeneratorAdapter ga = bc.getAdapter(); 045 046 ga.visitTryCatchBlock(beginTry, endTry, endTry2, type.getInternalName()); 047 ga.visitLabel(endTry); 048 l5 = new Label(); 049 ga.visitJumpInsn(GOTO, l5); 050 ga.visitLabel(endTry2); 051 int lThrow = ga.newLocal(type); 052 ga.storeLocal(lThrow); 053 //mv.visitVarInsn(ASTORE, 1); 054 l6 = new Label(); 055 ga.visitLabel(l6); 056 return lThrow; 057 } 058 059 public void visitCatchEnd(BytecodeContext bc) throws BytecodeException { 060 Label end = new Label(); 061 GeneratorAdapter ga = bc.getAdapter(); 062 bc.popOnFinally(); 063 ga.visitLabel(l3); 064 ga.visitJumpInsn(GOTO, l5); 065 ga.visitLabel(l4); 066 int lThrow = ga.newLocal(Types.THROWABLE); 067 ga.storeLocal(lThrow); 068 //mv.visitVarInsn(ASTORE, 2); 069 Label l8 = new Label(); 070 ga.visitLabel(l8); 071 072 onFinally.writeOut(bc); 073 074 ga.loadLocal(lThrow); 075 ga.visitInsn(ATHROW); 076 ga.visitLabel(l5); 077 078 onFinally.writeOut(bc); 079 if(fcf!=null && fcf.getAfterFinalGOTOLabel()!=null) { 080 Label _end=new Label(); 081 ga.visitJumpInsn(Opcodes.GOTO, _end); // ignore when coming not from break/continue 082 ASMUtil.visitLabel(ga,fcf.getFinalEntryLabel()); 083 onFinally.writeOut(bc); 084 ga.visitJumpInsn(Opcodes.GOTO, fcf.getAfterFinalGOTOLabel()); 085 ga.visitLabel(_end); 086 } 087 088 089 090 091 092 ga.visitLabel(end); 093 ga.visitTryCatchBlock(beginTry, l3, l4, null); 094 095 } 096 }