You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tapestry.apache.org by hl...@apache.org on 2012/05/30 21:20:36 UTC
[3/17] TAP5-1852: Upgrade Plastic to use ASM 4.0 - Remove unused
utility classes
http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/d6e5f413/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/MethodVisitor.java
----------------------------------------------------------------------
diff --git a/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/MethodVisitor.java b/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/MethodVisitor.java
index 17b6fae..f0676b7 100644
--- a/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/MethodVisitor.java
+++ b/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/MethodVisitor.java
@@ -1,6 +1,6 @@
/***
* ASM: a very small and fast Java bytecode manipulation framework
- * Copyright (c) 2000-2007 INRIA, France Telecom
+ * Copyright (c) 2000-2011 INRIA, France Telecom
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -30,12 +30,12 @@
package org.apache.tapestry5.internal.plastic.asm;
/**
- * A visitor to visit a Java method. The methods of this interface must be
+ * A visitor to visit a Java method. The methods of this class must be
* called in the following order: [ <tt>visitAnnotationDefault</tt> ] (
* <tt>visitAnnotation</tt> | <tt>visitParameterAnnotation</tt> |
* <tt>visitAttribute</tt> )* [ <tt>visitCode</tt> ( <tt>visitFrame</tt> |
* <tt>visit</tt><i>X</i>Insn</tt> | <tt>visitLabel</tt> | <tt>visitTryCatchBlock</tt> |
- * <tt>visitLocalVariable</tt> | <tt>visitLineNumber</tt>)* <tt>visitMaxs</tt> ]
+ * <tt>visitLocalVariable</tt> | <tt>visitLineNumber</tt> )* <tt>visitMaxs</tt> ]
* <tt>visitEnd</tt>. In addition, the <tt>visit</tt><i>X</i>Insn</tt>
* and <tt>visitLabel</tt> methods must be called in the sequential order of
* the bytecode instructions of the visited code, <tt>visitTryCatchBlock</tt>
@@ -43,10 +43,48 @@ package org.apache.tapestry5.internal.plastic.asm;
* visited, and the <tt>visitLocalVariable</tt> and <tt>visitLineNumber</tt>
* methods must be called <i>after</i> the labels passed as arguments have been
* visited.
- *
+ *
* @author Eric Bruneton
*/
-public interface MethodVisitor {
+public abstract class MethodVisitor {
+
+ /**
+ * The ASM API version implemented by this visitor. The value of this field
+ * must be one of {@link Opcodes#ASM4}.
+ */
+ protected final int api;
+
+ /**
+ * The method visitor to which this visitor must delegate method calls. May
+ * be null.
+ */
+ protected MethodVisitor mv;
+
+ /**
+ * Constructs a new {@link MethodVisitor}.
+ *
+ * @param api the ASM API version implemented by this visitor. Must be one
+ * of {@link Opcodes#ASM4}.
+ */
+ public MethodVisitor(final int api) {
+ this(api, null);
+ }
+
+ /**
+ * Constructs a new {@link MethodVisitor}.
+ *
+ * @param api the ASM API version implemented by this visitor. Must be one
+ * of {@link Opcodes#ASM4}.
+ * @param mv the method visitor to which this visitor must delegate method
+ * calls. May be null.
+ */
+ public MethodVisitor(final int api, final MethodVisitor mv) {
+ /*if (api != Opcodes.ASM4) {
+ throw new IllegalArgumentException();
+ }*/
+ this.api = api;
+ this.mv = mv;
+ }
// -------------------------------------------------------------------------
// Annotations and non standard attributes
@@ -54,7 +92,7 @@ public interface MethodVisitor {
/**
* Visits the default value of this annotation interface method.
- *
+ *
* @return a visitor to the visit the actual default value of this
* annotation interface method, or <tt>null</tt> if this visitor
* is not interested in visiting this default value. The 'name'
@@ -62,43 +100,67 @@ public interface MethodVisitor {
* ignored. Moreover, exacly one visit method must be called on this
* annotation visitor, followed by visitEnd.
*/
- AnnotationVisitor visitAnnotationDefault();
+ public AnnotationVisitor visitAnnotationDefault() {
+ if (mv != null) {
+ return mv.visitAnnotationDefault();
+ }
+ return null;
+ }
/**
* Visits an annotation of this method.
- *
+ *
* @param desc the class descriptor of the annotation class.
* @param visible <tt>true</tt> if the annotation is visible at runtime.
* @return a visitor to visit the annotation values, or <tt>null</tt> if
* this visitor is not interested in visiting this annotation.
*/
- AnnotationVisitor visitAnnotation(String desc, boolean visible);
+ public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
+ if (mv != null) {
+ return mv.visitAnnotation(desc, visible);
+ }
+ return null;
+ }
/**
* Visits an annotation of a parameter this method.
- *
+ *
* @param parameter the parameter index.
* @param desc the class descriptor of the annotation class.
* @param visible <tt>true</tt> if the annotation is visible at runtime.
* @return a visitor to visit the annotation values, or <tt>null</tt> if
* this visitor is not interested in visiting this annotation.
*/
- AnnotationVisitor visitParameterAnnotation(
+ public AnnotationVisitor visitParameterAnnotation(
int parameter,
String desc,
- boolean visible);
+ boolean visible)
+ {
+ if (mv != null) {
+ return mv.visitParameterAnnotation(parameter, desc, visible);
+ }
+ return null;
+ }
/**
* Visits a non standard attribute of this method.
- *
+ *
* @param attr an attribute.
*/
- void visitAttribute(Attribute attr);
+ public void visitAttribute(Attribute attr) {
+ if (mv != null) {
+ mv.visitAttribute(attr);
+ }
+ }
/**
* Starts the visit of the method's code, if any (i.e. non abstract method).
*/
- void visitCode();
+ public void visitCode() {
+ if (mv != null) {
+ mv.visitCode();
+ }
+ }
/**
* Visits the current state of the local variables and operand stack
@@ -126,7 +188,7 @@ public interface MethodVisitor {
* locals are absent and with the empty stack (<code>nLocals</code> is 1,
* 2 or 3). </li> <li>{@link Opcodes#F_FULL} representing complete frame
* data.</li> </li> </ul>
- *
+ *
* @param type the type of this stack map frame. Must be
* {@link Opcodes#F_NEW} for expanded frames, or
* {@link Opcodes#F_FULL}, {@link Opcodes#F_APPEND},
@@ -141,22 +203,27 @@ public interface MethodVisitor {
* {@link Opcodes#DOUBLE},{@link Opcodes#NULL} or
* {@link Opcodes#UNINITIALIZED_THIS} (long and double are
* represented by a single element). Reference types are represented
- * by String objects (representing internal names), and uninitialized
- * types by Label objects (this label designates the NEW instruction
+ * by String objects (representing internal names), and uninitialized
+ * types by Label objects (this label designates the NEW instruction
* that created this uninitialized value).
* @param nStack the number of operand stack elements in the visited frame.
* @param stack the operand stack types in this frame. This array must not
* be modified. Its content has the same format as the "local" array.
- * @throw IllegalStateException if a frame is visited just after another
+ * @throws IllegalStateException if a frame is visited just after another
* one, without any instruction between the two (unless this frame
* is a Opcodes#F_SAME frame, in which case it is silently ignored).
*/
- void visitFrame(
+ public void visitFrame(
int type,
int nLocal,
Object[] local,
int nStack,
- Object[] stack);
+ Object[] stack)
+ {
+ if (mv != null) {
+ mv.visitFrame(type, nLocal, local, nStack, stack);
+ }
+ }
// -------------------------------------------------------------------------
// Normal instructions
@@ -164,7 +231,7 @@ public interface MethodVisitor {
/**
* Visits a zero operand instruction.
- *
+ *
* @param opcode the opcode of the instruction to be visited. This opcode is
* either NOP, ACONST_NULL, ICONST_M1, ICONST_0, ICONST_1, ICONST_2,
* ICONST_3, ICONST_4, ICONST_5, LCONST_0, LCONST_1, FCONST_0,
@@ -180,11 +247,15 @@ public interface MethodVisitor {
* FRETURN, DRETURN, ARETURN, RETURN, ARRAYLENGTH, ATHROW,
* MONITORENTER, or MONITOREXIT.
*/
- void visitInsn(int opcode);
+ public void visitInsn(int opcode) {
+ if (mv != null) {
+ mv.visitInsn(opcode);
+ }
+ }
/**
* Visits an instruction with a single int operand.
- *
+ *
* @param opcode the opcode of the instruction to be visited. This opcode is
* either BIPUSH, SIPUSH or NEWARRAY.
* @param operand the operand of the instruction to be visited.<br> When
@@ -197,36 +268,48 @@ public interface MethodVisitor {
* {@link Opcodes#T_BYTE}, {@link Opcodes#T_SHORT},
* {@link Opcodes#T_INT} or {@link Opcodes#T_LONG}.
*/
- void visitIntInsn(int opcode, int operand);
+ public void visitIntInsn(int opcode, int operand) {
+ if (mv != null) {
+ mv.visitIntInsn(opcode, operand);
+ }
+ }
/**
* Visits a local variable instruction. A local variable instruction is an
* instruction that loads or stores the value of a local variable.
- *
+ *
* @param opcode the opcode of the local variable instruction to be visited.
* This opcode is either ILOAD, LLOAD, FLOAD, DLOAD, ALOAD, ISTORE,
* LSTORE, FSTORE, DSTORE, ASTORE or RET.
* @param var the operand of the instruction to be visited. This operand is
* the index of a local variable.
*/
- void visitVarInsn(int opcode, int var);
+ public void visitVarInsn(int opcode, int var) {
+ if (mv != null) {
+ mv.visitVarInsn(opcode, var);
+ }
+ }
/**
* Visits a type instruction. A type instruction is an instruction that
* takes the internal name of a class as parameter.
- *
+ *
* @param opcode the opcode of the type instruction to be visited. This
* opcode is either NEW, ANEWARRAY, CHECKCAST or INSTANCEOF.
* @param type the operand of the instruction to be visited. This operand
- * must be the internal name of an object or array class (see {@link
+ * must be the internal name of an object or array class (see {@link
* Type#getInternalName() getInternalName}).
*/
- void visitTypeInsn(int opcode, String type);
+ public void visitTypeInsn(int opcode, String type) {
+ if (mv != null) {
+ mv.visitTypeInsn(opcode, type);
+ }
+ }
/**
* Visits a field instruction. A field instruction is an instruction that
* loads or stores the value of a field of an object.
- *
+ *
* @param opcode the opcode of the type instruction to be visited. This
* opcode is either GETSTATIC, PUTSTATIC, GETFIELD or PUTFIELD.
* @param owner the internal name of the field's owner class (see {@link
@@ -234,27 +317,52 @@ public interface MethodVisitor {
* @param name the field's name.
* @param desc the field's descriptor (see {@link Type Type}).
*/
- void visitFieldInsn(int opcode, String owner, String name, String desc);
+ public void visitFieldInsn(int opcode, String owner, String name, String desc) {
+ if (mv != null) {
+ mv.visitFieldInsn(opcode, owner, name, desc);
+ }
+ }
/**
* Visits a method instruction. A method instruction is an instruction that
* invokes a method.
- *
+ *
* @param opcode the opcode of the type instruction to be visited. This
- * opcode is either INVOKEVIRTUAL, INVOKESPECIAL, INVOKESTATIC,
- * INVOKEINTERFACE or INVOKEDYNAMIC.
+ * opcode is either INVOKEVIRTUAL, INVOKESPECIAL, INVOKESTATIC
+ * or INVOKEINTERFACE.
* @param owner the internal name of the method's owner class (see {@link
- * Type#getInternalName() getInternalName})
- * or {@link org.apache.tapestry5.internal.plastic.asm.Opcodes#INVOKEDYNAMIC_OWNER}.
+ * Type#getInternalName() getInternalName}).
+ * @param name the method's name.
+ * @param desc the method's descriptor (see {@link Type Type}).
+ */
+ public void visitMethodInsn(int opcode, String owner, String name, String desc) {
+ if (mv != null) {
+ mv.visitMethodInsn(opcode, owner, name, desc);
+ }
+ }
+
+ /**
+ * Visits an invokedynamic instruction.
+ *
* @param name the method's name.
* @param desc the method's descriptor (see {@link Type Type}).
+ * @param bsm the bootstrap method.
+ * @param bsmArgs the bootstrap method constant arguments. Each argument
+ * must be an {@link Integer}, {@link Float}, {@link Long},
+ * {@link Double}, {@link String}, {@link Type} or {@link Handle}
+ * value. This method is allowed to modify the content of the array
+ * so a caller should expect that this array may change.
*/
- void visitMethodInsn(int opcode, String owner, String name, String desc);
+ public void visitInvokeDynamicInsn(String name, String desc, Handle bsm, Object... bsmArgs) {
+ if (mv != null) {
+ mv.visitInvokeDynamicInsn(name, desc, bsm, bsmArgs);
+ }
+ }
/**
* Visits a jump instruction. A jump instruction is an instruction that may
* jump to another instruction.
- *
+ *
* @param opcode the opcode of the type instruction to be visited. This
* opcode is either IFEQ, IFNE, IFLT, IFGE, IFGT, IFLE, IF_ICMPEQ,
* IF_ICMPNE, IF_ICMPLT, IF_ICMPGE, IF_ICMPGT, IF_ICMPLE, IF_ACMPEQ,
@@ -263,67 +371,127 @@ public interface MethodVisitor {
* is a label that designates the instruction to which the jump
* instruction may jump.
*/
- void visitJumpInsn(int opcode, Label label);
+ public void visitJumpInsn(int opcode, Label label) {
+ if (mv != null) {
+ mv.visitJumpInsn(opcode, label);
+ }
+ }
/**
* Visits a label. A label designates the instruction that will be visited
* just after it.
- *
+ *
* @param label a {@link Label Label} object.
*/
- void visitLabel(Label label);
+ public void visitLabel(Label label) {
+ if (mv != null) {
+ mv.visitLabel(label);
+ }
+ }
// -------------------------------------------------------------------------
// Special instructions
// -------------------------------------------------------------------------
/**
- * Visits a LDC instruction.
- *
+ * Visits a LDC instruction. Note that new constant types may be added in
+ * future versions of the Java Virtual Machine. To easily detect new
+ * constant types, implementations of this method should check for
+ * unexpected constant types, like this:
+ * <pre>
+ * if (cst instanceof Integer) {
+ * // ...
+ * } else if (cst instanceof Float) {
+ * // ...
+ * } else if (cst instanceof Long) {
+ * // ...
+ * } else if (cst instanceof Double) {
+ * // ...
+ * } else if (cst instanceof String) {
+ * // ...
+ * } else if (cst instanceof Type) {
+ * int sort = ((Type) cst).getSort();
+ * if (sort == Type.OBJECT) {
+ * // ...
+ * } else if (sort == Type.ARRAY) {
+ * // ...
+ * } else if (sort == Type.METHOD) {
+ * // ...
+ * } else {
+ * // throw an exception
+ * }
+ * } else if (cst instanceof Handle) {
+ * // ...
+ * } else {
+ * // throw an exception
+ * }</pre>
+ *
* @param cst the constant to be loaded on the stack. This parameter must be
* a non null {@link Integer}, a {@link Float}, a {@link Long}, a
- * {@link Double} a {@link String} (or a {@link Type} for
- * <tt>.class</tt> constants, for classes whose version is 49.0 or
- * more).
+ * {@link Double}, a {@link String}, a {@link Type} of OBJECT or ARRAY
+ * sort for <tt>.class</tt> constants, for classes whose version is
+ * 49.0, a {@link Type} of METHOD sort or a {@link Handle} for
+ * MethodType and MethodHandle constants, for classes whose version
+ * is 51.0.
*/
- void visitLdcInsn(Object cst);
+ public void visitLdcInsn(Object cst) {
+ if (mv != null) {
+ mv.visitLdcInsn(cst);
+ }
+ }
/**
* Visits an IINC instruction.
- *
+ *
* @param var index of the local variable to be incremented.
* @param increment amount to increment the local variable by.
*/
- void visitIincInsn(int var, int increment);
+ public void visitIincInsn(int var, int increment) {
+ if (mv != null) {
+ mv.visitIincInsn(var, increment);
+ }
+ }
/**
* Visits a TABLESWITCH instruction.
- *
+ *
* @param min the minimum key value.
* @param max the maximum key value.
* @param dflt beginning of the default handler block.
* @param labels beginnings of the handler blocks. <tt>labels[i]</tt> is
* the beginning of the handler block for the <tt>min + i</tt> key.
*/
- void visitTableSwitchInsn(int min, int max, Label dflt, Label[] labels);
+ public void visitTableSwitchInsn(int min, int max, Label dflt, Label... labels) {
+ if (mv != null) {
+ mv.visitTableSwitchInsn(min, max, dflt, labels);
+ }
+ }
/**
* Visits a LOOKUPSWITCH instruction.
- *
+ *
* @param dflt beginning of the default handler block.
* @param keys the values of the keys.
* @param labels beginnings of the handler blocks. <tt>labels[i]</tt> is
* the beginning of the handler block for the <tt>keys[i]</tt> key.
*/
- void visitLookupSwitchInsn(Label dflt, int[] keys, Label[] labels);
+ public void visitLookupSwitchInsn(Label dflt, int[] keys, Label[] labels) {
+ if (mv != null) {
+ mv.visitLookupSwitchInsn(dflt, keys, labels);
+ }
+ }
/**
* Visits a MULTIANEWARRAY instruction.
- *
+ *
* @param desc an array type descriptor (see {@link Type Type}).
* @param dims number of dimensions of the array to allocate.
*/
- void visitMultiANewArrayInsn(String desc, int dims);
+ public void visitMultiANewArrayInsn(String desc, int dims) {
+ if (mv != null) {
+ mv.visitMultiANewArrayInsn(desc, dims);
+ }
+ }
// -------------------------------------------------------------------------
// Exceptions table entries, debug information, max stack and max locals
@@ -331,7 +499,7 @@ public interface MethodVisitor {
/**
* Visits a try catch block.
- *
+ *
* @param start beginning of the exception handler's scope (inclusive).
* @param end end of the exception handler's scope (exclusive).
* @param handler beginning of the exception handler's code.
@@ -342,11 +510,15 @@ public interface MethodVisitor {
* visited by this visitor (by the {@link #visitLabel visitLabel}
* method).
*/
- void visitTryCatchBlock(Label start, Label end, Label handler, String type);
+ public void visitTryCatchBlock(Label start, Label end, Label handler, String type) {
+ if (mv != null) {
+ mv.visitTryCatchBlock(start, end, handler, type);
+ }
+ }
/**
* Visits a local variable declaration.
- *
+ *
* @param name the name of a local variable.
* @param desc the type descriptor of this local variable.
* @param signature the type signature of this local variable. May be
@@ -361,17 +533,22 @@ public interface MethodVisitor {
* been visited by this visitor (by the
* {@link #visitLabel visitLabel} method).
*/
- void visitLocalVariable(
+ public void visitLocalVariable(
String name,
String desc,
String signature,
Label start,
Label end,
- int index);
+ int index)
+ {
+ if (mv != null) {
+ mv.visitLocalVariable(name, desc, signature, start, end, index);
+ }
+ }
/**
* Visits a line number declaration.
- *
+ *
* @param line a line number. This number refers to the source file from
* which the class was compiled.
* @param start the first instruction corresponding to this line number.
@@ -379,21 +556,33 @@ public interface MethodVisitor {
* visited by this visitor (by the {@link #visitLabel visitLabel}
* method).
*/
- void visitLineNumber(int line, Label start);
+ public void visitLineNumber(int line, Label start) {
+ if (mv != null) {
+ mv.visitLineNumber(line, start);
+ }
+ }
/**
* Visits the maximum stack size and the maximum number of local variables
* of the method.
- *
+ *
* @param maxStack maximum stack size of the method.
* @param maxLocals maximum number of local variables for the method.
*/
- void visitMaxs(int maxStack, int maxLocals);
+ public void visitMaxs(int maxStack, int maxLocals) {
+ if (mv != null) {
+ mv.visitMaxs(maxStack, maxLocals);
+ }
+ }
/**
* Visits the end of the method. This method, which is the last one to be
* called, is used to inform the visitor that all the annotations and
* attributes of the method have been visited.
*/
- void visitEnd();
+ public void visitEnd() {
+ if (mv != null) {
+ mv.visitEnd();
+ }
+ }
}
http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/d6e5f413/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/MethodWriter.java
----------------------------------------------------------------------
diff --git a/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/MethodWriter.java b/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/MethodWriter.java
index cd50a3e..70b26b8 100644
--- a/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/MethodWriter.java
+++ b/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/MethodWriter.java
@@ -1,6 +1,6 @@
/***
* ASM: a very small and fast Java bytecode manipulation framework
- * Copyright (c) 2000-2007 INRIA, France Telecom
+ * Copyright (c) 2000-2011 INRIA, France Telecom
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -33,11 +33,11 @@ package org.apache.tapestry5.internal.plastic.asm;
* A {@link MethodVisitor} that generates methods in bytecode form. Each visit
* method of this class appends the bytecode corresponding to the visited
* instruction to a byte vector, in the order these methods are called.
- *
+ *
* @author Eric Bruneton
* @author Eugene Kuleshov
*/
-class MethodWriter implements MethodVisitor {
+class MethodWriter extends MethodVisitor {
/**
* Pseudo access flag used to denote constructors.
@@ -96,7 +96,7 @@ class MethodWriter implements MethodVisitor {
* Indicates that the stack map frames must be recomputed from scratch. In
* this case the maximum stack size and number of local variables is also
* recomputed from scratch.
- *
+ *
* @see #compute
*/
private static final int FRAMES = 0;
@@ -104,24 +104,19 @@ class MethodWriter implements MethodVisitor {
/**
* Indicates that the maximum stack size and number of local variables must
* be automatically computed.
- *
+ *
* @see #compute
*/
private static final int MAXS = 1;
/**
* Indicates that nothing must be automatically computed.
- *
+ *
* @see #compute
*/
private static final int NOTHING = 2;
/**
- * Next method writer (see {@link ClassWriter#firstMethod firstMethod}).
- */
- MethodWriter next;
-
- /**
* The class writer to which this method must be added.
*/
final ClassWriter cw;
@@ -234,6 +229,11 @@ class MethodWriter implements MethodVisitor {
private int maxLocals;
/**
+ * Number of local variables in the current stack map frame.
+ */
+ private int currentLocals;
+
+ /**
* Number of stack map frames in the StackMapTable attribute.
*/
private int frameCount;
@@ -251,7 +251,7 @@ class MethodWriter implements MethodVisitor {
/**
* The last frame that was written in the StackMapTable attribute.
- *
+ *
* @see #frame
*/
private int[] previousFrame;
@@ -346,7 +346,7 @@ class MethodWriter implements MethodVisitor {
/**
* Indicates what must be automatically computed.
- *
+ *
* @see #FRAMES
* @see #MAXS
* @see #NOTHING
@@ -395,7 +395,7 @@ class MethodWriter implements MethodVisitor {
/**
* Constructs a new {@link MethodWriter}.
- *
+ *
* @param cw the class writer in which the method must be added.
* @param access the method's access flags (see {@link Opcodes}).
* @param name the method's name.
@@ -418,10 +418,11 @@ class MethodWriter implements MethodVisitor {
final boolean computeMaxs,
final boolean computeFrames)
{
+ super(Opcodes.ASM4);
if (cw.firstMethod == null) {
cw.firstMethod = this;
} else {
- cw.lastMethod.next = this;
+ cw.lastMethod.mv = this;
}
cw.lastMethod = this;
this.cw = cw;
@@ -450,6 +451,7 @@ class MethodWriter implements MethodVisitor {
--size;
}
maxLocals = size;
+ currentLocals = size;
// creates and visits the label for the first basic block
labels = new Label();
labels.status |= Label.PUSHED;
@@ -458,9 +460,10 @@ class MethodWriter implements MethodVisitor {
}
// ------------------------------------------------------------------------
- // Implementation of the MethodVisitor interface
+ // Implementation of the MethodVisitor abstract class
// ------------------------------------------------------------------------
+ @Override
public AnnotationVisitor visitAnnotationDefault() {
if (!ClassReader.ANNOTATIONS) {
return null;
@@ -469,6 +472,7 @@ class MethodWriter implements MethodVisitor {
return new AnnotationWriter(cw, false, annd, null, 0);
}
+ @Override
public AnnotationVisitor visitAnnotation(
final String desc,
final boolean visible)
@@ -490,6 +494,7 @@ class MethodWriter implements MethodVisitor {
return aw;
}
+ @Override
public AnnotationVisitor visitParameterAnnotation(
final int parameter,
final String desc,
@@ -524,6 +529,7 @@ class MethodWriter implements MethodVisitor {
return aw;
}
+ @Override
public void visitAttribute(final Attribute attr) {
if (attr.isCodeAttribute()) {
attr.next = cattrs;
@@ -534,9 +540,11 @@ class MethodWriter implements MethodVisitor {
}
}
+ @Override
public void visitCode() {
}
+ @Override
public void visitFrame(
final int type,
final int nLocal,
@@ -549,6 +557,7 @@ class MethodWriter implements MethodVisitor {
}
if (type == Opcodes.F_NEW) {
+ currentLocals = nLocal;
startFrame(code.length, nLocal, nStack);
for (int i = 0; i < nLocal; ++i) {
if (local[i] instanceof String) {
@@ -593,6 +602,7 @@ class MethodWriter implements MethodVisitor {
switch (type) {
case Opcodes.F_FULL:
+ currentLocals = nLocal;
stackMap.putByte(FULL_FRAME)
.putShort(delta)
.putShort(nLocal);
@@ -605,6 +615,7 @@ class MethodWriter implements MethodVisitor {
}
break;
case Opcodes.F_APPEND:
+ currentLocals += nLocal;
stackMap.putByte(SAME_FRAME_EXTENDED + nLocal)
.putShort(delta);
for (int i = 0; i < nLocal; ++i) {
@@ -612,6 +623,7 @@ class MethodWriter implements MethodVisitor {
}
break;
case Opcodes.F_CHOP:
+ currentLocals -= nLocal;
stackMap.putByte(SAME_FRAME_EXTENDED - nLocal)
.putShort(delta);
break;
@@ -636,8 +648,12 @@ class MethodWriter implements MethodVisitor {
previousFrameOffset = code.length;
++frameCount;
}
+
+ maxStack = Math.max(maxStack, nStack);
+ maxLocals = Math.max(maxLocals, currentLocals);
}
+ @Override
public void visitInsn(final int opcode) {
// adds the instruction to the bytecode of the method
code.putByte(opcode);
@@ -663,6 +679,7 @@ class MethodWriter implements MethodVisitor {
}
}
+ @Override
public void visitIntInsn(final int opcode, final int operand) {
// Label currentBlock = this.currentBlock;
if (currentBlock != null) {
@@ -686,6 +703,7 @@ class MethodWriter implements MethodVisitor {
}
}
+ @Override
public void visitVarInsn(final int opcode, final int var) {
// Label currentBlock = this.currentBlock;
if (currentBlock != null) {
@@ -744,6 +762,7 @@ class MethodWriter implements MethodVisitor {
}
}
+ @Override
public void visitTypeInsn(final int opcode, final String type) {
Item i = cw.newClassItem(type);
// Label currentBlock = this.currentBlock;
@@ -764,6 +783,7 @@ class MethodWriter implements MethodVisitor {
code.put12(opcode, i.index);
}
+ @Override
public void visitFieldInsn(
final int opcode,
final String owner,
@@ -805,6 +825,7 @@ class MethodWriter implements MethodVisitor {
code.put12(opcode, i.index);
}
+ @Override
public void visitMethodInsn(
final int opcode,
final String owner,
@@ -812,9 +833,7 @@ class MethodWriter implements MethodVisitor {
final String desc)
{
boolean itf = opcode == Opcodes.INVOKEINTERFACE;
- Item i = (opcode == Opcodes.INVOKEDYNAMIC) ?
- cw.newNameTypeItem(name, desc):
- cw.newMethodItem(owner, name, desc, itf);
+ Item i = cw.newMethodItem(owner, name, desc, itf);
int argSize = i.intVal;
// Label currentBlock = this.currentBlock;
if (currentBlock != null) {
@@ -838,7 +857,7 @@ class MethodWriter implements MethodVisitor {
i.intVal = argSize;
}
int size;
- if (opcode == Opcodes.INVOKESTATIC || opcode == Opcodes.INVOKEDYNAMIC) {
+ if (opcode == Opcodes.INVOKESTATIC) {
size = stackSize - (argSize >> 2) + (argSize & 0x03) + 1;
} else {
size = stackSize - (argSize >> 2) + (argSize & 0x03);
@@ -859,12 +878,54 @@ class MethodWriter implements MethodVisitor {
code.put12(Opcodes.INVOKEINTERFACE, i.index).put11(argSize >> 2, 0);
} else {
code.put12(opcode, i.index);
- if (opcode==Opcodes.INVOKEDYNAMIC) {
- code.putShort(0);
+ }
+ }
+
+ @Override
+ public void visitInvokeDynamicInsn(
+ final String name,
+ final String desc,
+ final Handle bsm,
+ final Object... bsmArgs)
+ {
+ Item i = cw.newInvokeDynamicItem(name, desc, bsm, bsmArgs);
+ int argSize = i.intVal;
+ // Label currentBlock = this.currentBlock;
+ if (currentBlock != null) {
+ if (compute == FRAMES) {
+ currentBlock.frame.execute(Opcodes.INVOKEDYNAMIC, 0, cw, i);
+ } else {
+ /*
+ * computes the stack size variation. In order not to recompute
+ * several times this variation for the same Item, we use the
+ * intVal field of this item to store this variation, once it
+ * has been computed. More precisely this intVal field stores
+ * the sizes of the arguments and of the return value
+ * corresponding to desc.
+ */
+ if (argSize == 0) {
+ // the above sizes have not been computed yet,
+ // so we compute them...
+ argSize = Type.getArgumentsAndReturnSizes(desc);
+ // ... and we save them in order
+ // not to recompute them in the future
+ i.intVal = argSize;
+ }
+ int size = stackSize - (argSize >> 2) + (argSize & 0x03) + 1;
+
+ // updates current and max stack sizes
+ if (size > maxStackSize) {
+ maxStackSize = size;
+ }
+ stackSize = size;
}
}
+ // adds the instruction to the bytecode of the method
+ code.put12(Opcodes.INVOKEDYNAMIC, i.index);
+ code.putShort(0);
}
+ @Override
public void visitJumpInsn(final int opcode, final Label label) {
Label nextInsn = null;
// Label currentBlock = this.currentBlock;
@@ -956,6 +1017,7 @@ class MethodWriter implements MethodVisitor {
}
}
+ @Override
public void visitLabel(final Label label) {
// resolves previous forward references to label, if any
resize |= label.resolve(this, code.length, code.data);
@@ -1010,6 +1072,7 @@ class MethodWriter implements MethodVisitor {
}
}
+ @Override
public void visitLdcInsn(final Object cst) {
Item i = cw.newConstItem(cst);
// Label currentBlock = this.currentBlock;
@@ -1043,6 +1106,7 @@ class MethodWriter implements MethodVisitor {
}
}
+ @Override
public void visitIincInsn(final int var, final int increment) {
if (currentBlock != null) {
if (compute == FRAMES) {
@@ -1066,11 +1130,12 @@ class MethodWriter implements MethodVisitor {
}
}
+ @Override
public void visitTableSwitchInsn(
final int min,
final int max,
final Label dflt,
- final Label[] labels)
+ final Label... labels)
{
// adds the instruction to the bytecode of the method
int source = code.length;
@@ -1085,6 +1150,7 @@ class MethodWriter implements MethodVisitor {
visitSwitchInsn(dflt, labels);
}
+ @Override
public void visitLookupSwitchInsn(
final Label dflt,
final int[] keys,
@@ -1130,6 +1196,7 @@ class MethodWriter implements MethodVisitor {
}
}
+ @Override
public void visitMultiANewArrayInsn(final String desc, final int dims) {
Item i = cw.newClassItem(desc);
// Label currentBlock = this.currentBlock;
@@ -1146,6 +1213,7 @@ class MethodWriter implements MethodVisitor {
code.put12(Opcodes.MULTIANEWARRAY, i.index).putByte(dims);
}
+ @Override
public void visitTryCatchBlock(
final Label start,
final Label end,
@@ -1167,6 +1235,7 @@ class MethodWriter implements MethodVisitor {
lastHandler = h;
}
+ @Override
public void visitLocalVariable(
final String name,
final String desc,
@@ -1205,6 +1274,7 @@ class MethodWriter implements MethodVisitor {
}
}
+ @Override
public void visitLineNumber(final int line, final Label start) {
if (lineNumber == null) {
lineNumber = new ByteVector();
@@ -1214,6 +1284,7 @@ class MethodWriter implements MethodVisitor {
lineNumber.putShort(line);
}
+ @Override
public void visitMaxs(final int maxStack, final int maxLocals) {
if (ClassReader.FRAMES && compute == FRAMES) {
// completes the control flow graph with exception handler blocks
@@ -1315,11 +1386,20 @@ class MethodWriter implements MethodVisitor {
frame[frameIndex++] = Frame.OBJECT
| cw.addType("java/lang/Throwable");
endFrame();
+ // removes the start-end range from the exception handlers
+ firstHandler = Handler.remove(firstHandler, l, k);
}
}
l = l.successor;
}
-
+
+ handler = firstHandler;
+ handlerCount = 0;
+ while (handler != null) {
+ handlerCount += 1;
+ handler = handler.next;
+ }
+
this.maxStack = max;
} else if (compute == MAXS) {
// completes the control flow graph with exception handler blocks
@@ -1437,13 +1517,14 @@ class MethodWriter implements MethodVisitor {
b = b.next;
}
}
- this.maxStack = max;
+ this.maxStack = Math.max(maxStack, max);
} else {
this.maxStack = maxStack;
this.maxLocals = maxLocals;
}
}
+ @Override
public void visitEnd() {
}
@@ -1453,7 +1534,7 @@ class MethodWriter implements MethodVisitor {
/**
* Adds a successor to the {@link #currentBlock currentBlock} block.
- *
+ *
* @param info information about the control flow edge to be added.
* @param successor the successor block to be added to the current block.
*/
@@ -1491,7 +1572,7 @@ class MethodWriter implements MethodVisitor {
/**
* Visits a frame that has been computed from scratch.
- *
+ *
* @param f the frame that must be visited.
*/
private void visitFrame(final Frame f) {
@@ -1545,7 +1626,7 @@ class MethodWriter implements MethodVisitor {
/**
* Starts the visit of a stack map frame.
- *
+ *
* @param offset the offset of the instruction to which the frame
* corresponds.
* @param nLocal the number of local variables in the frame.
@@ -1675,7 +1756,7 @@ class MethodWriter implements MethodVisitor {
* StackMapTableAttribute. This method converts types from the format used
* in {@link Label} to the format used in StackMapTable attributes. In
* particular, it converts type table indexes to constant pool indexes.
- *
+ *
* @param start index of the first type in {@link #frame} to write.
* @param end index of last type in {@link #frame} to write (exclusive).
*/
@@ -1754,7 +1835,7 @@ class MethodWriter implements MethodVisitor {
/**
* Returns the size of the bytecode of this method.
- *
+ *
* @return the size of the bytecode of this method.
*/
final int getSize() {
@@ -1771,6 +1852,9 @@ class MethodWriter implements MethodVisitor {
}
int size = 8;
if (code.length > 0) {
+ if (code.length > 65536) {
+ throw new RuntimeException("Method code too large!");
+ }
cw.newUTF8("Code");
size += 18 + code.length + 8 * handlerCount;
if (localVar != null) {
@@ -1851,7 +1935,7 @@ class MethodWriter implements MethodVisitor {
/**
* Puts the bytecode of this method in the given byte vector.
- *
+ *
* @param out the byte vector into which the bytecode of this method must be
* copied.
*/
@@ -2054,17 +2138,17 @@ class MethodWriter implements MethodVisitor {
* so on. The first step of the algorithm consists in finding all the
* instructions that need to be resized, without modifying the code.
* This is done by the following "fix point" algorithm:
- *
+ *
* Parse the code to find the jump instructions whose offset will need
* more than 2 bytes to be stored (the future offset is computed from
* the current offset and from the number of bytes that will be inserted
* or removed between the source and target instructions). For each such
* instruction, adds an entry in (a copy of) the indexes and sizes
* arrays (if this has not already been done in a previous iteration!).
- *
+ *
* If at least one entry has been added during the previous step, go
* back to the beginning, otherwise stop.
- *
+ *
* In fact the real algorithm is complicated by the fact that the size
* of TABLESWITCH and LOOKUPSWITCH instructions depends on their
* position in the bytecode (because of padding). In order to ensure the
@@ -2191,7 +2275,8 @@ class MethodWriter implements MethodVisitor {
case ClassWriter.IINC_INSN:
u += 3;
break;
- case ClassWriter.ITFDYNMETH_INSN:
+ case ClassWriter.ITFMETH_INSN:
+ case ClassWriter.INDYMETH_INSN:
u += 5;
break;
// case ClassWriter.MANA_INSN:
@@ -2354,7 +2439,8 @@ class MethodWriter implements MethodVisitor {
newCode.putByteArray(b, u, 3);
u += 3;
break;
- case ClassWriter.ITFDYNMETH_INSN:
+ case ClassWriter.ITFMETH_INSN:
+ case ClassWriter.INDYMETH_INSN:
newCode.putByteArray(b, u, 5);
u += 5;
break;
@@ -2467,7 +2553,7 @@ class MethodWriter implements MethodVisitor {
/**
* Reads an unsigned short value in the given byte array.
- *
+ *
* @param b a byte array.
* @param index the start index of the value to be read.
* @return the read value.
@@ -2478,7 +2564,7 @@ class MethodWriter implements MethodVisitor {
/**
* Reads a signed short value in the given byte array.
- *
+ *
* @param b a byte array.
* @param index the start index of the value to be read.
* @return the read value.
@@ -2489,7 +2575,7 @@ class MethodWriter implements MethodVisitor {
/**
* Reads a signed int value in the given byte array.
- *
+ *
* @param b a byte array.
* @param index the start index of the value to be read.
* @return the read value.
@@ -2501,7 +2587,7 @@ class MethodWriter implements MethodVisitor {
/**
* Writes a short value in the given byte array.
- *
+ *
* @param b a byte array.
* @param index where the first byte of the short value must be written.
* @param s the value to be written in the given byte array.
@@ -2516,7 +2602,7 @@ class MethodWriter implements MethodVisitor {
* to have several entries for the same instruction in the <tt>indexes</tt>
* and <tt>sizes</tt>: two entries (index=a,size=b) and (index=a,size=b')
* are equivalent to a single entry (index=a,size=b+b').
- *
+ *
* @param indexes current positions of the instructions to be resized. Each
* instruction must be designated by the index of its <i>last</i>
* byte, plus one (or, in other words, by the index of the <i>first</i>
@@ -2553,7 +2639,7 @@ class MethodWriter implements MethodVisitor {
/**
* Updates the offset of the given label.
- *
+ *
* @param indexes current positions of the instructions to be resized. Each
* instruction must be designated by the index of its <i>last</i>
* byte, plus one (or, in other words, by the index of the <i>first</i>
http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/d6e5f413/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/Opcodes.java
----------------------------------------------------------------------
diff --git a/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/Opcodes.java b/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/Opcodes.java
index 18ccda6..ac7c671 100644
--- a/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/Opcodes.java
+++ b/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/Opcodes.java
@@ -1,6 +1,6 @@
/***
* ASM: a very small and fast Java bytecode manipulation framework
- * Copyright (c) 2000-2007 INRIA, France Telecom
+ * Copyright (c) 2000-2011 INRIA, France Telecom
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -37,12 +37,16 @@ package org.apache.tapestry5.internal.plastic.asm;
* opcodes are therefore not defined in this interface. Likewise for LDC,
* automatically replaced by LDC_W or LDC2_W when necessary, WIDE, GOTO_W and
* JSR_W.
- *
+ *
* @author Eric Bruneton
* @author Eugene Kuleshov
*/
public interface Opcodes {
+ // ASM API versions
+
+ int ASM4 = 4 << 16 | 0 << 8 | 0;
+
// versions
int V1_1 = 3 << 16 | 45;
@@ -89,6 +93,18 @@ public interface Opcodes {
int T_INT = 10;
int T_LONG = 11;
+ // tags for Handle
+
+ int H_GETFIELD = 1;
+ int H_GETSTATIC = 2;
+ int H_PUTFIELD = 3;
+ int H_PUTSTATIC = 4;
+ int H_INVOKEVIRTUAL = 5;
+ int H_INVOKESTATIC = 6;
+ int H_INVOKESPECIAL = 7;
+ int H_NEWINVOKESPECIAL = 8;
+ int H_INVOKEINTERFACE = 9;
+
// stack map frame types
/**
@@ -135,11 +151,6 @@ public interface Opcodes {
Integer NULL = new Integer(5);
Integer UNINITIALIZED_THIS = new Integer(6);
- /**
- * Represents a owner of an invokedynamic call.
- */
- String INVOKEDYNAMIC_OWNER = "java/lang/dyn/Dynamic";
-
// opcodes // visit method (- = idem)
int NOP = 0; // visitInsn
@@ -328,7 +339,7 @@ public interface Opcodes {
int INVOKESPECIAL = 183; // -
int INVOKESTATIC = 184; // -
int INVOKEINTERFACE = 185; // -
- int INVOKEDYNAMIC = 186; // -
+ int INVOKEDYNAMIC = 186; // visitInvokeDynamicInsn
int NEW = 187; // visitTypeInsn
int NEWARRAY = 188; // visitIntInsn
int ANEWARRAY = 189; // visitTypeInsn
http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/d6e5f413/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/Type.java
----------------------------------------------------------------------
diff --git a/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/Type.java b/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/Type.java
index c1d3e27..6011aa4 100644
--- a/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/Type.java
+++ b/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/Type.java
@@ -1,6 +1,6 @@
/***
* ASM: a very small and fast Java bytecode manipulation framework
- * Copyright (c) 2000-2007 INRIA, France Telecom
+ * Copyright (c) 2000-2011 INRIA, France Telecom
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -33,9 +33,9 @@ import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
/**
- * A Java type. This class can be used to make it easier to manipulate type and
- * method descriptors.
- *
+ * A Java field or method type. This class can be used to make it easier to
+ * manipulate type and method descriptors.
+ *
* @author Eric Bruneton
* @author Chris Nokleberg
*/
@@ -92,11 +92,16 @@ public class Type {
public static final int ARRAY = 9;
/**
- * The sort of object reference type. See {@link #getSort getSort}.
+ * The sort of object reference types. See {@link #getSort getSort}.
*/
public static final int OBJECT = 10;
/**
+ * The sort of method types. See {@link #getSort getSort}.
+ */
+ public static final int METHOD = 11;
+
+ /**
* The <tt>void</tt> type.
*/
public static final Type VOID_TYPE = new Type(VOID, null, ('V' << 24)
@@ -184,7 +189,7 @@ public class Type {
/**
* Constructs a reference type.
- *
+ *
* @param sort the sort of the reference type to be constructed.
* @param buf a buffer containing the descriptor of the previous type.
* @param off the offset of this descriptor in the previous buffer.
@@ -200,8 +205,8 @@ public class Type {
/**
* Returns the Java type corresponding to the given type descriptor.
- *
- * @param typeDescriptor a type descriptor.
+ *
+ * @param typeDescriptor a field or method type descriptor.
* @return the Java type corresponding to the given type descriptor.
*/
public static Type getType(final String typeDescriptor) {
@@ -210,7 +215,7 @@ public class Type {
/**
* Returns the Java type corresponding to the given internal name.
- *
+ *
* @param internalName an internal name.
* @return the Java type corresponding to the given internal name.
*/
@@ -220,12 +225,35 @@ public class Type {
}
/**
+ * Returns the Java type corresponding to the given method descriptor.
+ * Equivalent to <code>Type.getType(methodDescriptor)</code>.
+ *
+ * @param methodDescriptor a method descriptor.
+ * @return the Java type corresponding to the given method descriptor.
+ */
+ public static Type getMethodType(final String methodDescriptor) {
+ return getType(methodDescriptor.toCharArray(), 0);
+ }
+
+ /**
+ * Returns the Java method type corresponding to the given argument and
+ * return types.
+ *
+ * @param returnType the return type of the method.
+ * @param argumentTypes the argument types of the method.
+ * @return the Java type corresponding to the given argument and return types.
+ */
+ public static Type getMethodType(final Type returnType, final Type... argumentTypes) {
+ return getType(getMethodDescriptor(returnType, argumentTypes));
+ }
+
+ /**
* Returns the Java type corresponding to the given class.
- *
+ *
* @param c a class.
* @return the Java type corresponding to the given class.
*/
- public static Type getType(final Class c) {
+ public static Type getType(final Class<?> c) {
if (c.isPrimitive()) {
if (c == Integer.TYPE) {
return INT_TYPE;
@@ -252,9 +280,29 @@ public class Type {
}
/**
+ * Returns the Java method type corresponding to the given constructor.
+ *
+ * @param c a {@link Constructor Constructor} object.
+ * @return the Java method type corresponding to the given constructor.
+ */
+ public static Type getType(final Constructor<?> c) {
+ return getType(getConstructorDescriptor(c));
+ }
+
+ /**
+ * Returns the Java method type corresponding to the given method.
+ *
+ * @param m a {@link Method Method} object.
+ * @return the Java method type corresponding to the given method.
+ */
+ public static Type getType(final Method m) {
+ return getType(getMethodDescriptor(m));
+ }
+
+ /**
* Returns the Java types corresponding to the argument types of the given
* method descriptor.
- *
+ *
* @param methodDescriptor a method descriptor.
* @return the Java types corresponding to the argument types of the given
* method descriptor.
@@ -289,13 +337,13 @@ public class Type {
/**
* Returns the Java types corresponding to the argument types of the given
* method.
- *
+ *
* @param method a method.
* @return the Java types corresponding to the argument types of the given
* method.
*/
public static Type[] getArgumentTypes(final Method method) {
- Class[] classes = method.getParameterTypes();
+ Class<?>[] classes = method.getParameterTypes();
Type[] types = new Type[classes.length];
for (int i = classes.length - 1; i >= 0; --i) {
types[i] = getType(classes[i]);
@@ -306,7 +354,7 @@ public class Type {
/**
* Returns the Java type corresponding to the return type of the given
* method descriptor.
- *
+ *
* @param methodDescriptor a method descriptor.
* @return the Java type corresponding to the return type of the given
* method descriptor.
@@ -319,7 +367,7 @@ public class Type {
/**
* Returns the Java type corresponding to the return type of the given
* method.
- *
+ *
* @param method a method.
* @return the Java type corresponding to the return type of the given
* method.
@@ -330,7 +378,7 @@ public class Type {
/**
* Computes the size of the arguments and of the return value of a method.
- *
+ *
* @param desc the descriptor of a method.
* @return the size of the arguments of the method (plus one for the
* implicit this argument), argSize, and the size of its return
@@ -367,8 +415,10 @@ public class Type {
}
/**
- * Returns the Java type corresponding to the given type descriptor.
- *
+ * Returns the Java type corresponding to the given type descriptor. For
+ * method descriptors, buf is supposed to contain nothing more than the
+ * descriptor itself.
+ *
* @param buf a buffer containing a type descriptor.
* @param off the offset of this descriptor in the previous buffer.
* @return the Java type corresponding to the given type descriptor.
@@ -406,13 +456,15 @@ public class Type {
}
}
return new Type(ARRAY, buf, off, len + 1);
- // case 'L':
- default:
+ case 'L':
len = 1;
while (buf[off + len] != ';') {
++len;
}
return new Type(OBJECT, buf, off + 1, len - 1);
+ // case '(':
+ default:
+ return new Type(METHOD, buf, 0, buf.length);
}
}
@@ -422,12 +474,12 @@ public class Type {
/**
* Returns the sort of this Java type.
- *
+ *
* @return {@link #VOID VOID}, {@link #BOOLEAN BOOLEAN},
* {@link #CHAR CHAR}, {@link #BYTE BYTE}, {@link #SHORT SHORT},
* {@link #INT INT}, {@link #FLOAT FLOAT}, {@link #LONG LONG},
- * {@link #DOUBLE DOUBLE}, {@link #ARRAY ARRAY} or
- * {@link #OBJECT OBJECT}.
+ * {@link #DOUBLE DOUBLE}, {@link #ARRAY ARRAY},
+ * {@link #OBJECT OBJECT} or {@link #METHOD METHOD}.
*/
public int getSort() {
return sort;
@@ -436,7 +488,7 @@ public class Type {
/**
* Returns the number of dimensions of this array type. This method should
* only be used for an array type.
- *
+ *
* @return the number of dimensions of this array type.
*/
public int getDimensions() {
@@ -450,7 +502,7 @@ public class Type {
/**
* Returns the type of the elements of this array type. This method should
* only be used for an array type.
- *
+ *
* @return Returns the type of the elements of this array type.
*/
public Type getElementType() {
@@ -458,9 +510,10 @@ public class Type {
}
/**
- * Returns the name of the class corresponding to this type.
- *
- * @return the fully qualified name of the class corresponding to this type.
+ * Returns the binary name of the class corresponding to this type. This
+ * method must not be used on method types.
+ *
+ * @return the binary name of the class corresponding to this type.
*/
public String getClassName() {
switch (sort) {
@@ -488,9 +541,10 @@ public class Type {
b.append("[]");
}
return b.toString();
- // case OBJECT:
- default:
+ case OBJECT:
return new String(buf, off, len).replace('/', '.');
+ default:
+ return null;
}
}
@@ -499,20 +553,54 @@ public class Type {
* array type. The internal name of a class is its fully qualified name (as
* returned by Class.getName(), where '.' are replaced by '/'. This method
* should only be used for an object or array type.
- *
+ *
* @return the internal name of the class corresponding to this object type.
*/
public String getInternalName() {
return new String(buf, off, len);
}
+ /**
+ * Returns the argument types of methods of this type. This method should
+ * only be used for method types.
+ *
+ * @return the argument types of methods of this type.
+ */
+ public Type[] getArgumentTypes() {
+ return getArgumentTypes(getDescriptor());
+ }
+
+ /**
+ * Returns the return type of methods of this type. This method should only
+ * be used for method types.
+ *
+ * @return the return type of methods of this type.
+ */
+ public Type getReturnType() {
+ return getReturnType(getDescriptor());
+ }
+
+ /**
+ * Returns the size of the arguments and of the return value of methods of
+ * this type. This method should only be used for method types.
+ *
+ * @return the size of the arguments (plus one for the implicit this
+ * argument), argSize, and the size of the return value, retSize,
+ * packed into a single int i = <tt>(argSize << 2) | retSize</tt>
+ * (argSize is therefore equal to <tt>i >> 2</tt>, and retSize to
+ * <tt>i & 0x03</tt>).
+ */
+ public int getArgumentsAndReturnSizes() {
+ return getArgumentsAndReturnSizes(getDescriptor());
+ }
+
// ------------------------------------------------------------------------
// Conversion to type descriptors
// ------------------------------------------------------------------------
/**
* Returns the descriptor corresponding to this Java type.
- *
+ *
* @return the descriptor corresponding to this Java type.
*/
public String getDescriptor() {
@@ -524,7 +612,7 @@ public class Type {
/**
* Returns the descriptor corresponding to the given argument and return
* types.
- *
+ *
* @param returnType the return type of the method.
* @param argumentTypes the argument types of the method.
* @return the descriptor corresponding to the given argument and return
@@ -532,7 +620,7 @@ public class Type {
*/
public static String getMethodDescriptor(
final Type returnType,
- final Type[] argumentTypes)
+ final Type... argumentTypes)
{
StringBuffer buf = new StringBuffer();
buf.append('(');
@@ -547,19 +635,19 @@ public class Type {
/**
* Appends the descriptor corresponding to this Java type to the given
* string buffer.
- *
+ *
* @param buf the string buffer to which the descriptor must be appended.
*/
private void getDescriptor(final StringBuffer buf) {
if (this.buf == null) {
// descriptor is in byte 3 of 'off' for primitive types (buf == null)
buf.append((char) ((off & 0xFF000000) >>> 24));
- } else if (sort == ARRAY) {
- buf.append(this.buf, off, len);
- } else { // sort == OBJECT
+ } else if (sort == OBJECT) {
buf.append('L');
buf.append(this.buf, off, len);
buf.append(';');
+ } else { // sort == ARRAY || sort == METHOD
+ buf.append(this.buf, off, len);
}
}
@@ -572,21 +660,21 @@ public class Type {
* Returns the internal name of the given class. The internal name of a
* class is its fully qualified name, as returned by Class.getName(), where
* '.' are replaced by '/'.
- *
+ *
* @param c an object or array class.
* @return the internal name of the given class.
*/
- public static String getInternalName(final Class c) {
+ public static String getInternalName(final Class<?> c) {
return c.getName().replace('.', '/');
}
/**
* Returns the descriptor corresponding to the given Java type.
- *
+ *
* @param c an object class, a primitive class or an array class.
* @return the descriptor corresponding to the given class.
*/
- public static String getDescriptor(final Class c) {
+ public static String getDescriptor(final Class<?> c) {
StringBuffer buf = new StringBuffer();
getDescriptor(buf, c);
return buf.toString();
@@ -594,12 +682,12 @@ public class Type {
/**
* Returns the descriptor corresponding to the given constructor.
- *
+ *
* @param c a {@link Constructor Constructor} object.
* @return the descriptor of the given constructor.
*/
- public static String getConstructorDescriptor(final Constructor c) {
- Class[] parameters = c.getParameterTypes();
+ public static String getConstructorDescriptor(final Constructor<?> c) {
+ Class<?>[] parameters = c.getParameterTypes();
StringBuffer buf = new StringBuffer();
buf.append('(');
for (int i = 0; i < parameters.length; ++i) {
@@ -610,12 +698,12 @@ public class Type {
/**
* Returns the descriptor corresponding to the given method.
- *
+ *
* @param m a {@link Method Method} object.
* @return the descriptor of the given method.
*/
public static String getMethodDescriptor(final Method m) {
- Class[] parameters = m.getParameterTypes();
+ Class<?>[] parameters = m.getParameterTypes();
StringBuffer buf = new StringBuffer();
buf.append('(');
for (int i = 0; i < parameters.length; ++i) {
@@ -628,12 +716,12 @@ public class Type {
/**
* Appends the descriptor of the given class to the given string buffer.
- *
+ *
* @param buf the string buffer to which the descriptor must be appended.
* @param c the class whose descriptor must be computed.
*/
- private static void getDescriptor(final StringBuffer buf, final Class c) {
- Class d = c;
+ private static void getDescriptor(final StringBuffer buf, final Class<?> c) {
+ Class<?> d = c;
while (true) {
if (d.isPrimitive()) {
char car;
@@ -680,8 +768,9 @@ public class Type {
// ------------------------------------------------------------------------
/**
- * Returns the size of values of this type.
- *
+ * Returns the size of values of this type. This method must not be used for
+ * method types.
+ *
* @return the size of values of this type, i.e., 2 for <tt>long</tt> and
* <tt>double</tt>, 0 for <tt>void</tt> and 1 otherwise.
*/
@@ -691,8 +780,9 @@ public class Type {
}
/**
- * Returns a JVM instruction opcode adapted to this Java type.
- *
+ * Returns a JVM instruction opcode adapted to this Java type. This method
+ * must not be used for method types.
+ *
* @param opcode a JVM instruction opcode. This opcode must be one of ILOAD,
* ISTORE, IALOAD, IASTORE, IADD, ISUB, IMUL, IDIV, IREM, INEG, ISHL,
* ISHR, IUSHR, IAND, IOR, IXOR and IRETURN.
@@ -718,10 +808,11 @@ public class Type {
/**
* Tests if the given object is equal to this type.
- *
+ *
* @param o the object to be compared to this type.
* @return <tt>true</tt> if the given object is equal to this type.
*/
+ @Override
public boolean equals(final Object o) {
if (this == o) {
return true;
@@ -733,7 +824,7 @@ public class Type {
if (sort != t.sort) {
return false;
}
- if (sort == OBJECT || sort == ARRAY) {
+ if (sort >= ARRAY) {
if (len != t.len) {
return false;
}
@@ -748,12 +839,13 @@ public class Type {
/**
* Returns a hash code value for this type.
- *
+ *
* @return a hash code value for this type.
*/
+ @Override
public int hashCode() {
int hc = 13 * sort;
- if (sort == OBJECT || sort == ARRAY) {
+ if (sort >= ARRAY) {
for (int i = off, end = i + len; i < end; i++) {
hc = 17 * (hc + buf[i]);
}
@@ -763,9 +855,10 @@ public class Type {
/**
* Returns a string representation of this type.
- *
+ *
* @return the descriptor of this type.
*/
+ @Override
public String toString() {
return getDescriptor();
}
http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/d6e5f413/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/attrs/package.html
----------------------------------------------------------------------
diff --git a/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/attrs/package.html b/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/attrs/package.html
index 51f0a02..28d827d 100644
--- a/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/attrs/package.html
+++ b/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/attrs/package.html
@@ -1,7 +1,7 @@
<html>
<!--
* ASM: a very small and fast Java bytecode manipulation framework
- * Copyright (c) 2000-2005 INRIA, France Telecom
+ * Copyright (c) 2000-2011 INRIA, France Telecom
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -37,9 +37,9 @@ By default ASM strips optional attributes, in order to keep them in
the bytecode that is being readed you should pass an array of required attribute
instances to {@link org.objectweb.asm.ClassReader#accept(org.objectweb.asm.ClassVisitor, org.objectweb.asm.Attribute[], boolean) ClassReader.accept()} method.
In order to add custom attributes to the manually constructed bytecode concrete
-subclasses of the {@link org.objectweb.asm.Attribute Attribute} can be passed to
-the visitAttribute methods of the
-{@link org.objectweb.asm.ClassVisitor ClassVisitor},
+subclasses of the {@link org.objectweb.asm.Attribute Attribute} can be passed to
+the visitAttribute methods of the
+{@link org.objectweb.asm.ClassVisitor ClassVisitor},
{@link org.objectweb.asm.FieldVisitor FieldVisitor} and
{@link org.objectweb.asm.MethodVisitor MethodVisitor} interfaces.
http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/d6e5f413/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/commons/AdviceAdapter.java
----------------------------------------------------------------------
diff --git a/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/commons/AdviceAdapter.java b/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/commons/AdviceAdapter.java
deleted file mode 100644
index f50b84c..0000000
--- a/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/commons/AdviceAdapter.java
+++ /dev/null
@@ -1,613 +0,0 @@
-/***
- * ASM: a very small and fast Java bytecode manipulation framework
- * Copyright (c) 2000-2007 INRIA, France Telecom
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the copyright holders nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
- * THE POSSIBILITY OF SUCH DAMAGE.
- */
-package org.apache.tapestry5.internal.plastic.asm.commons;
-
-import org.apache.tapestry5.internal.plastic.asm.Label;
-import org.apache.tapestry5.internal.plastic.asm.MethodVisitor;
-import org.apache.tapestry5.internal.plastic.asm.Opcodes;
-import org.apache.tapestry5.internal.plastic.asm.Type;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-/**
- * A {@link org.apache.tapestry5.internal.plastic.asm.MethodAdapter} to insert before, after and around
- * advices in methods and constructors. <p> The behavior for constructors is
- * like this: <ol>
- *
- * <li>as long as the INVOKESPECIAL for the object initialization has not been
- * reached, every bytecode instruction is dispatched in the ctor code visitor</li>
- *
- * <li>when this one is reached, it is only added in the ctor code visitor and
- * a JP invoke is added</li>
- *
- * <li>after that, only the other code visitor receives the instructions</li>
- *
- * </ol>
- *
- * @author Eugene Kuleshov
- * @author Eric Bruneton
- */
-public abstract class AdviceAdapter extends GeneratorAdapter implements Opcodes
-{
- private static final Object THIS = new Object();
- private static final Object OTHER = new Object();
-
- protected int methodAccess;
- protected String methodDesc;
-
- private boolean constructor;
- private boolean superInitialized;
- private List stackFrame;
- private Map branches;
-
- /**
- * Creates a new {@link AdviceAdapter}.
- *
- * @param mv the method visitor to which this adapter delegates calls.
- * @param access the method's access flags (see {@link Opcodes}).
- * @param name the method's name.
- * @param desc the method's descriptor (see {@link Type Type}).
- */
- protected AdviceAdapter(
- final MethodVisitor mv,
- final int access,
- final String name,
- final String desc)
- {
- super(mv, access, name, desc);
- methodAccess = access;
- methodDesc = desc;
-
- constructor = "<init>".equals(name);
- }
-
- public void visitCode() {
- mv.visitCode();
- if (constructor) {
- stackFrame = new ArrayList();
- branches = new HashMap();
- } else {
- superInitialized = true;
- onMethodEnter();
- }
- }
-
- public void visitLabel(final Label label) {
- mv.visitLabel(label);
-
- if (constructor && branches != null) {
- List frame = (List) branches.get(label);
- if (frame != null) {
- stackFrame = frame;
- branches.remove(label);
- }
- }
- }
-
- public void visitInsn(final int opcode) {
- if (constructor) {
- int s;
- switch (opcode) {
- case RETURN: // empty stack
- onMethodExit(opcode);
- break;
-
- case IRETURN: // 1 before n/a after
- case FRETURN: // 1 before n/a after
- case ARETURN: // 1 before n/a after
- case ATHROW: // 1 before n/a after
- popValue();
- onMethodExit(opcode);
- break;
-
- case LRETURN: // 2 before n/a after
- case DRETURN: // 2 before n/a after
- popValue();
- popValue();
- onMethodExit(opcode);
- break;
-
- case NOP:
- case LALOAD: // remove 2 add 2
- case DALOAD: // remove 2 add 2
- case LNEG:
- case DNEG:
- case FNEG:
- case INEG:
- case L2D:
- case D2L:
- case F2I:
- case I2B:
- case I2C:
- case I2S:
- case I2F:
- case ARRAYLENGTH:
- break;
-
- case ACONST_NULL:
- case ICONST_M1:
- case ICONST_0:
- case ICONST_1:
- case ICONST_2:
- case ICONST_3:
- case ICONST_4:
- case ICONST_5:
- case FCONST_0:
- case FCONST_1:
- case FCONST_2:
- case F2L: // 1 before 2 after
- case F2D:
- case I2L:
- case I2D:
- pushValue(OTHER);
- break;
-
- case LCONST_0:
- case LCONST_1:
- case DCONST_0:
- case DCONST_1:
- pushValue(OTHER);
- pushValue(OTHER);
- break;
-
- case IALOAD: // remove 2 add 1
- case FALOAD: // remove 2 add 1
- case AALOAD: // remove 2 add 1
- case BALOAD: // remove 2 add 1
- case CALOAD: // remove 2 add 1
- case SALOAD: // remove 2 add 1
- case POP:
- case IADD:
- case FADD:
- case ISUB:
- case LSHL: // 3 before 2 after
- case LSHR: // 3 before 2 after
- case LUSHR: // 3 before 2 after
- case L2I: // 2 before 1 after
- case L2F: // 2 before 1 after
- case D2I: // 2 before 1 after
- case D2F: // 2 before 1 after
- case FSUB:
- case FMUL:
- case FDIV:
- case FREM:
- case FCMPL: // 2 before 1 after
- case FCMPG: // 2 before 1 after
- case IMUL:
- case IDIV:
- case IREM:
- case ISHL:
- case ISHR:
- case IUSHR:
- case IAND:
- case IOR:
- case IXOR:
- case MONITORENTER:
- case MONITOREXIT:
- popValue();
- break;
-
- case POP2:
- case LSUB:
- case LMUL:
- case LDIV:
- case LREM:
- case LADD:
- case LAND:
- case LOR:
- case LXOR:
- case DADD:
- case DMUL:
- case DSUB:
- case DDIV:
- case DREM:
- popValue();
- popValue();
- break;
-
- case IASTORE:
- case FASTORE:
- case AASTORE:
- case BASTORE:
- case CASTORE:
- case SASTORE:
- case LCMP: // 4 before 1 after
- case DCMPL:
- case DCMPG:
- popValue();
- popValue();
- popValue();
- break;
-
- case LASTORE:
- case DASTORE:
- popValue();
- popValue();
- popValue();
- popValue();
- break;
-
- case DUP:
- pushValue(peekValue());
- break;
-
- case DUP_X1:
- s = stackFrame.size();
- stackFrame.add(s - 2, stackFrame.get(s - 1));
- break;
-
- case DUP_X2:
- s = stackFrame.size();
- stackFrame.add(s - 3, stackFrame.get(s - 1));
- break;
-
- case DUP2:
- s = stackFrame.size();
- stackFrame.add(s - 2, stackFrame.get(s - 1));
- stackFrame.add(s - 2, stackFrame.get(s - 1));
- break;
-
- case DUP2_X1:
- s = stackFrame.size();
- stackFrame.add(s - 3, stackFrame.get(s - 1));
- stackFrame.add(s - 3, stackFrame.get(s - 1));
- break;
-
- case DUP2_X2:
- s = stackFrame.size();
- stackFrame.add(s - 4, stackFrame.get(s - 1));
- stackFrame.add(s - 4, stackFrame.get(s - 1));
- break;
-
- case SWAP:
- s = stackFrame.size();
- stackFrame.add(s - 2, stackFrame.get(s - 1));
- stackFrame.remove(s);
- break;
- }
- } else {
- switch (opcode) {
- case RETURN:
- case IRETURN:
- case FRETURN:
- case ARETURN:
- case LRETURN:
- case DRETURN:
- case ATHROW:
- onMethodExit(opcode);
- break;
- }
- }
- mv.visitInsn(opcode);
- }
-
- public void visitVarInsn(final int opcode, final int var) {
- super.visitVarInsn(opcode, var);
-
- if (constructor) {
- switch (opcode) {
- case ILOAD:
- case FLOAD:
- pushValue(OTHER);
- break;
- case LLOAD:
- case DLOAD:
- pushValue(OTHER);
- pushValue(OTHER);
- break;
- case ALOAD:
- pushValue(var == 0 ? THIS : OTHER);
- break;
- case ASTORE:
- case ISTORE:
- case FSTORE:
- popValue();
- break;
- case LSTORE:
- case DSTORE:
- popValue();
- popValue();
- break;
- }
- }
- }
-
- public void visitFieldInsn(
- final int opcode,
- final String owner,
- final String name,
- final String desc)
- {
- mv.visitFieldInsn(opcode, owner, name, desc);
-
- if (constructor) {
- char c = desc.charAt(0);
- boolean longOrDouble = c == 'J' || c == 'D';
- switch (opcode) {
- case GETSTATIC:
- pushValue(OTHER);
- if (longOrDouble) {
- pushValue(OTHER);
- }
- break;
- case PUTSTATIC:
- popValue();
- if (longOrDouble) {
- popValue();
- }
- break;
- case PUTFIELD:
- popValue();
- if (longOrDouble) {
- popValue();
- popValue();
- }
- break;
- // case GETFIELD:
- default:
- if (longOrDouble) {
- pushValue(OTHER);
- }
- }
- }
- }
-
- public void visitIntInsn(final int opcode, final int operand) {
- mv.visitIntInsn(opcode, operand);
-
- if (constructor && opcode!=NEWARRAY) {
- pushValue(OTHER);
- }
- }
-
- public void visitLdcInsn(final Object cst) {
- mv.visitLdcInsn(cst);
-
- if (constructor) {
- pushValue(OTHER);
- if (cst instanceof Double || cst instanceof Long) {
- pushValue(OTHER);
- }
- }
- }
-
- public void visitMultiANewArrayInsn(final String desc, final int dims) {
- mv.visitMultiANewArrayInsn(desc, dims);
-
- if (constructor) {
- for (int i = 0; i < dims; i++) {
- popValue();
- }
- pushValue(OTHER);
- }
- }
-
- public void visitTypeInsn(final int opcode, final String type) {
- mv.visitTypeInsn(opcode, type);
-
- // ANEWARRAY, CHECKCAST or INSTANCEOF don't change stack
- if (constructor && opcode == NEW) {
- pushValue(OTHER);
- }
- }
-
- public void visitMethodInsn(
- final int opcode,
- final String owner,
- final String name,
- final String desc)
- {
- mv.visitMethodInsn(opcode, owner, name, desc);
-
- if (constructor) {
- Type[] types = Type.getArgumentTypes(desc);
- for (int i = 0; i < types.length; i++) {
- popValue();
- if (types[i].getSize() == 2) {
- popValue();
- }
- }
- switch (opcode) {
- // case INVOKESTATIC:
- // case INVOKEDYNAMIC
- // break;
-
- case INVOKEINTERFACE:
- case INVOKEVIRTUAL:
- popValue(); // objectref
- break;
-
- case INVOKESPECIAL:
- Object type = popValue(); // objectref
- if (type == THIS && !superInitialized) {
- onMethodEnter();
- superInitialized = true;
- // once super has been initialized it is no longer
- // necessary to keep track of stack state
- constructor = false;
- }
- break;
- }
-
- Type returnType = Type.getReturnType(desc);
- if (returnType != Type.VOID_TYPE) {
- pushValue(OTHER);
- if (returnType.getSize() == 2) {
- pushValue(OTHER);
- }
- }
- }
- }
-
- public void visitJumpInsn(final int opcode, final Label label) {
- mv.visitJumpInsn(opcode, label);
-
- if (constructor) {
- switch (opcode) {
- case IFEQ:
- case IFNE:
- case IFLT:
- case IFGE:
- case IFGT:
- case IFLE:
- case IFNULL:
- case IFNONNULL:
- popValue();
- break;
-
- case IF_ICMPEQ:
- case IF_ICMPNE:
- case IF_ICMPLT:
- case IF_ICMPGE:
- case IF_ICMPGT:
- case IF_ICMPLE:
- case IF_ACMPEQ:
- case IF_ACMPNE:
- popValue();
- popValue();
- break;
-
- case JSR:
- pushValue(OTHER);
- break;
- }
- addBranch(label);
- }
- }
-
- public void visitLookupSwitchInsn(
- final Label dflt,
- final int[] keys,
- final Label[] labels)
- {
- mv.visitLookupSwitchInsn(dflt, keys, labels);
-
- if (constructor) {
- popValue();
- addBranches(dflt, labels);
- }
- }
-
- public void visitTableSwitchInsn(
- final int min,
- final int max,
- final Label dflt,
- final Label[] labels)
- {
- mv.visitTableSwitchInsn(min, max, dflt, labels);
-
- if (constructor) {
- popValue();
- addBranches(dflt, labels);
- }
- }
-
- private void addBranches(final Label dflt, final Label[] labels) {
- addBranch(dflt);
- for (int i = 0; i < labels.length; i++) {
- addBranch(labels[i]);
- }
- }
-
- private void addBranch(final Label label) {
- if (branches.containsKey(label)) {
- return;
- }
- branches.put(label, new ArrayList(stackFrame));
- }
-
- private Object popValue() {
- return stackFrame.remove(stackFrame.size() - 1);
- }
-
- private Object peekValue() {
- return stackFrame.get(stackFrame.size() - 1);
- }
-
- private void pushValue(final Object o) {
- stackFrame.add(o);
- }
-
- /**
- * Called at the beginning of the method or after super class class call in
- * the constructor. <br><br>
- *
- * <i>Custom code can use or change all the local variables, but should not
- * change state of the stack.</i>
- */
- protected void onMethodEnter() {
- }
-
- /**
- * Called before explicit exit from the method using either return or throw.
- * Top element on the stack contains the return value or exception instance.
- * For example:
- *
- * <pre>
- * public void onMethodExit(int opcode) {
- * if(opcode==RETURN) {
- * visitInsn(ACONST_NULL);
- * } else if(opcode==ARETURN || opcode==ATHROW) {
- * dup();
- * } else {
- * if(opcode==LRETURN || opcode==DRETURN) {
- * dup2();
- * } else {
- * dup();
- * }
- * box(Type.getReturnType(this.methodDesc));
- * }
- * visitIntInsn(SIPUSH, opcode);
- * visitMethodInsn(INVOKESTATIC, owner, "onExit", "(Ljava/lang/Object;I)V");
- * }
- *
- * // an actual call back method
- * public static void onExit(Object param, int opcode) {
- * ...
- * </pre>
- *
- * <br><br>
- *
- * <i>Custom code can use or change all the local variables, but should not
- * change state of the stack.</i>
- *
- * @param opcode one of the RETURN, IRETURN, FRETURN, ARETURN, LRETURN,
- * DRETURN or ATHROW
- *
- */
- protected void onMethodExit(int opcode) {
- }
-
- // TODO onException, onMethodCall
-
-}