1579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson/* 2579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * Copyright (C) 2007 The Android Open Source Project 3579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * 4579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * Licensed under the Apache License, Version 2.0 (the "License"); 5579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * you may not use this file except in compliance with the License. 6579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * You may obtain a copy of the License at 7579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * 8579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * http://www.apache.org/licenses/LICENSE-2.0 9579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * 10579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * Unless required by applicable law or agreed to in writing, software 11579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * distributed under the License is distributed on an "AS IS" BASIS, 12579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * See the License for the specific language governing permissions and 14579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * limitations under the License. 15579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson */ 16579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 17579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilsonpackage com.android.dx.rop.type; 18579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 19579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilsonimport com.android.dx.util.Hex; 20579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 21579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilsonimport java.util.HashMap; 22579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 23579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson/** 24579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * Representation of a value type, such as may appear in a field, in a 25579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * local, on a stack, or in a method descriptor. Instances of this 26579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * class are generally interned and may be usefully compared with each 27579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * other using {@code ==}. 28579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson */ 29579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilsonpublic final class Type implements TypeBearer, Comparable<Type> { 30579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** 31579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * {@code non-null;} intern table mapping string descriptors to 32579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * instances 33579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson */ 34579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson private static final HashMap<String, Type> internTable = 35579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson new HashMap<String, Type>(500); 36579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 37579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** basic type constant for {@code void} */ 38579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public static final int BT_VOID = 0; 39579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 40579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** basic type constant for {@code boolean} */ 41579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public static final int BT_BOOLEAN = 1; 42579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 43579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** basic type constant for {@code byte} */ 44579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public static final int BT_BYTE = 2; 45579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 46579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** basic type constant for {@code char} */ 47579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public static final int BT_CHAR = 3; 48579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 49579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** basic type constant for {@code double} */ 50579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public static final int BT_DOUBLE = 4; 51579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 52579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** basic type constant for {@code float} */ 53579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public static final int BT_FLOAT = 5; 54579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 55579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** basic type constant for {@code int} */ 56579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public static final int BT_INT = 6; 57579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 58579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** basic type constant for {@code long} */ 59579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public static final int BT_LONG = 7; 60579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 61579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** basic type constant for {@code short} */ 62579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public static final int BT_SHORT = 8; 63579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 64579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** basic type constant for {@code Object} */ 65579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public static final int BT_OBJECT = 9; 66579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 67579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** basic type constant for a return address */ 68579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public static final int BT_ADDR = 10; 69579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 70579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** count of basic type constants */ 71579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public static final int BT_COUNT = 11; 72579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 73579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** {@code non-null;} instance representing {@code boolean} */ 74579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public static final Type BOOLEAN = new Type("Z", BT_BOOLEAN); 75579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 76579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** {@code non-null;} instance representing {@code byte} */ 77579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public static final Type BYTE = new Type("B", BT_BYTE); 78579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 79579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** {@code non-null;} instance representing {@code char} */ 80579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public static final Type CHAR = new Type("C", BT_CHAR); 81579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 82579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** {@code non-null;} instance representing {@code double} */ 83579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public static final Type DOUBLE = new Type("D", BT_DOUBLE); 84579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 85579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** {@code non-null;} instance representing {@code float} */ 86579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public static final Type FLOAT = new Type("F", BT_FLOAT); 87579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 88579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** {@code non-null;} instance representing {@code int} */ 89579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public static final Type INT = new Type("I", BT_INT); 90579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 91579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** {@code non-null;} instance representing {@code long} */ 92579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public static final Type LONG = new Type("J", BT_LONG); 93579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 94579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** {@code non-null;} instance representing {@code short} */ 95579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public static final Type SHORT = new Type("S", BT_SHORT); 96579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 97579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** {@code non-null;} instance representing {@code void} */ 98579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public static final Type VOID = new Type("V", BT_VOID); 99579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 100579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** {@code non-null;} instance representing a known-{@code null} */ 101579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public static final Type KNOWN_NULL = new Type("<null>", BT_OBJECT); 102579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 103579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** {@code non-null;} instance representing a subroutine return address */ 104579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public static final Type RETURN_ADDRESS = new Type("<addr>", BT_ADDR); 105579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 106579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson static { 107579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /* 108579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * Put all the primitive types into the intern table. This needs 109579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * to happen before the array types below get interned. 110579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson */ 111579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson putIntern(BOOLEAN); 112579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson putIntern(BYTE); 113579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson putIntern(CHAR); 114579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson putIntern(DOUBLE); 115579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson putIntern(FLOAT); 116579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson putIntern(INT); 117579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson putIntern(LONG); 118579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson putIntern(SHORT); 119579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /* 120579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * Note: VOID isn't put in the intern table, since it's special and 121579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * shouldn't be found by a normal call to intern(). 122579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson */ 123579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 124579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 125579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** 126579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * {@code non-null;} instance representing 127579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * {@code java.lang.annotation.Annotation} 128579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson */ 129579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public static final Type ANNOTATION = 130579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson intern("Ljava/lang/annotation/Annotation;"); 131579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 132579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** {@code non-null;} instance representing {@code java.lang.Class} */ 133579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public static final Type CLASS = intern("Ljava/lang/Class;"); 134579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 135579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** {@code non-null;} instance representing {@code java.lang.Cloneable} */ 136579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public static final Type CLONEABLE = intern("Ljava/lang/Cloneable;"); 137579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 138579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** {@code non-null;} instance representing {@code java.lang.Object} */ 139579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public static final Type OBJECT = intern("Ljava/lang/Object;"); 140579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 141579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** {@code non-null;} instance representing {@code java.io.Serializable} */ 142579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public static final Type SERIALIZABLE = intern("Ljava/io/Serializable;"); 143579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 144579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** {@code non-null;} instance representing {@code java.lang.String} */ 145579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public static final Type STRING = intern("Ljava/lang/String;"); 146579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 147579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** {@code non-null;} instance representing {@code java.lang.Throwable} */ 148579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public static final Type THROWABLE = intern("Ljava/lang/Throwable;"); 149579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 150579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** 151579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * {@code non-null;} instance representing {@code java.lang.Boolean}; the 152579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * suffix on the name helps disambiguate this from the instance 153579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * representing a primitive type 154579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson */ 155579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public static final Type BOOLEAN_CLASS = intern("Ljava/lang/Boolean;"); 156579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 157579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** 158579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * {@code non-null;} instance representing {@code java.lang.Byte}; the 159579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * suffix on the name helps disambiguate this from the instance 160579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * representing a primitive type 161579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson */ 162579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public static final Type BYTE_CLASS = intern("Ljava/lang/Byte;"); 163579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 164579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** 165579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * {@code non-null;} instance representing {@code java.lang.Character}; the 166579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * suffix on the name helps disambiguate this from the instance 167579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * representing a primitive type 168579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson */ 169579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public static final Type CHARACTER_CLASS = intern("Ljava/lang/Character;"); 170579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 171579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** 172579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * {@code non-null;} instance representing {@code java.lang.Double}; the 173579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * suffix on the name helps disambiguate this from the instance 174579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * representing a primitive type 175579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson */ 176579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public static final Type DOUBLE_CLASS = intern("Ljava/lang/Double;"); 177579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 178579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** 179579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * {@code non-null;} instance representing {@code java.lang.Float}; the 180579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * suffix on the name helps disambiguate this from the instance 181579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * representing a primitive type 182579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson */ 183579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public static final Type FLOAT_CLASS = intern("Ljava/lang/Float;"); 184579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 185579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** 186579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * {@code non-null;} instance representing {@code java.lang.Integer}; the 187579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * suffix on the name helps disambiguate this from the instance 188579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * representing a primitive type 189579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson */ 190579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public static final Type INTEGER_CLASS = intern("Ljava/lang/Integer;"); 191579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 192579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** 193579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * {@code non-null;} instance representing {@code java.lang.Long}; the 194579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * suffix on the name helps disambiguate this from the instance 195579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * representing a primitive type 196579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson */ 197579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public static final Type LONG_CLASS = intern("Ljava/lang/Long;"); 198579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 199579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** 200579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * {@code non-null;} instance representing {@code java.lang.Short}; the 201579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * suffix on the name helps disambiguate this from the instance 202579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * representing a primitive type 203579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson */ 204579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public static final Type SHORT_CLASS = intern("Ljava/lang/Short;"); 205579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 206579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** 207579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * {@code non-null;} instance representing {@code java.lang.Void}; the 208579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * suffix on the name helps disambiguate this from the instance 209579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * representing a primitive type 210579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson */ 211579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public static final Type VOID_CLASS = intern("Ljava/lang/Void;"); 212579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 213579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** {@code non-null;} instance representing {@code boolean[]} */ 214579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public static final Type BOOLEAN_ARRAY = BOOLEAN.getArrayType(); 215579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 216579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** {@code non-null;} instance representing {@code byte[]} */ 217579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public static final Type BYTE_ARRAY = BYTE.getArrayType(); 218579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 219579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** {@code non-null;} instance representing {@code char[]} */ 220579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public static final Type CHAR_ARRAY = CHAR.getArrayType(); 221579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 222579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** {@code non-null;} instance representing {@code double[]} */ 223579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public static final Type DOUBLE_ARRAY = DOUBLE.getArrayType(); 224579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 225579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** {@code non-null;} instance representing {@code float[]} */ 226579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public static final Type FLOAT_ARRAY = FLOAT.getArrayType(); 227579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 228579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** {@code non-null;} instance representing {@code int[]} */ 229579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public static final Type INT_ARRAY = INT.getArrayType(); 230579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 231579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** {@code non-null;} instance representing {@code long[]} */ 232579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public static final Type LONG_ARRAY = LONG.getArrayType(); 233579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 234579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** {@code non-null;} instance representing {@code Object[]} */ 235579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public static final Type OBJECT_ARRAY = OBJECT.getArrayType(); 236579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 237579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** {@code non-null;} instance representing {@code short[]} */ 238579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public static final Type SHORT_ARRAY = SHORT.getArrayType(); 239579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 240579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** {@code non-null;} field descriptor for the type */ 241579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson private final String descriptor; 242579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 243579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** 244579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * basic type corresponding to this type; one of the 245579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * {@code BT_*} constants 246579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson */ 247579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson private final int basicType; 248579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 249579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** 250579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * {@code >= -1;} for an uninitialized type, bytecode index that this 251579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * instance was allocated at; {@code Integer.MAX_VALUE} if it 252579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * was an incoming uninitialized instance; {@code -1} if this 253579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * is an <i>inititialized</i> instance 254579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson */ 255579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson private final int newAt; 256579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 257579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** 258579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * {@code null-ok;} the internal-form class name corresponding to 259579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * this type, if calculated; only valid if {@code this} is a 260579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * reference type and additionally not a return address 261579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson */ 262579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson private String className; 263579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 264579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** 265579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * {@code null-ok;} the type corresponding to an array of this type, if 266579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * calculated 267579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson */ 268579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson private Type arrayType; 269579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 270579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** 271579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * {@code null-ok;} the type corresponding to elements of this type, if 272579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * calculated; only valid if {@code this} is an array type 273579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson */ 274579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson private Type componentType; 275579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 276579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** 277579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * {@code null-ok;} the type corresponding to the initialized version of 278579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * this type, if this instance is in fact an uninitialized type 279579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson */ 280579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson private Type initializedType; 281579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 282579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** 283579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * Returns the unique instance corresponding to the type with the 284579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * given descriptor. See vmspec-2 sec4.3.2 for details on the 285579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * field descriptor syntax. This method does <i>not</i> allow 286579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * {@code "V"} (that is, type {@code void}) as a valid 287579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * descriptor. 288579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * 289579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * @param descriptor {@code non-null;} the descriptor 290579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * @return {@code non-null;} the corresponding instance 291579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * @throws IllegalArgumentException thrown if the descriptor has 292579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * invalid syntax 293579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson */ 294579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public static Type intern(String descriptor) { 295579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson Type result; 296579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson synchronized (internTable) { 297579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson result = internTable.get(descriptor); 298579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 299579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson if (result != null) { 300579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson return result; 301579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 302579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 303579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson char firstChar; 304579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson try { 305579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson firstChar = descriptor.charAt(0); 306579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } catch (IndexOutOfBoundsException ex) { 307579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson // Translate the exception. 308579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson throw new IllegalArgumentException("descriptor is empty"); 309579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } catch (NullPointerException ex) { 310579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson // Elucidate the exception. 311579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson throw new NullPointerException("descriptor == null"); 312579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 313579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 314579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson if (firstChar == '[') { 315579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /* 316579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * Recursively strip away array markers to get at the underlying 317579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * type, and build back on to form the result. 318579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson */ 319579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson result = intern(descriptor.substring(1)); 320579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson return result.getArrayType(); 321579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 322579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 323579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /* 324579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * If the first character isn't '[' and it wasn't found in the 325579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * intern cache, then it had better be the descriptor for a class. 326579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson */ 327579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 328579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson int length = descriptor.length(); 329579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson if ((firstChar != 'L') || 330579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson (descriptor.charAt(length - 1) != ';')) { 331579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson throw new IllegalArgumentException("bad descriptor: " + descriptor); 332579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 333579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 334579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /* 335579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * Validate the characters of the class name itself. Note that 336579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * vmspec-2 does not have a coherent definition for valid 337579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * internal-form class names, and the definition here is fairly 338579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * liberal: A name is considered valid as long as it doesn't 339579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * contain any of '[' ';' '.' '(' ')', and it has no more than one 340579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * '/' in a row, and no '/' at either end. 341579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson */ 342579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 343579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson int limit = (length - 1); // Skip the final ';'. 344579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson for (int i = 1; i < limit; i++) { 345579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson char c = descriptor.charAt(i); 346579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson switch (c) { 347579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson case '[': 348579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson case ';': 349579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson case '.': 350579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson case '(': 351579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson case ')': { 352579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson throw new IllegalArgumentException("bad descriptor: " + descriptor); 353579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 354579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson case '/': { 355579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson if ((i == 1) || 356579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson (i == (length - 1)) || 357579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson (descriptor.charAt(i - 1) == '/')) { 358579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson throw new IllegalArgumentException("bad descriptor: " + descriptor); 359579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 360579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson break; 361579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 362579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 363579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 364579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 365579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson result = new Type(descriptor, BT_OBJECT); 366579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson return putIntern(result); 367579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 368579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 369579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** 370579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * Returns the unique instance corresponding to the type with the 371579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * given descriptor, allowing {@code "V"} to return the type 372579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * for {@code void}. Other than that one caveat, this method 373579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * is identical to {@link #intern}. 374579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * 375579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * @param descriptor {@code non-null;} the descriptor 376579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * @return {@code non-null;} the corresponding instance 377579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * @throws IllegalArgumentException thrown if the descriptor has 378579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * invalid syntax 379579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson */ 380579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public static Type internReturnType(String descriptor) { 381579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson try { 382579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson if (descriptor.equals("V")) { 383579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson // This is the one special case where void may be returned. 384579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson return VOID; 385579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 386579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } catch (NullPointerException ex) { 387579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson // Elucidate the exception. 388579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson throw new NullPointerException("descriptor == null"); 389579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 390579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 391579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson return intern(descriptor); 392579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 393579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 394579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** 395579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * Returns the unique instance corresponding to the type of the 396579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * class with the given name. Calling this method is equivalent to 397579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * calling {@code intern(name)} if {@code name} begins 398579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * with {@code "["} and calling {@code intern("L" + name + ";")} 399579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * in all other cases. 400579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * 401579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * @param name {@code non-null;} the name of the class whose type 402579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * is desired 403579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * @return {@code non-null;} the corresponding type 404579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * @throws IllegalArgumentException thrown if the name has 405579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * invalid syntax 406579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson */ 407579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public static Type internClassName(String name) { 408579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson if (name == null) { 409579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson throw new NullPointerException("name == null"); 410579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 411579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 412579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson if (name.startsWith("[")) { 413579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson return intern(name); 414579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 415579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 416579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson return intern('L' + name + ';'); 417579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 418579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 419579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** 420579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * Constructs an instance corresponding to an "uninitialized type." 421579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * This is a private constructor; use one of the public static 422579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * methods to get instances. 423579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * 424579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * @param descriptor {@code non-null;} the field descriptor for the type 425579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * @param basicType basic type corresponding to this type; one of the 426579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * {@code BT_*} constants 427579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * @param newAt {@code >= -1;} allocation bytecode index 428579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson */ 429579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson private Type(String descriptor, int basicType, int newAt) { 430579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson if (descriptor == null) { 431579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson throw new NullPointerException("descriptor == null"); 432579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 433579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 434579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson if ((basicType < 0) || (basicType >= BT_COUNT)) { 435579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson throw new IllegalArgumentException("bad basicType"); 436579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 437579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 438579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson if (newAt < -1) { 439579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson throw new IllegalArgumentException("newAt < -1"); 440579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 441579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 442579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson this.descriptor = descriptor; 443579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson this.basicType = basicType; 444579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson this.newAt = newAt; 445579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson this.arrayType = null; 446579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson this.componentType = null; 447579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson this.initializedType = null; 448579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 449579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 450579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** 451579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * Constructs an instance corresponding to an "initialized type." 452579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * This is a private constructor; use one of the public static 453579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * methods to get instances. 454579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * 455579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * @param descriptor {@code non-null;} the field descriptor for the type 456579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * @param basicType basic type corresponding to this type; one of the 457579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * {@code BT_*} constants 458579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson */ 459579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson private Type(String descriptor, int basicType) { 460579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson this(descriptor, basicType, -1); 461579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 462579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 463579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** {@inheritDoc} */ 464579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson @Override 465579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public boolean equals(Object other) { 466579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson if (this == other) { 467579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /* 468579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * Since externally-visible types are interned, this check 469579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * helps weed out some easy cases. 470579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson */ 471579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson return true; 472579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 473579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 474579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson if (!(other instanceof Type)) { 475579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson return false; 476579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 477579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 478579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson return descriptor.equals(((Type) other).descriptor); 479579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 480579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 481579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** {@inheritDoc} */ 482579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson @Override 483579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public int hashCode() { 484579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson return descriptor.hashCode(); 485579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 486579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 487579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** {@inheritDoc} */ 488579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public int compareTo(Type other) { 489579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson return descriptor.compareTo(other.descriptor); 490579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 491579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 492579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** {@inheritDoc} */ 493579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson @Override 494579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public String toString() { 495579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson return descriptor; 496579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 497579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 498579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** {@inheritDoc} */ 499579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public String toHuman() { 500579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson switch (basicType) { 501579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson case BT_VOID: return "void"; 502579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson case BT_BOOLEAN: return "boolean"; 503579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson case BT_BYTE: return "byte"; 504579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson case BT_CHAR: return "char"; 505579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson case BT_DOUBLE: return "double"; 506579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson case BT_FLOAT: return "float"; 507579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson case BT_INT: return "int"; 508579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson case BT_LONG: return "long"; 509579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson case BT_SHORT: return "short"; 510579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson case BT_OBJECT: break; 511579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson default: return descriptor; 512579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 513579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 514579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson if (isArray()) { 515579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson return getComponentType().toHuman() + "[]"; 516579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 517579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 518579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson // Remove the "L...;" around the type and convert "/" to ".". 519579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson return getClassName().replace("/", "."); 520579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 521579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 522579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** {@inheritDoc} */ 523579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public Type getType() { 524579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson return this; 525579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 526579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 527579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** {@inheritDoc} */ 528579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public Type getFrameType() { 529579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson switch (basicType) { 530579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson case BT_BOOLEAN: 531579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson case BT_BYTE: 532579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson case BT_CHAR: 533579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson case BT_INT: 534579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson case BT_SHORT: { 535579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson return INT; 536579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 537579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 538579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 539579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson return this; 540579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 541579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 542579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** {@inheritDoc} */ 543579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public int getBasicType() { 544579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson return basicType; 545579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 546579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 547579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** {@inheritDoc} */ 548579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public int getBasicFrameType() { 549579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson switch (basicType) { 550579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson case BT_BOOLEAN: 551579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson case BT_BYTE: 552579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson case BT_CHAR: 553579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson case BT_INT: 554579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson case BT_SHORT: { 555579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson return BT_INT; 556579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 557579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 558579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 559579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson return basicType; 560579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 561579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 562579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** {@inheritDoc} */ 563579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public boolean isConstant() { 564579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson return false; 565579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 566579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 567579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** 568579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * Gets the descriptor. 569579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * 570579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * @return {@code non-null;} the descriptor 571579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson */ 572579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public String getDescriptor() { 573579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson return descriptor; 574579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 575579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 576579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** 577579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * Gets the name of the class this type corresponds to, in internal 578579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * form. This method is only valid if this instance is for a 579579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * normal reference type (that is, a reference type and 580579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * additionally not a return address). 581579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * 582579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * @return {@code non-null;} the internal-form class name 583579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson */ 584579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public String getClassName() { 585579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson if (className == null) { 586579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson if (!isReference()) { 587579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson throw new IllegalArgumentException("not an object type: " + 588579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson descriptor); 589579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 590579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 591579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson if (descriptor.charAt(0) == '[') { 592579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson className = descriptor; 593579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } else { 594579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson className = descriptor.substring(1, descriptor.length() - 1); 595579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 596579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 597579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 598579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson return className; 599579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 600579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 601579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** 602579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * Gets the category. Most instances are category 1. {@code long} 603579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * and {@code double} are the only category 2 types. 604579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * 605579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * @see #isCategory1 606579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * @see #isCategory2 607579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * @return the category 608579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson */ 609579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public int getCategory() { 610579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson switch (basicType) { 611579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson case BT_LONG: 612579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson case BT_DOUBLE: { 613579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson return 2; 614579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 615579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 616579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 617579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson return 1; 618579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 619579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 620579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** 621579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * Returns whether or not this is a category 1 type. 622579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * 623579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * @see #getCategory 624579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * @see #isCategory2 625579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * @return whether or not this is a category 1 type 626579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson */ 627579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public boolean isCategory1() { 628579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson switch (basicType) { 629579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson case BT_LONG: 630579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson case BT_DOUBLE: { 631579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson return false; 632579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 633579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 634579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 635579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson return true; 636579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 637579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 638579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** 639579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * Returns whether or not this is a category 2 type. 640579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * 641579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * @see #getCategory 642579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * @see #isCategory1 643579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * @return whether or not this is a category 2 type 644579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson */ 645579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public boolean isCategory2() { 646579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson switch (basicType) { 647579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson case BT_LONG: 648579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson case BT_DOUBLE: { 649579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson return true; 650579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 651579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 652579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 653579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson return false; 654579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 655579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 656579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** 657579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * Gets whether this type is "intlike." An intlike type is one which, when 658579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * placed on a stack or in a local, is automatically converted to an 659579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * {@code int}. 660579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * 661579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * @return whether this type is "intlike" 662579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson */ 663579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public boolean isIntlike() { 664579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson switch (basicType) { 665579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson case BT_BOOLEAN: 666579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson case BT_BYTE: 667579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson case BT_CHAR: 668579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson case BT_INT: 669579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson case BT_SHORT: { 670579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson return true; 671579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 672579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 673579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 674579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson return false; 675579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 676579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 677579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** 678579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * Gets whether this type is a primitive type. All types are either 679579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * primitive or reference types. 680579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * 681579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * @return whether this type is primitive 682579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson */ 683579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public boolean isPrimitive() { 684579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson switch (basicType) { 685579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson case BT_BOOLEAN: 686579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson case BT_BYTE: 687579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson case BT_CHAR: 688579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson case BT_DOUBLE: 689579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson case BT_FLOAT: 690579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson case BT_INT: 691579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson case BT_LONG: 692579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson case BT_SHORT: 693579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson case BT_VOID: { 694579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson return true; 695579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 696579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 697579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 698579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson return false; 699579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 700579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 701579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** 702579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * Gets whether this type is a normal reference type. A normal 703579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * reference type is a reference type that is not a return 704579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * address. This method is just convenient shorthand for 705579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * {@code getBasicType() == Type.BT_OBJECT}. 706579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * 707579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * @return whether this type is a normal reference type 708579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson */ 709579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public boolean isReference() { 710579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson return (basicType == BT_OBJECT); 711579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 712579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 713579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** 714579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * Gets whether this type is an array type. If this method returns 715579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * {@code true}, then it is safe to use {@link #getComponentType} 716579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * to determine the component type. 717579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * 718579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * @return whether this type is an array type 719579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson */ 720579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public boolean isArray() { 721579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson return (descriptor.charAt(0) == '['); 722579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 723579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 724579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** 725579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * Gets whether this type is an array type or is a known-null, and 726579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * hence is compatible with array types. 727579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * 728579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * @return whether this type is an array type 729579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson */ 730579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public boolean isArrayOrKnownNull() { 731579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson return isArray() || equals(KNOWN_NULL); 732579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 733579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 734579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** 735579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * Gets whether this type represents an uninitialized instance. An 736579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * uninitialized instance is what one gets back from the {@code new} 737579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * opcode, and remains uninitialized until a valid constructor is 738579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * invoked on it. 739579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * 740579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * @return whether this type is "uninitialized" 741579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson */ 742579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public boolean isUninitialized() { 743579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson return (newAt >= 0); 744579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 745579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 746579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** 747579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * Gets the bytecode index at which this uninitialized type was 748579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * allocated. This returns {@code Integer.MAX_VALUE} if this 749579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * type is an uninitialized incoming parameter (i.e., the 750579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * {@code this} of an {@code <init>} method) or 751579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * {@code -1} if this type is in fact <i>initialized</i>. 752579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * 753579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * @return {@code >= -1;} the allocation bytecode index 754579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson */ 755579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public int getNewAt() { 756579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson return newAt; 757579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 758579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 759579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** 760579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * Gets the initialized type corresponding to this instance, but only 761579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * if this instance is in fact an uninitialized object type. 762579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * 763579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * @return {@code non-null;} the initialized type 764579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson */ 765579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public Type getInitializedType() { 766579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson if (initializedType == null) { 767579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson throw new IllegalArgumentException("initialized type: " + 768579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson descriptor); 769579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 770579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 771579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson return initializedType; 772579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 773579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 774579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** 775579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * Gets the type corresponding to an array of this type. 776579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * 777579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * @return {@code non-null;} the array type 778579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson */ 779579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public Type getArrayType() { 780579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson if (arrayType == null) { 781579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson arrayType = putIntern(new Type('[' + descriptor, BT_OBJECT)); 782579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 783579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 784579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson return arrayType; 785579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 786579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 787579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** 788579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * Gets the component type of this type. This method is only valid on 789579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * array types. 790579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * 791579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * @return {@code non-null;} the component type 792579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson */ 793579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public Type getComponentType() { 794579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson if (componentType == null) { 795579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson if (descriptor.charAt(0) != '[') { 796579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson throw new IllegalArgumentException("not an array type: " + 797579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson descriptor); 798579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 799579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson componentType = intern(descriptor.substring(1)); 800579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 801579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 802579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson return componentType; 803579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 804579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 805579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** 806579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * Returns a new interned instance which is identical to this one, except 807579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * it is indicated as uninitialized and allocated at the given bytecode 808579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * index. This instance must be an initialized object type. 809579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * 810579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * @param newAt {@code >= 0;} the allocation bytecode index 811579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * @return {@code non-null;} an appropriately-constructed instance 812579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson */ 813579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public Type asUninitialized(int newAt) { 814579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson if (newAt < 0) { 815579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson throw new IllegalArgumentException("newAt < 0"); 816579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 817579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 818579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson if (!isReference()) { 819579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson throw new IllegalArgumentException("not a reference type: " + 820579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson descriptor); 821579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 822579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 823579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson if (isUninitialized()) { 824579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /* 825579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * Dealing with uninitialized types as a starting point is 826579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * a pain, and it's not clear that it'd ever be used, so 827579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * just disallow it. 828579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson */ 829579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson throw new IllegalArgumentException("already uninitialized: " + 830579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson descriptor); 831579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 832579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 833579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /* 834579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * Create a new descriptor that is unique and shouldn't conflict 835579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * with "normal" type descriptors 836579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson */ 837579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson String newDesc = 'N' + Hex.u2(newAt) + descriptor; 838579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson Type result = new Type(newDesc, BT_OBJECT, newAt); 839579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson result.initializedType = this; 840579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson return putIntern(result); 841579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 842579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 843579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** 844579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * Puts the given instance in the intern table if it's not already 845579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * there. If a conflicting value is already in the table, then leave it. 846579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * Return the interned value. 847579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * 848579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * @param type {@code non-null;} instance to make interned 849579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * @return {@code non-null;} the actual interned object 850579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson */ 851579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson private static Type putIntern(Type type) { 852579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson synchronized (internTable) { 853579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson String descriptor = type.getDescriptor(); 854579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson Type already = internTable.get(descriptor); 855579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson if (already != null) { 856579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson return already; 857579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 858579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson internTable.put(descriptor, type); 859579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson return type; 860579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 861579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 862579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson} 863