1 15 16 package javassist.expr; 17 18 import javassist.bytecode.*; 19 import javassist.CtClass; 20 import javassist.CannotCompileException; 21 22 69 public class ExprEditor { 70 73 public ExprEditor() {} 74 75 static class NewOp { 76 NewOp next; 77 int pos; 78 String type; 79 80 NewOp(NewOp n, int p, String t) { 81 next = n; 82 pos = p; 83 type = t; 84 } 85 } 86 87 90 public boolean doit(CtClass clazz, MethodInfo minfo) 91 throws CannotCompileException 92 { 93 CodeAttribute codeAttr = minfo.getCodeAttribute(); 94 if (codeAttr == null) 95 return false; 96 97 CodeIterator iterator = codeAttr.iterator(); 98 boolean edited = false; 99 int maxLocals = codeAttr.getMaxLocals(); 100 int maxStack = 0; 101 102 NewOp newList = null; 103 ConstPool cp = minfo.getConstPool(); 104 105 while (iterator.hasNext()) 106 try { 107 Expr expr = null; 108 int pos = iterator.next(); 109 int c = iterator.byteAt(pos); 110 111 if (c < Opcode.GETSTATIC) ; 113 else if (c < Opcode.NEWARRAY) { if (c == Opcode.INVOKESTATIC 115 || c == Opcode.INVOKEINTERFACE 116 || c == Opcode.INVOKEVIRTUAL) { 117 expr = new MethodCall(pos, iterator, clazz, minfo); 118 edit((MethodCall)expr); 119 } 120 else if (c == Opcode.GETFIELD || c == Opcode.GETSTATIC 121 || c == Opcode.PUTFIELD 122 || c == Opcode.PUTSTATIC) { 123 expr = new FieldAccess(pos, iterator, clazz, minfo, c); 124 edit((FieldAccess)expr); 125 } 126 else if (c == Opcode.NEW) { 127 int index = iterator.u16bitAt(pos + 1); 128 newList = new NewOp(newList, pos, 129 cp.getClassInfo(index)); 130 } 131 else if (c == Opcode.INVOKESPECIAL) { 132 if (newList != null && cp.isConstructor(newList.type, 133 iterator.u16bitAt(pos + 1)) > 0) { 134 expr = new NewExpr(pos, iterator, clazz, minfo, 135 newList.type, newList.pos); 136 edit((NewExpr)expr); 137 newList = newList.next; 138 } 139 else { 140 expr = new MethodCall(pos, iterator, clazz, minfo); 141 MethodCall mcall = (MethodCall)expr; 142 if (!mcall.getMethodName().equals( 143 MethodInfo.nameInit)) 144 edit(mcall); 145 } 146 } 147 } 148 else { if (c == Opcode.NEWARRAY || c == Opcode.ANEWARRAY 150 || c == Opcode.MULTIANEWARRAY) { 151 expr = new NewArray(pos, iterator, clazz, minfo, c); 152 edit((NewArray)expr); 153 } 154 else if (c == Opcode.INSTANCEOF) { 155 expr = new Instanceof(pos, iterator, clazz, minfo); 156 edit((Instanceof)expr); 157 } 158 else if (c == Opcode.CHECKCAST) { 159 expr = new Cast(pos, iterator, clazz, minfo); 160 edit((Cast)expr); 161 } 162 } 163 164 if (expr != null && expr.edited()) { 165 edited = true; 166 maxLocals = max(maxLocals, expr.locals()); 167 maxStack = max(maxStack, expr.stack()); 168 } 169 } 170 catch (BadBytecode e) { 171 throw new CannotCompileException(e); 172 } 173 174 ExceptionTable et = codeAttr.getExceptionTable(); 175 int n = et.size(); 176 for (int i = 0; i < n; ++i) { 177 Handler h = new Handler(et, i, iterator, clazz, minfo); 178 edit(h); 179 if (h.edited()) { 180 edited = true; 181 maxLocals = max(maxLocals, h.locals()); 182 maxStack = max(maxStack, h.stack()); 183 } 184 } 185 186 codeAttr.setMaxLocals(maxLocals); 187 codeAttr.setMaxStack(codeAttr.getMaxStack() + maxStack); 188 return edited; 189 } 190 191 private int max(int i, int j) { 192 return i > j ? i : j; 193 } 194 195 201 public void edit(NewExpr e) throws CannotCompileException {} 202 203 210 public void edit(NewArray a) throws CannotCompileException {} 211 212 216 public void edit(MethodCall m) throws CannotCompileException {} 217 218 223 public void edit(FieldAccess f) throws CannotCompileException {} 224 225 229 public void edit(Instanceof i) throws CannotCompileException {} 230 231 235 public void edit(Cast c) throws CannotCompileException {} 236 237 241 public void edit(Handler h) throws CannotCompileException {} 242 } 243 | Popular Tags |