• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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