| // 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; |
| |
| import java.util.Arrays; |
| |
| /** |
| * A constant whose value is computed at runtime, with a bootstrap method. |
| * |
| * @author Remi Forax |
| */ |
| public final class ConstantDynamic { |
| |
| /** The constant name (can be arbitrary). */ |
| private final String name; |
| |
| /** The constant type (must be a field descriptor). */ |
| private final String descriptor; |
| |
| /** The bootstrap method to use to compute the constant value at runtime. */ |
| private final Handle bootstrapMethod; |
| |
| /** |
| * The arguments to pass to the bootstrap method, in order to compute the constant value at |
| * runtime. |
| */ |
| private final Object[] bootstrapMethodArguments; |
| |
| /** |
| * Constructs a new {@link ConstantDynamic}. |
| * |
| * @param name the constant name (can be arbitrary). |
| * @param descriptor the constant type (must be a field descriptor). |
| * @param bootstrapMethod the bootstrap method to use to compute the constant value at runtime. |
| * @param bootstrapMethodArguments the arguments to pass to the bootstrap method, in order to |
| * compute the constant value at runtime. |
| */ |
| public ConstantDynamic( |
| final String name, |
| final String descriptor, |
| final Handle bootstrapMethod, |
| final Object... bootstrapMethodArguments) { |
| this.name = name; |
| this.descriptor = descriptor; |
| this.bootstrapMethod = bootstrapMethod; |
| this.bootstrapMethodArguments = bootstrapMethodArguments; |
| } |
| |
| /** |
| * Returns the name of this constant. |
| * |
| * @return the name of this constant. |
| */ |
| public String getName() { |
| return name; |
| } |
| |
| /** |
| * Returns the type of this constant. |
| * |
| * @return the type of this constant, as a field descriptor. |
| */ |
| public String getDescriptor() { |
| return descriptor; |
| } |
| |
| /** |
| * Returns the bootstrap method used to compute the value of this constant. |
| * |
| * @return the bootstrap method used to compute the value of this constant. |
| */ |
| public Handle getBootstrapMethod() { |
| return bootstrapMethod; |
| } |
| |
| /** |
| * Returns the number of arguments passed to the bootstrap method, in order to compute the value |
| * of this constant. |
| * |
| * @return the number of arguments passed to the bootstrap method, in order to compute the value |
| * of this constant. |
| */ |
| public int getBootstrapMethodArgumentCount() { |
| return bootstrapMethodArguments.length; |
| } |
| |
| /** |
| * Returns an argument passed to the bootstrap method, in order to compute the value of this |
| * constant. |
| * |
| * @param index an argument index, between 0 and {@link #getBootstrapMethodArgumentCount()} |
| * (exclusive). |
| * @return the argument passed to the bootstrap method, with the given index. |
| */ |
| public Object getBootstrapMethodArgument(final int index) { |
| return bootstrapMethodArguments[index]; |
| } |
| |
| /** |
| * Returns the arguments to pass to the bootstrap method, in order to compute the value of this |
| * constant. WARNING: this array must not be modified, and must not be returned to the user. |
| * |
| * @return the arguments to pass to the bootstrap method, in order to compute the value of this |
| * constant. |
| */ |
| Object[] getBootstrapMethodArgumentsUnsafe() { |
| return bootstrapMethodArguments; |
| } |
| |
| /** |
| * Returns the size of this constant. |
| * |
| * @return the size of this constant, i.e., 2 for {@code long} and {@code double}, 1 otherwise. |
| */ |
| public int getSize() { |
| char firstCharOfDescriptor = descriptor.charAt(0); |
| return (firstCharOfDescriptor == 'J' || firstCharOfDescriptor == 'D') ? 2 : 1; |
| } |
| |
| @Override |
| public boolean equals(final Object object) { |
| if (object == this) { |
| return true; |
| } |
| if (!(object instanceof ConstantDynamic)) { |
| return false; |
| } |
| ConstantDynamic constantDynamic = (ConstantDynamic) object; |
| return name.equals(constantDynamic.name) |
| && descriptor.equals(constantDynamic.descriptor) |
| && bootstrapMethod.equals(constantDynamic.bootstrapMethod) |
| && Arrays.equals(bootstrapMethodArguments, constantDynamic.bootstrapMethodArguments); |
| } |
| |
| @Override |
| public int hashCode() { |
| return name.hashCode() |
| ^ Integer.rotateLeft(descriptor.hashCode(), 8) |
| ^ Integer.rotateLeft(bootstrapMethod.hashCode(), 16) |
| ^ Integer.rotateLeft(Arrays.hashCode(bootstrapMethodArguments), 24); |
| } |
| |
| @Override |
| public String toString() { |
| return name |
| + " : " |
| + descriptor |
| + ' ' |
| + bootstrapMethod |
| + ' ' |
| + Arrays.toString(bootstrapMethodArguments); |
| } |
| } |