001 package railo.transformer.bytecode.util; 002 003 import java.util.HashMap; 004 import java.util.Map; 005 006 import org.objectweb.asm.Opcodes; 007 import org.objectweb.asm.Type; 008 import org.objectweb.asm.commons.GeneratorAdapter; 009 import org.objectweb.asm.commons.Method; 010 011 import railo.commons.lang.CFTypes; 012 import railo.commons.lang.StringUtil; 013 import railo.runtime.op.Caster; 014 import railo.transformer.bytecode.BytecodeContext; 015 import railo.transformer.bytecode.BytecodeException; 016 import railo.transformer.bytecode.Statement; 017 import railo.transformer.bytecode.expression.ExprString; 018 import railo.transformer.bytecode.expression.Expression; 019 import railo.transformer.bytecode.literal.LitString; 020 import railo.transformer.bytecode.statement.StatementBase; 021 import railo.transformer.bytecode.statement.tag.Tag; 022 023 public final class ExpressionUtil { 024 025 /*public static final Method END_LINE = new Method( 026 "exeLogEndline", 027 Types.VOID, 028 new Type[]{Types.INT_VALUE});*/ 029 030 public static final Method START = new Method( 031 "exeLogStart", 032 Types.VOID, 033 new Type[]{Types.INT_VALUE,Types.STRING}); 034 public static final Method END = new Method( 035 "exeLogEnd", 036 Types.VOID, 037 new Type[]{Types.INT_VALUE,Types.STRING}); 038 039 040 private static Map<String,String> last=new HashMap<String,String>(); 041 042 public static void writeOutExpressionArray(BytecodeContext bc, Type arrayType, Expression[] array) throws BytecodeException { 043 GeneratorAdapter adapter = bc.getAdapter(); 044 adapter.push(array.length); 045 adapter.newArray(arrayType); 046 for (int i = 0; i < array.length; i++) { 047 adapter.dup(); 048 adapter.push(i); 049 array[i].writeOut(bc, Expression.MODE_REF); 050 adapter.visitInsn(Opcodes.AASTORE); 051 } 052 } 053 054 /** 055 * visit line number 056 * @param adapter 057 * @param line 058 * @param silent id silent this is ignored for log 059 */ 060 public static synchronized void visitLine(BytecodeContext bc, int line) { 061 if(line>0){ 062 if(!(""+line).equals(last.get(bc.getClassName()+":"+bc.getId()))){ 063 //writeLog(bc,line); 064 bc.visitLineNumber(line); 065 last.put(bc.getClassName()+":"+bc.getId(),""+line); 066 last.put(bc.getClassName(),""+line); 067 } 068 } 069 } 070 071 public static synchronized void lastLine(BytecodeContext bc) { 072 int line = Caster.toIntValue(last.get(bc.getClassName()),-1); 073 visitLine(bc, line); 074 } 075 076 /** 077 * write out expression without LNT 078 * @param value 079 * @param bc 080 * @param mode 081 * @throws BytecodeException 082 */ 083 public static void writeOutSilent(Expression value, BytecodeContext bc, int mode) throws BytecodeException { 084 int line = value.getLine(); 085 value.setLine(-1); 086 value.writeOut(bc, mode); 087 value.setLine(line); 088 } 089 public static void writeOut(Expression value, BytecodeContext bc, int mode) throws BytecodeException { 090 value.writeOut(bc, mode); 091 } 092 093 public static short toShortType(ExprString expr, short defaultValue) { 094 if(expr instanceof LitString){ 095 return CFTypes.toShort(((LitString)expr).getString(),defaultValue); 096 } 097 return defaultValue; 098 } 099 100 public static void callStartLog(BytecodeContext bc, Statement s, String id) { 101 call_Log(bc, START, getStartLine(s),id); 102 } 103 public static void callEndLog(BytecodeContext bc, Statement s, String id) { 104 call_Log(bc, END, getEndLine(s),id); 105 } 106 107 private static void call_Log(BytecodeContext bc, Method method, int line, String id) { 108 if(!bc.writeLog() || line<0 || (StringUtil.indexOfIgnoreCase(bc.getMethod().getName(),"call")==-1))return; 109 try{ 110 GeneratorAdapter adapter = bc.getAdapter(); 111 adapter.loadArg(0); 112 adapter.checkCast(Types.PAGE_CONTEXT_IMPL); 113 adapter.push(line); 114 adapter.push(id); 115 adapter.invokeVirtual(Types.PAGE_CONTEXT_IMPL, method); 116 } 117 catch(Throwable t) { 118 t.printStackTrace(); 119 } 120 } 121 122 public static int getStartLine(Statement s){ 123 if(s instanceof StatementBase)return ((StatementBase)s).getStartLine(); 124 if(s instanceof Tag)return ((Tag)s).getStartLine(); 125 return s.getLine(); 126 } 127 128 public static int getEndLine(Statement s){ 129 if(s instanceof StatementBase)return ((StatementBase)s).getEndLine(); 130 if(s instanceof Tag)return ((Tag)s).getEndLine(); 131 return s.getLine(); 132 } 133 134 public static boolean doLog(BytecodeContext bc) { 135 return bc.writeLog() && StringUtil.indexOfIgnoreCase(bc.getMethod().getName(),"call")!=-1; 136 } 137 }