You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tapestry.apache.org by th...@apache.org on 2018/11/29 00:34:19 UTC
[32/46] tapestry-5 git commit: TAP5-2588: upgrading from ASM 6 to 7
for Java 9+ support
http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/1c71aec7/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/TypeReference.java
----------------------------------------------------------------------
diff --git a/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/TypeReference.java b/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/TypeReference.java
old mode 100644
new mode 100755
index d518864..96bfe33
--- a/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/TypeReference.java
+++ b/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/TypeReference.java
@@ -1,452 +1,436 @@
-/***
- * ASM: a very small and fast Java bytecode manipulation framework
- * Copyright (c) 2000-2013 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;
-
-/**
- * A reference to a type appearing in a class, field or method declaration, or
- * on an instruction. Such a reference designates the part of the class where
- * the referenced type is appearing (e.g. an 'extends', 'implements' or 'throws'
- * clause, a 'new' instruction, a 'catch' clause, a type cast, a local variable
- * declaration, etc).
- *
- * @author Eric Bruneton
- */
-public class TypeReference {
-
- /**
- * The sort of type references that target a type parameter of a generic
- * class. See {@link #getSort getSort}.
- */
- public final static int CLASS_TYPE_PARAMETER = 0x00;
-
- /**
- * The sort of type references that target a type parameter of a generic
- * method. See {@link #getSort getSort}.
- */
- public final static int METHOD_TYPE_PARAMETER = 0x01;
-
- /**
- * The sort of type references that target the super class of a class or one
- * of the interfaces it implements. See {@link #getSort getSort}.
- */
- public final static int CLASS_EXTENDS = 0x10;
-
- /**
- * The sort of type references that target a bound of a type parameter of a
- * generic class. See {@link #getSort getSort}.
- */
- public final static int CLASS_TYPE_PARAMETER_BOUND = 0x11;
-
- /**
- * The sort of type references that target a bound of a type parameter of a
- * generic method. See {@link #getSort getSort}.
- */
- public final static int METHOD_TYPE_PARAMETER_BOUND = 0x12;
-
- /**
- * The sort of type references that target the type of a field. See
- * {@link #getSort getSort}.
- */
- public final static int FIELD = 0x13;
-
- /**
- * The sort of type references that target the return type of a method. See
- * {@link #getSort getSort}.
- */
- public final static int METHOD_RETURN = 0x14;
-
- /**
- * The sort of type references that target the receiver type of a method.
- * See {@link #getSort getSort}.
- */
- public final static int METHOD_RECEIVER = 0x15;
-
- /**
- * The sort of type references that target the type of a formal parameter of
- * a method. See {@link #getSort getSort}.
- */
- public final static int METHOD_FORMAL_PARAMETER = 0x16;
-
- /**
- * The sort of type references that target the type of an exception declared
- * in the throws clause of a method. See {@link #getSort getSort}.
- */
- public final static int THROWS = 0x17;
-
- /**
- * The sort of type references that target the type of a local variable in a
- * method. See {@link #getSort getSort}.
- */
- public final static int LOCAL_VARIABLE = 0x40;
-
- /**
- * The sort of type references that target the type of a resource variable
- * in a method. See {@link #getSort getSort}.
- */
- public final static int RESOURCE_VARIABLE = 0x41;
-
- /**
- * The sort of type references that target the type of the exception of a
- * 'catch' clause in a method. See {@link #getSort getSort}.
- */
- public final static int EXCEPTION_PARAMETER = 0x42;
-
- /**
- * The sort of type references that target the type declared in an
- * 'instanceof' instruction. See {@link #getSort getSort}.
- */
- public final static int INSTANCEOF = 0x43;
-
- /**
- * The sort of type references that target the type of the object created by
- * a 'new' instruction. See {@link #getSort getSort}.
- */
- public final static int NEW = 0x44;
-
- /**
- * The sort of type references that target the receiver type of a
- * constructor reference. See {@link #getSort getSort}.
- */
- public final static int CONSTRUCTOR_REFERENCE = 0x45;
-
- /**
- * The sort of type references that target the receiver type of a method
- * reference. See {@link #getSort getSort}.
- */
- public final static int METHOD_REFERENCE = 0x46;
-
- /**
- * The sort of type references that target the type declared in an explicit
- * or implicit cast instruction. See {@link #getSort getSort}.
- */
- public final static int CAST = 0x47;
-
- /**
- * The sort of type references that target a type parameter of a generic
- * constructor in a constructor call. See {@link #getSort getSort}.
- */
- public final static int CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT = 0x48;
-
- /**
- * The sort of type references that target a type parameter of a generic
- * method in a method call. See {@link #getSort getSort}.
- */
- public final static int METHOD_INVOCATION_TYPE_ARGUMENT = 0x49;
-
- /**
- * The sort of type references that target a type parameter of a generic
- * constructor in a constructor reference. See {@link #getSort getSort}.
- */
- public final static int CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT = 0x4A;
-
- /**
- * The sort of type references that target a type parameter of a generic
- * method in a method reference. See {@link #getSort getSort}.
- */
- public final static int METHOD_REFERENCE_TYPE_ARGUMENT = 0x4B;
-
- /**
- * The type reference value in Java class file format.
- */
- private int value;
-
- /**
- * Creates a new TypeReference.
- *
- * @param typeRef
- * the int encoded value of the type reference, as received in a
- * visit method related to type annotations, like
- * visitTypeAnnotation.
- */
- public TypeReference(int typeRef) {
- this.value = typeRef;
- }
-
- /**
- * Returns a type reference of the given sort.
- *
- * @param sort
- * {@link #FIELD FIELD}, {@link #METHOD_RETURN METHOD_RETURN},
- * {@link #METHOD_RECEIVER METHOD_RECEIVER},
- * {@link #LOCAL_VARIABLE LOCAL_VARIABLE},
- * {@link #RESOURCE_VARIABLE RESOURCE_VARIABLE},
- * {@link #INSTANCEOF INSTANCEOF}, {@link #NEW NEW},
- * {@link #CONSTRUCTOR_REFERENCE CONSTRUCTOR_REFERENCE}, or
- * {@link #METHOD_REFERENCE METHOD_REFERENCE}.
- * @return a type reference of the given sort.
- */
- public static TypeReference newTypeReference(int sort) {
- return new TypeReference(sort << 24);
- }
-
- /**
- * Returns a reference to a type parameter of a generic class or method.
- *
- * @param sort
- * {@link #CLASS_TYPE_PARAMETER CLASS_TYPE_PARAMETER} or
- * {@link #METHOD_TYPE_PARAMETER METHOD_TYPE_PARAMETER}.
- * @param paramIndex
- * the type parameter index.
- * @return a reference to the given generic class or method type parameter.
- */
- public static TypeReference newTypeParameterReference(int sort,
- int paramIndex) {
- return new TypeReference((sort << 24) | (paramIndex << 16));
- }
-
- /**
- * Returns a reference to a type parameter bound of a generic class or
- * method.
- *
- * @param sort
- * {@link #CLASS_TYPE_PARAMETER CLASS_TYPE_PARAMETER} or
- * {@link #METHOD_TYPE_PARAMETER METHOD_TYPE_PARAMETER}.
- * @param paramIndex
- * the type parameter index.
- * @param boundIndex
- * the type bound index within the above type parameters.
- * @return a reference to the given generic class or method type parameter
- * bound.
- */
- public static TypeReference newTypeParameterBoundReference(int sort,
- int paramIndex, int boundIndex) {
- return new TypeReference((sort << 24) | (paramIndex << 16)
- | (boundIndex << 8));
- }
-
- /**
- * Returns a reference to the super class or to an interface of the
- * 'implements' clause of a class.
- *
- * @param itfIndex
- * the index of an interface in the 'implements' clause of a
- * class, or -1 to reference the super class of the class.
- * @return a reference to the given super type of a class.
- */
- public static TypeReference newSuperTypeReference(int itfIndex) {
- itfIndex &= 0xFFFF;
- return new TypeReference((CLASS_EXTENDS << 24) | (itfIndex << 8));
- }
-
- /**
- * Returns a reference to the type of a formal parameter of a method.
- *
- * @param paramIndex
- * the formal parameter index.
- *
- * @return a reference to the type of the given method formal parameter.
- */
- public static TypeReference newFormalParameterReference(int paramIndex) {
- return new TypeReference((METHOD_FORMAL_PARAMETER << 24)
- | (paramIndex << 16));
- }
-
- /**
- * Returns a reference to the type of an exception, in a 'throws' clause of
- * a method.
- *
- * @param exceptionIndex
- * the index of an exception in a 'throws' clause of a method.
- *
- * @return a reference to the type of the given exception.
- */
- public static TypeReference newExceptionReference(int exceptionIndex) {
- return new TypeReference((THROWS << 24) | (exceptionIndex << 8));
- }
-
- /**
- * Returns a reference to the type of the exception declared in a 'catch'
- * clause of a method.
- *
- * @param tryCatchBlockIndex
- * the index of a try catch block (using the order in which they
- * are visited with visitTryCatchBlock).
- *
- * @return a reference to the type of the given exception.
- */
- public static TypeReference newTryCatchReference(int tryCatchBlockIndex) {
- return new TypeReference((EXCEPTION_PARAMETER << 24)
- | (tryCatchBlockIndex << 8));
- }
-
- /**
- * Returns a reference to the type of a type argument in a constructor or
- * method call or reference.
- *
- * @param sort
- * {@link #CAST CAST},
- * {@link #CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT
- * CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT},
- * {@link #METHOD_INVOCATION_TYPE_ARGUMENT
- * METHOD_INVOCATION_TYPE_ARGUMENT},
- * {@link #CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT
- * CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT}, or
- * {@link #METHOD_REFERENCE_TYPE_ARGUMENT
- * METHOD_REFERENCE_TYPE_ARGUMENT}.
- * @param argIndex
- * the type argument index.
- *
- * @return a reference to the type of the given type argument.
- */
- public static TypeReference newTypeArgumentReference(int sort, int argIndex) {
- return new TypeReference((sort << 24) | argIndex);
- }
-
- /**
- * Returns the sort of this type reference.
- *
- * @return {@link #CLASS_TYPE_PARAMETER CLASS_TYPE_PARAMETER},
- * {@link #METHOD_TYPE_PARAMETER METHOD_TYPE_PARAMETER},
- * {@link #CLASS_EXTENDS CLASS_EXTENDS},
- * {@link #CLASS_TYPE_PARAMETER_BOUND CLASS_TYPE_PARAMETER_BOUND},
- * {@link #METHOD_TYPE_PARAMETER_BOUND METHOD_TYPE_PARAMETER_BOUND},
- * {@link #FIELD FIELD}, {@link #METHOD_RETURN METHOD_RETURN},
- * {@link #METHOD_RECEIVER METHOD_RECEIVER},
- * {@link #METHOD_FORMAL_PARAMETER METHOD_FORMAL_PARAMETER},
- * {@link #THROWS THROWS}, {@link #LOCAL_VARIABLE LOCAL_VARIABLE},
- * {@link #RESOURCE_VARIABLE RESOURCE_VARIABLE},
- * {@link #EXCEPTION_PARAMETER EXCEPTION_PARAMETER},
- * {@link #INSTANCEOF INSTANCEOF}, {@link #NEW NEW},
- * {@link #CONSTRUCTOR_REFERENCE CONSTRUCTOR_REFERENCE},
- * {@link #METHOD_REFERENCE METHOD_REFERENCE}, {@link #CAST CAST},
- * {@link #CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT
- * CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT},
- * {@link #METHOD_INVOCATION_TYPE_ARGUMENT
- * METHOD_INVOCATION_TYPE_ARGUMENT},
- * {@link #CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT
- * CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT}, or
- * {@link #METHOD_REFERENCE_TYPE_ARGUMENT
- * METHOD_REFERENCE_TYPE_ARGUMENT}.
- */
- public int getSort() {
- return value >>> 24;
- }
-
- /**
- * Returns the index of the type parameter referenced by this type
- * reference. This method must only be used for type references whose sort
- * is {@link #CLASS_TYPE_PARAMETER CLASS_TYPE_PARAMETER},
- * {@link #METHOD_TYPE_PARAMETER METHOD_TYPE_PARAMETER},
- * {@link #CLASS_TYPE_PARAMETER_BOUND CLASS_TYPE_PARAMETER_BOUND} or
- * {@link #METHOD_TYPE_PARAMETER_BOUND METHOD_TYPE_PARAMETER_BOUND}.
- *
- * @return a type parameter index.
- */
- public int getTypeParameterIndex() {
- return (value & 0x00FF0000) >> 16;
- }
-
- /**
- * Returns the index of the type parameter bound, within the type parameter
- * {@link #getTypeParameterIndex}, referenced by this type reference. This
- * method must only be used for type references whose sort is
- * {@link #CLASS_TYPE_PARAMETER_BOUND CLASS_TYPE_PARAMETER_BOUND} or
- * {@link #METHOD_TYPE_PARAMETER_BOUND METHOD_TYPE_PARAMETER_BOUND}.
- *
- * @return a type parameter bound index.
- */
- public int getTypeParameterBoundIndex() {
- return (value & 0x0000FF00) >> 8;
- }
-
- /**
- * Returns the index of the "super type" of a class that is referenced by
- * this type reference. This method must only be used for type references
- * whose sort is {@link #CLASS_EXTENDS CLASS_EXTENDS}.
- *
- * @return the index of an interface in the 'implements' clause of a class,
- * or -1 if this type reference references the type of the super
- * class.
- */
- public int getSuperTypeIndex() {
- return (short) ((value & 0x00FFFF00) >> 8);
- }
-
- /**
- * Returns the index of the formal parameter whose type is referenced by
- * this type reference. This method must only be used for type references
- * whose sort is {@link #METHOD_FORMAL_PARAMETER METHOD_FORMAL_PARAMETER}.
- *
- * @return a formal parameter index.
- */
- public int getFormalParameterIndex() {
- return (value & 0x00FF0000) >> 16;
- }
-
- /**
- * Returns the index of the exception, in a 'throws' clause of a method,
- * whose type is referenced by this type reference. This method must only be
- * used for type references whose sort is {@link #THROWS THROWS}.
- *
- * @return the index of an exception in the 'throws' clause of a method.
- */
- public int getExceptionIndex() {
- return (value & 0x00FFFF00) >> 8;
- }
-
- /**
- * Returns the index of the try catch block (using the order in which they
- * are visited with visitTryCatchBlock), whose 'catch' type is referenced by
- * this type reference. This method must only be used for type references
- * whose sort is {@link #EXCEPTION_PARAMETER EXCEPTION_PARAMETER} .
- *
- * @return the index of an exception in the 'throws' clause of a method.
- */
- public int getTryCatchBlockIndex() {
- return (value & 0x00FFFF00) >> 8;
- }
-
- /**
- * Returns the index of the type argument referenced by this type reference.
- * This method must only be used for type references whose sort is
- * {@link #CAST CAST}, {@link #CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT
- * CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT},
- * {@link #METHOD_INVOCATION_TYPE_ARGUMENT METHOD_INVOCATION_TYPE_ARGUMENT},
- * {@link #CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT
- * CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT}, or
- * {@link #METHOD_REFERENCE_TYPE_ARGUMENT METHOD_REFERENCE_TYPE_ARGUMENT}.
- *
- * @return a type parameter index.
- */
- public int getTypeArgumentIndex() {
- return value & 0xFF;
- }
-
- /**
- * Returns the int encoded value of this type reference, suitable for use in
- * visit methods related to type annotations, like visitTypeAnnotation.
- *
- * @return the int encoded value of this type reference.
- */
- public int getValue() {
- return value;
- }
-}
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 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;
+
+/**
+ * A reference to a type appearing in a class, field or method declaration, or on an instruction.
+ * Such a reference designates the part of the class where the referenced type is appearing (e.g. an
+ * 'extends', 'implements' or 'throws' clause, a 'new' instruction, a 'catch' clause, a type cast, a
+ * local variable declaration, etc).
+ *
+ * @author Eric Bruneton
+ */
+public class TypeReference {
+
+ /**
+ * The sort of type references that target a type parameter of a generic class. See {@link
+ * #getSort}.
+ */
+ public static final int CLASS_TYPE_PARAMETER = 0x00;
+
+ /**
+ * The sort of type references that target a type parameter of a generic method. See {@link
+ * #getSort}.
+ */
+ public static final int METHOD_TYPE_PARAMETER = 0x01;
+
+ /**
+ * The sort of type references that target the super class of a class or one of the interfaces it
+ * implements. See {@link #getSort}.
+ */
+ public static final int CLASS_EXTENDS = 0x10;
+
+ /**
+ * The sort of type references that target a bound of a type parameter of a generic class. See
+ * {@link #getSort}.
+ */
+ public static final int CLASS_TYPE_PARAMETER_BOUND = 0x11;
+
+ /**
+ * The sort of type references that target a bound of a type parameter of a generic method. See
+ * {@link #getSort}.
+ */
+ public static final int METHOD_TYPE_PARAMETER_BOUND = 0x12;
+
+ /** The sort of type references that target the type of a field. See {@link #getSort}. */
+ public static final int FIELD = 0x13;
+
+ /** The sort of type references that target the return type of a method. See {@link #getSort}. */
+ public static final int METHOD_RETURN = 0x14;
+
+ /**
+ * The sort of type references that target the receiver type of a method. See {@link #getSort}.
+ */
+ public static final int METHOD_RECEIVER = 0x15;
+
+ /**
+ * The sort of type references that target the type of a formal parameter of a method. See {@link
+ * #getSort}.
+ */
+ public static final int METHOD_FORMAL_PARAMETER = 0x16;
+
+ /**
+ * The sort of type references that target the type of an exception declared in the throws clause
+ * of a method. See {@link #getSort}.
+ */
+ public static final int THROWS = 0x17;
+
+ /**
+ * The sort of type references that target the type of a local variable in a method. See {@link
+ * #getSort}.
+ */
+ public static final int LOCAL_VARIABLE = 0x40;
+
+ /**
+ * The sort of type references that target the type of a resource variable in a method. See {@link
+ * #getSort}.
+ */
+ public static final int RESOURCE_VARIABLE = 0x41;
+
+ /**
+ * The sort of type references that target the type of the exception of a 'catch' clause in a
+ * method. See {@link #getSort}.
+ */
+ public static final int EXCEPTION_PARAMETER = 0x42;
+
+ /**
+ * The sort of type references that target the type declared in an 'instanceof' instruction. See
+ * {@link #getSort}.
+ */
+ public static final int INSTANCEOF = 0x43;
+
+ /**
+ * The sort of type references that target the type of the object created by a 'new' instruction.
+ * See {@link #getSort}.
+ */
+ public static final int NEW = 0x44;
+
+ /**
+ * The sort of type references that target the receiver type of a constructor reference. See
+ * {@link #getSort}.
+ */
+ public static final int CONSTRUCTOR_REFERENCE = 0x45;
+
+ /**
+ * The sort of type references that target the receiver type of a method reference. See {@link
+ * #getSort}.
+ */
+ public static final int METHOD_REFERENCE = 0x46;
+
+ /**
+ * The sort of type references that target the type declared in an explicit or implicit cast
+ * instruction. See {@link #getSort}.
+ */
+ public static final int CAST = 0x47;
+
+ /**
+ * The sort of type references that target a type parameter of a generic constructor in a
+ * constructor call. See {@link #getSort}.
+ */
+ public static final int CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT = 0x48;
+
+ /**
+ * The sort of type references that target a type parameter of a generic method in a method call.
+ * See {@link #getSort}.
+ */
+ public static final int METHOD_INVOCATION_TYPE_ARGUMENT = 0x49;
+
+ /**
+ * The sort of type references that target a type parameter of a generic constructor in a
+ * constructor reference. See {@link #getSort}.
+ */
+ public static final int CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT = 0x4A;
+
+ /**
+ * The sort of type references that target a type parameter of a generic method in a method
+ * reference. See {@link #getSort}.
+ */
+ public static final int METHOD_REFERENCE_TYPE_ARGUMENT = 0x4B;
+
+ /**
+ * The target_type and target_info structures - as defined in the Java Virtual Machine
+ * Specification (JVMS) - corresponding to this type reference. target_type uses one byte, and all
+ * the target_info union fields use up to 3 bytes (except localvar_target, handled with the
+ * specific method {@link MethodVisitor#visitLocalVariableAnnotation}). Thus, both structures can
+ * be stored in an int.
+ *
+ * <p>This int field stores target_type (called the TypeReference 'sort' in the public API of this
+ * class) in its most significant byte, followed by the target_info fields. Depending on
+ * target_type, 1, 2 or even 3 least significant bytes of this field are unused. target_info
+ * fields which reference bytecode offsets are set to 0 (these offsets are ignored in ClassReader,
+ * and recomputed in MethodWriter).
+ *
+ * @see <a href="https://docs.oracle.com/javase/specs/jvms/se9/html/jvms-4.html#jvms-4.7.20">JVMS
+ * 4.7.20</a>
+ * @see <a
+ * href="https://docs.oracle.com/javase/specs/jvms/se9/html/jvms-4.html#jvms-4.7.20.1">JVMS
+ * 4.7.20.1</a>
+ */
+ private final int targetTypeAndInfo;
+
+ /**
+ * Constructs a new TypeReference.
+ *
+ * @param typeRef the int encoded value of the type reference, as received in a visit method
+ * related to type annotations, such as {@link ClassVisitor#visitTypeAnnotation}.
+ */
+ public TypeReference(final int typeRef) {
+ this.targetTypeAndInfo = typeRef;
+ }
+
+ /**
+ * Returns a type reference of the given sort.
+ *
+ * @param sort one of {@link #FIELD}, {@link #METHOD_RETURN}, {@link #METHOD_RECEIVER}, {@link
+ * #LOCAL_VARIABLE}, {@link #RESOURCE_VARIABLE}, {@link #INSTANCEOF}, {@link #NEW}, {@link
+ * #CONSTRUCTOR_REFERENCE}, or {@link #METHOD_REFERENCE}.
+ * @return a type reference of the given sort.
+ */
+ public static TypeReference newTypeReference(final int sort) {
+ return new TypeReference(sort << 24);
+ }
+
+ /**
+ * Returns a reference to a type parameter of a generic class or method.
+ *
+ * @param sort one of {@link #CLASS_TYPE_PARAMETER} or {@link #METHOD_TYPE_PARAMETER}.
+ * @param paramIndex the type parameter index.
+ * @return a reference to the given generic class or method type parameter.
+ */
+ public static TypeReference newTypeParameterReference(final int sort, final int paramIndex) {
+ return new TypeReference((sort << 24) | (paramIndex << 16));
+ }
+
+ /**
+ * Returns a reference to a type parameter bound of a generic class or method.
+ *
+ * @param sort one of {@link #CLASS_TYPE_PARAMETER} or {@link #METHOD_TYPE_PARAMETER}.
+ * @param paramIndex the type parameter index.
+ * @param boundIndex the type bound index within the above type parameters.
+ * @return a reference to the given generic class or method type parameter bound.
+ */
+ public static TypeReference newTypeParameterBoundReference(
+ final int sort, final int paramIndex, final int boundIndex) {
+ return new TypeReference((sort << 24) | (paramIndex << 16) | (boundIndex << 8));
+ }
+
+ /**
+ * Returns a reference to the super class or to an interface of the 'implements' clause of a
+ * class.
+ *
+ * @param itfIndex the index of an interface in the 'implements' clause of a class, or -1 to
+ * reference the super class of the class.
+ * @return a reference to the given super type of a class.
+ */
+ public static TypeReference newSuperTypeReference(final int itfIndex) {
+ return new TypeReference((CLASS_EXTENDS << 24) | ((itfIndex & 0xFFFF) << 8));
+ }
+
+ /**
+ * Returns a reference to the type of a formal parameter of a method.
+ *
+ * @param paramIndex the formal parameter index.
+ * @return a reference to the type of the given method formal parameter.
+ */
+ public static TypeReference newFormalParameterReference(final int paramIndex) {
+ return new TypeReference((METHOD_FORMAL_PARAMETER << 24) | (paramIndex << 16));
+ }
+
+ /**
+ * Returns a reference to the type of an exception, in a 'throws' clause of a method.
+ *
+ * @param exceptionIndex the index of an exception in a 'throws' clause of a method.
+ * @return a reference to the type of the given exception.
+ */
+ public static TypeReference newExceptionReference(final int exceptionIndex) {
+ return new TypeReference((THROWS << 24) | (exceptionIndex << 8));
+ }
+
+ /**
+ * Returns a reference to the type of the exception declared in a 'catch' clause of a method.
+ *
+ * @param tryCatchBlockIndex the index of a try catch block (using the order in which they are
+ * visited with visitTryCatchBlock).
+ * @return a reference to the type of the given exception.
+ */
+ public static TypeReference newTryCatchReference(final int tryCatchBlockIndex) {
+ return new TypeReference((EXCEPTION_PARAMETER << 24) | (tryCatchBlockIndex << 8));
+ }
+
+ /**
+ * Returns a reference to the type of a type argument in a constructor or method call or
+ * reference.
+ *
+ * @param sort one of {@link #CAST}, {@link #CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT}, {@link
+ * #METHOD_INVOCATION_TYPE_ARGUMENT}, {@link #CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT}, or {@link
+ * #METHOD_REFERENCE_TYPE_ARGUMENT}.
+ * @param argIndex the type argument index.
+ * @return a reference to the type of the given type argument.
+ */
+ public static TypeReference newTypeArgumentReference(final int sort, final int argIndex) {
+ return new TypeReference((sort << 24) | argIndex);
+ }
+
+ /**
+ * Returns the sort of this type reference.
+ *
+ * @return one of {@link #CLASS_TYPE_PARAMETER}, {@link #METHOD_TYPE_PARAMETER}, {@link
+ * #CLASS_EXTENDS}, {@link #CLASS_TYPE_PARAMETER_BOUND}, {@link #METHOD_TYPE_PARAMETER_BOUND},
+ * {@link #FIELD}, {@link #METHOD_RETURN}, {@link #METHOD_RECEIVER}, {@link
+ * #METHOD_FORMAL_PARAMETER}, {@link #THROWS}, {@link #LOCAL_VARIABLE}, {@link
+ * #RESOURCE_VARIABLE}, {@link #EXCEPTION_PARAMETER}, {@link #INSTANCEOF}, {@link #NEW},
+ * {@link #CONSTRUCTOR_REFERENCE}, {@link #METHOD_REFERENCE}, {@link #CAST}, {@link
+ * #CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT}, {@link #METHOD_INVOCATION_TYPE_ARGUMENT}, {@link
+ * #CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT}, or {@link #METHOD_REFERENCE_TYPE_ARGUMENT}.
+ */
+ public int getSort() {
+ return targetTypeAndInfo >>> 24;
+ }
+
+ /**
+ * Returns the index of the type parameter referenced by this type reference. This method must
+ * only be used for type references whose sort is {@link #CLASS_TYPE_PARAMETER}, {@link
+ * #METHOD_TYPE_PARAMETER}, {@link #CLASS_TYPE_PARAMETER_BOUND} or {@link
+ * #METHOD_TYPE_PARAMETER_BOUND}.
+ *
+ * @return a type parameter index.
+ */
+ public int getTypeParameterIndex() {
+ return (targetTypeAndInfo & 0x00FF0000) >> 16;
+ }
+
+ /**
+ * Returns the index of the type parameter bound, within the type parameter {@link
+ * #getTypeParameterIndex}, referenced by this type reference. This method must only be used for
+ * type references whose sort is {@link #CLASS_TYPE_PARAMETER_BOUND} or {@link
+ * #METHOD_TYPE_PARAMETER_BOUND}.
+ *
+ * @return a type parameter bound index.
+ */
+ public int getTypeParameterBoundIndex() {
+ return (targetTypeAndInfo & 0x0000FF00) >> 8;
+ }
+
+ /**
+ * Returns the index of the "super type" of a class that is referenced by this type reference.
+ * This method must only be used for type references whose sort is {@link #CLASS_EXTENDS}.
+ *
+ * @return the index of an interface in the 'implements' clause of a class, or -1 if this type
+ * reference references the type of the super class.
+ */
+ public int getSuperTypeIndex() {
+ return (short) ((targetTypeAndInfo & 0x00FFFF00) >> 8);
+ }
+
+ /**
+ * Returns the index of the formal parameter whose type is referenced by this type reference. This
+ * method must only be used for type references whose sort is {@link #METHOD_FORMAL_PARAMETER}.
+ *
+ * @return a formal parameter index.
+ */
+ public int getFormalParameterIndex() {
+ return (targetTypeAndInfo & 0x00FF0000) >> 16;
+ }
+
+ /**
+ * Returns the index of the exception, in a 'throws' clause of a method, whose type is referenced
+ * by this type reference. This method must only be used for type references whose sort is {@link
+ * #THROWS}.
+ *
+ * @return the index of an exception in the 'throws' clause of a method.
+ */
+ public int getExceptionIndex() {
+ return (targetTypeAndInfo & 0x00FFFF00) >> 8;
+ }
+
+ /**
+ * Returns the index of the try catch block (using the order in which they are visited with
+ * visitTryCatchBlock), whose 'catch' type is referenced by this type reference. This method must
+ * only be used for type references whose sort is {@link #EXCEPTION_PARAMETER} .
+ *
+ * @return the index of an exception in the 'throws' clause of a method.
+ */
+ public int getTryCatchBlockIndex() {
+ return (targetTypeAndInfo & 0x00FFFF00) >> 8;
+ }
+
+ /**
+ * Returns the index of the type argument referenced by this type reference. This method must only
+ * be used for type references whose sort is {@link #CAST}, {@link
+ * #CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT}, {@link #METHOD_INVOCATION_TYPE_ARGUMENT}, {@link
+ * #CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT}, or {@link #METHOD_REFERENCE_TYPE_ARGUMENT}.
+ *
+ * @return a type parameter index.
+ */
+ public int getTypeArgumentIndex() {
+ return targetTypeAndInfo & 0xFF;
+ }
+
+ /**
+ * Returns the int encoded value of this type reference, suitable for use in visit methods related
+ * to type annotations, like visitTypeAnnotation.
+ *
+ * @return the int encoded value of this type reference.
+ */
+ public int getValue() {
+ return targetTypeAndInfo;
+ }
+
+ /**
+ * Puts the given target_type and target_info JVMS structures into the given ByteVector.
+ *
+ * @param targetTypeAndInfo a target_type and a target_info structures encoded as in {@link
+ * #targetTypeAndInfo}. LOCAL_VARIABLE and RESOURCE_VARIABLE target types are not supported.
+ * @param output where the type reference must be put.
+ */
+ static void putTarget(final int targetTypeAndInfo, final ByteVector output) {
+ switch (targetTypeAndInfo >>> 24) {
+ case CLASS_TYPE_PARAMETER:
+ case METHOD_TYPE_PARAMETER:
+ case METHOD_FORMAL_PARAMETER:
+ output.putShort(targetTypeAndInfo >>> 16);
+ break;
+ case FIELD:
+ case METHOD_RETURN:
+ case METHOD_RECEIVER:
+ output.putByte(targetTypeAndInfo >>> 24);
+ break;
+ case CAST:
+ case CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT:
+ case METHOD_INVOCATION_TYPE_ARGUMENT:
+ case CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT:
+ case METHOD_REFERENCE_TYPE_ARGUMENT:
+ output.putInt(targetTypeAndInfo);
+ break;
+ case CLASS_EXTENDS:
+ case CLASS_TYPE_PARAMETER_BOUND:
+ case METHOD_TYPE_PARAMETER_BOUND:
+ case THROWS:
+ case EXCEPTION_PARAMETER:
+ case INSTANCEOF:
+ case NEW:
+ case CONSTRUCTOR_REFERENCE:
+ case METHOD_REFERENCE:
+ output.put12(targetTypeAndInfo >>> 24, (targetTypeAndInfo & 0xFFFF00) >> 8);
+ break;
+ default:
+ throw new IllegalArgumentException();
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/1c71aec7/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
old mode 100644
new mode 100755
index a0f6880..96e0c48
--- 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
@@ -1,39 +1,37 @@
-/***
- * ASM: a very small and fast Java bytecode manipulation framework
- * Copyright (c) 2000-2011 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.
- */
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 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 java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
-
+import org.apache.tapestry5.internal.plastic.asm.ConstantDynamic;
import org.apache.tapestry5.internal.plastic.asm.Handle;
import org.apache.tapestry5.internal.plastic.asm.Label;
import org.apache.tapestry5.internal.plastic.asm.MethodVisitor;
@@ -41,606 +39,621 @@ import org.apache.tapestry5.internal.plastic.asm.Opcodes;
import org.apache.tapestry5.internal.plastic.asm.Type;
/**
- * A {@link org.objectweb.asm.MethodVisitor} 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>
- *
+ * A {@link MethodVisitor} to insert before, after and around advices in methods and constructors.
+ * For constructors, the code keeps track of the elements on the stack in order to detect when the
+ * super class constructor is called (note that there can be multiple such calls in different
+ * branches). {@code onMethodEnter} is called after each super class constructor call, because the
+ * object cannot be used before it is properly initialized.
+ *
* @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<Object> stackFrame;
-
- private Map<Label, List<Object>> branches;
-
- /**
- * Creates a new {@link AdviceAdapter}.
- *
- * @param api
- * the ASM API version implemented by this visitor. Must be one
- * of {@link Opcodes#ASM4}, {@link Opcodes#ASM5} or {@link Opcodes#ASM6}.
- * @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 int api, final MethodVisitor mv,
- final int access, final String name, final String desc) {
- super(api, mv, access, name, desc);
- methodAccess = access;
- methodDesc = desc;
- constructor = "<init>".equals(name);
- }
-
- @Override
- public void visitCode() {
- mv.visitCode();
- if (constructor) {
- stackFrame = new ArrayList<Object>();
- branches = new HashMap<Label, List<Object>>();
- } else {
- superInitialized = true;
- onMethodEnter();
- }
- }
-
- @Override
- public void visitLabel(final Label label) {
- mv.visitLabel(label);
- if (constructor && branches != null) {
- List<Object> frame = branches.get(label);
- if (frame != null) {
- stackFrame = frame;
- branches.remove(label);
- }
- }
+ /** The "uninitialized this" value. */
+ private static final Object UNINITIALIZED_THIS = new Object();
+
+ /** Any value other than "uninitialized this". */
+ private static final Object OTHER = new Object();
+
+ /** Prefix of the error message when invalid opcodes are found. */
+ private static final String INVALID_OPCODE = "Invalid opcode ";
+
+ /** The access flags of the visited method. */
+ protected int methodAccess;
+
+ /** The descriptor of the visited method. */
+ protected String methodDesc;
+
+ /** Whether the visited method is a constructor. */
+ private final boolean isConstructor;
+
+ /**
+ * Whether the super class constructor has been called (if the visited method is a constructor),
+ * at the current instruction. There can be multiple call sites to the super constructor (e.g. for
+ * Java code such as {@code super(expr ? value1 : value2);}), in different branches. When scanning
+ * the bytecode linearly, we can move from one branch where the super constructor has been called
+ * to another where it has not been called yet. Therefore, this value can change from false to
+ * true, and vice-versa.
+ */
+ private boolean superClassConstructorCalled;
+
+ /**
+ * The values on the current execution stack frame (long and double are represented by two
+ * elements). Each value is either {@link #UNINITIALIZED_THIS} (for the uninitialized this value),
+ * or {@link #OTHER} (for any other value). This field is only maintained for constructors, in
+ * branches where the super class constructor has not been called yet.
+ */
+ private List<Object> stackFrame;
+
+ /**
+ * The stack map frames corresponding to the labels of the forward jumps made *before* the super
+ * class constructor has been called (note that the Java Virtual Machine forbids backward jumps
+ * before the super class constructor is called). Note that by definition (cf. the 'before'), when
+ * we reach a label from this map, {@link #superClassConstructorCalled} must be reset to false.
+ * This field is only maintained for constructors.
+ */
+ private Map<Label, List<Object>> forwardJumpStackFrames;
+
+ /**
+ * Constructs a new {@link AdviceAdapter}.
+ *
+ * @param api the ASM API version implemented by this visitor. Must be one of {@link
+ * Opcodes#ASM4}, {@link Opcodes#ASM5}, {@link Opcodes#ASM6} or {@link Opcodes#ASM7}.
+ * @param methodVisitor 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 descriptor the method's descriptor (see {@link Type Type}).
+ */
+ protected AdviceAdapter(
+ final int api,
+ final MethodVisitor methodVisitor,
+ final int access,
+ final String name,
+ final String descriptor) {
+ super(api, methodVisitor, access, name, descriptor);
+ methodAccess = access;
+ methodDesc = descriptor;
+ isConstructor = "<init>".equals(name);
+ }
+
+ @Override
+ public void visitCode() {
+ super.visitCode();
+ if (isConstructor) {
+ stackFrame = new ArrayList<Object>();
+ forwardJumpStackFrames = new HashMap<Label, List<Object>>();
+ } else {
+ onMethodEnter();
}
-
- @Override
- 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);
+ }
+
+ @Override
+ public void visitLabel(final Label label) {
+ super.visitLabel(label);
+ if (isConstructor && forwardJumpStackFrames != null) {
+ List<Object> labelStackFrame = forwardJumpStackFrames.get(label);
+ if (labelStackFrame != null) {
+ stackFrame = labelStackFrame;
+ superClassConstructorCalled = false;
+ forwardJumpStackFrames.remove(label);
+ }
}
-
- @Override
- 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;
- }
- }
+ }
+
+ @Override
+ public void visitInsn(final int opcode) {
+ if (isConstructor && !superClassConstructorCalled) {
+ int stackSize;
+ switch (opcode) {
+ case IRETURN:
+ case FRETURN:
+ case ARETURN:
+ case LRETURN:
+ case DRETURN:
+ throw new IllegalArgumentException("Invalid return in constructor");
+ case RETURN: // empty stack
+ onMethodExit(opcode);
+ break;
+ case ATHROW: // 1 before n/a after
+ 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:
+ stackSize = stackFrame.size();
+ stackFrame.add(stackSize - 2, stackFrame.get(stackSize - 1));
+ break;
+ case DUP_X2:
+ stackSize = stackFrame.size();
+ stackFrame.add(stackSize - 3, stackFrame.get(stackSize - 1));
+ break;
+ case DUP2:
+ stackSize = stackFrame.size();
+ stackFrame.add(stackSize - 2, stackFrame.get(stackSize - 1));
+ stackFrame.add(stackSize - 2, stackFrame.get(stackSize - 1));
+ break;
+ case DUP2_X1:
+ stackSize = stackFrame.size();
+ stackFrame.add(stackSize - 3, stackFrame.get(stackSize - 1));
+ stackFrame.add(stackSize - 3, stackFrame.get(stackSize - 1));
+ break;
+ case DUP2_X2:
+ stackSize = stackFrame.size();
+ stackFrame.add(stackSize - 4, stackFrame.get(stackSize - 1));
+ stackFrame.add(stackSize - 4, stackFrame.get(stackSize - 1));
+ break;
+ case SWAP:
+ stackSize = stackFrame.size();
+ stackFrame.add(stackSize - 2, stackFrame.get(stackSize - 1));
+ stackFrame.remove(stackSize);
+ break;
+ default:
+ throw new IllegalArgumentException(INVALID_OPCODE + opcode);
+ }
+ } else {
+ switch (opcode) {
+ case RETURN:
+ case IRETURN:
+ case FRETURN:
+ case ARETURN:
+ case LRETURN:
+ case DRETURN:
+ case ATHROW:
+ onMethodExit(opcode);
+ break;
+ default:
+ break;
+ }
}
-
- @Override
- 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();
- popValue();
- if (longOrDouble) {
- popValue();
- }
- break;
- // case GETFIELD:
- default:
- if (longOrDouble) {
- pushValue(OTHER);
- }
- }
- }
+ super.visitInsn(opcode);
+ }
+
+ @Override
+ public void visitVarInsn(final int opcode, final int var) {
+ super.visitVarInsn(opcode, var);
+ if (isConstructor && !superClassConstructorCalled) {
+ switch (opcode) {
+ case ILOAD:
+ case FLOAD:
+ pushValue(OTHER);
+ break;
+ case LLOAD:
+ case DLOAD:
+ pushValue(OTHER);
+ pushValue(OTHER);
+ break;
+ case ALOAD:
+ pushValue(var == 0 ? UNINITIALIZED_THIS : OTHER);
+ break;
+ case ASTORE:
+ case ISTORE:
+ case FSTORE:
+ popValue();
+ break;
+ case LSTORE:
+ case DSTORE:
+ popValue();
+ popValue();
+ break;
+ default:
+ throw new IllegalArgumentException(INVALID_OPCODE + opcode);
+ }
}
-
- @Override
- public void visitIntInsn(final int opcode, final int operand) {
- mv.visitIntInsn(opcode, operand);
- if (constructor && opcode != NEWARRAY) {
- pushValue(OTHER);
- }
- }
-
- @Override
- public void visitLdcInsn(final Object cst) {
- mv.visitLdcInsn(cst);
- if (constructor) {
+ }
+
+ @Override
+ public void visitFieldInsn(
+ final int opcode, final String owner, final String name, final String descriptor) {
+ super.visitFieldInsn(opcode, owner, name, descriptor);
+ if (isConstructor && !superClassConstructorCalled) {
+ char firstDescriptorChar = descriptor.charAt(0);
+ boolean longOrDouble = firstDescriptorChar == 'J' || firstDescriptorChar == 'D';
+ switch (opcode) {
+ case GETSTATIC:
+ pushValue(OTHER);
+ if (longOrDouble) {
pushValue(OTHER);
- if (cst instanceof Double || cst instanceof Long) {
- pushValue(OTHER);
- }
- }
- }
-
- @Override
- public void visitMultiANewArrayInsn(final String desc, final int dims) {
- mv.visitMultiANewArrayInsn(desc, dims);
- if (constructor) {
- for (int i = 0; i < dims; i++) {
- popValue();
- }
+ }
+ break;
+ case PUTSTATIC:
+ popValue();
+ if (longOrDouble) {
+ popValue();
+ }
+ break;
+ case PUTFIELD:
+ popValue();
+ popValue();
+ if (longOrDouble) {
+ popValue();
+ }
+ break;
+ case GETFIELD:
+ if (longOrDouble) {
pushValue(OTHER);
- }
+ }
+ break;
+ default:
+ throw new IllegalArgumentException(INVALID_OPCODE + opcode);
+ }
}
+ }
- @Override
- 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);
- }
+ @Override
+ public void visitIntInsn(final int opcode, final int operand) {
+ super.visitIntInsn(opcode, operand);
+ if (isConstructor && !superClassConstructorCalled && opcode != NEWARRAY) {
+ pushValue(OTHER);
}
-
- @Deprecated
- @Override
- public void visitMethodInsn(final int opcode, final String owner,
- final String name, final String desc) {
- if (api >= Opcodes.ASM5) {
- super.visitMethodInsn(opcode, owner, name, desc);
- return;
- }
- doVisitMethodInsn(opcode, owner, name, desc,
- opcode == Opcodes.INVOKEINTERFACE);
+ }
+
+ @Override
+ public void visitLdcInsn(final Object value) {
+ super.visitLdcInsn(value);
+ if (isConstructor && !superClassConstructorCalled) {
+ pushValue(OTHER);
+ if (value instanceof Double
+ || value instanceof Long
+ || (value instanceof ConstantDynamic && ((ConstantDynamic) value).getSize() == 2)) {
+ pushValue(OTHER);
+ }
}
-
- @Override
- public void visitMethodInsn(final int opcode, final String owner,
- final String name, final String desc, final boolean itf) {
- if (api < Opcodes.ASM5) {
- super.visitMethodInsn(opcode, owner, name, desc, itf);
- return;
- }
- doVisitMethodInsn(opcode, owner, name, desc, itf);
+ }
+
+ @Override
+ public void visitMultiANewArrayInsn(final String descriptor, final int numDimensions) {
+ super.visitMultiANewArrayInsn(descriptor, numDimensions);
+ if (isConstructor && !superClassConstructorCalled) {
+ for (int i = 0; i < numDimensions; i++) {
+ popValue();
+ }
+ pushValue(OTHER);
}
-
- private void doVisitMethodInsn(int opcode, final String owner,
- final String name, final String desc, final boolean itf) {
- mv.visitMethodInsn(opcode, owner, name, desc, itf);
- 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:
- // 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);
- }
- }
- }
+ }
+
+ @Override
+ public void visitTypeInsn(final int opcode, final String type) {
+ super.visitTypeInsn(opcode, type);
+ // ANEWARRAY, CHECKCAST or INSTANCEOF don't change stack.
+ if (isConstructor && !superClassConstructorCalled && opcode == NEW) {
+ pushValue(OTHER);
}
-
- @Override
- public void visitInvokeDynamicInsn(String name, String desc, Handle bsm,
- Object... bsmArgs) {
- mv.visitInvokeDynamicInsn(name, desc, bsm, bsmArgs);
- if (constructor) {
- Type[] types = Type.getArgumentTypes(desc);
- for (int i = 0; i < types.length; i++) {
- popValue();
- if (types[i].getSize() == 2) {
- popValue();
- }
- }
-
- Type returnType = Type.getReturnType(desc);
- if (returnType != Type.VOID_TYPE) {
- pushValue(OTHER);
- if (returnType.getSize() == 2) {
- pushValue(OTHER);
- }
- }
- }
+ }
+
+ /**
+ * Deprecated.
+ *
+ * @deprecated use {@link #visitMethodInsn(int, String, String, String, boolean)} instead.
+ */
+ @Deprecated
+ @Override
+ public void visitMethodInsn(
+ final int opcode, final String owner, final String name, final String descriptor) {
+ if (api >= Opcodes.ASM5) {
+ super.visitMethodInsn(opcode, owner, name, descriptor);
+ return;
}
-
- @Override
- 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);
- }
+ mv.visitMethodInsn(opcode, owner, name, descriptor, opcode == Opcodes.INVOKEINTERFACE);
+ doVisitMethodInsn(opcode, descriptor);
+ }
+
+ @Override
+ public void visitMethodInsn(
+ final int opcode,
+ final String owner,
+ final String name,
+ final String descriptor,
+ final boolean isInterface) {
+ if (api < Opcodes.ASM5) {
+ super.visitMethodInsn(opcode, owner, name, descriptor, isInterface);
+ return;
}
-
- @Override
- public void visitLookupSwitchInsn(final Label dflt, final int[] keys,
- final Label[] labels) {
- mv.visitLookupSwitchInsn(dflt, keys, labels);
- if (constructor) {
- popValue();
- addBranches(dflt, labels);
+ mv.visitMethodInsn(opcode, owner, name, descriptor, isInterface);
+ doVisitMethodInsn(opcode, descriptor);
+ }
+
+ private void doVisitMethodInsn(final int opcode, final String descriptor) {
+ if (isConstructor && !superClassConstructorCalled) {
+ for (Type argumentType : Type.getArgumentTypes(descriptor)) {
+ popValue();
+ if (argumentType.getSize() == 2) {
+ popValue();
}
- }
-
- @Override
- 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);
- }
- }
-
- @Override
- public void visitTryCatchBlock(Label start, Label end, Label handler,
- String type) {
- super.visitTryCatchBlock(start, end, handler, type);
- if (constructor && !branches.containsKey(handler)) {
- List<Object> stackFrame = new ArrayList<Object>();
- stackFrame.add(OTHER);
- branches.put(handler, stackFrame);
- }
- }
-
- private void addBranches(final Label dflt, final Label[] labels) {
- addBranch(dflt);
- for (int i = 0; i < labels.length; i++) {
- addBranch(labels[i]);
+ }
+ switch (opcode) {
+ case INVOKEINTERFACE:
+ case INVOKEVIRTUAL:
+ popValue();
+ break;
+ case INVOKESPECIAL:
+ Object value = popValue();
+ if (value == UNINITIALIZED_THIS && !superClassConstructorCalled) {
+ superClassConstructorCalled = true;
+ onMethodEnter();
+ }
+ break;
+ default:
+ break;
+ }
+
+ Type returnType = Type.getReturnType(descriptor);
+ if (returnType != Type.VOID_TYPE) {
+ pushValue(OTHER);
+ if (returnType.getSize() == 2) {
+ pushValue(OTHER);
}
+ }
}
-
- private void addBranch(final Label label) {
- if (branches.containsKey(label)) {
- return;
- }
- branches.put(label, new ArrayList<Object>(stackFrame));
+ }
+
+ @Override
+ public void visitInvokeDynamicInsn(
+ final String name,
+ final String descriptor,
+ final Handle bootstrapMethodHandle,
+ final Object... bootstrapMethodArguments) {
+ super.visitInvokeDynamicInsn(name, descriptor, bootstrapMethodHandle, bootstrapMethodArguments);
+ doVisitMethodInsn(Opcodes.INVOKEDYNAMIC, descriptor);
+ }
+
+ @Override
+ public void visitJumpInsn(final int opcode, final Label label) {
+ super.visitJumpInsn(opcode, label);
+ if (isConstructor && !superClassConstructorCalled) {
+ 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;
+ default:
+ break;
+ }
+ addForwardJump(label);
}
-
- private Object popValue() {
- return stackFrame.remove(stackFrame.size() - 1);
+ }
+
+ @Override
+ public void visitLookupSwitchInsn(final Label dflt, final int[] keys, final Label[] labels) {
+ super.visitLookupSwitchInsn(dflt, keys, labels);
+ if (isConstructor && !superClassConstructorCalled) {
+ popValue();
+ addForwardJumps(dflt, labels);
}
-
- private Object peekValue() {
- return stackFrame.get(stackFrame.size() - 1);
+ }
+
+ @Override
+ public void visitTableSwitchInsn(
+ final int min, final int max, final Label dflt, final Label... labels) {
+ super.visitTableSwitchInsn(min, max, dflt, labels);
+ if (isConstructor && !superClassConstructorCalled) {
+ popValue();
+ addForwardJumps(dflt, labels);
}
-
- private void pushValue(final Object o) {
- stackFrame.add(o);
+ }
+
+ @Override
+ public void visitTryCatchBlock(
+ final Label start, final Label end, final Label handler, final String type) {
+ super.visitTryCatchBlock(start, end, handler, type);
+ // By definition of 'forwardJumpStackFrames', 'handler' should be pushed only if there is an
+ // instruction between 'start' and 'end' at which the super class constructor is not yet
+ // called. Unfortunately, try catch blocks must be visited before their labels, so we have no
+ // way to know this at this point. Instead, we suppose that the super class constructor has not
+ // been called at the start of *any* exception handler. If this is wrong, normally there should
+ // not be a second super class constructor call in the exception handler (an object can't be
+ // initialized twice), so this is not issue (in the sense that there is no risk to emit a wrong
+ // 'onMethodEnter').
+ if (isConstructor && !forwardJumpStackFrames.containsKey(handler)) {
+ List<Object> handlerStackFrame = new ArrayList<Object>();
+ handlerStackFrame.add(OTHER);
+ forwardJumpStackFrames.put(handler, handlerStackFrame);
}
+ }
- /**
- * Called at the beginning of the method or after super 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() {
+ private void addForwardJumps(final Label dflt, final Label[] labels) {
+ addForwardJump(dflt);
+ for (Label label : labels) {
+ addForwardJump(label);
}
+ }
- /**
- * 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) {
+ private void addForwardJump(final Label label) {
+ if (forwardJumpStackFrames.containsKey(label)) {
+ return;
}
-
- // TODO onException, onMethodCall
+ forwardJumpStackFrames.put(label, new ArrayList<Object>(stackFrame));
+ }
+
+ private Object popValue() {
+ return stackFrame.remove(stackFrame.size() - 1);
+ }
+
+ private Object peekValue() {
+ return stackFrame.get(stackFrame.size() - 1);
+ }
+
+ private void pushValue(final Object value) {
+ stackFrame.add(value);
+ }
+
+ /**
+ * Generates the "before" advice for the visited method. The default implementation of this method
+ * does nothing. Subclasses can use or change all the local variables, but should not change state
+ * of the stack. This method is called at the beginning of the method or after super class
+ * constructor has been called (in constructors).
+ */
+ protected void onMethodEnter() {}
+
+ /**
+ * Generates the "after" advice for the visited method. The default implementation of this method
+ * does nothing. Subclasses can use or change all the local variables, but should not change state
+ * of the stack. This method is called at the end of the method, just before return and athrow
+ * instructions. The top element on the stack contains the return value or the exception instance.
+ * For example:
+ *
+ * <pre>
+ * public void onMethodExit(final 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(final Object exitValue, final int opcode) {
+ * ...
+ * }
+ * </pre>
+ *
+ * @param opcode one of {@link Opcodes#RETURN}, {@link Opcodes#IRETURN}, {@link Opcodes#FRETURN},
+ * {@link Opcodes#ARETURN}, {@link Opcodes#LRETURN}, {@link Opcodes#DRETURN} or {@link
+ * Opcodes#ATHROW}.
+ */
+ protected void onMethodExit(final int opcode) {}
}