KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > javassist > convert > TransformCall


1 /*
2  * Javassist, a Java-bytecode translator toolkit.
3  * Copyright (C) 1999-2005 Shigeru Chiba. All Rights Reserved.
4  *
5  * The contents of this file are subject to the Mozilla Public License Version
6  * 1.1 (the "License"); you may not use this file except in compliance with
7  * the License. Alternatively, the contents of this file may be used under
8  * the terms of the GNU Lesser General Public License Version 2.1 or later.
9  *
10  * Software distributed under the License is distributed on an "AS IS" basis,
11  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12  * for the specific language governing rights and limitations under the
13  * License.
14  */

15
16 package javassist.convert;
17
18 import javassist.CtClass;
19 import javassist.CtMethod;
20 import javassist.bytecode.*;
21
22 public class TransformCall extends Transformer {
23     protected String JavaDoc classname, methodname, methodDescriptor;
24     protected String JavaDoc newClassname, newMethodname;
25
26     /* cache */
27     protected int newIndex;
28     protected ConstPool constPool;
29
30     public TransformCall(Transformer next, CtMethod origMethod,
31                          CtMethod substMethod)
32     {
33         super(next);
34         this.classname = origMethod.getDeclaringClass().getName();
35         this.methodname = origMethod.getName();
36         this.methodDescriptor = origMethod.getMethodInfo2().getDescriptor();
37         this.newClassname = substMethod.getDeclaringClass().getName();
38         this.newMethodname = substMethod.getName();
39         this.constPool = null;
40     }
41
42     public void initialize(ConstPool cp, CodeAttribute attr) {
43         if (constPool != cp)
44             newIndex = 0;
45     }
46
47     /**
48      * Modify INVOKEINTERFACE, INVOKESPECIAL, INVOKESTATIC and INVOKEVIRTUAL
49      * so that a different method is invoked.
50      */

51     public int transform(CtClass clazz, int pos, CodeIterator iterator,
52                          ConstPool cp) throws BadBytecode
53     {
54         int c = iterator.byteAt(pos);
55         if (c == INVOKEINTERFACE || c == INVOKESPECIAL
56                         || c == INVOKESTATIC || c == INVOKEVIRTUAL) {
57             int index = iterator.u16bitAt(pos + 1);
58             int typedesc = cp.isMember(classname, methodname, index);
59             if (typedesc != 0)
60                 if (cp.getUtf8Info(typedesc).equals(methodDescriptor))
61                     pos = match(c, pos, iterator, typedesc, cp);
62         }
63
64         return pos;
65     }
66
67     protected int match(int c, int pos, CodeIterator iterator,
68                         int typedesc, ConstPool cp) throws BadBytecode
69     {
70         if (newIndex == 0) {
71             int nt = cp.addNameAndTypeInfo(cp.addUtf8Info(newMethodname),
72                                            typedesc);
73             int ci = cp.addClassInfo(newClassname);
74             if (c == INVOKEINTERFACE)
75                 newIndex = cp.addInterfaceMethodrefInfo(ci, nt);
76             else
77                 newIndex = cp.addMethodrefInfo(ci, nt);
78
79             constPool = cp;
80         }
81
82         iterator.write16bit(newIndex, pos + 1);
83         return pos;
84     }
85 }
86
Popular Tags