1 15 16 package javassist.expr; 17 18 import javassist.*; 19 import javassist.bytecode.*; 20 import javassist.compiler.*; 21 22 25 public class MethodCall extends Expr { 26 29 protected MethodCall(int pos, CodeIterator i, CtClass declaring, 30 MethodInfo m) { 31 super(pos, i, declaring, m); 32 } 33 34 private int getNameAndType(ConstPool cp) { 35 String cname; 36 int pos = currentPos; 37 int c = iterator.byteAt(pos); 38 int index = iterator.u16bitAt(pos + 1); 39 40 if (c == INVOKEINTERFACE) 41 return cp.getInterfaceMethodrefNameAndType(index); 42 else 43 return cp.getMethodrefNameAndType(index); 44 } 45 46 50 public CtBehavior where() { return super.where(); } 51 52 58 public int getLineNumber() { 59 return super.getLineNumber(); 60 } 61 62 67 public String getFileName() { 68 return super.getFileName(); 69 } 70 71 75 private CtClass getCtClass() throws NotFoundException { 76 return thisClass.getClassPool().get(getClassName()); 77 } 78 79 83 public String getClassName() { 84 String cname; 85 86 ConstPool cp = getConstPool(); 87 int pos = currentPos; 88 int c = iterator.byteAt(pos); 89 int index = iterator.u16bitAt(pos + 1); 90 91 if (c == INVOKEINTERFACE) 92 cname = cp.getInterfaceMethodrefClassName(index); 93 else 94 cname = cp.getMethodrefClassName(index); 95 96 return cname; 97 } 98 99 102 public String getMethodName() { 103 ConstPool cp = getConstPool(); 104 int nt = getNameAndType(cp); 105 return cp.getUtf8Info(cp.getNameAndTypeName(nt)); 106 } 107 108 111 public CtMethod getMethod() throws NotFoundException { 112 return getCtClass().getMethod(getMethodName(), getMethodDesc()); 113 } 114 115 private String getMethodDesc() { 116 ConstPool cp = getConstPool(); 117 int nt = getNameAndType(cp); 118 return cp.getUtf8Info(cp.getNameAndTypeDescriptor(nt)); 119 } 120 121 127 public CtClass[] mayThrow() { 128 return super.mayThrow(); 129 } 130 131 135 public boolean isSuper() { 136 return iterator.byteAt(currentPos) == INVOKESPECIAL 137 && !where().getDeclaringClass().getName().equals(getClassName()); 138 } 139 140 148 149 157 158 166 public void replace(String statement) throws CannotCompileException { 167 ConstPool constPool = getConstPool(); 168 int pos = currentPos; 169 int index = iterator.u16bitAt(pos + 1); 170 171 String classname, methodname, signature; 172 int opcodeSize; 173 int c = iterator.byteAt(pos); 174 if (c == INVOKEINTERFACE) { 175 opcodeSize = 5; 176 classname = constPool.getInterfaceMethodrefClassName(index); 177 methodname = constPool.getInterfaceMethodrefName(index); 178 signature = constPool.getInterfaceMethodrefType(index); 179 } 180 else if (c == INVOKESTATIC 181 || c == INVOKESPECIAL || c == INVOKEVIRTUAL) { 182 opcodeSize = 3; 183 classname = constPool.getMethodrefClassName(index); 184 methodname = constPool.getMethodrefName(index); 185 signature = constPool.getMethodrefType(index); 186 } 187 else 188 throw new CannotCompileException("not method invocation"); 189 190 Javac jc = new Javac(thisClass); 191 ClassPool cp = thisClass.getClassPool(); 192 CodeAttribute ca = iterator.get(); 193 try { 194 CtClass[] params = Descriptor.getParameterTypes(signature, cp); 195 CtClass retType = Descriptor.getReturnType(signature, cp); 196 int paramVar = ca.getMaxLocals(); 197 jc.recordParams(classname, params, 198 true, paramVar, withinStatic()); 199 int retVar = jc.recordReturnType(retType, true); 200 if (c == INVOKESTATIC) 201 jc.recordStaticProceed(classname, methodname); 202 else if (c == INVOKESPECIAL) 203 jc.recordSpecialProceed(Javac.param0Name, classname, 204 methodname, signature); 205 else 206 jc.recordProceed(Javac.param0Name, methodname); 207 208 210 checkResultValue(retType, statement); 211 212 Bytecode bytecode = jc.getBytecode(); 213 storeStack(params, c == INVOKESTATIC, paramVar, bytecode); 214 jc.recordLocalVariables(ca, pos); 215 216 if (retType != CtClass.voidType) { 217 bytecode.addConstZero(retType); 218 bytecode.addStore(retVar, retType); } 220 221 jc.compileStmnt(statement); 222 if (retType != CtClass.voidType) 223 bytecode.addLoad(retVar, retType); 224 225 replace0(pos, bytecode, opcodeSize); 226 } 227 catch (CompileError e) { throw new CannotCompileException(e); } 228 catch (NotFoundException e) { throw new CannotCompileException(e); } 229 catch (BadBytecode e) { 230 throw new CannotCompileException("broken method"); 231 } 232 } 233 } 234 | Popular Tags |