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(); + } }
