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}