• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Javassist, a Java-bytecode translator toolkit.
3  * Copyright (C) 1999-2007 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 TransformNewClass extends Transformer {
23     private int nested;
24     private String classname, newClassName;
25     private int newClassIndex, newMethodNTIndex, newMethodIndex;
26 
TransformNewClass(Transformer next, String classname, String newClassName)27     public TransformNewClass(Transformer next,
28                              String classname, String newClassName) {
29         super(next);
30         this.classname = classname;
31         this.newClassName = newClassName;
32     }
33 
initialize(ConstPool cp, CodeAttribute attr)34     public void initialize(ConstPool cp, CodeAttribute attr) {
35         nested = 0;
36         newClassIndex = newMethodNTIndex = newMethodIndex = 0;
37     }
38 
39     /**
40      * Modifies a sequence of
41      *    NEW classname
42      *    DUP
43      *    ...
44      *    INVOKESPECIAL classname:method
45      */
transform(CtClass clazz, int pos, CodeIterator iterator, ConstPool cp)46     public int transform(CtClass clazz, int pos, CodeIterator iterator,
47                          ConstPool cp) throws CannotCompileException
48     {
49         int index;
50         int c = iterator.byteAt(pos);
51         if (c == NEW) {
52             index = iterator.u16bitAt(pos + 1);
53             if (cp.getClassInfo(index).equals(classname)) {
54                 if (iterator.byteAt(pos + 3) != DUP)
55                     throw new CannotCompileException(
56                                 "NEW followed by no DUP was found");
57 
58                 if (newClassIndex == 0)
59                     newClassIndex = cp.addClassInfo(newClassName);
60 
61                 iterator.write16bit(newClassIndex, pos + 1);
62                 ++nested;
63             }
64         }
65         else if (c == INVOKESPECIAL) {
66             index = iterator.u16bitAt(pos + 1);
67             int typedesc = cp.isConstructor(classname, index);
68             if (typedesc != 0 && nested > 0) {
69                 int nt = cp.getMethodrefNameAndType(index);
70                 if (newMethodNTIndex != nt) {
71                     newMethodNTIndex = nt;
72                     newMethodIndex = cp.addMethodrefInfo(newClassIndex, nt);
73                 }
74 
75                 iterator.write16bit(newMethodIndex, pos + 1);
76                 --nested;
77             }
78         }
79 
80         return pos;
81     }
82 }
83