Home | History | Annotate | Download | only in convert
      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 
     27     public TransformNewClass(Transformer next,
     28                              String classname, String newClassName) {
     29         super(next);
     30         this.classname = classname;
     31         this.newClassName = newClassName;
     32     }
     33 
     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      */
     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