• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.convert;
17 
18 import javassist.CtClass;
19 import javassist.CtMethod;
20 import javassist.NotFoundException;
21 import javassist.bytecode.*;
22 
23 public class TransformBefore extends TransformCall {
24     protected CtClass[] parameterTypes;
25     protected int locals;
26     protected int maxLocals;
27     protected byte[] saveCode, loadCode;
28 
TransformBefore(Transformer next, CtMethod origMethod, CtMethod beforeMethod)29     public TransformBefore(Transformer next,
30                            CtMethod origMethod, CtMethod beforeMethod)
31         throws NotFoundException
32     {
33         super(next, origMethod, beforeMethod);
34 
35         // override
36         methodDescriptor = origMethod.getMethodInfo2().getDescriptor();
37 
38         parameterTypes = origMethod.getParameterTypes();
39         locals = 0;
40         maxLocals = 0;
41         saveCode = loadCode = null;
42     }
43 
initialize(ConstPool cp, CodeAttribute attr)44     public void initialize(ConstPool cp, CodeAttribute attr) {
45         super.initialize(cp, attr);
46         locals = 0;
47         maxLocals = attr.getMaxLocals();
48         saveCode = loadCode = null;
49     }
50 
match(int c, int pos, CodeIterator iterator, int typedesc, ConstPool cp)51     protected int match(int c, int pos, CodeIterator iterator,
52                         int typedesc, ConstPool cp) throws BadBytecode
53     {
54         if (newIndex == 0) {
55             String desc = Descriptor.ofParameters(parameterTypes) + 'V';
56             desc = Descriptor.insertParameter(classname, desc);
57             int nt = cp.addNameAndTypeInfo(newMethodname, desc);
58             int ci = cp.addClassInfo(newClassname);
59             newIndex = cp.addMethodrefInfo(ci, nt);
60             constPool = cp;
61         }
62 
63         if (saveCode == null)
64             makeCode(parameterTypes, cp);
65 
66         return match2(pos, iterator);
67     }
68 
match2(int pos, CodeIterator iterator)69     protected int match2(int pos, CodeIterator iterator) throws BadBytecode {
70         iterator.move(pos);
71         iterator.insert(saveCode);
72         iterator.insert(loadCode);
73         int p = iterator.insertGap(3);
74         iterator.writeByte(INVOKESTATIC, p);
75         iterator.write16bit(newIndex, p + 1);
76         iterator.insert(loadCode);
77         return iterator.next();
78     }
79 
extraLocals()80     public int extraLocals() { return locals; }
81 
makeCode(CtClass[] paramTypes, ConstPool cp)82     protected void makeCode(CtClass[] paramTypes, ConstPool cp) {
83         Bytecode save = new Bytecode(cp, 0, 0);
84         Bytecode load = new Bytecode(cp, 0, 0);
85 
86         int var = maxLocals;
87         int len = (paramTypes == null) ? 0 : paramTypes.length;
88         load.addAload(var);
89         makeCode2(save, load, 0, len, paramTypes, var + 1);
90         save.addAstore(var);
91 
92         saveCode = save.get();
93         loadCode = load.get();
94     }
95 
makeCode2(Bytecode save, Bytecode load, int i, int n, CtClass[] paramTypes, int var)96     private void makeCode2(Bytecode save, Bytecode load,
97                            int i, int n, CtClass[] paramTypes, int var)
98     {
99         if (i < n) {
100             int size = load.addLoad(var, paramTypes[i]);
101             makeCode2(save, load, i + 1, n, paramTypes, var + size);
102             save.addStore(var, paramTypes[i]);
103         }
104         else
105             locals = var - maxLocals;
106     }
107 }
108