001    package railo.transformer.bytecode.visitor;
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.BytecodeContext;
008    import railo.transformer.bytecode.util.Types;
009    
010    public final class TryFinallyVisitor implements ITryFinallyVisitor {
011    
012    
013            private Label tryBegin                  = new Label();
014            private Label tryEndCatchBegin  = new Label();
015            private Label finallyBegin              = new Label();
016            private Label finallyEnd                = new Label();
017            private Label l4 = new Label();
018            private TryCatchFinallyData data;
019            
020            private int lThrow1;
021    
022            public void visitTryBegin(BytecodeContext bc) {
023                    data=new TryCatchFinallyData(l4);
024                    bc.pushTryCatchFinallyData(data);
025                    bc.getAdapter().visitLabel(tryBegin);
026            }
027            
028            public void visitTryEndFinallyBegin(BytecodeContext bc) {
029                    GeneratorAdapter adapter = bc.getAdapter();
030    
031                    adapter.visitJumpInsn(Opcodes.GOTO, finallyBegin);
032                    adapter.visitLabel(tryEndCatchBegin);
033                    int lThrow2 = adapter.newLocal(Types.THROWABLE);
034                    adapter.storeLocal(lThrow2);
035                    //mv.visitVarInsn(ASTORE, 3);
036                    
037                    adapter.visitJumpInsn(Opcodes.JSR, l4);
038                    Label l5 = new Label();
039                    adapter.visitLabel(l5);
040                    adapter.loadLocal(lThrow2);
041                    //mv.visitVarInsn(ALOAD, 3);
042                    adapter.visitInsn(Opcodes.ATHROW);
043                    adapter.visitLabel(l4);
044    
045                    lThrow1 = adapter.newLocal(Types.OBJECT);
046                    adapter.storeLocal(lThrow1);
047                    //mv.visitVarInsn(ASTORE, 2);
048                    Label l6 = new Label();
049                    adapter.visitLabel(l6);
050            }
051            
052            
053            public void visitFinallyEnd(BytecodeContext bc) {
054                    GeneratorAdapter adapter = bc.getAdapter();
055                    bc.popTryCatchFinallyData();
056                    Label l7 = new Label();
057                    adapter.visitLabel(l7);
058                    adapter.ret(lThrow1);
059                    adapter.visitVarInsn(Opcodes.RET, 2);
060                    adapter.visitLabel(finallyBegin);
061                    adapter.visitJumpInsn(Opcodes.JSR, l4);
062                    adapter.visitLabel(finallyEnd);
063                    
064    
065                    adapter.visitTryCatchBlock(tryBegin, tryEndCatchBegin, tryEndCatchBegin, null);
066            }
067    }