001    package railo.transformer.bytecode.statement.tag;
002    
003    import java.util.ArrayList;
004    import java.util.Iterator;
005    import java.util.List;
006    
007    import org.objectweb.asm.Label;
008    import org.objectweb.asm.Opcodes;
009    import org.objectweb.asm.Type;
010    import org.objectweb.asm.commons.GeneratorAdapter;
011    import org.objectweb.asm.commons.Method;
012    
013    import railo.transformer.bytecode.Body;
014    import railo.transformer.bytecode.BodyBase;
015    import railo.transformer.bytecode.BytecodeContext;
016    import railo.transformer.bytecode.BytecodeException;
017    import railo.transformer.bytecode.Statement;
018    import railo.transformer.bytecode.expression.ExprString;
019    import railo.transformer.bytecode.expression.Expression;
020    import railo.transformer.bytecode.literal.LitString;
021    import railo.transformer.bytecode.statement.TryCatchFinally;
022    import railo.transformer.bytecode.util.ExpressionUtil;
023    import railo.transformer.bytecode.util.Types;
024    import railo.transformer.bytecode.visitor.TryCatchFinallyVisitor;
025    
026    public final class TagTry extends TagBase {
027    
028            private static final ExprString ANY=LitString.toExprString("any", -1);
029    
030            private static final Method GET_VARIABLE = new Method(
031                            "getVariable",
032                            Types.OBJECT,
033                            new Type[]{Types.STRING});
034            
035            private static final Method TO_PAGE_EXCEPTION = new Method(
036                            "toPageException",
037                            Types.PAGE_EXCEPTION,
038                            new Type[]{Types.THROWABLE});
039            
040            // PageException setCatch(Throwable t)
041            private static final Method SET_CATCH_T = new Method(
042                            "setCatch",
043                            Types.PAGE_EXCEPTION,
044                            new Type[]{Types.THROWABLE});
045            
046            
047            public static final Method SET_CATCH_PE = new Method(
048                            "setCatch",
049                            Types.VOID,
050                            new Type[]{Types.PAGE_EXCEPTION});
051            
052            public static final Method SET_CATCH3 = new Method(
053                            "setCatch",
054                            Types.VOID,
055                            new Type[]{Types.PAGE_EXCEPTION,Types.BOOLEAN_VALUE,Types.BOOLEAN_VALUE});
056            
057            public static final Method GET_CATCH = new Method(
058                            "getCatch",
059                            Types.PAGE_EXCEPTION,
060                            new Type[]{});
061    
062            //  public boolean typeEqual(String type);
063            private static final Method TYPE_EQUAL = new Method(
064                            "typeEqual",
065                            Types.BOOLEAN_VALUE,
066                            new Type[]{Types.STRING});
067    
068            
069    
070            public TagTry(int line) {
071                    super(line);
072            }
073    
074            public TagTry(int sl,int el) {
075                    super(sl,el);
076            }
077    
078            /**
079             *
080             * @see railo.transformer.bytecode.statement.tag.TagBase#_writeOut(org.objectweb.asm.commons.GeneratorAdapter)
081             */
082            public void _writeOut(BytecodeContext bc) throws BytecodeException {
083                    GeneratorAdapter adapter = bc.getAdapter();
084                    Body tryBody=new BodyBase();
085                    List catches=new ArrayList();
086                    Tag _finally=null;
087    
088                    tryBody.setParent(getBody().getParent());
089                    
090                    List statements = getBody().getStatements();
091                    Statement stat;
092                    Tag tag;
093                    Iterator it = statements.iterator();
094                    while(it.hasNext()) {
095                            stat=(Statement) it.next();
096                            if(stat instanceof Tag) {
097                                    tag=(Tag) stat;
098                                    if(tag.getTagLibTag().getTagClassName().equals("railo.runtime.tag.Catch"))      {
099                                            catches.add(tag);
100                                            continue;
101                                    }
102                                    else if(tag.getTagLibTag().getTagClassName().equals("railo.runtime.tag.Finally"))       {
103                                            _finally=tag;
104                                            continue;
105                                    }
106                            }
107                            tryBody.addStatement(stat);
108                    };
109                    
110                    
111                    
112                    
113                    TryCatchFinallyVisitor tcfv=new TryCatchFinallyVisitor();
114                    // Try
115                    tcfv.visitTryBegin(bc);
116                            tryBody.writeOut(bc);
117                    tcfv.visitTryEnd(bc);
118                    
119                    // Catch
120                    int e=tcfv.visitCatchBegin(bc, Types.THROWABLE);
121                            // if(e instanceof railo.runtime.exp.Abort) throw e;
122                            Label abortEnd=new Label();
123                            adapter.loadLocal(e);
124                            // Abort.isAbort(t);
125                            adapter.invokeStatic(Types.ABORT, TryCatchFinally.IS_ABORT);
126                            //adapter.instanceOf(Types.ABORT);
127                            
128                            
129                            
130                    adapter.ifZCmp(Opcodes.IFEQ, abortEnd);
131                            adapter.loadLocal(e);
132                            adapter.throwException();
133                    adapter.visitLabel(abortEnd);
134                        
135    
136                    // PageExceptionImpl old=pc.getCatch();
137                    int old=adapter.newLocal(Types.PAGE_EXCEPTION);
138                    adapter.loadArg(0);
139                    adapter.checkCast(Types.PAGE_CONTEXT_IMPL);
140                    adapter.invokeVirtual(Types.PAGE_CONTEXT_IMPL, GET_CATCH);
141                            adapter.storeLocal(old);
142                            
143                            /*int obj=adapter.newLocal(Types.OBJECT);
144                    adapter.loadArg(0);
145                    adapter.push("cfcatch");
146                    adapter.invokeVirtual(Types.PAGE_CONTEXT, GET_VARIABLE);
147                            adapter.storeLocal(obj);*/
148                            
149                    
150                    // PageException pe=Caster.toPageEception(e);
151                    int pe=adapter.newLocal(Types.PAGE_EXCEPTION);
152                    adapter.loadLocal(e);
153                    adapter.invokeStatic(Types.CASTER, TO_PAGE_EXCEPTION);
154                            adapter.storeLocal(pe);
155                            /*
156                            adapter.loadArg(0);
157                    adapter.loadLocal(e);
158                    adapter.invokeVirtual(Types.PAGE_CONTEXT, SET_CATCH_T);
159                            adapter.storeLocal(pe);
160                            */
161                            
162                            
163                            it=catches.iterator();
164                            Attribute attrType;
165                            Expression type;
166                            Label endAllIfs=new Label();
167                            Tag tagElse=null;
168                            while(it.hasNext()) {
169                                    tag=(Tag) it.next();
170                                    Label endIf=new Label();
171                                    attrType = tag.getAttribute("type");
172                                    type=ANY;
173                                    if(attrType!=null)type=attrType.getValue();
174    
175                                    if(type instanceof LitString && ((LitString)type).getString().equalsIgnoreCase("any")){
176                                            tagElse=tag;
177                                            continue;
178                                    }
179                                    
180                                    ExpressionUtil.visitLine(bc, tag.getLine());
181                                    
182                                    // if(pe.typeEqual(@type)
183                                    adapter.loadLocal(pe);
184                                    type.writeOut(bc, Expression.MODE_REF);
185                                    adapter.invokeVirtual(Types.PAGE_EXCEPTION, TYPE_EQUAL);
186                                    
187                                    adapter.ifZCmp(Opcodes.IFEQ, endIf);
188                                            catchBody(bc,adapter,tag,pe,true);
189                                            
190                        adapter.visitJumpInsn(Opcodes.GOTO, endAllIfs);
191                        
192                        adapter.visitLabel(endIf);
193                                    
194                                    
195                            }
196                            // else 
197                            if(tagElse!=null){
198                                    catchBody(bc, adapter, tagElse, pe, true);
199                            }
200                            else{
201                                    // pc.setCatch(pe,true);
202                                    adapter.loadArg(0);
203                            adapter.checkCast(Types.PAGE_CONTEXT_IMPL);
204                            adapter.loadLocal(pe);
205                            adapter.push(false);
206                            adapter.push(true);
207                            adapter.invokeVirtual(Types.PAGE_CONTEXT_IMPL, SET_CATCH3);
208                                    
209                                    //throw pe;
210                                    adapter.loadLocal(pe);
211                                    adapter.throwException();
212                            }
213                            adapter.visitLabel(endAllIfs);
214                            
215                    
216                    // PageExceptionImpl old=pc.getCatch();
217            adapter.loadArg(0);
218            adapter.checkCast(Types.PAGE_CONTEXT_IMPL);
219            adapter.loadLocal(old);
220            adapter.invokeVirtual(Types.PAGE_CONTEXT_IMPL, SET_CATCH_PE);
221                            
222                    tcfv.visitCatchEnd(bc);
223                    
224                    
225                    
226                    // Finally
227                    tcfv.visitFinallyBegin(bc);
228                            // pc.clearCatch();
229                                    //adapter.loadArg(0);
230                                    //adapter.invokeVirtual(Types.PAGE_CONTEXT, CLEAR_CATCH);
231                    
232                            if(_finally!=null) {
233                                    ExpressionUtil.visitLine(bc, _finally.getLine());
234                                    _finally.getBody().writeOut(bc);
235                            }
236                    tcfv.visitFinallyEnd(bc);
237            }
238    
239            private static void catchBody(BytecodeContext bc, GeneratorAdapter adapter,Tag tag, int pe,boolean caugth) throws BytecodeException {
240                    // pc.setCatch(pe,true);
241                    adapter.loadArg(0);
242            adapter.checkCast(Types.PAGE_CONTEXT_IMPL);
243            adapter.loadLocal(pe);
244            adapter.push(caugth);
245            adapter.push(true);
246            adapter.invokeVirtual(Types.PAGE_CONTEXT_IMPL, SET_CATCH3);
247                    tag.getBody().writeOut(bc);
248            
249            }
250    
251    
252    }