169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal/* 269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Javassist, a Java-bytecode translator toolkit. 369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Copyright (C) 1999-2007 Shigeru Chiba. All Rights Reserved. 469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * The contents of this file are subject to the Mozilla Public License Version 669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 1.1 (the "License"); you may not use this file except in compliance with 769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * the License. Alternatively, the contents of this file may be used under 869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * the terms of the GNU Lesser General Public License Version 2.1 or later. 969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 1069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Software distributed under the License is distributed on an "AS IS" basis, 1169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License 1269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * for the specific language governing rights and limitations under the 1369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * License. 1469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 1569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 1669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigalpackage javassist.convert; 1769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 1869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigalimport javassist.bytecode.*; 1969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigalimport javassist.CtClass; 2069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigalimport javassist.CannotCompileException; 2169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 2269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigalfinal public class TransformNewClass extends Transformer { 2369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal private int nested; 2469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal private String classname, newClassName; 2569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal private int newClassIndex, newMethodNTIndex, newMethodIndex; 2669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 2769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public TransformNewClass(Transformer next, 2869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal String classname, String newClassName) { 2969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal super(next); 3069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal this.classname = classname; 3169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal this.newClassName = newClassName; 3269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 3369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 3469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public void initialize(ConstPool cp, CodeAttribute attr) { 3569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal nested = 0; 3669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal newClassIndex = newMethodNTIndex = newMethodIndex = 0; 3769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 3869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 3969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /** 4069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Modifies a sequence of 4169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * NEW classname 4269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * DUP 4369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * ... 4469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * INVOKESPECIAL classname:method 4569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 4669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public int transform(CtClass clazz, int pos, CodeIterator iterator, 4769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal ConstPool cp) throws CannotCompileException 4869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal { 4969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal int index; 5069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal int c = iterator.byteAt(pos); 5169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (c == NEW) { 5269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal index = iterator.u16bitAt(pos + 1); 5369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (cp.getClassInfo(index).equals(classname)) { 5469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (iterator.byteAt(pos + 3) != DUP) 5569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal throw new CannotCompileException( 5669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal "NEW followed by no DUP was found"); 5769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 5869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (newClassIndex == 0) 5969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal newClassIndex = cp.addClassInfo(newClassName); 6069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 6169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal iterator.write16bit(newClassIndex, pos + 1); 6269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal ++nested; 6369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 6469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 6569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal else if (c == INVOKESPECIAL) { 6669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal index = iterator.u16bitAt(pos + 1); 6769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal int typedesc = cp.isConstructor(classname, index); 6869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (typedesc != 0 && nested > 0) { 6969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal int nt = cp.getMethodrefNameAndType(index); 7069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (newMethodNTIndex != nt) { 7169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal newMethodNTIndex = nt; 7269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal newMethodIndex = cp.addMethodrefInfo(newClassIndex, nt); 7369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 7469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 7569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal iterator.write16bit(newMethodIndex, pos + 1); 7669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal --nested; 7769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 7869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 7969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 8069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return pos; 8169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 8269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal} 83