KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > javassist > convert > TransformNew


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.bytecode.*;
19 import javassist.CtClass;
20 import javassist.CannotCompileException;
21
22 final public class TransformNew extends Transformer {
23     private int nested;
24     private String JavaDoc classname, trapClass, trapMethod;
25
26     public TransformNew(Transformer next,
27                  String JavaDoc classname, String JavaDoc trapClass, String JavaDoc trapMethod) {
28         super(next);
29         this.classname = classname;
30         this.trapClass = trapClass;
31         this.trapMethod = trapMethod;
32     }
33
34     public void initialize(ConstPool cp, CodeAttribute attr) {
35         nested = 0;
36     }
37
38     /**
39      * Replace a sequence of
40      * NEW classname
41      * DUP
42      * ...
43      * INVOKESPECIAL
44      * with
45      * NOP
46      * NOP
47      * ...
48      * INVOKESTATIC trapMethod in trapClass
49      */

50     public int transform(CtClass clazz, int pos, CodeIterator iterator,
51                          ConstPool cp) throws CannotCompileException
52     {
53         int index;
54         int c = iterator.byteAt(pos);
55         if (c == NEW) {
56             index = iterator.u16bitAt(pos + 1);
57             if (cp.getClassInfo(index).equals(classname)) {
58                 if (iterator.byteAt(pos + 3) != DUP)
59                     throw new CannotCompileException(
60                                 "NEW followed by no DUP was found");
61
62                 iterator.writeByte(NOP, pos);
63                 iterator.writeByte(NOP, pos + 1);
64                 iterator.writeByte(NOP, pos + 2);
65                 iterator.writeByte(NOP, pos + 3);
66                 ++nested;
67             }
68         }
69         else if (c == INVOKESPECIAL) {
70             index = iterator.u16bitAt(pos + 1);
71             int typedesc = cp.isConstructor(classname, index);
72             if (typedesc != 0 && nested > 0) {
73                 int methodref = computeMethodref(typedesc, cp);
74                 iterator.writeByte(INVOKESTATIC, pos);
75                 iterator.write16bit(methodref, pos + 1);
76                 --nested;
77             }
78         }
79
80         return pos;
81     }
82
83     private int computeMethodref(int typedesc, ConstPool cp) {
84         int classIndex = cp.addClassInfo(trapClass);
85         int mnameIndex = cp.addUtf8Info(trapMethod);
86         typedesc = cp.addUtf8Info(
87                 Descriptor.changeReturnType(classname,
88                                             cp.getUtf8Info(typedesc)));
89         return cp.addMethodrefInfo(classIndex,
90                         cp.addNameAndTypeInfo(mnameIndex, typedesc));
91     }
92 }
93
Popular Tags