aboutsummaryrefslogtreecommitdiff
path: root/src/main/javassist/convert/TransformBefore.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/javassist/convert/TransformBefore.java')
-rw-r--r--src/main/javassist/convert/TransformBefore.java107
1 files changed, 107 insertions, 0 deletions
diff --git a/src/main/javassist/convert/TransformBefore.java b/src/main/javassist/convert/TransformBefore.java
new file mode 100644
index 0000000..2ad585f
--- /dev/null
+++ b/src/main/javassist/convert/TransformBefore.java
@@ -0,0 +1,107 @@
+/*
+ * Javassist, a Java-bytecode translator toolkit.
+ * Copyright (C) 1999-2007 Shigeru Chiba. All Rights Reserved.
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. Alternatively, the contents of this file may be used under
+ * the terms of the GNU Lesser General Public License Version 2.1 or later.
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ */
+
+package javassist.convert;
+
+import javassist.CtClass;
+import javassist.CtMethod;
+import javassist.NotFoundException;
+import javassist.bytecode.*;
+
+public class TransformBefore extends TransformCall {
+ protected CtClass[] parameterTypes;
+ protected int locals;
+ protected int maxLocals;
+ protected byte[] saveCode, loadCode;
+
+ public TransformBefore(Transformer next,
+ CtMethod origMethod, CtMethod beforeMethod)
+ throws NotFoundException
+ {
+ super(next, origMethod, beforeMethod);
+
+ // override
+ methodDescriptor = origMethod.getMethodInfo2().getDescriptor();
+
+ parameterTypes = origMethod.getParameterTypes();
+ locals = 0;
+ maxLocals = 0;
+ saveCode = loadCode = null;
+ }
+
+ public void initialize(ConstPool cp, CodeAttribute attr) {
+ super.initialize(cp, attr);
+ locals = 0;
+ maxLocals = attr.getMaxLocals();
+ saveCode = loadCode = null;
+ }
+
+ protected int match(int c, int pos, CodeIterator iterator,
+ int typedesc, ConstPool cp) throws BadBytecode
+ {
+ if (newIndex == 0) {
+ String desc = Descriptor.ofParameters(parameterTypes) + 'V';
+ desc = Descriptor.insertParameter(classname, desc);
+ int nt = cp.addNameAndTypeInfo(newMethodname, desc);
+ int ci = cp.addClassInfo(newClassname);
+ newIndex = cp.addMethodrefInfo(ci, nt);
+ constPool = cp;
+ }
+
+ if (saveCode == null)
+ makeCode(parameterTypes, cp);
+
+ return match2(pos, iterator);
+ }
+
+ protected int match2(int pos, CodeIterator iterator) throws BadBytecode {
+ iterator.move(pos);
+ iterator.insert(saveCode);
+ iterator.insert(loadCode);
+ int p = iterator.insertGap(3);
+ iterator.writeByte(INVOKESTATIC, p);
+ iterator.write16bit(newIndex, p + 1);
+ iterator.insert(loadCode);
+ return iterator.next();
+ }
+
+ public int extraLocals() { return locals; }
+
+ protected void makeCode(CtClass[] paramTypes, ConstPool cp) {
+ Bytecode save = new Bytecode(cp, 0, 0);
+ Bytecode load = new Bytecode(cp, 0, 0);
+
+ int var = maxLocals;
+ int len = (paramTypes == null) ? 0 : paramTypes.length;
+ load.addAload(var);
+ makeCode2(save, load, 0, len, paramTypes, var + 1);
+ save.addAstore(var);
+
+ saveCode = save.get();
+ loadCode = load.get();
+ }
+
+ private void makeCode2(Bytecode save, Bytecode load,
+ int i, int n, CtClass[] paramTypes, int var)
+ {
+ if (i < n) {
+ int size = load.addLoad(var, paramTypes[i]);
+ makeCode2(save, load, i + 1, n, paramTypes, var + size);
+ save.addStore(var, paramTypes[i]);
+ }
+ else
+ locals = var - maxLocals;
+ }
+}