1 /* 2 * Javassist, a Java-bytecode translator toolkit. 3 * Copyright (C) 1999- 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 * or the Apache License Version 2.0. 10 * 11 * Software distributed under the License is distributed on an "AS IS" basis, 12 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License 13 * for the specific language governing rights and limitations under the 14 * License. 15 */ 16 17 package javassist; 18 19 import javassist.CtMethod.ConstParameter; 20 import javassist.bytecode.Bytecode; 21 import javassist.bytecode.ClassFile; 22 import javassist.bytecode.Descriptor; 23 24 class CtNewWrappedConstructor extends CtNewWrappedMethod { 25 private static final int PASS_NONE = CtNewConstructor.PASS_NONE; 26 // private static final int PASS_ARRAY = CtNewConstructor.PASS_ARRAY; 27 private static final int PASS_PARAMS = CtNewConstructor.PASS_PARAMS; 28 wrapped(CtClass[] parameterTypes, CtClass[] exceptionTypes, int howToCallSuper, CtMethod body, ConstParameter constParam, CtClass declaring)29 public static CtConstructor wrapped(CtClass[] parameterTypes, 30 CtClass[] exceptionTypes, 31 int howToCallSuper, 32 CtMethod body, 33 ConstParameter constParam, 34 CtClass declaring) 35 throws CannotCompileException 36 { 37 try { 38 CtConstructor cons = new CtConstructor(parameterTypes, declaring); 39 cons.setExceptionTypes(exceptionTypes); 40 Bytecode code = makeBody(declaring, declaring.getClassFile2(), 41 howToCallSuper, body, 42 parameterTypes, constParam); 43 cons.getMethodInfo2().setCodeAttribute(code.toCodeAttribute()); 44 // a stack map table is not needed. 45 return cons; 46 } 47 catch (NotFoundException e) { 48 throw new CannotCompileException(e); 49 } 50 } 51 makeBody(CtClass declaring, ClassFile classfile, int howToCallSuper, CtMethod wrappedBody, CtClass[] parameters, ConstParameter cparam)52 protected static Bytecode makeBody(CtClass declaring, ClassFile classfile, 53 int howToCallSuper, 54 CtMethod wrappedBody, 55 CtClass[] parameters, 56 ConstParameter cparam) 57 throws CannotCompileException 58 { 59 int stacksize, stacksize2; 60 61 int superclazz = classfile.getSuperclassId(); 62 Bytecode code = new Bytecode(classfile.getConstPool(), 0, 0); 63 code.setMaxLocals(false, parameters, 0); 64 code.addAload(0); 65 if (howToCallSuper == PASS_NONE) { 66 stacksize = 1; 67 code.addInvokespecial(superclazz, "<init>", "()V"); 68 } 69 else if (howToCallSuper == PASS_PARAMS) { 70 stacksize = code.addLoadParameters(parameters, 1) + 1; 71 code.addInvokespecial(superclazz, "<init>", 72 Descriptor.ofConstructor(parameters)); 73 } 74 else { 75 stacksize = compileParameterList(code, parameters, 1); 76 String desc; 77 if (cparam == null) { 78 stacksize2 = 2; 79 desc = ConstParameter.defaultConstDescriptor(); 80 } 81 else { 82 stacksize2 = cparam.compile(code) + 2; 83 desc = cparam.constDescriptor(); 84 } 85 86 if (stacksize < stacksize2) 87 stacksize = stacksize2; 88 89 code.addInvokespecial(superclazz, "<init>", desc); 90 } 91 92 if (wrappedBody == null) 93 code.add(Bytecode.RETURN); 94 else { 95 stacksize2 = makeBody0(declaring, classfile, wrappedBody, 96 false, parameters, CtClass.voidType, 97 cparam, code); 98 if (stacksize < stacksize2) 99 stacksize = stacksize2; 100 } 101 102 code.setMaxStack(stacksize); 103 return code; 104 } 105 } 106