001 package railo.transformer.bytecode; 002 003 import java.util.List; 004 import java.util.Stack; 005 006 import org.objectweb.asm.ClassWriter; 007 import org.objectweb.asm.commons.GeneratorAdapter; 008 import org.objectweb.asm.commons.Method; 009 010 import railo.commons.lang.StringUtil; 011 import railo.transformer.Context; 012 import railo.transformer.bytecode.extern.StringExternalizerWriter; 013 import railo.transformer.bytecode.literal.LitString; 014 import railo.transformer.bytecode.visitor.OnFinally; 015 016 public class BytecodeContext implements Context { 017 018 019 private ClassWriter classWriter; 020 private GeneratorAdapter adapter; 021 private String className; 022 private List<LitString> keys; 023 private int count=0; 024 private Method method; 025 private boolean doSubFunctions=true; 026 private BytecodeContext staticConstr; 027 private BytecodeContext constr; 028 private final boolean supressWSbeforeArg; 029 030 private static long _id=0; 031 private synchronized static String id() { 032 if(_id<0)_id=0; 033 return StringUtil.addZeros(++_id,4); 034 } 035 036 private String id=id(); 037 private Page page; 038 039 public BytecodeContext(BytecodeContext statConstr,BytecodeContext constr,Page page,StringExternalizerWriter externalizer,List<LitString> keys,ClassWriter classWriter,String className, GeneratorAdapter adapter, 040 Method method,boolean writeLog, boolean supressWSbeforeArg) { 041 this.classWriter = classWriter; 042 this.className = className; 043 this.writeLog = writeLog; 044 this.adapter = adapter; 045 this.keys = keys; 046 this.method=method; 047 this.staticConstr=statConstr; 048 this.constr=constr; 049 this.externalizer=externalizer; 050 this.page=page; 051 this.supressWSbeforeArg=supressWSbeforeArg; 052 } 053 054 public BytecodeContext(BytecodeContext statConstr,BytecodeContext constr,List<LitString> keys,BytecodeContext bc, GeneratorAdapter adapter,Method method) { 055 this.classWriter = bc.getClassWriter(); 056 this.className = bc.getClassName(); 057 this.writeLog = bc.writeLog(); 058 this.externalizer=bc.externalizer; 059 060 this.adapter = adapter; 061 this.keys = keys; 062 this.method=method; 063 this.staticConstr=statConstr; 064 this.constr=constr; 065 this.page=bc.getPage(); 066 this.supressWSbeforeArg=bc.supressWSbeforeArg; 067 } 068 069 /** 070 * @return the id 071 */ 072 public String getId() { 073 return id; 074 } 075 076 /** 077 * @return the count 078 */ 079 public int getCount() { 080 return count; 081 } 082 083 /** 084 * @param count the count to set 085 */ 086 public int incCount() { 087 return ++this.count; 088 } 089 public void resetCount() { 090 this.count=0; 091 } 092 /** 093 * @return the adapter 094 */ 095 public GeneratorAdapter getAdapter() { 096 return adapter; 097 } 098 /** 099 * @param adapter the adapter to set 100 */ 101 public void setAdapter(BytecodeContext bc) { 102 this.adapter = bc.getAdapter(); 103 } 104 /** 105 * @return the classWriter 106 */ 107 public ClassWriter getClassWriter() { 108 return classWriter; 109 } 110 /** 111 * @param classWriter the classWriter to set 112 */ 113 public void setClassWriter(ClassWriter classWriter) { 114 this.classWriter = classWriter; 115 } 116 /** 117 * @return the className 118 */ 119 public String getClassName() { 120 return className; 121 } 122 /** 123 * @param className the className to set 124 */ 125 public void setClassName(String className) { 126 this.className = className; 127 } 128 129 public synchronized int registerKey(LitString lit) { 130 int index = keys.indexOf(lit); 131 if(index!=-1)return index;// calls the toString method of litString 132 133 keys.add(lit); 134 135 return keys.size()-1; 136 } 137 138 public List<LitString> getKeys() { 139 return keys; 140 } 141 142 143 Stack<OnFinally> tcf=new Stack<OnFinally>(); 144 private int currentTag; 145 private int line; 146 private BytecodeContext root; 147 private boolean writeLog; 148 private StringExternalizerWriter externalizer; 149 //private static BytecodeContext staticConstr; 150 151 public void pushOnFinally(OnFinally onFinally) { 152 tcf.push(onFinally); 153 } 154 public void popOnFinally() { 155 tcf.pop(); 156 } 157 158 /*public void pushTryCatchFinallyData(TryCatchFinallyData data) { 159 tcf.push(data); 160 } 161 public void popTryCatchFinallyData() { 162 tcf.pop(); 163 }*/ 164 165 public Stack<OnFinally> getOnFinallyStack() { 166 return tcf; 167 } 168 169 /** 170 * @return the method 171 */ 172 public Method getMethod() { 173 return method; 174 } 175 176 /** 177 * @return the doSubFunctions 178 */ 179 public boolean doSubFunctions() { 180 return doSubFunctions; 181 } 182 183 /** 184 * @param doSubFunctions the doSubFunctions to set 185 * @return 186 */ 187 public boolean changeDoSubFunctions(boolean doSubFunctions) { 188 boolean old=this.doSubFunctions; 189 this.doSubFunctions = doSubFunctions; 190 return old; 191 } 192 193 /** 194 * @return the currentTag 195 */ 196 public int getCurrentTag() { 197 return currentTag; 198 } 199 200 /** 201 * @param currentTag the currentTag to set 202 */ 203 public void setCurrentTag(int currentTag) { 204 this.currentTag = currentTag; 205 } 206 207 public BytecodeContext getStaticConstructor() { 208 return staticConstr; 209 } 210 public BytecodeContext getConstructor() { 211 return constr; 212 } 213 214 public void visitLineNumber(int line) { 215 this.line=line; 216 getAdapter().visitLineNumber(line,getAdapter().mark()); 217 } 218 219 public int getLine() { 220 return line; 221 } 222 223 public BytecodeContext getRoot() { 224 return root; 225 } 226 public void setRoot(BytecodeContext root) { 227 this.root= root; 228 } 229 230 public boolean writeLog() { 231 return this.writeLog; 232 } 233 234 public StringExternalizerWriter getStringExternalizerWriter() { 235 return externalizer; 236 } 237 238 public Page getPage() { 239 return page; 240 } 241 242 public boolean getSupressWSbeforeArg(){ 243 return supressWSbeforeArg; 244 } 245 }