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
16package javassist;
17
18import javassist.bytecode.*;
19import javassist.CtMethod.ConstParameter;
20
21class 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