Home | History | Annotate | Download | only in javassist
      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;
     17 
     18 import javassist.bytecode.*;
     19 import javassist.CtMethod.ConstParameter;
     20 
     21 class CtNewWrappedConstructor extends CtNewWrappedMethod {
     22     private static final int PASS_NONE = CtNewConstructor.PASS_NONE;
     23     // private static final int PASS_ARRAY = CtNewConstructor.PASS_ARRAY;
     24     private static final int PASS_PARAMS = CtNewConstructor.PASS_PARAMS;
     25 
     26     public static CtConstructor wrapped(CtClass[] parameterTypes,
     27                                         CtClass[] exceptionTypes,
     28                                         int howToCallSuper,
     29                                         CtMethod body,
     30                                         ConstParameter constParam,
     31                                         CtClass declaring)
     32         throws CannotCompileException
     33     {
     34         try {
     35             CtConstructor cons = new CtConstructor(parameterTypes, declaring);
     36             cons.setExceptionTypes(exceptionTypes);
     37             Bytecode code = makeBody(declaring, declaring.getClassFile2(),
     38                                      howToCallSuper, body,
     39                                      parameterTypes, constParam);
     40             cons.getMethodInfo2().setCodeAttribute(code.toCodeAttribute());
     41             return cons;
     42         }
     43         catch (NotFoundException e) {
     44             throw new CannotCompileException(e);
     45         }
     46     }
     47 
     48     protected static Bytecode makeBody(CtClass declaring, ClassFile classfile,
     49                                        int howToCallSuper,
     50                                        CtMethod wrappedBody,
     51                                        CtClass[] parameters,
     52                                        ConstParameter cparam)
     53         throws CannotCompileException
     54     {
     55         int stacksize, stacksize2;
     56 
     57         int superclazz = classfile.getSuperclassId();
     58         Bytecode code = new Bytecode(classfile.getConstPool(), 0, 0);
     59         code.setMaxLocals(false, parameters, 0);
     60         code.addAload(0);
     61         if (howToCallSuper == PASS_NONE) {
     62             stacksize = 1;
     63             code.addInvokespecial(superclazz, "<init>", "()V");
     64         }
     65         else if (howToCallSuper == PASS_PARAMS) {
     66             stacksize = code.addLoadParameters(parameters, 1) + 1;
     67             code.addInvokespecial(superclazz, "<init>",
     68                                   Descriptor.ofConstructor(parameters));
     69         }
     70         else {
     71             stacksize = compileParameterList(code, parameters, 1);
     72             String desc;
     73             if (cparam == null) {
     74                 stacksize2 = 2;
     75                 desc = ConstParameter.defaultConstDescriptor();
     76             }
     77             else {
     78                 stacksize2 = cparam.compile(code) + 2;
     79                 desc = cparam.constDescriptor();
     80             }
     81 
     82             if (stacksize < stacksize2)
     83                 stacksize = stacksize2;
     84 
     85             code.addInvokespecial(superclazz, "<init>", desc);
     86         }
     87 
     88         if (wrappedBody == null)
     89             code.add(Bytecode.RETURN);
     90         else {
     91             stacksize2 = makeBody0(declaring, classfile, wrappedBody,
     92                                    false, parameters, CtClass.voidType,
     93                                    cparam, code);
     94             if (stacksize < stacksize2)
     95                 stacksize = stacksize2;
     96         }
     97 
     98         code.setMaxStack(stacksize);
     99         return code;
    100     }
    101 }
    102