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.util.Types;
010    
011    
012    public final class TryCatchFinallyVisitor {
013    
014    
015            private Label beginTry;
016            private Label endTry;
017            
018            private Label endTryCatch;
019            private TryCatchFinallyData data;
020            
021            private Label beginGoToFinally;
022            private Label endGoToFinally;
023            private int lThrow;
024            private Label l13= new Label();;
025            //private boolean isFirst=true;
026            
027            public void visitTryBegin(BytecodeContext bc) {
028                    beginTry = new Label();
029                    endTry = new Label();
030                    endTryCatch = new Label();
031                    beginGoToFinally = new Label();
032                    endGoToFinally = new Label();
033                    data=new TryCatchFinallyData(l13);
034                    bc.pushTryCatchFinallyData(data);
035                    bc.getAdapter().visitLabel(beginTry);
036            }
037    
038            public void visitTryEnd(BytecodeContext bc) {
039                    //bc.popTryCatchFinallyData();
040                    bc.getAdapter().visitJumpInsn(Opcodes.GOTO, beginGoToFinally);
041                    bc.getAdapter().visitLabel(endTry);
042            }
043    
044            public int visitCatchBegin(BytecodeContext bc, Type type) {
045                    //doReturnCatch(bc);
046                    GeneratorAdapter adapter = bc.getAdapter();
047                    
048                    Label beginCatch=new Label();
049                    Label beginCatchBody=new Label();
050                            
051                    adapter.visitTryCatchBlock(beginTry, endTry, beginCatch,type.getInternalName());
052                    adapter.visitLabel(beginCatch);
053                    int lThrow = adapter.newLocal(type);
054                    adapter.storeLocal(lThrow);
055                    adapter.visitLabel(beginCatchBody);
056                            
057                    //bc.pushTryCatchFinallyData(data);
058                    return lThrow;
059            }
060    
061    
062            public void visitCatchEnd(BytecodeContext bc) {
063                    //bc.popTryCatchFinallyData();
064                    bc.getAdapter().visitLabel(new Label());
065                    bc.getAdapter().visitJumpInsn(Opcodes.GOTO, beginGoToFinally);
066            }
067    
068            public int visitFinallyBegin(BytecodeContext bc) {
069                    GeneratorAdapter adapter = bc.getAdapter();
070                    adapter.visitLabel(endTryCatch);
071                    int lThrow2 = adapter.newLocal(Types.THROWABLE);
072                    adapter.storeLocal(lThrow2);
073                    adapter.visitJumpInsn(Opcodes.JSR, l13);
074                    Label l14 = new Label();
075                    adapter.visitLabel(l14);
076                    adapter.loadLocal(lThrow2);
077                    adapter.visitInsn(Opcodes.ATHROW);
078                    adapter.visitLabel(l13);
079                    
080                    lThrow = adapter.newLocal(Types.OBJECT);
081                    adapter.storeLocal(lThrow);
082                    Label l15 = new Label(); 
083                    adapter.visitLabel(l15);
084                    return lThrow;
085            }
086    
087            public void visitFinallyEnd(BytecodeContext bc) {
088                    bc.popTryCatchFinallyData();
089                    GeneratorAdapter adapter = bc.getAdapter();
090                    Label l16 = new Label();
091                    adapter.visitLabel(l16);
092                    adapter.ret(lThrow);
093                    adapter.visitVarInsn(Opcodes.RET, 2);
094                    adapter.visitLabel(beginGoToFinally);
095                    adapter.visitJumpInsn(Opcodes.JSR, l13);
096                    adapter.visitLabel(endGoToFinally);
097                    adapter.visitTryCatchBlock(beginTry, endTryCatch, endTryCatch, null);
098            }
099    
100    }