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 }