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 /src/main/javassist/convert | |
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
Diffstat (limited to 'src/main/javassist/convert')
-rw-r--r-- | src/main/javassist/convert/TransformCall.java | 41 |
1 files changed, 36 insertions, 5 deletions
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 { |