1 15 16 package javassist.expr; 17 18 import javassist.CannotCompileException; 19 import javassist.ClassPool; 20 import javassist.CtBehavior; 21 import javassist.CtClass; 22 import javassist.CtConstructor; 23 import javassist.CtPrimitiveType; 24 import javassist.NotFoundException; 25 import javassist.bytecode.AccessFlag; 26 import javassist.bytecode.BadBytecode; 27 import javassist.bytecode.Bytecode; 28 import javassist.bytecode.ClassFile; 29 import javassist.bytecode.CodeAttribute; 30 import javassist.bytecode.CodeIterator; 31 import javassist.bytecode.ConstPool; 32 import javassist.bytecode.ExceptionTable; 33 import javassist.bytecode.ExceptionsAttribute; 34 import javassist.bytecode.MethodInfo; 35 import javassist.bytecode.Opcode; 36 import javassist.compiler.Javac; 37 38 import java.util.Iterator ; 39 import java.util.LinkedList ; 40 41 44 public abstract class Expr implements Opcode { 45 int currentPos; 46 47 CodeIterator iterator; 48 49 CtClass thisClass; 50 51 MethodInfo thisMethod; 52 53 boolean edited; 54 55 int maxLocals, maxStack; 56 57 static final String javaLangObject = "java.lang.Object"; 58 59 62 protected Expr(int pos, CodeIterator i, CtClass declaring, MethodInfo m) { 63 currentPos = pos; 64 iterator = i; 65 thisClass = declaring; 66 thisMethod = m; 67 } 68 69 protected final ConstPool getConstPool() { 70 return thisMethod.getConstPool(); 71 } 72 73 protected final boolean edited() { 74 return edited; 75 } 76 77 protected final int locals() { 78 return maxLocals; 79 } 80 81 protected final int stack() { 82 return maxStack; 83 } 84 85 88 protected final boolean withinStatic() { 89 return (thisMethod.getAccessFlags() & AccessFlag.STATIC) != 0; 90 } 91 92 95 public CtBehavior where() { 96 MethodInfo mi = thisMethod; 97 CtBehavior[] cb = thisClass.getDeclaredBehaviors(); 98 for (int i = cb.length - 1; i >= 0; --i) 99 if (cb[i].getMethodInfo2() == mi) 100 return cb[i]; 101 102 CtConstructor init = thisClass.getClassInitializer(); 103 if (init != null && init.getMethodInfo2() == mi) 104 return init; 105 106 111 for (int i = cb.length - 1; i >= 0; --i) { 112 if (thisMethod.getName().equals(cb[i].getMethodInfo2().getName()) 113 && thisMethod.getDescriptor() 114 .equals(cb[i].getMethodInfo2().getDescriptor())) { 115 return cb[i]; 116 } 117 } 118 119 throw new RuntimeException ("fatal: not found"); 120 } 121 122 128 public CtClass[] mayThrow() { 129 ClassPool pool = thisClass.getClassPool(); 130 ConstPool cp = thisMethod.getConstPool(); 131 LinkedList list = new LinkedList (); 132 try { 133 CodeAttribute ca = thisMethod.getCodeAttribute(); 134 ExceptionTable et = ca.getExceptionTable(); 135 int pos = currentPos; 136 int n = et.size(); 137 for (int i = 0; i < n; ++i) 138 if (et.startPc(i) <= pos && pos < et.endPc(i)) { 139 int t = et.catchType(i); 140 if (t > 0) 141 try { 142 addClass(list, pool.get(cp.getClassInfo(t))); 143 } 144 catch (NotFoundException e) { 145 } 146 } 147 } 148 catch (NullPointerException e) { 149 } 150 151 ExceptionsAttribute ea = thisMethod.getExceptionsAttribute(); 152 if (ea != null) { 153 String [] exceptions = ea.getExceptions(); 154 if (exceptions != null) { 155 int n = exceptions.length; 156 for (int i = 0; i < n; ++i) 157 try { 158 addClass(list, pool.get(exceptions[i])); 159 } 160 catch (NotFoundException e) { 161 } 162 } 163 } 164 165 return (CtClass[])list.toArray(new CtClass[list.size()]); 166 } 167 168 private static void addClass(LinkedList list, CtClass c) { 169 Iterator it = list.iterator(); 170 while (it.hasNext()) 171 if (it.next() == c) 172 return; 173 174 list.add(c); 175 } 176 177 182 public int indexOfBytecode() { 183 return currentPos; 184 } 185 186 191 public int getLineNumber() { 192 return thisMethod.getLineNumber(currentPos); 193 } 194 195 200 public String getFileName() { 201 ClassFile cf = thisClass.getClassFile2(); 202 if (cf == null) 203 return null; 204 else 205 return cf.getSourceFile(); 206 } 207 208 static final boolean checkResultValue(CtClass retType, String prog) 209 throws CannotCompileException { 210 213 boolean hasIt = (prog.indexOf(Javac.resultVarName) >= 0); 214 if (!hasIt && retType != CtClass.voidType) 215 throw new CannotCompileException( 216 "the resulting value is not stored in " 217 + Javac.resultVarName); 218 219 return hasIt; 220 } 221 222 229 static final void storeStack(CtClass[] params, boolean isStaticCall, 230 int regno, Bytecode bytecode) { 231 storeStack0(0, params.length, params, regno + 1, bytecode); 232 if (isStaticCall) 233 bytecode.addOpcode(ACONST_NULL); 234 235 bytecode.addAstore(regno); 236 } 237 238 private static void storeStack0(int i, int n, CtClass[] params, int regno, 239 Bytecode bytecode) { 240 if (i >= n) 241 return; 242 else { 243 CtClass c = params[i]; 244 int size; 245 if (c instanceof CtPrimitiveType) 246 size = ((CtPrimitiveType)c).getDataSize(); 247 else 248 size = 1; 249 250 storeStack0(i + 1, n, params, regno + size, bytecode); 251 bytecode.addStore(regno, c); 252 } 253 } 254 255 protected void replace0(int pos, Bytecode bytecode, int size) 256 throws BadBytecode { 257 byte[] code = bytecode.get(); 258 edited = true; 259 int gap = code.length - size; 260 for (int i = 0; i < size; ++i) 261 iterator.writeByte(NOP, pos + i); 262 263 if (gap > 0) 264 iterator.insertGap(pos, gap); 265 266 iterator.write(code, pos); 267 iterator.insert(bytecode.getExceptionTable(), pos); 268 maxLocals = bytecode.getMaxLocals(); 269 maxStack = bytecode.getMaxStack(); 270 } 271 } 272 | Popular Tags |