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