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