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:02 UTC
[15/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/tree/analysis/Interpreter.java
----------------------------------------------------------------------
diff --git a/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/tree/analysis/Interpreter.java b/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/tree/analysis/Interpreter.java
old mode 100644
new mode 100755
index b7c94c8..afe4d78
--- a/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/tree/analysis/Interpreter.java
+++ b/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/tree/analysis/Interpreter.java
@@ -1,226 +1,268 @@
-/***
- * 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.tree.analysis;
import java.util.List;
-
import org.apache.tapestry5.internal.plastic.asm.Type;
import org.apache.tapestry5.internal.plastic.asm.tree.AbstractInsnNode;
+import org.apache.tapestry5.internal.plastic.asm.tree.TryCatchBlockNode;
/**
- * A semantic bytecode interpreter. More precisely, this interpreter only
- * manages the computation of values from other values: it does not manage the
- * transfer of values to or from the stack, and to or from the local variables.
- * This separation allows a generic bytecode {@link Analyzer} to work with
- * various semantic interpreters, without needing to duplicate the code to
- * simulate the transfer of values.
- *
- * @param <V>
- * type of the Value used for the analysis.
- *
+ * A semantic bytecode interpreter. More precisely, this interpreter only manages the computation of
+ * values from other values: it does not manage the transfer of values to or from the stack, and to
+ * or from the local variables. This separation allows a generic bytecode {@link Analyzer} to work
+ * with various semantic interpreters, without needing to duplicate the code to simulate the
+ * transfer of values.
+ *
+ * @param <V> type of the Value used for the analysis.
* @author Eric Bruneton
*/
public abstract class Interpreter<V extends Value> {
- protected final int api;
-
- protected Interpreter(final int api) {
- this.api = api;
- }
-
- /**
- * Creates a new value that represents the given type.
- *
- * Called for method parameters (including <code>this</code>), exception
- * handler variable and with <code>null</code> type for variables reserved
- * by long and double types.
- *
- * @param type
- * a primitive or reference type, or <tt>null</tt> to represent
- * an uninitialized value.
- * @return a value that represents the given type. The size of the returned
- * value must be equal to the size of the given type.
- */
- public abstract V newValue(Type type);
-
- /**
- * Interprets a bytecode instruction without arguments. This method is
- * called for the following opcodes:
- *
- * ACONST_NULL, ICONST_M1, ICONST_0, ICONST_1, ICONST_2, ICONST_3, ICONST_4,
- * ICONST_5, LCONST_0, LCONST_1, FCONST_0, FCONST_1, FCONST_2, DCONST_0,
- * DCONST_1, BIPUSH, SIPUSH, LDC, JSR, GETSTATIC, NEW
- *
- * @param insn
- * the bytecode instruction to be interpreted.
- * @return the result of the interpretation of the given instruction.
- * @throws AnalyzerException
- * if an error occured during the interpretation.
- */
- public abstract V newOperation(AbstractInsnNode insn)
- throws AnalyzerException;
-
- /**
- * Interprets a bytecode instruction that moves a value on the stack or to
- * or from local variables. This method is called for the following opcodes:
- *
- * ILOAD, LLOAD, FLOAD, DLOAD, ALOAD, ISTORE, LSTORE, FSTORE, DSTORE,
- * ASTORE, DUP, DUP_X1, DUP_X2, DUP2, DUP2_X1, DUP2_X2, SWAP
- *
- * @param insn
- * the bytecode instruction to be interpreted.
- * @param value
- * the value that must be moved by the instruction.
- * @return the result of the interpretation of the given instruction. The
- * returned value must be <tt>equal</tt> to the given value.
- * @throws AnalyzerException
- * if an error occured during the interpretation.
- */
- public abstract V copyOperation(AbstractInsnNode insn, V value)
- throws AnalyzerException;
-
- /**
- * Interprets a bytecode instruction with a single argument. This method is
- * called for the following opcodes:
- *
- * INEG, LNEG, FNEG, DNEG, IINC, I2L, I2F, I2D, L2I, L2F, L2D, F2I, F2L,
- * F2D, D2I, D2L, D2F, I2B, I2C, I2S, IFEQ, IFNE, IFLT, IFGE, IFGT, IFLE,
- * TABLESWITCH, LOOKUPSWITCH, IRETURN, LRETURN, FRETURN, DRETURN, ARETURN,
- * PUTSTATIC, GETFIELD, NEWARRAY, ANEWARRAY, ARRAYLENGTH, ATHROW, CHECKCAST,
- * INSTANCEOF, MONITORENTER, MONITOREXIT, IFNULL, IFNONNULL
- *
- * @param insn
- * the bytecode instruction to be interpreted.
- * @param value
- * the argument of the instruction to be interpreted.
- * @return the result of the interpretation of the given instruction.
- * @throws AnalyzerException
- * if an error occured during the interpretation.
- */
- public abstract V unaryOperation(AbstractInsnNode insn, V value)
- throws AnalyzerException;
-
- /**
- * Interprets a bytecode instruction with two arguments. This method is
- * called for the following opcodes:
- *
- * IALOAD, LALOAD, FALOAD, DALOAD, AALOAD, BALOAD, CALOAD, SALOAD, IADD,
- * LADD, FADD, DADD, ISUB, LSUB, FSUB, DSUB, IMUL, LMUL, FMUL, DMUL, IDIV,
- * LDIV, FDIV, DDIV, IREM, LREM, FREM, DREM, ISHL, LSHL, ISHR, LSHR, IUSHR,
- * LUSHR, IAND, LAND, IOR, LOR, IXOR, LXOR, LCMP, FCMPL, FCMPG, DCMPL,
- * DCMPG, IF_ICMPEQ, IF_ICMPNE, IF_ICMPLT, IF_ICMPGE, IF_ICMPGT, IF_ICMPLE,
- * IF_ACMPEQ, IF_ACMPNE, PUTFIELD
- *
- * @param insn
- * the bytecode instruction to be interpreted.
- * @param value1
- * the first argument of the instruction to be interpreted.
- * @param value2
- * the second argument of the instruction to be interpreted.
- * @return the result of the interpretation of the given instruction.
- * @throws AnalyzerException
- * if an error occured during the interpretation.
- */
- public abstract V binaryOperation(AbstractInsnNode insn, V value1, V value2)
- throws AnalyzerException;
-
- /**
- * Interprets a bytecode instruction with three arguments. This method is
- * called for the following opcodes:
- *
- * IASTORE, LASTORE, FASTORE, DASTORE, AASTORE, BASTORE, CASTORE, SASTORE
- *
- * @param insn
- * the bytecode instruction to be interpreted.
- * @param value1
- * the first argument of the instruction to be interpreted.
- * @param value2
- * the second argument of the instruction to be interpreted.
- * @param value3
- * the third argument of the instruction to be interpreted.
- * @return the result of the interpretation of the given instruction.
- * @throws AnalyzerException
- * if an error occured during the interpretation.
- */
- public abstract V ternaryOperation(AbstractInsnNode insn, V value1,
- V value2, V value3) throws AnalyzerException;
-
- /**
- * Interprets a bytecode instruction with a variable number of arguments.
- * This method is called for the following opcodes:
- *
- * INVOKEVIRTUAL, INVOKESPECIAL, INVOKESTATIC, INVOKEINTERFACE,
- * MULTIANEWARRAY and INVOKEDYNAMIC
- *
- * @param insn
- * the bytecode instruction to be interpreted.
- * @param values
- * the arguments of the instruction to be interpreted.
- * @return the result of the interpretation of the given instruction.
- * @throws AnalyzerException
- * if an error occured during the interpretation.
- */
- public abstract V naryOperation(AbstractInsnNode insn,
- List<? extends V> values) throws AnalyzerException;
-
- /**
- * Interprets a bytecode return instruction. This method is called for the
- * following opcodes:
- *
- * IRETURN, LRETURN, FRETURN, DRETURN, ARETURN
- *
- * @param insn
- * the bytecode instruction to be interpreted.
- * @param value
- * the argument of the instruction to be interpreted.
- * @param expected
- * the expected return type of the analyzed method.
- * @throws AnalyzerException
- * if an error occured during the interpretation.
- */
- public abstract void returnOperation(AbstractInsnNode insn, V value,
- V expected) throws AnalyzerException;
-
- /**
- * Merges two values. The merge operation must return a value that
- * represents both values (for instance, if the two values are two types,
- * the merged value must be a common super type of the two types. If the two
- * values are integer intervals, the merged value must be an interval that
- * contains the previous ones. Likewise for other types of values).
- *
- * @param v
- * a value.
- * @param w
- * another value.
- * @return the merged value. If the merged value is equal to <tt>v</tt>,
- * this method <i>must</i> return <tt>v</tt>.
- */
- public abstract V merge(V v, V w);
+ /**
+ * The ASM API version supported by this interpreter. The value of this field must be one of
+ * {@link org.apache.tapestry5.internal.plastic.asm.Opcodes#ASM4}, {@link org.apache.tapestry5.internal.plastic.asm.Opcodes#ASM5}, {@link
+ * org.apache.tapestry5.internal.plastic.asm.Opcodes#ASM6} or {@link org.apache.tapestry5.internal.plastic.asm.Opcodes#ASM7}.
+ */
+ protected final int api;
+
+ /**
+ * Constructs a new {@link Interpreter}.
+ *
+ * @param api the ASM API version supported by this interpreter. Must be one of {@link
+ * org.apache.tapestry5.internal.plastic.asm.Opcodes#ASM4}, {@link org.apache.tapestry5.internal.plastic.asm.Opcodes#ASM5}, {@link
+ * org.apache.tapestry5.internal.plastic.asm.Opcodes#ASM6} or {@link org.apache.tapestry5.internal.plastic.asm.Opcodes#ASM7}.
+ */
+ protected Interpreter(final int api) {
+ this.api = api;
+ }
+
+ /**
+ * Creates a new value that represents the given type.
+ *
+ * <p>Called for method parameters (including <code>this</code>), exception handler variable and
+ * with <code>null</code> type for variables reserved by long and double types.
+ *
+ * <p>An interpreter may choose to implement one or more of {@link
+ * Interpreter#newReturnTypeValue(Type)}, {@link Interpreter#newParameterValue(boolean, int,
+ * Type)}, {@link Interpreter#newEmptyValue(int)}, {@link
+ * Interpreter#newExceptionValue(TryCatchBlockNode, Frame, Type)} to distinguish different types
+ * of new value.
+ *
+ * @param type a primitive or reference type, or {@literal null} to represent an uninitialized
+ * value.
+ * @return a value that represents the given type. The size of the returned value must be equal to
+ * the size of the given type.
+ */
+ public abstract V newValue(Type type);
+
+ /**
+ * Creates a new value that represents the given parameter type. This method is called to
+ * initialize the value of a local corresponding to a method parameter in a frame.
+ *
+ * <p>By default, calls <code>newValue(type)</code>.
+ *
+ * @param isInstanceMethod {@literal true} if the method is non-static.
+ * @param local the local variable index.
+ * @param type a primitive or reference type.
+ * @return a value that represents the given type. The size of the returned value must be equal to
+ * the size of the given type.
+ */
+ public V newParameterValue(final boolean isInstanceMethod, final int local, final Type type) {
+ return newValue(type);
+ }
+
+ /**
+ * Creates a new value that represents the given return type. This method is called to initialize
+ * the return type value of a frame.
+ *
+ * <p>By default, calls <code>newValue(type)</code>.
+ *
+ * @param type a primitive or reference type.
+ * @return a value that represents the given type. The size of the returned value must be equal to
+ * the size of the given type.
+ */
+ public V newReturnTypeValue(final Type type) {
+ return newValue(type);
+ }
+
+ /**
+ * Creates a new uninitialized value for a local variable. This method is called to initialize the
+ * value of a local that does not correspond to a method parameter, and to reset one half of a
+ * size-2 value when the other half is assigned a size-1 value.
+ *
+ * <p>By default, calls <code>newValue(null)</code>.
+ *
+ * @param local the local variable index.
+ * @return a value representing an uninitialized value. The size of the returned value must be
+ * equal to 1.
+ */
+ public V newEmptyValue(final int local) {
+ return newValue(null);
+ }
+
+ /**
+ * Creates a new value that represents the given exception type. This method is called to
+ * initialize the exception value on the call stack at the entry of an exception handler.
+ *
+ * <p>By default, calls <code>newValue(exceptionType)</code>.
+ *
+ * @param tryCatchBlockNode the exception handler.
+ * @param handlerFrame the exception handler frame.
+ * @param exceptionType the exception type handled by this handler.
+ * @return a value that represents the given {@code exceptionType}. The size of the returned value
+ * must be equal to 1.
+ */
+ public V newExceptionValue(
+ final TryCatchBlockNode tryCatchBlockNode,
+ final Frame<V> handlerFrame,
+ final Type exceptionType) {
+ return newValue(exceptionType);
+ }
+
+ /**
+ * Interprets a bytecode instruction without arguments. This method is called for the following
+ * opcodes:
+ *
+ * <p>ACONST_NULL, ICONST_M1, ICONST_0, ICONST_1, ICONST_2, ICONST_3, ICONST_4, ICONST_5,
+ * LCONST_0, LCONST_1, FCONST_0, FCONST_1, FCONST_2, DCONST_0, DCONST_1, BIPUSH, SIPUSH, LDC, JSR,
+ * GETSTATIC, NEW
+ *
+ * @param insn the bytecode instruction to be interpreted.
+ * @return the result of the interpretation of the given instruction.
+ * @throws AnalyzerException if an error occurred during the interpretation.
+ */
+ public abstract V newOperation(AbstractInsnNode insn) throws AnalyzerException;
+
+ /**
+ * Interprets a bytecode instruction that moves a value on the stack or to or from local
+ * variables. This method is called for the following opcodes:
+ *
+ * <p>ILOAD, LLOAD, FLOAD, DLOAD, ALOAD, ISTORE, LSTORE, FSTORE, DSTORE, ASTORE, DUP, DUP_X1,
+ * DUP_X2, DUP2, DUP2_X1, DUP2_X2, SWAP
+ *
+ * @param insn the bytecode instruction to be interpreted.
+ * @param value the value that must be moved by the instruction.
+ * @return the result of the interpretation of the given instruction. The returned value must be
+ * {@code equal} to the given value.
+ * @throws AnalyzerException if an error occurred during the interpretation.
+ */
+ public abstract V copyOperation(AbstractInsnNode insn, V value) throws AnalyzerException;
+
+ /**
+ * Interprets a bytecode instruction with a single argument. This method is called for the
+ * following opcodes:
+ *
+ * <p>INEG, LNEG, FNEG, DNEG, IINC, I2L, I2F, I2D, L2I, L2F, L2D, F2I, F2L, F2D, D2I, D2L, D2F,
+ * I2B, I2C, I2S, IFEQ, IFNE, IFLT, IFGE, IFGT, IFLE, TABLESWITCH, LOOKUPSWITCH, IRETURN, LRETURN,
+ * FRETURN, DRETURN, ARETURN, PUTSTATIC, GETFIELD, NEWARRAY, ANEWARRAY, ARRAYLENGTH, ATHROW,
+ * CHECKCAST, INSTANCEOF, MONITORENTER, MONITOREXIT, IFNULL, IFNONNULL
+ *
+ * @param insn the bytecode instruction to be interpreted.
+ * @param value the argument of the instruction to be interpreted.
+ * @return the result of the interpretation of the given instruction.
+ * @throws AnalyzerException if an error occurred during the interpretation.
+ */
+ public abstract V unaryOperation(AbstractInsnNode insn, V value) throws AnalyzerException;
+
+ /**
+ * Interprets a bytecode instruction with two arguments. This method is called for the following
+ * opcodes:
+ *
+ * <p>IALOAD, LALOAD, FALOAD, DALOAD, AALOAD, BALOAD, CALOAD, SALOAD, IADD, LADD, FADD, DADD,
+ * ISUB, LSUB, FSUB, DSUB, IMUL, LMUL, FMUL, DMUL, IDIV, LDIV, FDIV, DDIV, IREM, LREM, FREM, DREM,
+ * ISHL, LSHL, ISHR, LSHR, IUSHR, LUSHR, IAND, LAND, IOR, LOR, IXOR, LXOR, LCMP, FCMPL, FCMPG,
+ * DCMPL, DCMPG, IF_ICMPEQ, IF_ICMPNE, IF_ICMPLT, IF_ICMPGE, IF_ICMPGT, IF_ICMPLE, IF_ACMPEQ,
+ * IF_ACMPNE, PUTFIELD
+ *
+ * @param insn the bytecode instruction to be interpreted.
+ * @param value1 the first argument of the instruction to be interpreted.
+ * @param value2 the second argument of the instruction to be interpreted.
+ * @return the result of the interpretation of the given instruction.
+ * @throws AnalyzerException if an error occurred during the interpretation.
+ */
+ public abstract V binaryOperation(AbstractInsnNode insn, V value1, V value2)
+ throws AnalyzerException;
+
+ /**
+ * Interprets a bytecode instruction with three arguments. This method is called for the following
+ * opcodes:
+ *
+ * <p>IASTORE, LASTORE, FASTORE, DASTORE, AASTORE, BASTORE, CASTORE, SASTORE
+ *
+ * @param insn the bytecode instruction to be interpreted.
+ * @param value1 the first argument of the instruction to be interpreted.
+ * @param value2 the second argument of the instruction to be interpreted.
+ * @param value3 the third argument of the instruction to be interpreted.
+ * @return the result of the interpretation of the given instruction.
+ * @throws AnalyzerException if an error occurred during the interpretation.
+ */
+ public abstract V ternaryOperation(AbstractInsnNode insn, V value1, V value2, V value3)
+ throws AnalyzerException;
+
+ /**
+ * Interprets a bytecode instruction with a variable number of arguments. This method is called
+ * for the following opcodes:
+ *
+ * <p>INVOKEVIRTUAL, INVOKESPECIAL, INVOKESTATIC, INVOKEINTERFACE, MULTIANEWARRAY and
+ * INVOKEDYNAMIC
+ *
+ * @param insn the bytecode instruction to be interpreted.
+ * @param values the arguments of the instruction to be interpreted.
+ * @return the result of the interpretation of the given instruction.
+ * @throws AnalyzerException if an error occurred during the interpretation.
+ */
+ public abstract V naryOperation(AbstractInsnNode insn, List<? extends V> values)
+ throws AnalyzerException;
+
+ /**
+ * Interprets a bytecode return instruction. This method is called for the following opcodes:
+ *
+ * <p>IRETURN, LRETURN, FRETURN, DRETURN, ARETURN
+ *
+ * @param insn the bytecode instruction to be interpreted.
+ * @param value the argument of the instruction to be interpreted.
+ * @param expected the expected return type of the analyzed method.
+ * @throws AnalyzerException if an error occurred during the interpretation.
+ */
+ public abstract void returnOperation(AbstractInsnNode insn, V value, V expected)
+ throws AnalyzerException;
+
+ /**
+ * Merges two values. The merge operation must return a value that represents both values (for
+ * instance, if the two values are two types, the merged value must be a common super type of the
+ * two types. If the two values are integer intervals, the merged value must be an interval that
+ * contains the previous ones. Likewise for other types of values).
+ *
+ * @param value1 a value.
+ * @param value2 another value.
+ * @return the merged value. If the merged value is equal to {@code value1}, this method
+ * <i>must</i> return {@code value1}.
+ */
+ public abstract V merge(V value1, V value2);
}
http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/1c71aec7/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/tree/analysis/SimpleVerifier.java
----------------------------------------------------------------------
diff --git a/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/tree/analysis/SimpleVerifier.java b/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/tree/analysis/SimpleVerifier.java
old mode 100644
new mode 100755
index 0cc2f28..90487a4
--- a/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/tree/analysis/SimpleVerifier.java
+++ b/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/tree/analysis/SimpleVerifier.java
@@ -1,320 +1,376 @@
-/***
- * 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.tree.analysis;
import java.util.List;
-
import org.apache.tapestry5.internal.plastic.asm.Type;
/**
- * An extended {@link BasicVerifier} that performs more precise verifications.
- * This verifier computes exact class types, instead of using a single "object
- * reference" type (as done in the {@link BasicVerifier}).
- *
+ * An extended {@link BasicVerifier} that performs more precise verifications. This verifier
+ * computes exact class types, instead of using a single "object reference" type (as done in {@link
+ * BasicVerifier}).
+ *
* @author Eric Bruneton
* @author Bing Ran
*/
public class SimpleVerifier extends BasicVerifier {
- /**
- * The class that is verified.
- */
- private final Type currentClass;
+ /** The type of the class that is verified. */
+ private final Type currentClass;
- /**
- * The super class of the class that is verified.
- */
- private final Type currentSuperClass;
+ /** The type of the super class of the class that is verified. */
+ private final Type currentSuperClass;
- /**
- * The interfaces implemented by the class that is verified.
- */
- private final List<Type> currentClassInterfaces;
+ /** The types of the interfaces directly implemented by the class that is verified. */
+ private final List<Type> currentClassInterfaces;
- /**
- * If the class that is verified is an interface.
- */
- private final boolean isInterface;
+ /** Whether the class that is verified is an interface. */
+ private final boolean isInterface;
- /**
- * The loader to use for referenced classes.
- */
- private ClassLoader loader = getClass().getClassLoader();
+ /** The loader to use to load the referenced classes. */
+ private ClassLoader loader = getClass().getClassLoader();
- /**
- * Constructs a new {@link SimpleVerifier}.
- */
- public SimpleVerifier() {
- this(null, null, false);
- }
+ /**
+ * Constructs a new {@link SimpleVerifier}. <i>Subclasses must not use this constructor</i>.
+ * Instead, they must use the {@link #SimpleVerifier(int, Type, Type, List, boolean)} version.
+ */
+ public SimpleVerifier() {
+ this(null, null, false);
+ }
- /**
- * Constructs a new {@link SimpleVerifier} to verify a specific class. This
- * class will not be loaded into the JVM since it may be incorrect.
- *
- * @param currentClass
- * the class that is verified.
- * @param currentSuperClass
- * the super class of the class that is verified.
- * @param isInterface
- * if the class that is verified is an interface.
- */
- public SimpleVerifier(final Type currentClass,
- final Type currentSuperClass, final boolean isInterface) {
- this(currentClass, currentSuperClass, null, isInterface);
- }
+ /**
+ * Constructs a new {@link SimpleVerifier} to verify a specific class. This class will not be
+ * loaded into the JVM since it may be incorrect. <i>Subclasses must not use this constructor</i>.
+ * Instead, they must use the {@link #SimpleVerifier(int, Type, Type, List, boolean)} version.
+ *
+ * @param currentClass the type of the class to be verified.
+ * @param currentSuperClass the type of the super class of the class to be verified.
+ * @param isInterface whether the class to be verifier is an interface.
+ */
+ public SimpleVerifier(
+ final Type currentClass, final Type currentSuperClass, final boolean isInterface) {
+ this(currentClass, currentSuperClass, null, isInterface);
+ }
- /**
- * Constructs a new {@link SimpleVerifier} to verify a specific class. This
- * class will not be loaded into the JVM since it may be incorrect.
- *
- * @param currentClass
- * the class that is verified.
- * @param currentSuperClass
- * the super class of the class that is verified.
- * @param currentClassInterfaces
- * the interfaces implemented by the class that is verified.
- * @param isInterface
- * if the class that is verified is an interface.
- */
- public SimpleVerifier(final Type currentClass,
- final Type currentSuperClass,
- final List<Type> currentClassInterfaces, final boolean isInterface) {
- this(ASM6, currentClass, currentSuperClass, currentClassInterfaces,
- isInterface);
+ /**
+ * Constructs a new {@link SimpleVerifier} to verify a specific class. This class will not be
+ * loaded into the JVM since it may be incorrect. <i>Subclasses must not use this constructor</i>.
+ * Instead, they must use the {@link #SimpleVerifier(int, Type, Type, List, boolean)} version.
+ *
+ * @param currentClass the type of the class to be verified.
+ * @param currentSuperClass the type of the super class of the class to be verified.
+ * @param currentClassInterfaces the types of the interfaces directly implemented by the class to
+ * be verified.
+ * @param isInterface whether the class to be verifier is an interface.
+ */
+ public SimpleVerifier(
+ final Type currentClass,
+ final Type currentSuperClass,
+ final List<Type> currentClassInterfaces,
+ final boolean isInterface) {
+ this(ASM7, currentClass, currentSuperClass, currentClassInterfaces, isInterface);
+ if (getClass() != SimpleVerifier.class) {
+ throw new IllegalStateException();
}
+ }
+
+ /**
+ * Constructs a new {@link SimpleVerifier} to verify a specific class. This class will not be
+ * loaded into the JVM since it may be incorrect.
+ *
+ * @param api the ASM API version supported by this verifier. Must be one of {@link
+ * org.apache.tapestry5.internal.plastic.asm.Opcodes#ASM4}, {@link org.apache.tapestry5.internal.plastic.asm.Opcodes#ASM5}, {@link
+ * org.apache.tapestry5.internal.plastic.asm.Opcodes#ASM6} or {@link org.apache.tapestry5.internal.plastic.asm.Opcodes#ASM7}.
+ * @param currentClass the type of the class to be verified.
+ * @param currentSuperClass the type of the super class of the class to be verified.
+ * @param currentClassInterfaces the types of the interfaces directly implemented by the class to
+ * be verified.
+ * @param isInterface whether the class to be verifier is an interface.
+ */
+ protected SimpleVerifier(
+ final int api,
+ final Type currentClass,
+ final Type currentSuperClass,
+ final List<Type> currentClassInterfaces,
+ final boolean isInterface) {
+ super(api);
+ this.currentClass = currentClass;
+ this.currentSuperClass = currentSuperClass;
+ this.currentClassInterfaces = currentClassInterfaces;
+ this.isInterface = isInterface;
+ }
- protected SimpleVerifier(final int api, final Type currentClass,
- final Type currentSuperClass,
- final List<Type> currentClassInterfaces, final boolean isInterface) {
- super(api);
- this.currentClass = currentClass;
- this.currentSuperClass = currentSuperClass;
- this.currentClassInterfaces = currentClassInterfaces;
- this.isInterface = isInterface;
+ /**
+ * Sets the <code>ClassLoader</code> to be used in {@link #getClass}.
+ *
+ * @param loader the <code>ClassLoader</code> to use.
+ */
+ public void setClassLoader(final ClassLoader loader) {
+ this.loader = loader;
+ }
+
+ @Override
+ public BasicValue newValue(final Type type) {
+ if (type == null) {
+ return BasicValue.UNINITIALIZED_VALUE;
}
- /**
- * Set the <code>ClassLoader</code> which will be used to load referenced
- * classes. This is useful if you are verifying multiple interdependent
- * classes.
- *
- * @param loader
- * a <code>ClassLoader</code> to use
- */
- public void setClassLoader(final ClassLoader loader) {
- this.loader = loader;
+ boolean isArray = type.getSort() == Type.ARRAY;
+ if (isArray) {
+ switch (type.getElementType().getSort()) {
+ case Type.BOOLEAN:
+ case Type.CHAR:
+ case Type.BYTE:
+ case Type.SHORT:
+ return new BasicValue(type);
+ default:
+ break;
+ }
}
- @Override
- public BasicValue newValue(final Type type) {
- if (type == null) {
- return BasicValue.UNINITIALIZED_VALUE;
+ BasicValue value = super.newValue(type);
+ if (BasicValue.REFERENCE_VALUE.equals(value)) {
+ if (isArray) {
+ value = newValue(type.getElementType());
+ StringBuilder descriptor = new StringBuilder();
+ for (int i = 0; i < type.getDimensions(); ++i) {
+ descriptor.append('[');
}
+ descriptor.append(value.getType().getDescriptor());
+ value = new BasicValue(Type.getType(descriptor.toString()));
+ } else {
+ value = new BasicValue(type);
+ }
+ }
+ return value;
+ }
- boolean isArray = type.getSort() == Type.ARRAY;
- if (isArray) {
- switch (type.getElementType().getSort()) {
- case Type.BOOLEAN:
- case Type.CHAR:
- case Type.BYTE:
- case Type.SHORT:
- return new BasicValue(type);
- }
- }
+ @Override
+ protected boolean isArrayValue(final BasicValue value) {
+ Type type = value.getType();
+ return type != null && (type.getSort() == Type.ARRAY || type.equals(NULL_TYPE));
+ }
- BasicValue v = super.newValue(type);
- if (BasicValue.REFERENCE_VALUE.equals(v)) {
- if (isArray) {
- v = newValue(type.getElementType());
- String desc = v.getType().getDescriptor();
- for (int i = 0; i < type.getDimensions(); ++i) {
- desc = '[' + desc;
- }
- v = new BasicValue(Type.getType(desc));
- } else {
- v = new BasicValue(type);
- }
- }
- return v;
+ @Override
+ protected BasicValue getElementValue(final BasicValue objectArrayValue) throws AnalyzerException {
+ Type arrayType = objectArrayValue.getType();
+ if (arrayType != null) {
+ if (arrayType.getSort() == Type.ARRAY) {
+ return newValue(Type.getType(arrayType.getDescriptor().substring(1)));
+ } else if (arrayType.equals(NULL_TYPE)) {
+ return objectArrayValue;
+ }
}
+ throw new AssertionError();
+ }
- @Override
- protected boolean isArrayValue(final BasicValue value) {
- Type t = value.getType();
- return t != null
- && ("Lnull;".equals(t.getDescriptor()) || t.getSort() == Type.ARRAY);
+ @Override
+ protected boolean isSubTypeOf(final BasicValue value, final BasicValue expected) {
+ Type expectedType = expected.getType();
+ Type type = value.getType();
+ switch (expectedType.getSort()) {
+ case Type.INT:
+ case Type.FLOAT:
+ case Type.LONG:
+ case Type.DOUBLE:
+ return type.equals(expectedType);
+ case Type.ARRAY:
+ case Type.OBJECT:
+ if (type.equals(NULL_TYPE)) {
+ return true;
+ } else if (type.getSort() == Type.OBJECT || type.getSort() == Type.ARRAY) {
+ if (isAssignableFrom(expectedType, type)) {
+ return true;
+ } else if (getClass(expectedType).isInterface()) {
+ // The merge of class or interface types can only yield class types (because it is not
+ // possible in general to find an unambiguous common super interface, due to multiple
+ // inheritance). Because of this limitation, we need to relax the subtyping check here
+ // if 'value' is an interface.
+ return Object.class.isAssignableFrom(getClass(type));
+ } else {
+ return false;
+ }
+ } else {
+ return false;
+ }
+ default:
+ throw new AssertionError();
}
+ }
- @Override
- protected BasicValue getElementValue(final BasicValue objectArrayValue)
- throws AnalyzerException {
- Type arrayType = objectArrayValue.getType();
- if (arrayType != null) {
- if (arrayType.getSort() == Type.ARRAY) {
- return newValue(Type.getType(arrayType.getDescriptor()
- .substring(1)));
- } else if ("Lnull;".equals(arrayType.getDescriptor())) {
- return objectArrayValue;
- }
+ @Override
+ public BasicValue merge(final BasicValue value1, final BasicValue value2) {
+ if (!value1.equals(value2)) {
+ Type type1 = value1.getType();
+ Type type2 = value2.getType();
+ if (type1 != null
+ && (type1.getSort() == Type.OBJECT || type1.getSort() == Type.ARRAY)
+ && type2 != null
+ && (type2.getSort() == Type.OBJECT || type2.getSort() == Type.ARRAY)) {
+ if (type1.equals(NULL_TYPE)) {
+ return value2;
}
- throw new Error("Internal error");
+ if (type2.equals(NULL_TYPE)) {
+ return value1;
+ }
+ if (isAssignableFrom(type1, type2)) {
+ return value1;
+ }
+ if (isAssignableFrom(type2, type1)) {
+ return value2;
+ }
+ int numDimensions = 0;
+ if (type1.getSort() == Type.ARRAY
+ && type2.getSort() == Type.ARRAY
+ && type1.getDimensions() == type2.getDimensions()
+ && type1.getElementType().getSort() == Type.OBJECT
+ && type2.getElementType().getSort() == Type.OBJECT) {
+ numDimensions = type1.getDimensions();
+ type1 = type1.getElementType();
+ type2 = type2.getElementType();
+ }
+ do {
+ if (type1 == null || isInterface(type1)) {
+ return newArrayValue(Type.getObjectType("java/lang/Object"), numDimensions);
+ }
+ type1 = getSuperClass(type1);
+ if (isAssignableFrom(type1, type2)) {
+ return newArrayValue(type1, numDimensions);
+ }
+ } while (true);
+ }
+ return BasicValue.UNINITIALIZED_VALUE;
}
+ return value1;
+ }
- @Override
- protected boolean isSubTypeOf(final BasicValue value,
- final BasicValue expected) {
- Type expectedType = expected.getType();
- Type type = value.getType();
- switch (expectedType.getSort()) {
- case Type.INT:
- case Type.FLOAT:
- case Type.LONG:
- case Type.DOUBLE:
- return type.equals(expectedType);
- case Type.ARRAY:
- case Type.OBJECT:
- if ("Lnull;".equals(type.getDescriptor())) {
- return true;
- } else if (type.getSort() == Type.OBJECT
- || type.getSort() == Type.ARRAY) {
- return isAssignableFrom(expectedType, type);
- } else {
- return false;
- }
- default:
- throw new Error("Internal error");
- }
+ private BasicValue newArrayValue(final Type type, final int dimensions) {
+ if (dimensions == 0) {
+ return newValue(type);
+ } else {
+ StringBuilder descriptor = new StringBuilder();
+ for (int i = 0; i < dimensions; ++i) {
+ descriptor.append('[');
+ }
+ descriptor.append(type.getDescriptor());
+ return newValue(Type.getType(descriptor.toString()));
}
+ }
- @Override
- public BasicValue merge(final BasicValue v, final BasicValue w) {
- if (!v.equals(w)) {
- Type t = v.getType();
- Type u = w.getType();
- if (t != null
- && (t.getSort() == Type.OBJECT || t.getSort() == Type.ARRAY)) {
- if (u != null
- && (u.getSort() == Type.OBJECT || u.getSort() == Type.ARRAY)) {
- if ("Lnull;".equals(t.getDescriptor())) {
- return w;
- }
- if ("Lnull;".equals(u.getDescriptor())) {
- return v;
- }
- if (isAssignableFrom(t, u)) {
- return v;
- }
- if (isAssignableFrom(u, t)) {
- return w;
- }
- // TODO case of array classes of the same dimension
- // TODO should we look also for a common super interface?
- // problem: there may be several possible common super
- // interfaces
- do {
- if (t == null || isInterface(t)) {
- return BasicValue.REFERENCE_VALUE;
- }
- t = getSuperClass(t);
- if (isAssignableFrom(t, u)) {
- return newValue(t);
- }
- } while (true);
- }
- }
- return BasicValue.UNINITIALIZED_VALUE;
- }
- return v;
+ /**
+ * Returns whether the given type corresponds to the type of an interface. The default
+ * implementation of this method loads the class and uses the reflection API to return its result
+ * (unless the given type corresponds to the class being verified).
+ *
+ * @param type a type.
+ * @return whether 'type' corresponds to an interface.
+ */
+ protected boolean isInterface(final Type type) {
+ if (currentClass != null && currentClass.equals(type)) {
+ return isInterface;
}
+ return getClass(type).isInterface();
+ }
- protected boolean isInterface(final Type t) {
- if (currentClass != null && t.equals(currentClass)) {
- return isInterface;
- }
- return getClass(t).isInterface();
+ /**
+ * Returns the type corresponding to the super class of the given type. The default implementation
+ * of this method loads the class and uses the reflection API to return its result (unless the
+ * given type corresponds to the class being verified).
+ *
+ * @param type a type.
+ * @return the type corresponding to the super class of 'type'.
+ */
+ protected Type getSuperClass(final Type type) {
+ if (currentClass != null && currentClass.equals(type)) {
+ return currentSuperClass;
}
+ Class<?> superClass = getClass(type).getSuperclass();
+ return superClass == null ? null : Type.getType(superClass);
+ }
- protected Type getSuperClass(final Type t) {
- if (currentClass != null && t.equals(currentClass)) {
- return currentSuperClass;
+ /**
+ * Returns whether the class corresponding to the first argument is either the same as, or is a
+ * superclass or superinterface of the class corresponding to the second argument. The default
+ * implementation of this method loads the classes and uses the reflection API to return its
+ * result (unless the result can be computed from the class being verified, and the types of its
+ * super classes and implemented interfaces).
+ *
+ * @param type1 a type.
+ * @param type2 another type.
+ * @return whether the class corresponding to 'type1' is either the same as, or is a superclass or
+ * superinterface of the class corresponding to 'type2'.
+ */
+ protected boolean isAssignableFrom(final Type type1, final Type type2) {
+ if (type1.equals(type2)) {
+ return true;
+ }
+ if (currentClass != null && currentClass.equals(type1)) {
+ if (getSuperClass(type2) == null) {
+ return false;
+ } else {
+ if (isInterface) {
+ return type2.getSort() == Type.OBJECT || type2.getSort() == Type.ARRAY;
}
- Class<?> c = getClass(t).getSuperclass();
- return c == null ? null : Type.getType(c);
+ return isAssignableFrom(type1, getSuperClass(type2));
+ }
}
-
- protected boolean isAssignableFrom(final Type t, final Type u) {
- if (t.equals(u)) {
+ if (currentClass != null && currentClass.equals(type2)) {
+ if (isAssignableFrom(type1, currentSuperClass)) {
+ return true;
+ }
+ if (currentClassInterfaces != null) {
+ for (Type currentClassInterface : currentClassInterfaces) {
+ if (isAssignableFrom(type1, currentClassInterface)) {
return true;
+ }
}
- if (currentClass != null && t.equals(currentClass)) {
- if (getSuperClass(u) == null) {
- return false;
- } else {
- if (isInterface) {
- return u.getSort() == Type.OBJECT
- || u.getSort() == Type.ARRAY;
- }
- return isAssignableFrom(t, getSuperClass(u));
- }
- }
- if (currentClass != null && u.equals(currentClass)) {
- if (isAssignableFrom(t, currentSuperClass)) {
- return true;
- }
- if (currentClassInterfaces != null) {
- for (int i = 0; i < currentClassInterfaces.size(); ++i) {
- Type v = currentClassInterfaces.get(i);
- if (isAssignableFrom(t, v)) {
- return true;
- }
- }
- }
- return false;
- }
- Class<?> tc = getClass(t);
- if (tc.isInterface()) {
- tc = Object.class;
- }
- return tc.isAssignableFrom(getClass(u));
+ }
+ return false;
}
+ return getClass(type1).isAssignableFrom(getClass(type2));
+ }
- protected Class<?> getClass(final Type t) {
- try {
- if (t.getSort() == Type.ARRAY) {
- return Class.forName(t.getDescriptor().replace('/', '.'),
- false, loader);
- }
- return Class.forName(t.getClassName(), false, loader);
- } catch (ClassNotFoundException e) {
- throw new RuntimeException(e.toString());
- }
+ /**
+ * Loads the class corresponding to the given type. The class is loaded with the class loader
+ * specified with {@link #setClassLoader}, or with the class loader of this class if no class
+ * loader was specified.
+ *
+ * @param type a type.
+ * @return the class corresponding to 'type'.
+ */
+ protected Class<?> getClass(final Type type) {
+ try {
+ if (type.getSort() == Type.ARRAY) {
+ return Class.forName(type.getDescriptor().replace('/', '.'), false, loader);
+ }
+ return Class.forName(type.getClassName(), false, loader);
+ } catch (ClassNotFoundException e) {
+ throw new TypeNotPresentException(e.toString(), e);
}
+ }
}
http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/1c71aec7/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/tree/analysis/SmallSet.java
----------------------------------------------------------------------
diff --git a/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/tree/analysis/SmallSet.java b/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/tree/analysis/SmallSet.java
old mode 100644
new mode 100755
index 2aacb42..45df958
--- a/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/tree/analysis/SmallSet.java
+++ b/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/tree/analysis/SmallSet.java
@@ -1,32 +1,30 @@
-/***
- * 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.tree.analysis;
import java.util.AbstractSet;
@@ -36,99 +34,159 @@ import java.util.NoSuchElementException;
import java.util.Set;
/**
- * A set of at most two elements.
- *
+ * An immutable set of at most two elements, optimized for speed compared to a generic set
+ * implementation.
+ *
* @author Eric Bruneton
*/
-class SmallSet<E> extends AbstractSet<E> implements Iterator<E> {
+final class SmallSet<T> extends AbstractSet<T> {
- // if e1 is null, e2 must be null; otherwise e2 must be different from e1
+ /** The first element of this set, maybe {@literal null}. */
+ private final T element1;
- E e1, e2;
+ /**
+ * The second element of this set, maybe {@literal null}. If {@link #element1} is {@literal null}
+ * then this field must be {@literal null}, otherwise it must be different from {@link #element1}.
+ */
+ private final T element2;
- static final <T> Set<T> emptySet() {
- return new SmallSet<T>(null, null);
- }
+ // -----------------------------------------------------------------------------------------------
+ // Constructors
+ // -----------------------------------------------------------------------------------------------
- SmallSet(final E e1, final E e2) {
- this.e1 = e1;
- this.e2 = e2;
- }
+ /** Constructs an empty set. */
+ SmallSet() {
+ this.element1 = null;
+ this.element2 = null;
+ }
- // -------------------------------------------------------------------------
- // Implementation of inherited abstract methods
- // -------------------------------------------------------------------------
+ /**
+ * Constructs a set with exactly one element.
+ *
+ * @param element the unique set element.
+ */
+ SmallSet(final T element) {
+ this.element1 = element;
+ this.element2 = null;
+ }
- @Override
- public Iterator<E> iterator() {
- return new SmallSet<E>(e1, e2);
+ /**
+ * Constructs a new {@link SmallSet}.
+ *
+ * @param element1 see {@link #element1}.
+ * @param element2 see {@link #element2}.
+ */
+ private SmallSet(final T element1, final T element2) {
+ this.element1 = element1;
+ this.element2 = element2;
+ }
+
+ // -----------------------------------------------------------------------------------------------
+ // Implementation of the inherited abstract methods
+ // -----------------------------------------------------------------------------------------------
+
+ @Override
+ public Iterator<T> iterator() {
+ return new IteratorImpl<T>(element1, element2);
+ }
+
+ @Override
+ public int size() {
+ return element1 == null ? 0 : (element2 == null ? 1 : 2);
+ }
+
+ // -----------------------------------------------------------------------------------------------
+ // Utility methods
+ // -----------------------------------------------------------------------------------------------
+
+ /**
+ * Returns the union of this set and of the given set.
+ *
+ * @param otherSet another small set.
+ * @return the union of this set and of otherSet.
+ */
+ Set<T> union(final SmallSet<T> otherSet) {
+ // If the two sets are equal, return this set.
+ if ((otherSet.element1 == element1 && otherSet.element2 == element2)
+ || (otherSet.element1 == element2 && otherSet.element2 == element1)) {
+ return this;
+ }
+ // If one set is empty, return the other.
+ if (otherSet.element1 == null) {
+ return this;
+ }
+ if (element1 == null) {
+ return otherSet;
}
- @Override
- public int size() {
- return e1 == null ? 0 : (e2 == null ? 1 : 2);
+ // At this point we know that the two sets are non empty and are different.
+ // If otherSet contains exactly one element:
+ if (otherSet.element2 == null) {
+ // If this set also contains exactly one element, we have two distinct elements.
+ if (element2 == null) {
+ return new SmallSet<T>(element1, otherSet.element1);
+ }
+ // If otherSet is included in this set, return this set.
+ if (otherSet.element1 == element1 || otherSet.element1 == element2) {
+ return this;
+ }
+ }
+ // If this set contains exactly one element, then otherSet contains two elements (because of the
+ // above tests). Thus, if otherSet contains this set, return otherSet:
+ if (element2 == null && (element1 == otherSet.element1 || element1 == otherSet.element2)) {
+ return otherSet;
}
- // -------------------------------------------------------------------------
- // Implementation of the Iterator interface
- // -------------------------------------------------------------------------
+ // At this point we know that there are at least 3 distinct elements, so we need a generic set
+ // to store the result.
+ HashSet<T> result = new HashSet<T>(4);
+ result.add(element1);
+ if (element2 != null) {
+ result.add(element2);
+ }
+ result.add(otherSet.element1);
+ if (otherSet.element2 != null) {
+ result.add(otherSet.element2);
+ }
+ return result;
+ }
- public boolean hasNext() {
- return e1 != null;
+ static class IteratorImpl<T> implements Iterator<T> {
+
+ /** The next element to return in {@link #next}. Maybe {@literal null}. */
+ private T firstElement;
+
+ /**
+ * The element to return in {@link #next}, after {@link #firstElement} is returned. If {@link
+ * #firstElement} is {@literal null} then this field must be {@literal null}, otherwise it must
+ * be different from {@link #firstElement}.
+ */
+ private T secondElement;
+
+ IteratorImpl(final T firstElement, final T secondElement) {
+ this.firstElement = firstElement;
+ this.secondElement = secondElement;
}
- public E next() {
- if (e1 == null) {
- throw new NoSuchElementException();
- }
- E e = e1;
- e1 = e2;
- e2 = null;
- return e;
+ @Override
+ public boolean hasNext() {
+ return firstElement != null;
}
- public void remove() {
+ @Override
+ public T next() {
+ if (firstElement == null) {
+ throw new NoSuchElementException();
+ }
+ T element = firstElement;
+ firstElement = secondElement;
+ secondElement = null;
+ return element;
}
- // -------------------------------------------------------------------------
- // Utility methods
- // -------------------------------------------------------------------------
-
- Set<E> union(final SmallSet<E> s) {
- if ((s.e1 == e1 && s.e2 == e2) || (s.e1 == e2 && s.e2 == e1)) {
- return this; // if the two sets are equal, return this
- }
- if (s.e1 == null) {
- return this; // if s is empty, return this
- }
- if (e1 == null) {
- return s; // if this is empty, return s
- }
- if (s.e2 == null) { // s contains exactly one element
- if (e2 == null) {
- return new SmallSet<E>(e1, s.e1); // necessarily e1 != s.e1
- } else if (s.e1 == e1 || s.e1 == e2) { // s is included in this
- return this;
- }
- }
- if (e2 == null) { // this contains exactly one element
- // if (s.e2 == null) { // cannot happen
- // return new SmallSet(e1, s.e1); // necessarily e1 != s.e1
- // } else
- if (e1 == s.e1 || e1 == s.e2) { // this in included in s
- return s;
- }
- }
- // here we know that there are at least 3 distinct elements
- HashSet<E> r = new HashSet<E>(4);
- r.add(e1);
- if (e2 != null) {
- r.add(e2);
- }
- r.add(s.e1);
- if (s.e2 != null) {
- r.add(s.e2);
- }
- return r;
+ @Override
+ public void remove() {
+ throw new UnsupportedOperationException();
}
+ }
}
http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/1c71aec7/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/tree/analysis/SourceInterpreter.java
----------------------------------------------------------------------
diff --git a/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/tree/analysis/SourceInterpreter.java b/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/tree/analysis/SourceInterpreter.java
old mode 100644
new mode 100755
index 7a257e7..a84b44a
--- a/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/tree/analysis/SourceInterpreter.java
+++ b/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/tree/analysis/SourceInterpreter.java
@@ -1,38 +1,35 @@
-/***
- * 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.tree.analysis;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
-
import org.apache.tapestry5.internal.plastic.asm.Opcodes;
import org.apache.tapestry5.internal.plastic.asm.Type;
import org.apache.tapestry5.internal.plastic.asm.tree.AbstractInsnNode;
@@ -43,156 +40,182 @@ import org.apache.tapestry5.internal.plastic.asm.tree.MethodInsnNode;
/**
* An {@link Interpreter} for {@link SourceValue} values.
- *
+ *
* @author Eric Bruneton
*/
-public class SourceInterpreter extends Interpreter<SourceValue> implements
- Opcodes {
+public class SourceInterpreter extends Interpreter<SourceValue> implements Opcodes {
- public SourceInterpreter() {
- super(ASM6);
+ /**
+ * Constructs a new {@link SourceInterpreter} for the latest ASM API version. <i>Subclasses must
+ * not use this constructor</i>. Instead, they must use the {@link #SourceInterpreter(int)}
+ * version.
+ */
+ public SourceInterpreter() {
+ super(ASM7);
+ if (getClass() != SourceInterpreter.class) {
+ throw new IllegalStateException();
}
+ }
- protected SourceInterpreter(final int api) {
- super(api);
- }
+ /**
+ * Constructs a new {@link SourceInterpreter}.
+ *
+ * @param api the ASM API version supported by this interpreter. Must be one of {@link
+ * org.apache.tapestry5.internal.plastic.asm.Opcodes#ASM4}, {@link org.apache.tapestry5.internal.plastic.asm.Opcodes#ASM5}, {@link
+ * org.apache.tapestry5.internal.plastic.asm.Opcodes#ASM6} or {@link org.apache.tapestry5.internal.plastic.asm.Opcodes#ASM7}.
+ */
+ protected SourceInterpreter(final int api) {
+ super(api);
+ }
- @Override
- public SourceValue newValue(final Type type) {
- if (type == Type.VOID_TYPE) {
- return null;
- }
- return new SourceValue(type == null ? 1 : type.getSize());
+ @Override
+ public SourceValue newValue(final Type type) {
+ if (type == Type.VOID_TYPE) {
+ return null;
}
+ return new SourceValue(type == null ? 1 : type.getSize());
+ }
- @Override
- public SourceValue newOperation(final AbstractInsnNode insn) {
- int size;
- switch (insn.getOpcode()) {
- case LCONST_0:
- case LCONST_1:
- case DCONST_0:
- case DCONST_1:
- size = 2;
- break;
- case LDC:
- Object cst = ((LdcInsnNode) insn).cst;
- size = cst instanceof Long || cst instanceof Double ? 2 : 1;
- break;
- case GETSTATIC:
- size = Type.getType(((FieldInsnNode) insn).desc).getSize();
- break;
- default:
- size = 1;
- }
- return new SourceValue(size, insn);
+ @Override
+ public SourceValue newOperation(final AbstractInsnNode insn) {
+ int size;
+ switch (insn.getOpcode()) {
+ case LCONST_0:
+ case LCONST_1:
+ case DCONST_0:
+ case DCONST_1:
+ size = 2;
+ break;
+ case LDC:
+ Object value = ((LdcInsnNode) insn).cst;
+ size = value instanceof Long || value instanceof Double ? 2 : 1;
+ break;
+ case GETSTATIC:
+ size = Type.getType(((FieldInsnNode) insn).desc).getSize();
+ break;
+ default:
+ size = 1;
+ break;
}
+ return new SourceValue(size, insn);
+ }
- @Override
- public SourceValue copyOperation(final AbstractInsnNode insn,
- final SourceValue value) {
- return new SourceValue(value.getSize(), insn);
- }
+ @Override
+ public SourceValue copyOperation(final AbstractInsnNode insn, final SourceValue value) {
+ return new SourceValue(value.getSize(), insn);
+ }
- @Override
- public SourceValue unaryOperation(final AbstractInsnNode insn,
- final SourceValue value) {
- int size;
- switch (insn.getOpcode()) {
- case LNEG:
- case DNEG:
- case I2L:
- case I2D:
- case L2D:
- case F2L:
- case F2D:
- case D2L:
- size = 2;
- break;
- case GETFIELD:
- size = Type.getType(((FieldInsnNode) insn).desc).getSize();
- break;
- default:
- size = 1;
- }
- return new SourceValue(size, insn);
+ @Override
+ public SourceValue unaryOperation(final AbstractInsnNode insn, final SourceValue value) {
+ int size;
+ switch (insn.getOpcode()) {
+ case LNEG:
+ case DNEG:
+ case I2L:
+ case I2D:
+ case L2D:
+ case F2L:
+ case F2D:
+ case D2L:
+ size = 2;
+ break;
+ case GETFIELD:
+ size = Type.getType(((FieldInsnNode) insn).desc).getSize();
+ break;
+ default:
+ size = 1;
+ break;
}
+ return new SourceValue(size, insn);
+ }
- @Override
- public SourceValue binaryOperation(final AbstractInsnNode insn,
- final SourceValue value1, final SourceValue value2) {
- int size;
- switch (insn.getOpcode()) {
- case LALOAD:
- case DALOAD:
- case LADD:
- case DADD:
- case LSUB:
- case DSUB:
- case LMUL:
- case DMUL:
- case LDIV:
- case DDIV:
- case LREM:
- case DREM:
- case LSHL:
- case LSHR:
- case LUSHR:
- case LAND:
- case LOR:
- case LXOR:
- size = 2;
- break;
- default:
- size = 1;
- }
- return new SourceValue(size, insn);
+ @Override
+ public SourceValue binaryOperation(
+ final AbstractInsnNode insn, final SourceValue value1, final SourceValue value2) {
+ int size;
+ switch (insn.getOpcode()) {
+ case LALOAD:
+ case DALOAD:
+ case LADD:
+ case DADD:
+ case LSUB:
+ case DSUB:
+ case LMUL:
+ case DMUL:
+ case LDIV:
+ case DDIV:
+ case LREM:
+ case DREM:
+ case LSHL:
+ case LSHR:
+ case LUSHR:
+ case LAND:
+ case LOR:
+ case LXOR:
+ size = 2;
+ break;
+ default:
+ size = 1;
+ break;
}
+ return new SourceValue(size, insn);
+ }
- @Override
- public SourceValue ternaryOperation(final AbstractInsnNode insn,
- final SourceValue value1, final SourceValue value2,
- final SourceValue value3) {
- return new SourceValue(1, insn);
- }
+ @Override
+ public SourceValue ternaryOperation(
+ final AbstractInsnNode insn,
+ final SourceValue value1,
+ final SourceValue value2,
+ final SourceValue value3) {
+ return new SourceValue(1, insn);
+ }
- @Override
- public SourceValue naryOperation(final AbstractInsnNode insn,
- final List<? extends SourceValue> values) {
- int size;
- int opcode = insn.getOpcode();
- if (opcode == MULTIANEWARRAY) {
- size = 1;
- } else {
- String desc = (opcode == INVOKEDYNAMIC) ? ((InvokeDynamicInsnNode) insn).desc
- : ((MethodInsnNode) insn).desc;
- size = Type.getReturnType(desc).getSize();
- }
- return new SourceValue(size, insn);
+ @Override
+ public SourceValue naryOperation(
+ final AbstractInsnNode insn, final List<? extends SourceValue> values) {
+ int size;
+ int opcode = insn.getOpcode();
+ if (opcode == MULTIANEWARRAY) {
+ size = 1;
+ } else if (opcode == INVOKEDYNAMIC) {
+ size = Type.getReturnType(((InvokeDynamicInsnNode) insn).desc).getSize();
+ } else {
+ size = Type.getReturnType(((MethodInsnNode) insn).desc).getSize();
}
+ return new SourceValue(size, insn);
+ }
- @Override
- public void returnOperation(final AbstractInsnNode insn,
- final SourceValue value, final SourceValue expected) {
+ @Override
+ public void returnOperation(
+ final AbstractInsnNode insn, final SourceValue value, final SourceValue expected) {
+ // Nothing to do.
+ }
+
+ @Override
+ public SourceValue merge(final SourceValue value1, final SourceValue value2) {
+ if (value1.insns instanceof SmallSet && value2.insns instanceof SmallSet) {
+ Set<AbstractInsnNode> setUnion =
+ ((SmallSet<AbstractInsnNode>) value1.insns)
+ .union((SmallSet<AbstractInsnNode>) value2.insns);
+ if (setUnion == value1.insns && value1.size == value2.size) {
+ return value1;
+ } else {
+ return new SourceValue(Math.min(value1.size, value2.size), setUnion);
+ }
+ }
+ if (value1.size != value2.size || !containsAll(value1.insns, value2.insns)) {
+ HashSet<AbstractInsnNode> setUnion = new HashSet<AbstractInsnNode>();
+ setUnion.addAll(value1.insns);
+ setUnion.addAll(value2.insns);
+ return new SourceValue(Math.min(value1.size, value2.size), setUnion);
}
+ return value1;
+ }
- @Override
- public SourceValue merge(final SourceValue d, final SourceValue w) {
- if (d.insns instanceof SmallSet && w.insns instanceof SmallSet) {
- Set<AbstractInsnNode> s = ((SmallSet<AbstractInsnNode>) d.insns)
- .union((SmallSet<AbstractInsnNode>) w.insns);
- if (s == d.insns && d.size == w.size) {
- return d;
- } else {
- return new SourceValue(Math.min(d.size, w.size), s);
- }
- }
- if (d.size != w.size || !d.insns.containsAll(w.insns)) {
- HashSet<AbstractInsnNode> s = new HashSet<AbstractInsnNode>();
- s.addAll(d.insns);
- s.addAll(w.insns);
- return new SourceValue(Math.min(d.size, w.size), s);
- }
- return d;
+ private static <E> boolean containsAll(final Set<E> self, final Set<E> other) {
+ if (self.size() < other.size()) {
+ return false;
}
+ return self.containsAll(other);
+ }
}
http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/1c71aec7/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/tree/analysis/SourceValue.java
----------------------------------------------------------------------
diff --git a/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/tree/analysis/SourceValue.java b/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/tree/analysis/SourceValue.java
old mode 100644
new mode 100755
index 0cb2f50..3b68854
--- a/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/tree/analysis/SourceValue.java
+++ b/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/tree/analysis/SourceValue.java
@@ -1,97 +1,119 @@
-/***
- * 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.tree.analysis;
import java.util.Set;
-
import org.apache.tapestry5.internal.plastic.asm.tree.AbstractInsnNode;
/**
- * A {@link Value} that is represented by its type in a two types type system.
- * This type system distinguishes the ONEWORD and TWOWORDS types.
- *
+ * A {@link Value} which keeps track of the bytecode instructions that can produce it.
+ *
* @author Eric Bruneton
*/
public class SourceValue implements Value {
- /**
- * The size of this value.
- */
- public final int size;
+ /**
+ * The size of this value, in 32 bits words. This size is 1 for byte, boolean, char, short, int,
+ * float, object and array types, and 2 for long and double.
+ */
+ public final int size;
- /**
- * The instructions that can produce this value. For example, for the Java
- * code below, the instructions that can produce the value of <tt>i</tt> at
- * line 5 are the txo ISTORE instructions at line 1 and 3:
- *
- * <pre>
- * 1: i = 0;
- * 2: if (...) {
- * 3: i = 1;
- * 4: }
- * 5: return i;
- * </pre>
- *
- * This field is a set of {@link AbstractInsnNode} objects.
- */
- public final Set<AbstractInsnNode> insns;
+ /**
+ * The instructions that can produce this value. For example, for the Java code below, the
+ * instructions that can produce the value of {@code i} at line 5 are the two ISTORE instructions
+ * at line 1 and 3:
+ *
+ * <pre>
+ * 1: i = 0;
+ * 2: if (...) {
+ * 3: i = 1;
+ * 4: }
+ * 5: return i;
+ * </pre>
+ */
+ public final Set<AbstractInsnNode> insns;
- public SourceValue(final int size) {
- this(size, SmallSet.<AbstractInsnNode> emptySet());
- }
+ /**
+ * Constructs a new {@link SourceValue}.
+ *
+ * @param size the size of this value, in 32 bits words. This size is 1 for byte, boolean, char,
+ * short, int, float, object and array types, and 2 for long and double.
+ */
+ public SourceValue(final int size) {
+ this(size, new SmallSet<AbstractInsnNode>());
+ }
- public SourceValue(final int size, final AbstractInsnNode insn) {
- this.size = size;
- this.insns = new SmallSet<AbstractInsnNode>(insn, null);
- }
+ /**
+ * Constructs a new {@link SourceValue}.
+ *
+ * @param size the size of this value, in 32 bits words. This size is 1 for byte, boolean, char,
+ * short, int, float, object and array types, and 2 for long and double.
+ * @param insnNode an instruction that can produce this value.
+ */
+ public SourceValue(final int size, final AbstractInsnNode insnNode) {
+ this.size = size;
+ this.insns = new SmallSet<AbstractInsnNode>(insnNode);
+ }
- public SourceValue(final int size, final Set<AbstractInsnNode> insns) {
- this.size = size;
- this.insns = insns;
- }
+ /**
+ * Constructs a new {@link SourceValue}.
+ *
+ * @param size the size of this value, in 32 bits words. This size is 1 for byte, boolean, char,
+ * short, int, float, object and array types, and 2 for long and double.
+ * @param insnSet the instructions that can produce this value.
+ */
+ public SourceValue(final int size, final Set<AbstractInsnNode> insnSet) {
+ this.size = size;
+ this.insns = insnSet;
+ }
- public int getSize() {
- return size;
- }
+ /**
+ * Returns the size of this value.
+ *
+ * @return the size of this value, in 32 bits words. This size is 1 for byte, boolean, char,
+ * short, int, float, object and array types, and 2 for long and double.
+ */
+ @Override
+ public int getSize() {
+ return size;
+ }
- @Override
- public boolean equals(final Object value) {
- if (!(value instanceof SourceValue)) {
- return false;
- }
- SourceValue v = (SourceValue) value;
- return size == v.size && insns.equals(v.insns);
+ @Override
+ public boolean equals(final Object value) {
+ if (!(value instanceof SourceValue)) {
+ return false;
}
+ SourceValue sourceValue = (SourceValue) value;
+ return size == sourceValue.size && insns.equals(sourceValue.insns);
+ }
- @Override
- public int hashCode() {
- return insns.hashCode();
- }
+ @Override
+ public int hashCode() {
+ return insns.hashCode();
+ }
}