diff options
author | chiba <chiba@30ef5769-5b8d-40dd-aea6-55b5d6557bb3> | 2007-07-19 10:21:26 +0000 |
---|---|---|
committer | chiba <chiba@30ef5769-5b8d-40dd-aea6-55b5d6557bb3> | 2007-07-19 10:21:26 +0000 |
commit | 8dac8e2ce448d7f1d79e1fe9de71b551d62b0a63 (patch) | |
tree | 3c6166df7cea09d58c7ff021f24a70b2abe40fc2 | |
parent | 82e918f2e4d778e8de26f76da73275fce226e366 (diff) | |
download | javassist-8dac8e2ce448d7f1d79e1fe9de71b551d62b0a63.tar.gz javassist-8dac8e2ce448d7f1d79e1fe9de71b551d62b0a63.zip |
modified redirectMethodCall() in CodeConverter
git-svn-id: http://anonsvn.jboss.org/repos/javassist/trunk@397 30ef5769-5b8d-40dd-aea6-55b5d6557bb3
-rw-r--r-- | src/main/javassist/bytecode/ConstPool.java | 58 | ||||
-rw-r--r-- | src/main/javassist/convert/TransformCall.java | 41 |
2 files changed, 93 insertions, 6 deletions
diff --git a/src/main/javassist/bytecode/ConstPool.java b/src/main/javassist/bytecode/ConstPool.java index 2b2348e8..7ac8dc2f 100644 --- a/src/main/javassist/bytecode/ConstPool.java +++ b/src/main/javassist/bytecode/ConstPool.java @@ -207,6 +207,34 @@ public final class ConstPool { /** * Reads the <code>class_index</code> field of the + * <code>CONSTANT_Fieldref_info</code>, + * <code>CONSTANT_Methodref_info</code>, + * or <code>CONSTANT_Interfaceref_info</code>, + * structure at the given index. + * + * @since 3.6 + */ + public int getMemberClass(int index) { + MemberrefInfo minfo = (MemberrefInfo)getItem(index); + return minfo.classIndex; + } + + /** + * Reads the <code>name_and_type_index</code> field of the + * <code>CONSTANT_Fieldref_info</code>, + * <code>CONSTANT_Methodref_info</code>, + * or <code>CONSTANT_Interfaceref_info</code>, + * structure at the given index. + * + * @since 3.6 + */ + public int getMemberNameAndType(int index) { + MemberrefInfo minfo = (MemberrefInfo)getItem(index); + return minfo.nameAndTypeIndex; + } + + /** + * Reads the <code>class_index</code> field of the * <code>CONSTANT_Fieldref_info</code> structure * at the given index. */ @@ -274,7 +302,7 @@ public final class ConstPool { if (f == null) return null; else { - NameAndTypeInfo n = (NameAndTypeInfo) getItem(f.nameAndTypeIndex); + NameAndTypeInfo n = (NameAndTypeInfo)getItem(f.nameAndTypeIndex); if(n == null) return null; else @@ -579,6 +607,34 @@ public final class ConstPool { return 0; // false } + /** + * Determines whether <code>CONSTANT_Methodref_info</code>, + * <code>CONSTANT_Fieldref_info</code>, or + * <code>CONSTANT_InterfaceMethodref_info</code> structure + * at the given index has the name and the descriptor + * given as the arguments. + * + * @param membername the member name + * @param desc the descriptor of the member. + * @param index the index into the constant pool table + * + * @return the name of the target class specified by + * the <code>..._info</code> structure + * at <code>index</code>. + * Otherwise, null if that structure does not + * match the given member name and descriptor. + */ + public String eqMember(String membername, String desc, int index) { + MemberrefInfo minfo = (MemberrefInfo)getItem(index); + NameAndTypeInfo ntinfo + = (NameAndTypeInfo)getItem(minfo.nameAndTypeIndex); + if (getUtf8Info(ntinfo.memberName).equals(membername) + && getUtf8Info(ntinfo.typeDescriptor).equals(desc)) + return getClassInfo(minfo.classIndex); + else + return null; // false + } + private int addItem(ConstInfo info) { items.addElement(info); return numOfItems++; diff --git a/src/main/javassist/convert/TransformCall.java b/src/main/javassist/convert/TransformCall.java index bfa81cb3..fb8395ee 100644 --- a/src/main/javassist/convert/TransformCall.java +++ b/src/main/javassist/convert/TransformCall.java @@ -17,7 +17,9 @@ package javassist.convert; import javassist.CtClass; import javassist.CtMethod; +import javassist.ClassPool; import javassist.Modifier; +import javassist.NotFoundException; import javassist.bytecode.*; public class TransformCall extends Transformer { @@ -55,7 +57,10 @@ public class TransformCall extends Transformer { /** * Modify INVOKEINTERFACE, INVOKESPECIAL, INVOKESTATIC and INVOKEVIRTUAL - * so that a different method is invoked. + * so that a different method is invoked. The class name in the operand + * of these instructions might be a subclass of the target class specified + * by <code>classname</code>. This method transforms the instruction + * in that case unless the subclass overrides the target method. */ public int transform(CtClass clazz, int pos, CodeIterator iterator, ConstPool cp) throws BadBytecode @@ -64,15 +69,41 @@ public class TransformCall extends Transformer { if (c == INVOKEINTERFACE || c == INVOKESPECIAL || c == INVOKESTATIC || c == INVOKEVIRTUAL) { int index = iterator.u16bitAt(pos + 1); - int typedesc = cp.isMember(classname, methodname, index); - if (typedesc != 0) - if (cp.getUtf8Info(typedesc).equals(methodDescriptor)) - pos = match(c, pos, iterator, typedesc, cp); + String cname = cp.eqMember(methodname, methodDescriptor, index); + if (cname != null && matchClass(cname, clazz.getClassPool())) { + int ntinfo = cp.getMemberNameAndType(index); + pos = match(c, pos, iterator, + cp.getNameAndTypeDescriptor(ntinfo), cp); + } } return pos; } + private boolean matchClass(String name, ClassPool pool) { + if (classname.equals(name)) + return true; + + try { + CtClass clazz = pool.get(name); + CtClass declClazz = pool.get(classname); + if (clazz.subtypeOf(declClazz)) + try { + CtMethod m = clazz.getMethod(methodname, methodDescriptor); + return m.getDeclaringClass().getName().equals(classname); + } + catch (NotFoundException e) { + // maybe the original method has been removed. + return true; + } + } + catch (NotFoundException e) { + return false; + } + + return false; + } + protected int match(int c, int pos, CodeIterator iterator, int typedesc, ConstPool cp) throws BadBytecode { |