/Users/lyon/j4p/src/javassist/convert/TransformNew.java
|
1 /*
2 * Javassist, a Java-bytecode translator toolkit.
3 * Copyright (C) 1999-2003 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 classname, trapClass, trapMethod;
25
26 public TransformNew(Transformer next,
27 String classname, String trapClass, String 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 int index;
53 int c = iterator.byteAt(pos);
54 if (c == NEW) {
55 index = iterator.u16bitAt(pos + 1);
56 if (cp.getClassInfo(index).equals(classname)) {
57 if (iterator.byteAt(pos + 3) != DUP)
58 throw new CannotCompileException(
59 "NEW followed by no DUP was found");
60
61 iterator.writeByte(NOP, pos);
62 iterator.writeByte(NOP, pos + 1);
63 iterator.writeByte(NOP, pos + 2);
64 iterator.writeByte(NOP, pos + 3);
65 ++nested;
66 }
67 } else if (c == INVOKESPECIAL) {
68 index = iterator.u16bitAt(pos + 1);
69 int typedesc = cp.isConstructor(classname, index);
70 if (typedesc != 0 && nested > 0) {
71 int methodref = computeMethodref(typedesc, cp);
72 iterator.writeByte(INVOKESTATIC, pos);
73 iterator.write16bit(methodref, pos + 1);
74 --nested;
75 }
76 }
77
78 return pos;
79 }
80
81 private int computeMethodref(int typedesc, ConstPool cp) {
82 int classIndex = cp.addClassInfo(trapClass);
83 int mnameIndex = cp.addUtf8Info(trapMethod);
84 typedesc = cp.addUtf8Info(
85 Descriptor.changeReturnType(classname,
86 cp.getUtf8Info(typedesc)));
87 return cp.addMethodrefInfo(classIndex,
88 cp.addNameAndTypeInfo(mnameIndex, typedesc));
89 }
90 }
91