01: /*
02: * Javassist, a Java-bytecode translator toolkit.
03: * Copyright (C) 1999-2006 Shigeru Chiba. All Rights Reserved.
04: *
05: * The contents of this file are subject to the Mozilla Public License Version
06: * 1.1 (the "License"); you may not use this file except in compliance with
07: * the License. Alternatively, the contents of this file may be used under
08: * the terms of the GNU Lesser General Public License Version 2.1 or later.
09: *
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, String classname,
27: 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(Descriptor.changeReturnType(
85: classname, cp.getUtf8Info(typedesc)));
86: return cp.addMethodrefInfo(classIndex, cp.addNameAndTypeInfo(
87: mnameIndex, typedesc));
88: }
89: }
|