1917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul/* 2917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * Copyright (C) 2007 The Android Open Source Project 3917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * 4917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * Licensed under the Apache License, Version 2.0 (the "License"); 5917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * you may not use this file except in compliance with the License. 6917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * You may obtain a copy of the License at 7917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * 8917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * http://www.apache.org/licenses/LICENSE-2.0 9917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * 10917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * Unless required by applicable law or agreed to in writing, software 11917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * distributed under the License is distributed on an "AS IS" BASIS, 12917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * See the License for the specific language governing permissions and 14917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * limitations under the License. 15917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul */ 16917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 17917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgulpackage com.android.dexgen.rop.type; 18917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 19917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgulimport com.android.dexgen.util.Hex; 20917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 21917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgulimport java.util.HashMap; 22917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 23917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul/** 24917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * Representation of a value type, such as may appear in a field, in a 25917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * local, on a stack, or in a method descriptor. Instances of this 26917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * class are generally interned and may be usefully compared with each 27917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * other using {@code ==}. 28917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul */ 29917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgulpublic final class Type implements TypeBearer, Comparable<Type> { 30917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** {@code non-null;} intern table mapping string descriptors to instances */ 31917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul private static final HashMap<String, Type> internTable = 32917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul new HashMap<String, Type>(500); 33917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 3494e569246cb1b3409fca701096eb687eecf4612fPiotr Gurgul /** {@code non-null;} table mapping types as {@code Class} objects to internal form */ 3594e569246cb1b3409fca701096eb687eecf4612fPiotr Gurgul private static final HashMap<Class, Type> CLASS_TYPE_MAP = 3694e569246cb1b3409fca701096eb687eecf4612fPiotr Gurgul new HashMap<Class, Type>(); 3794e569246cb1b3409fca701096eb687eecf4612fPiotr Gurgul 38917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** basic type constant for {@code void} */ 39917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul public static final int BT_VOID = 0; 40917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 41917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** basic type constant for {@code boolean} */ 42917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul public static final int BT_BOOLEAN = 1; 43917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 44917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** basic type constant for {@code byte} */ 45917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul public static final int BT_BYTE = 2; 46917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 47917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** basic type constant for {@code char} */ 48917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul public static final int BT_CHAR = 3; 49917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 50917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** basic type constant for {@code double} */ 51917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul public static final int BT_DOUBLE = 4; 52917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 53917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** basic type constant for {@code float} */ 54917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul public static final int BT_FLOAT = 5; 55917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 56917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** basic type constant for {@code int} */ 57917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul public static final int BT_INT = 6; 58917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 59917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** basic type constant for {@code long} */ 60917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul public static final int BT_LONG = 7; 61917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 62917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** basic type constant for {@code short} */ 63917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul public static final int BT_SHORT = 8; 64917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 65917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** basic type constant for {@code Object} */ 66917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul public static final int BT_OBJECT = 9; 67917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 68917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** basic type constant for a return address */ 69917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul public static final int BT_ADDR = 10; 70917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 71917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** count of basic type constants */ 72917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul public static final int BT_COUNT = 11; 73917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 74917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** {@code non-null;} instance representing {@code boolean} */ 75917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul public static final Type BOOLEAN = new Type("Z", BT_BOOLEAN); 76917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 77917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** {@code non-null;} instance representing {@code byte} */ 78917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul public static final Type BYTE = new Type("B", BT_BYTE); 79917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 80917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** {@code non-null;} instance representing {@code char} */ 81917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul public static final Type CHAR = new Type("C", BT_CHAR); 82917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 83917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** {@code non-null;} instance representing {@code double} */ 84917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul public static final Type DOUBLE = new Type("D", BT_DOUBLE); 85917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 86917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** {@code non-null;} instance representing {@code float} */ 87917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul public static final Type FLOAT = new Type("F", BT_FLOAT); 88917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 89917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** {@code non-null;} instance representing {@code int} */ 90917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul public static final Type INT = new Type("I", BT_INT); 91917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 92917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** {@code non-null;} instance representing {@code long} */ 93917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul public static final Type LONG = new Type("J", BT_LONG); 94917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 95917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** {@code non-null;} instance representing {@code short} */ 96917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul public static final Type SHORT = new Type("S", BT_SHORT); 97917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 98917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** {@code non-null;} instance representing {@code void} */ 99917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul public static final Type VOID = new Type("V", BT_VOID); 100917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 101917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** {@code non-null;} instance representing a known-{@code null} */ 102917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul public static final Type KNOWN_NULL = new Type("<null>", BT_OBJECT); 103917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 104917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** {@code non-null;} instance representing a subroutine return address */ 105917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul public static final Type RETURN_ADDRESS = new Type("<addr>", BT_ADDR); 106917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 107917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul static { 108917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /* 109917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * Put all the primitive types into the intern table. This needs 110917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * to happen before the array types below get interned. 111917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul */ 112917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul putIntern(BOOLEAN); 113917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul putIntern(BYTE); 114917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul putIntern(CHAR); 115917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul putIntern(DOUBLE); 116917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul putIntern(FLOAT); 117917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul putIntern(INT); 118917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul putIntern(LONG); 119917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul putIntern(SHORT); 120917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /* 121917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * Note: VOID isn't put in the intern table, since it's special and 122917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * shouldn't be found by a normal call to intern(). 123917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul */ 12494e569246cb1b3409fca701096eb687eecf4612fPiotr Gurgul 12594e569246cb1b3409fca701096eb687eecf4612fPiotr Gurgul /* 12694e569246cb1b3409fca701096eb687eecf4612fPiotr Gurgul * Create a mapping between types as Java Class objects 12794e569246cb1b3409fca701096eb687eecf4612fPiotr Gurgul * and types in dx internal format. 12894e569246cb1b3409fca701096eb687eecf4612fPiotr Gurgul */ 12994e569246cb1b3409fca701096eb687eecf4612fPiotr Gurgul CLASS_TYPE_MAP.put(boolean.class, BOOLEAN); 13094e569246cb1b3409fca701096eb687eecf4612fPiotr Gurgul CLASS_TYPE_MAP.put(short.class, SHORT); 13194e569246cb1b3409fca701096eb687eecf4612fPiotr Gurgul CLASS_TYPE_MAP.put(int.class, INT); 13294e569246cb1b3409fca701096eb687eecf4612fPiotr Gurgul CLASS_TYPE_MAP.put(long.class, LONG); 13394e569246cb1b3409fca701096eb687eecf4612fPiotr Gurgul CLASS_TYPE_MAP.put(char.class, CHAR); 13494e569246cb1b3409fca701096eb687eecf4612fPiotr Gurgul CLASS_TYPE_MAP.put(byte.class, BYTE); 13594e569246cb1b3409fca701096eb687eecf4612fPiotr Gurgul CLASS_TYPE_MAP.put(float.class, FLOAT); 13694e569246cb1b3409fca701096eb687eecf4612fPiotr Gurgul CLASS_TYPE_MAP.put(double.class, DOUBLE); 13794e569246cb1b3409fca701096eb687eecf4612fPiotr Gurgul CLASS_TYPE_MAP.put(void.class, VOID); 138917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 139917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 140917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** 141917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * {@code non-null;} instance representing 142917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * {@code java.lang.annotation.Annotation} 143917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul */ 144917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul public static final Type ANNOTATION = 145917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul intern("Ljava/lang/annotation/Annotation;"); 146917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 147917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** {@code non-null;} instance representing {@code java.lang.Class} */ 148917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul public static final Type CLASS = intern("Ljava/lang/Class;"); 149917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 150917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** {@code non-null;} instance representing {@code java.lang.Cloneable} */ 151917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul public static final Type CLONEABLE = intern("Ljava/lang/Cloneable;"); 152917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 153917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** {@code non-null;} instance representing {@code java.lang.Object} */ 154917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul public static final Type OBJECT = intern("Ljava/lang/Object;"); 155917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 156917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** {@code non-null;} instance representing {@code java.io.Serializable} */ 157917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul public static final Type SERIALIZABLE = intern("Ljava/io/Serializable;"); 158917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 159917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** {@code non-null;} instance representing {@code java.lang.String} */ 160917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul public static final Type STRING = intern("Ljava/lang/String;"); 161917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 162917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** {@code non-null;} instance representing {@code java.lang.Throwable} */ 163917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul public static final Type THROWABLE = intern("Ljava/lang/Throwable;"); 164917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 165917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** 166917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * {@code non-null;} instance representing {@code java.lang.Boolean}; the 167917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * suffix on the name helps disambiguate this from the instance 168917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * representing a primitive type 169917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul */ 170917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul public static final Type BOOLEAN_CLASS = intern("Ljava/lang/Boolean;"); 171917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 172917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** 173917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * {@code non-null;} instance representing {@code java.lang.Byte}; the 174917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * suffix on the name helps disambiguate this from the instance 175917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * representing a primitive type 176917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul */ 177917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul public static final Type BYTE_CLASS = intern("Ljava/lang/Byte;"); 178917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 179917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** 180917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * {@code non-null;} instance representing {@code java.lang.Character}; the 181917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * suffix on the name helps disambiguate this from the instance 182917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * representing a primitive type 183917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul */ 184917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul public static final Type CHARACTER_CLASS = intern("Ljava/lang/Character;"); 185917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 186917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** 187917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * {@code non-null;} instance representing {@code java.lang.Double}; the 188917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * suffix on the name helps disambiguate this from the instance 189917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * representing a primitive type 190917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul */ 191917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul public static final Type DOUBLE_CLASS = intern("Ljava/lang/Double;"); 192917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 193917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** 194917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * {@code non-null;} instance representing {@code java.lang.Float}; the 195917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * suffix on the name helps disambiguate this from the instance 196917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * representing a primitive type 197917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul */ 198917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul public static final Type FLOAT_CLASS = intern("Ljava/lang/Float;"); 199917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 200917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** 201917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * {@code non-null;} instance representing {@code java.lang.Integer}; the 202917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * suffix on the name helps disambiguate this from the instance 203917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * representing a primitive type 204917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul */ 205917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul public static final Type INTEGER_CLASS = intern("Ljava/lang/Integer;"); 206917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 207917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** 208917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * {@code non-null;} instance representing {@code java.lang.Long}; the 209917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * suffix on the name helps disambiguate this from the instance 210917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * representing a primitive type 211917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul */ 212917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul public static final Type LONG_CLASS = intern("Ljava/lang/Long;"); 213917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 214917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** 215917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * {@code non-null;} instance representing {@code java.lang.Short}; the 216917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * suffix on the name helps disambiguate this from the instance 217917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * representing a primitive type 218917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul */ 219917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul public static final Type SHORT_CLASS = intern("Ljava/lang/Short;"); 220917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 221917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** 222917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * {@code non-null;} instance representing {@code java.lang.Void}; the 223917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * suffix on the name helps disambiguate this from the instance 224917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * representing a primitive type 225917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul */ 226917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul public static final Type VOID_CLASS = intern("Ljava/lang/Void;"); 227917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 228917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** {@code non-null;} instance representing {@code boolean[]} */ 229917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul public static final Type BOOLEAN_ARRAY = BOOLEAN.getArrayType(); 230917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 231917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** {@code non-null;} instance representing {@code byte[]} */ 232917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul public static final Type BYTE_ARRAY = BYTE.getArrayType(); 233917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 234917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** {@code non-null;} instance representing {@code char[]} */ 235917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul public static final Type CHAR_ARRAY = CHAR.getArrayType(); 236917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 237917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** {@code non-null;} instance representing {@code double[]} */ 238917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul public static final Type DOUBLE_ARRAY = DOUBLE.getArrayType(); 239917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 240917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** {@code non-null;} instance representing {@code float[]} */ 241917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul public static final Type FLOAT_ARRAY = FLOAT.getArrayType(); 242917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 243917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** {@code non-null;} instance representing {@code int[]} */ 244917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul public static final Type INT_ARRAY = INT.getArrayType(); 245917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 246917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** {@code non-null;} instance representing {@code long[]} */ 247917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul public static final Type LONG_ARRAY = LONG.getArrayType(); 248917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 249917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** {@code non-null;} instance representing {@code Object[]} */ 250917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul public static final Type OBJECT_ARRAY = OBJECT.getArrayType(); 251917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 252917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** {@code non-null;} instance representing {@code short[]} */ 253917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul public static final Type SHORT_ARRAY = SHORT.getArrayType(); 254917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 255917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** {@code non-null;} field descriptor for the type */ 256917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul private final String descriptor; 257917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 258917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** 259917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * basic type corresponding to this type; one of the 260917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * {@code BT_*} constants 261917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul */ 262917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul private final int basicType; 263917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 264917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** 265917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * {@code >= -1;} for an uninitialized type, bytecode index that this 266917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * instance was allocated at; {@code Integer.MAX_VALUE} if it 267917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * was an incoming uninitialized instance; {@code -1} if this 268917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * is an <i>inititialized</i> instance 269917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul */ 270917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul private final int newAt; 271917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 272917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** 273917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * {@code null-ok;} the internal-form class name corresponding to this type, if 274917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * calculated; only valid if {@code this} is a reference type and 275917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * additionally not a return address 276917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul */ 277917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul private String className; 278917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 279917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** 280917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * {@code null-ok;} the type corresponding to an array of this type, if 281917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * calculated 282917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul */ 283917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul private Type arrayType; 284917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 285917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** 286917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * {@code null-ok;} the type corresponding to elements of this type, if 287917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * calculated; only valid if {@code this} is an array type 288917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul */ 289917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul private Type componentType; 290917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 291917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** 292917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * {@code null-ok;} the type corresponding to the initialized version of 293917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * this type, if this instance is in fact an uninitialized type 294917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul */ 295917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul private Type initializedType; 296917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 297917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** 29894e569246cb1b3409fca701096eb687eecf4612fPiotr Gurgul * Returns the unique instance corresponding to the type represented by 29994e569246cb1b3409fca701096eb687eecf4612fPiotr Gurgul * given {@code Class} object. See vmspec-2 sec4.3.2 for details on the 30094e569246cb1b3409fca701096eb687eecf4612fPiotr Gurgul * field descriptor syntax. This method does <i>not</i> allow 30194e569246cb1b3409fca701096eb687eecf4612fPiotr Gurgul * {@code "V"} (that is, type {@code void}) as a valid 30294e569246cb1b3409fca701096eb687eecf4612fPiotr Gurgul * descriptor. 30394e569246cb1b3409fca701096eb687eecf4612fPiotr Gurgul * 30494e569246cb1b3409fca701096eb687eecf4612fPiotr Gurgul * @param clazz {@code non-null;} class whose descriptor 30594e569246cb1b3409fca701096eb687eecf4612fPiotr Gurgul * will be internalized 30694e569246cb1b3409fca701096eb687eecf4612fPiotr Gurgul * @return {@code non-null;} the corresponding instance 30794e569246cb1b3409fca701096eb687eecf4612fPiotr Gurgul */ 30894e569246cb1b3409fca701096eb687eecf4612fPiotr Gurgul public static Type intern(Class clazz) { 30994e569246cb1b3409fca701096eb687eecf4612fPiotr Gurgul return intern(getInternalTypeName(clazz)); 31094e569246cb1b3409fca701096eb687eecf4612fPiotr Gurgul } 31194e569246cb1b3409fca701096eb687eecf4612fPiotr Gurgul 31294e569246cb1b3409fca701096eb687eecf4612fPiotr Gurgul /** 313917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * Returns the unique instance corresponding to the type with the 314917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * given descriptor. See vmspec-2 sec4.3.2 for details on the 315917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * field descriptor syntax. This method does <i>not</i> allow 316917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * {@code "V"} (that is, type {@code void}) as a valid 317917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * descriptor. 318917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * 319917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * @param descriptor {@code non-null;} the descriptor 320917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * @return {@code non-null;} the corresponding instance 321917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * @throws IllegalArgumentException thrown if the descriptor has 322917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * invalid syntax 323917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul */ 324917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul public static Type intern(String descriptor) { 32594e569246cb1b3409fca701096eb687eecf4612fPiotr Gurgul 326917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul Type result = internTable.get(descriptor); 327917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul if (result != null) { 328917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul return result; 329917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 330917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 331917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul char firstChar; 332917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul try { 333917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul firstChar = descriptor.charAt(0); 334917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } catch (IndexOutOfBoundsException ex) { 335917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul // Translate the exception. 336917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul throw new IllegalArgumentException("descriptor is empty"); 337917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } catch (NullPointerException ex) { 338917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul // Elucidate the exception. 339917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul throw new NullPointerException("descriptor == null"); 340917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 341917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 342917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul if (firstChar == '[') { 343917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /* 344917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * Recursively strip away array markers to get at the underlying 345917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * type, and build back on to form the result. 346917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul */ 347917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul result = intern(descriptor.substring(1)); 348917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul return result.getArrayType(); 349917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 350917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 351917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /* 352917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * If the first character isn't '[' and it wasn't found in the 353917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * intern cache, then it had better be the descriptor for a class. 354917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul */ 355917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 356917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul int length = descriptor.length(); 357917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul if ((firstChar != 'L') || 358917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul (descriptor.charAt(length - 1) != ';')) { 359917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul throw new IllegalArgumentException("bad descriptor" + descriptor); 360917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 361917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 362917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /* 363917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * Validate the characters of the class name itself. Note that 364917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * vmspec-2 does not have a coherent definition for valid 365917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * internal-form class names, and the definition here is fairly 366917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * liberal: A name is considered valid as long as it doesn't 367917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * contain any of '[' ';' '.' '(' ')', and it has no more than one 368917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * '/' in a row, and no '/' at either end. 369917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul */ 370917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 371917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul int limit = (length - 1); // Skip the final ';'. 372917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul for (int i = 1; i < limit; i++) { 373917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul char c = descriptor.charAt(i); 374917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul switch (c) { 375917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul case '[': 376917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul case ';': 377917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul case '.': 378917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul case '(': 379917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul case ')': { 380917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul throw new IllegalArgumentException("bad descriptor" + descriptor); 381917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 382917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul case '/': { 383917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul if ((i == 1) || 384917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul (i == (length - 1)) || 385917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul (descriptor.charAt(i - 1) == '/')) { 386917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul throw new IllegalArgumentException("bad descriptor"); 387917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 388917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul break; 389917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 390917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 391917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 392917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 393917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul result = new Type(descriptor, BT_OBJECT); 394917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul return putIntern(result); 395917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 396917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 397917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** 39894e569246cb1b3409fca701096eb687eecf4612fPiotr Gurgul * Returns the unique instance corresponding to the type represented by 39994e569246cb1b3409fca701096eb687eecf4612fPiotr Gurgul * given {@code Class} object, allowing {@code "V"} to return the type 40094e569246cb1b3409fca701096eb687eecf4612fPiotr Gurgul * for {@code void}. Other than that one caveat, this method 40194e569246cb1b3409fca701096eb687eecf4612fPiotr Gurgul * is identical to {@link #intern}. 40294e569246cb1b3409fca701096eb687eecf4612fPiotr Gurgul * 40394e569246cb1b3409fca701096eb687eecf4612fPiotr Gurgul * @param clazz {@code non-null;} class which descriptor 40494e569246cb1b3409fca701096eb687eecf4612fPiotr Gurgul * will be internalized 40594e569246cb1b3409fca701096eb687eecf4612fPiotr Gurgul * @return {@code non-null;} the corresponding instance 40694e569246cb1b3409fca701096eb687eecf4612fPiotr Gurgul */ 40794e569246cb1b3409fca701096eb687eecf4612fPiotr Gurgul public static Type internReturnType(Class clazz) { 40894e569246cb1b3409fca701096eb687eecf4612fPiotr Gurgul return internReturnType(getInternalTypeName(clazz)); 40994e569246cb1b3409fca701096eb687eecf4612fPiotr Gurgul } 41094e569246cb1b3409fca701096eb687eecf4612fPiotr Gurgul 41194e569246cb1b3409fca701096eb687eecf4612fPiotr Gurgul /** 412917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * Returns the unique instance corresponding to the type with the 413917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * given descriptor, allowing {@code "V"} to return the type 414917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * for {@code void}. Other than that one caveat, this method 415917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * is identical to {@link #intern}. 416917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * 417917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * @param descriptor {@code non-null;} the descriptor 418917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * @return {@code non-null;} the corresponding instance 419917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * @throws IllegalArgumentException thrown if the descriptor has 420917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * invalid syntax 421917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul */ 422917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul public static Type internReturnType(String descriptor) { 423917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul try { 424917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul if (descriptor.equals("V")) { 425917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul // This is the one special case where void may be returned. 426917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul return VOID; 427917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 428917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } catch (NullPointerException ex) { 429917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul // Elucidate the exception. 430917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul throw new NullPointerException("descriptor == null"); 431917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 432917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 433917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul return intern(descriptor); 434917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 435917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 436917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** 437917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * Returns the unique instance corresponding to the type of the 438917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * class with the given name. Calling this method is equivalent to 439917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * calling {@code intern(name)} if {@code name} begins 440917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * with {@code "["} and calling {@code intern("L" + name + ";")} 441917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * in all other cases. 442917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * 443917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * @param name {@code non-null;} the name of the class whose type is desired 444917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * @return {@code non-null;} the corresponding type 445917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * @throws IllegalArgumentException thrown if the name has 446917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * invalid syntax 447917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul */ 448917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul public static Type internClassName(String name) { 449917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul if (name == null) { 450917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul throw new NullPointerException("name == null"); 451917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 452917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 453917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul if (name.startsWith("[")) { 454917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul return intern(name); 455917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 456917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 457917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul return intern('L' + name + ';'); 458917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 459917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 460917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** 46194e569246cb1b3409fca701096eb687eecf4612fPiotr Gurgul * Converts type name in the format as returned by reflection 46294e569246cb1b3409fca701096eb687eecf4612fPiotr Gurgul * into dex internal form. 46394e569246cb1b3409fca701096eb687eecf4612fPiotr Gurgul * 46494e569246cb1b3409fca701096eb687eecf4612fPiotr Gurgul * @param clazz {@code non-null;} class whose name will be internalized 46594e569246cb1b3409fca701096eb687eecf4612fPiotr Gurgul * @return string with the type name in dex internal format 46694e569246cb1b3409fca701096eb687eecf4612fPiotr Gurgul */ 46794e569246cb1b3409fca701096eb687eecf4612fPiotr Gurgul public static String getInternalTypeName(Class clazz) { 46894e569246cb1b3409fca701096eb687eecf4612fPiotr Gurgul if (clazz == null) { 46994e569246cb1b3409fca701096eb687eecf4612fPiotr Gurgul throw new NullPointerException("clazz == null"); 47094e569246cb1b3409fca701096eb687eecf4612fPiotr Gurgul } 47194e569246cb1b3409fca701096eb687eecf4612fPiotr Gurgul 47294e569246cb1b3409fca701096eb687eecf4612fPiotr Gurgul if (clazz.isPrimitive()) { 47394e569246cb1b3409fca701096eb687eecf4612fPiotr Gurgul return CLASS_TYPE_MAP.get(clazz).getDescriptor(); 47494e569246cb1b3409fca701096eb687eecf4612fPiotr Gurgul } 47594e569246cb1b3409fca701096eb687eecf4612fPiotr Gurgul 47694e569246cb1b3409fca701096eb687eecf4612fPiotr Gurgul String slashed = clazz.getName().replace('.', '/'); 47794e569246cb1b3409fca701096eb687eecf4612fPiotr Gurgul 47894e569246cb1b3409fca701096eb687eecf4612fPiotr Gurgul if (clazz.isArray()) { 47994e569246cb1b3409fca701096eb687eecf4612fPiotr Gurgul return slashed; 48094e569246cb1b3409fca701096eb687eecf4612fPiotr Gurgul } 48194e569246cb1b3409fca701096eb687eecf4612fPiotr Gurgul 48294e569246cb1b3409fca701096eb687eecf4612fPiotr Gurgul return 'L' + slashed + ';'; 48394e569246cb1b3409fca701096eb687eecf4612fPiotr Gurgul } 48494e569246cb1b3409fca701096eb687eecf4612fPiotr Gurgul 48594e569246cb1b3409fca701096eb687eecf4612fPiotr Gurgul /** 486917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * Constructs an instance corresponding to an "uninitialized type." 487917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * This is a private constructor; use one of the public static 488917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * methods to get instances. 489917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * 490917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * @param descriptor {@code non-null;} the field descriptor for the type 491917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * @param basicType basic type corresponding to this type; one of the 492917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * {@code BT_*} constants 493917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * @param newAt {@code >= -1;} allocation bytecode index 494917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul */ 495917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul private Type(String descriptor, int basicType, int newAt) { 496917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul if (descriptor == null) { 497917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul throw new NullPointerException("descriptor == null"); 498917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 499917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 500917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul if ((basicType < 0) || (basicType >= BT_COUNT)) { 501917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul throw new IllegalArgumentException("bad basicType"); 502917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 503917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 504917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul if (newAt < -1) { 505917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul throw new IllegalArgumentException("newAt < -1"); 506917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 507917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 508917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul this.descriptor = descriptor; 509917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul this.basicType = basicType; 510917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul this.newAt = newAt; 511917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul this.arrayType = null; 512917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul this.componentType = null; 513917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul this.initializedType = null; 514917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 515917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 516917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** 517917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * Constructs an instance corresponding to an "initialized type." 518917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * This is a private constructor; use one of the public static 519917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * methods to get instances. 520917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * 521917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * @param descriptor {@code non-null;} the field descriptor for the type 522917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * @param basicType basic type corresponding to this type; one of the 523917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * {@code BT_*} constants 524917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul */ 525917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul private Type(String descriptor, int basicType) { 526917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul this(descriptor, basicType, -1); 527917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 528917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 529917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** {@inheritDoc} */ 530917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul @Override 531917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul public boolean equals(Object other) { 532917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul if (this == other) { 533917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /* 534917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * Since externally-visible types are interned, this check 535917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * helps weed out some easy cases. 536917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul */ 537917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul return true; 538917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 539917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 540917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul if (!(other instanceof Type)) { 541917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul return false; 542917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 543917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 544917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul return descriptor.equals(((Type) other).descriptor); 545917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 546917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 547917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** {@inheritDoc} */ 548917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul @Override 549917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul public int hashCode() { 550917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul return descriptor.hashCode(); 551917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 552917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 553917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** {@inheritDoc} */ 554917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul public int compareTo(Type other) { 555917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul return descriptor.compareTo(other.descriptor); 556917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 557917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 558917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** {@inheritDoc} */ 559917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul @Override 560917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul public String toString() { 561917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul return descriptor; 562917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 563917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 564917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** {@inheritDoc} */ 565917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul public String toHuman() { 566917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul switch (basicType) { 567917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul case BT_VOID: return "void"; 568917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul case BT_BOOLEAN: return "boolean"; 569917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul case BT_BYTE: return "byte"; 570917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul case BT_CHAR: return "char"; 571917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul case BT_DOUBLE: return "double"; 572917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul case BT_FLOAT: return "float"; 573917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul case BT_INT: return "int"; 574917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul case BT_LONG: return "long"; 575917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul case BT_SHORT: return "short"; 576917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul case BT_OBJECT: break; 577917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul default: return descriptor; 578917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 579917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 580917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul if (isArray()) { 581917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul return getComponentType().toHuman() + "[]"; 582917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 583917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 584917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul // Remove the "L...;" around the type and convert "/" to ".". 585917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul return getClassName().replace("/", "."); 586917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 587917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 588917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** {@inheritDoc} */ 589917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul public Type getType() { 590917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul return this; 591917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 592917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 593917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** {@inheritDoc} */ 594917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul public Type getFrameType() { 595917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul switch (basicType) { 596917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul case BT_BOOLEAN: 597917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul case BT_BYTE: 598917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul case BT_CHAR: 599917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul case BT_INT: 600917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul case BT_SHORT: { 601917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul return INT; 602917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 603917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 604917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 605917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul return this; 606917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 607917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 608917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** {@inheritDoc} */ 609917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul public int getBasicType() { 610917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul return basicType; 611917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 612917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 613917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** {@inheritDoc} */ 614917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul public int getBasicFrameType() { 615917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul switch (basicType) { 616917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul case BT_BOOLEAN: 617917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul case BT_BYTE: 618917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul case BT_CHAR: 619917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul case BT_INT: 620917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul case BT_SHORT: { 621917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul return BT_INT; 622917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 623917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 624917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 625917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul return basicType; 626917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 627917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 628917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** {@inheritDoc} */ 629917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul public boolean isConstant() { 630917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul return false; 631917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 632917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 633917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** 634917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * Gets the descriptor. 635917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * 636917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * @return {@code non-null;} the descriptor 637917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul */ 638917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul public String getDescriptor() { 639917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul return descriptor; 640917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 641917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 642917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** 643917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * Gets the name of the class this type corresponds to, in internal 644917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * form. This method is only valid if this instance is for a 645917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * normal reference type (that is, a reference type and 646917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * additionally not a return address). 647917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * 648917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * @return {@code non-null;} the internal-form class name 649917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul */ 650917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul public String getClassName() { 651917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul if (className == null) { 652917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul if (!isReference()) { 653917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul throw new IllegalArgumentException("not an object type: " + 654917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul descriptor); 655917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 656917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 657917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul if (descriptor.charAt(0) == '[') { 658917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul className = descriptor; 659917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } else { 660917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul className = descriptor.substring(1, descriptor.length() - 1); 661917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 662917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 663917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 664917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul return className; 665917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 666917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 667917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** 668917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * Gets the category. Most instances are category 1. {@code long} 669917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * and {@code double} are the only category 2 types. 670917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * 671917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * @see #isCategory1 672917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * @see #isCategory2 673917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * @return the category 674917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul */ 675917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul public int getCategory() { 676917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul switch (basicType) { 677917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul case BT_LONG: 678917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul case BT_DOUBLE: { 679917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul return 2; 680917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 681917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 682917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 683917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul return 1; 684917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 685917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 686917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** 687917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * Returns whether or not this is a category 1 type. 688917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * 689917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * @see #getCategory 690917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * @see #isCategory2 691917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * @return whether or not this is a category 1 type 692917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul */ 693917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul public boolean isCategory1() { 694917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul switch (basicType) { 695917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul case BT_LONG: 696917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul case BT_DOUBLE: { 697917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul return false; 698917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 699917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 700917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 701917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul return true; 702917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 703917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 704917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** 705917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * Returns whether or not this is a category 2 type. 706917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * 707917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * @see #getCategory 708917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * @see #isCategory1 709917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * @return whether or not this is a category 2 type 710917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul */ 711917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul public boolean isCategory2() { 712917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul switch (basicType) { 713917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul case BT_LONG: 714917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul case BT_DOUBLE: { 715917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul return true; 716917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 717917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 718917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 719917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul return false; 720917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 721917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 722917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** 723917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * Gets whether this type is "intlike." An intlike type is one which, when 724917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * placed on a stack or in a local, is automatically converted to an 725917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * {@code int}. 726917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * 727917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * @return whether this type is "intlike" 728917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul */ 729917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul public boolean isIntlike() { 730917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul switch (basicType) { 731917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul case BT_BOOLEAN: 732917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul case BT_BYTE: 733917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul case BT_CHAR: 734917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul case BT_INT: 735917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul case BT_SHORT: { 736917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul return true; 737917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 738917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 739917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 740917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul return false; 741917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 742917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 743917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** 744917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * Gets whether this type is a primitive type. All types are either 745917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * primitive or reference types. 746917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * 747917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * @return whether this type is primitive 748917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul */ 749917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul public boolean isPrimitive() { 750917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul switch (basicType) { 751917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul case BT_BOOLEAN: 752917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul case BT_BYTE: 753917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul case BT_CHAR: 754917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul case BT_DOUBLE: 755917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul case BT_FLOAT: 756917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul case BT_INT: 757917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul case BT_LONG: 758917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul case BT_SHORT: 759917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul case BT_VOID: { 760917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul return true; 761917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 762917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 763917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 764917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul return false; 765917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 766917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 767917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** 768917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * Gets whether this type is a normal reference type. A normal 769917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * reference type is a reference type that is not a return 770917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * address. This method is just convenient shorthand for 771917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * {@code getBasicType() == Type.BT_OBJECT}. 772917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * 773917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * @return whether this type is a normal reference type 774917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul */ 775917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul public boolean isReference() { 776917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul return (basicType == BT_OBJECT); 777917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 778917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 779917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** 780917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * Gets whether this type is an array type. If this method returns 781917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * {@code true}, then it is safe to use {@link #getComponentType} 782917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * to determine the component type. 783917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * 784917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * @return whether this type is an array type 785917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul */ 786917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul public boolean isArray() { 787917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul return (descriptor.charAt(0) == '['); 788917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 789917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 790917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** 791917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * Gets whether this type is an array type or is a known-null, and 792917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * hence is compatible with array types. 793917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * 794917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * @return whether this type is an array type 795917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul */ 796917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul public boolean isArrayOrKnownNull() { 797917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul return isArray() || equals(KNOWN_NULL); 798917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 799917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 800917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** 801917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * Gets whether this type represents an uninitialized instance. An 802917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * uninitialized instance is what one gets back from the {@code new} 803917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * opcode, and remains uninitialized until a valid constructor is 804917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * invoked on it. 805917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * 806917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * @return whether this type is "uninitialized" 807917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul */ 808917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul public boolean isUninitialized() { 809917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul return (newAt >= 0); 810917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 811917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 812917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** 813917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * Gets the bytecode index at which this uninitialized type was 814917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * allocated. This returns {@code Integer.MAX_VALUE} if this 815917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * type is an uninitialized incoming parameter (i.e., the 816917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * {@code this} of an {@code <init>} method) or 817917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * {@code -1} if this type is in fact <i>initialized</i>. 818917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * 819917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * @return {@code >= -1;} the allocation bytecode index 820917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul */ 821917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul public int getNewAt() { 822917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul return newAt; 823917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 824917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 825917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** 826917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * Gets the initialized type corresponding to this instance, but only 827917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * if this instance is in fact an uninitialized object type. 828917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * 829917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * @return {@code non-null;} the initialized type 830917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul */ 831917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul public Type getInitializedType() { 832917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul if (initializedType == null) { 833917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul throw new IllegalArgumentException("initialized type: " + 834917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul descriptor); 835917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 836917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 837917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul return initializedType; 838917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 839917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 840917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** 841917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * Gets the type corresponding to an array of this type. 842917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * 843917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * @return {@code non-null;} the array type 844917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul */ 845917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul public Type getArrayType() { 846917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul if (arrayType == null) { 847917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul arrayType = putIntern(new Type('[' + descriptor, BT_OBJECT)); 848917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 849917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 850917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul return arrayType; 851917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 852917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 853917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** 854917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * Gets the component type of this type. This method is only valid on 855917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * array types. 856917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * 857917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * @return {@code non-null;} the component type 858917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul */ 859917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul public Type getComponentType() { 860917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul if (componentType == null) { 861917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul if (descriptor.charAt(0) != '[') { 862917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul throw new IllegalArgumentException("not an array type: " + 863917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul descriptor); 864917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 865917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul componentType = intern(descriptor.substring(1)); 866917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 867917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 868917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul return componentType; 869917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 870917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 871917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** 872917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * Returns a new interned instance which is identical to this one, except 873917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * it is indicated as uninitialized and allocated at the given bytecode 874917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * index. This instance must be an initialized object type. 875917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * 876917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * @param newAt {@code >= 0;} the allocation bytecode index 877917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * @return {@code non-null;} an appropriately-constructed instance 878917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul */ 879917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul public Type asUninitialized(int newAt) { 880917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul if (newAt < 0) { 881917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul throw new IllegalArgumentException("newAt < 0"); 882917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 883917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 884917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul if (!isReference()) { 885917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul throw new IllegalArgumentException("not a reference type: " + 886917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul descriptor); 887917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 888917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 889917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul if (isUninitialized()) { 890917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /* 891917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * Dealing with uninitialized types as a starting point is 892917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * a pain, and it's not clear that it'd ever be used, so 893917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * just disallow it. 894917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul */ 895917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul throw new IllegalArgumentException("already uninitialized: " + 896917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul descriptor); 897917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 898917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 899917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /* 900917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * Create a new descriptor that is unique and shouldn't conflict 901917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * with "normal" type descriptors 902917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul */ 903917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul String newDesc = 'N' + Hex.u2(newAt) + descriptor; 904917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul Type result = new Type(newDesc, BT_OBJECT, newAt); 905917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul result.initializedType = this; 906917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul return putIntern(result); 907917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 908917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 909917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** 910917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * Puts the given instance in the intern table if it's not already 911917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * there. If a conflicting value is already in the table, then leave it. 912917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * Return the interned value. 913917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * 914917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * @param type {@code non-null;} instance to make interned 915917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * @return {@code non-null;} the actual interned object 916917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul */ 917917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul private static Type putIntern(Type type) { 918917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul synchronized (internTable) { 919917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul String descriptor = type.getDescriptor(); 920917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul Type already = internTable.get(descriptor); 921917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul if (already != null) { 922917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul return already; 923917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 924917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul internTable.put(descriptor, type); 925917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul return type; 926917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 927917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 92894e569246cb1b3409fca701096eb687eecf4612fPiotr Gurgul}