• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // ASM: a very small and fast Java bytecode manipulation framework
2 // Copyright (c) 2000-2011 INRIA, France Telecom
3 // All rights reserved.
4 //
5 // Redistribution and use in source and binary forms, with or without
6 // modification, are permitted provided that the following conditions
7 // are met:
8 // 1. Redistributions of source code must retain the above copyright
9 //    notice, this list of conditions and the following disclaimer.
10 // 2. Redistributions in binary form must reproduce the above copyright
11 //    notice, this list of conditions and the following disclaimer in the
12 //    documentation and/or other materials provided with the distribution.
13 // 3. Neither the name of the copyright holders nor the names of its
14 //    contributors may be used to endorse or promote products derived from
15 //    this software without specific prior written permission.
16 //
17 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18 // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
21 // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22 // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23 // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24 // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25 // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26 // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
27 // THE POSSIBILITY OF SUCH DAMAGE.
28 package org.objectweb.asm;
29 
30 import java.util.Arrays;
31 
32 /**
33  * A constant whose value is computed at runtime, with a bootstrap method.
34  *
35  * @author Remi Forax
36  */
37 public final class ConstantDynamic {
38 
39   /** The constant name (can be arbitrary). */
40   private final String name;
41 
42   /** The constant type (must be a field descriptor). */
43   private final String descriptor;
44 
45   /** The bootstrap method to use to compute the constant value at runtime. */
46   private final Handle bootstrapMethod;
47 
48   /**
49    * The arguments to pass to the bootstrap method, in order to compute the constant value at
50    * runtime.
51    */
52   private final Object[] bootstrapMethodArguments;
53 
54   /**
55    * Constructs a new {@link ConstantDynamic}.
56    *
57    * @param name the constant name (can be arbitrary).
58    * @param descriptor the constant type (must be a field descriptor).
59    * @param bootstrapMethod the bootstrap method to use to compute the constant value at runtime.
60    * @param bootstrapMethodArguments the arguments to pass to the bootstrap method, in order to
61    *     compute the constant value at runtime.
62    */
ConstantDynamic( final String name, final String descriptor, final Handle bootstrapMethod, final Object... bootstrapMethodArguments)63   public ConstantDynamic(
64       final String name,
65       final String descriptor,
66       final Handle bootstrapMethod,
67       final Object... bootstrapMethodArguments) {
68     this.name = name;
69     this.descriptor = descriptor;
70     this.bootstrapMethod = bootstrapMethod;
71     this.bootstrapMethodArguments = bootstrapMethodArguments;
72   }
73 
74   /**
75    * Returns the name of this constant.
76    *
77    * @return the name of this constant.
78    */
getName()79   public String getName() {
80     return name;
81   }
82 
83   /**
84    * Returns the type of this constant.
85    *
86    * @return the type of this constant, as a field descriptor.
87    */
getDescriptor()88   public String getDescriptor() {
89     return descriptor;
90   }
91 
92   /**
93    * Returns the bootstrap method used to compute the value of this constant.
94    *
95    * @return the bootstrap method used to compute the value of this constant.
96    */
getBootstrapMethod()97   public Handle getBootstrapMethod() {
98     return bootstrapMethod;
99   }
100 
101   /**
102    * Returns the number of arguments passed to the bootstrap method, in order to compute the value
103    * of this constant.
104    *
105    * @return the number of arguments passed to the bootstrap method, in order to compute the value
106    *     of this constant.
107    */
getBootstrapMethodArgumentCount()108   public int getBootstrapMethodArgumentCount() {
109     return bootstrapMethodArguments.length;
110   }
111 
112   /**
113    * Returns an argument passed to the bootstrap method, in order to compute the value of this
114    * constant.
115    *
116    * @param index an argument index, between 0 and {@link #getBootstrapMethodArgumentCount()}
117    *     (exclusive).
118    * @return the argument passed to the bootstrap method, with the given index.
119    */
getBootstrapMethodArgument(final int index)120   public Object getBootstrapMethodArgument(final int index) {
121     return bootstrapMethodArguments[index];
122   }
123 
124   /**
125    * Returns the arguments to pass to the bootstrap method, in order to compute the value of this
126    * constant. WARNING: this array must not be modified, and must not be returned to the user.
127    *
128    * @return the arguments to pass to the bootstrap method, in order to compute the value of this
129    *     constant.
130    */
getBootstrapMethodArgumentsUnsafe()131   Object[] getBootstrapMethodArgumentsUnsafe() {
132     return bootstrapMethodArguments;
133   }
134 
135   /**
136    * Returns the size of this constant.
137    *
138    * @return the size of this constant, i.e., 2 for {@code long} and {@code double}, 1 otherwise.
139    */
getSize()140   public int getSize() {
141     char firstCharOfDescriptor = descriptor.charAt(0);
142     return (firstCharOfDescriptor == 'J' || firstCharOfDescriptor == 'D') ? 2 : 1;
143   }
144 
145   @Override
equals(final Object object)146   public boolean equals(final Object object) {
147     if (object == this) {
148       return true;
149     }
150     if (!(object instanceof ConstantDynamic)) {
151       return false;
152     }
153     ConstantDynamic constantDynamic = (ConstantDynamic) object;
154     return name.equals(constantDynamic.name)
155         && descriptor.equals(constantDynamic.descriptor)
156         && bootstrapMethod.equals(constantDynamic.bootstrapMethod)
157         && Arrays.equals(bootstrapMethodArguments, constantDynamic.bootstrapMethodArguments);
158   }
159 
160   @Override
hashCode()161   public int hashCode() {
162     return name.hashCode()
163         ^ Integer.rotateLeft(descriptor.hashCode(), 8)
164         ^ Integer.rotateLeft(bootstrapMethod.hashCode(), 16)
165         ^ Integer.rotateLeft(Arrays.hashCode(bootstrapMethodArguments), 24);
166   }
167 
168   @Override
toString()169   public String toString() {
170     return name
171         + " : "
172         + descriptor
173         + ' '
174         + bootstrapMethod
175         + ' '
176         + Arrays.toString(bootstrapMethodArguments);
177   }
178 }
179