001: /*
002: * Javassist, a Java-bytecode translator toolkit.
003: * Copyright (C) 1999-2006 Shigeru Chiba. All Rights Reserved.
004: *
005: * The contents of this file are subject to the Mozilla Public License Version
006: * 1.1 (the "License"); you may not use this file except in compliance with
007: * the License. Alternatively, the contents of this file may be used under
008: * the terms of the GNU Lesser General Public License Version 2.1 or later.
009: *
010: * Software distributed under the License is distributed on an "AS IS" basis,
011: * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
012: * for the specific language governing rights and limitations under the
013: * License.
014: */
015:
016: package javassist.convert;
017:
018: import javassist.CtClass;
019: import javassist.CtMethod;
020: import javassist.NotFoundException;
021: import javassist.bytecode.*;
022:
023: public class TransformBefore extends TransformCall {
024: protected CtClass[] parameterTypes;
025: protected int locals;
026: protected int maxLocals;
027: protected byte[] saveCode, loadCode;
028:
029: public TransformBefore(Transformer next, CtMethod origMethod,
030: CtMethod beforeMethod) throws NotFoundException {
031: super (next, origMethod, beforeMethod);
032: parameterTypes = origMethod.getParameterTypes();
033: locals = 0;
034: maxLocals = 0;
035: saveCode = loadCode = null;
036: }
037:
038: public void initialize(ConstPool cp, CodeAttribute attr) {
039: super .initialize(cp, attr);
040: locals = 0;
041: maxLocals = attr.getMaxLocals();
042: saveCode = loadCode = null;
043: }
044:
045: protected int match(int c, int pos, CodeIterator iterator,
046: int typedesc, ConstPool cp) throws BadBytecode {
047: if (newIndex == 0) {
048: String desc = Descriptor.ofParameters(parameterTypes) + 'V';
049: desc = Descriptor.insertParameter(classname, desc);
050: int nt = cp.addNameAndTypeInfo(newMethodname, desc);
051: int ci = cp.addClassInfo(newClassname);
052: newIndex = cp.addMethodrefInfo(ci, nt);
053: constPool = cp;
054: }
055:
056: if (saveCode == null)
057: makeCode(parameterTypes, cp);
058:
059: return match2(pos, iterator);
060: }
061:
062: protected int match2(int pos, CodeIterator iterator)
063: throws BadBytecode {
064: iterator.move(pos);
065: iterator.insert(saveCode);
066: iterator.insert(loadCode);
067: int p = iterator.insertGap(3);
068: iterator.writeByte(INVOKESTATIC, p);
069: iterator.write16bit(newIndex, p + 1);
070: iterator.insert(loadCode);
071: return iterator.next();
072: }
073:
074: public int extraLocals() {
075: return locals;
076: }
077:
078: protected void makeCode(CtClass[] paramTypes, ConstPool cp) {
079: Bytecode save = new Bytecode(cp, 0, 0);
080: Bytecode load = new Bytecode(cp, 0, 0);
081:
082: int var = maxLocals;
083: int len = (paramTypes == null) ? 0 : paramTypes.length;
084: load.addAload(var);
085: makeCode2(save, load, 0, len, paramTypes, var + 1);
086: save.addAstore(var);
087:
088: saveCode = save.get();
089: loadCode = load.get();
090: }
091:
092: private void makeCode2(Bytecode save, Bytecode load, int i, int n,
093: CtClass[] paramTypes, int var) {
094: if (i < n) {
095: int size = load.addLoad(var, paramTypes[i]);
096: makeCode2(save, load, i + 1, n, paramTypes, var + size);
097: save.addStore(var, paramTypes[i]);
098: } else
099: locals = var - maxLocals;
100: }
101: }
|