OSDN Git Service

Mechanical refactoring of dx into two parts.
[android-x86/dalvik.git] / dx / src / com / android / dx / rop / type / Type.java
1 /*
2  * Copyright (C) 2007 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 package com.android.dx.rop.type;
18
19 import com.android.dx.util.Hex;
20 import java.util.HashMap;
21
22 /**
23  * Representation of a value type, such as may appear in a field, in a
24  * local, on a stack, or in a method descriptor. Instances of this
25  * class are generally interned and may be usefully compared with each
26  * other using {@code ==}.
27  */
28 public final class Type implements TypeBearer, Comparable<Type> {
29     /**
30      * {@code non-null;} intern table mapping string descriptors to
31      * instances
32      */
33     private static final HashMap<String, Type> internTable =
34         new HashMap<String, Type>(500);
35
36     /** basic type constant for {@code void} */
37     public static final int BT_VOID = 0;
38
39     /** basic type constant for {@code boolean} */
40     public static final int BT_BOOLEAN = 1;
41
42     /** basic type constant for {@code byte} */
43     public static final int BT_BYTE = 2;
44
45     /** basic type constant for {@code char} */
46     public static final int BT_CHAR = 3;
47
48     /** basic type constant for {@code double} */
49     public static final int BT_DOUBLE = 4;
50
51     /** basic type constant for {@code float} */
52     public static final int BT_FLOAT = 5;
53
54     /** basic type constant for {@code int} */
55     public static final int BT_INT = 6;
56
57     /** basic type constant for {@code long} */
58     public static final int BT_LONG = 7;
59
60     /** basic type constant for {@code short} */
61     public static final int BT_SHORT = 8;
62
63     /** basic type constant for {@code Object} */
64     public static final int BT_OBJECT = 9;
65
66     /** basic type constant for a return address */
67     public static final int BT_ADDR = 10;
68
69     /** count of basic type constants */
70     public static final int BT_COUNT = 11;
71
72     /** {@code non-null;} instance representing {@code boolean} */
73     public static final Type BOOLEAN = new Type("Z", BT_BOOLEAN);
74
75     /** {@code non-null;} instance representing {@code byte} */
76     public static final Type BYTE = new Type("B", BT_BYTE);
77
78     /** {@code non-null;} instance representing {@code char} */
79     public static final Type CHAR = new Type("C", BT_CHAR);
80
81     /** {@code non-null;} instance representing {@code double} */
82     public static final Type DOUBLE = new Type("D", BT_DOUBLE);
83
84     /** {@code non-null;} instance representing {@code float} */
85     public static final Type FLOAT = new Type("F", BT_FLOAT);
86
87     /** {@code non-null;} instance representing {@code int} */
88     public static final Type INT = new Type("I", BT_INT);
89
90     /** {@code non-null;} instance representing {@code long} */
91     public static final Type LONG = new Type("J", BT_LONG);
92
93     /** {@code non-null;} instance representing {@code short} */
94     public static final Type SHORT = new Type("S", BT_SHORT);
95
96     /** {@code non-null;} instance representing {@code void} */
97     public static final Type VOID = new Type("V", BT_VOID);
98
99     /** {@code non-null;} instance representing a known-{@code null} */
100     public static final Type KNOWN_NULL = new Type("<null>", BT_OBJECT);
101
102     /** {@code non-null;} instance representing a subroutine return address */
103     public static final Type RETURN_ADDRESS = new Type("<addr>", BT_ADDR);
104
105     static {
106         /*
107          * Put all the primitive types into the intern table. This needs
108          * to happen before the array types below get interned.
109          */
110         putIntern(BOOLEAN);
111         putIntern(BYTE);
112         putIntern(CHAR);
113         putIntern(DOUBLE);
114         putIntern(FLOAT);
115         putIntern(INT);
116         putIntern(LONG);
117         putIntern(SHORT);
118         /*
119          * Note: VOID isn't put in the intern table, since it's special and
120          * shouldn't be found by a normal call to intern().
121          */
122     }
123
124     /**
125      * {@code non-null;} instance representing
126      * {@code java.lang.annotation.Annotation}
127      */
128     public static final Type ANNOTATION =
129         intern("Ljava/lang/annotation/Annotation;");
130
131     /** {@code non-null;} instance representing {@code java.lang.Class} */
132     public static final Type CLASS = intern("Ljava/lang/Class;");
133
134     /** {@code non-null;} instance representing {@code java.lang.Cloneable} */
135     public static final Type CLONEABLE = intern("Ljava/lang/Cloneable;");
136
137     /** {@code non-null;} instance representing {@code java.lang.Object} */
138     public static final Type OBJECT = intern("Ljava/lang/Object;");
139
140     /** {@code non-null;} instance representing {@code java.io.Serializable} */
141     public static final Type SERIALIZABLE = intern("Ljava/io/Serializable;");
142
143     /** {@code non-null;} instance representing {@code java.lang.String} */
144     public static final Type STRING = intern("Ljava/lang/String;");
145
146     /** {@code non-null;} instance representing {@code java.lang.Throwable} */
147     public static final Type THROWABLE = intern("Ljava/lang/Throwable;");
148
149     /**
150      * {@code non-null;} instance representing {@code java.lang.Boolean}; the
151      * suffix on the name helps disambiguate this from the instance
152      * representing a primitive type
153      */
154     public static final Type BOOLEAN_CLASS = intern("Ljava/lang/Boolean;");
155
156     /**
157      * {@code non-null;} instance representing {@code java.lang.Byte}; the
158      * suffix on the name helps disambiguate this from the instance
159      * representing a primitive type
160      */
161     public static final Type BYTE_CLASS = intern("Ljava/lang/Byte;");
162
163     /**
164      * {@code non-null;} instance representing {@code java.lang.Character}; the
165      * suffix on the name helps disambiguate this from the instance
166      * representing a primitive type
167      */
168     public static final Type CHARACTER_CLASS = intern("Ljava/lang/Character;");
169
170     /**
171      * {@code non-null;} instance representing {@code java.lang.Double}; the
172      * suffix on the name helps disambiguate this from the instance
173      * representing a primitive type
174      */
175     public static final Type DOUBLE_CLASS = intern("Ljava/lang/Double;");
176
177     /**
178      * {@code non-null;} instance representing {@code java.lang.Float}; the
179      * suffix on the name helps disambiguate this from the instance
180      * representing a primitive type
181      */
182     public static final Type FLOAT_CLASS = intern("Ljava/lang/Float;");
183
184     /**
185      * {@code non-null;} instance representing {@code java.lang.Integer}; the
186      * suffix on the name helps disambiguate this from the instance
187      * representing a primitive type
188      */
189     public static final Type INTEGER_CLASS = intern("Ljava/lang/Integer;");
190
191     /**
192      * {@code non-null;} instance representing {@code java.lang.Long}; the
193      * suffix on the name helps disambiguate this from the instance
194      * representing a primitive type
195      */
196     public static final Type LONG_CLASS = intern("Ljava/lang/Long;");
197
198     /**
199      * {@code non-null;} instance representing {@code java.lang.Short}; the
200      * suffix on the name helps disambiguate this from the instance
201      * representing a primitive type
202      */
203     public static final Type SHORT_CLASS = intern("Ljava/lang/Short;");
204
205     /**
206      * {@code non-null;} instance representing {@code java.lang.Void}; the
207      * suffix on the name helps disambiguate this from the instance
208      * representing a primitive type
209      */
210     public static final Type VOID_CLASS = intern("Ljava/lang/Void;");
211
212     /** {@code non-null;} instance representing {@code boolean[]} */
213     public static final Type BOOLEAN_ARRAY = BOOLEAN.getArrayType();
214
215     /** {@code non-null;} instance representing {@code byte[]} */
216     public static final Type BYTE_ARRAY = BYTE.getArrayType();
217
218     /** {@code non-null;} instance representing {@code char[]} */
219     public static final Type CHAR_ARRAY = CHAR.getArrayType();
220
221     /** {@code non-null;} instance representing {@code double[]} */
222     public static final Type DOUBLE_ARRAY = DOUBLE.getArrayType();
223
224     /** {@code non-null;} instance representing {@code float[]} */
225     public static final Type FLOAT_ARRAY = FLOAT.getArrayType();
226
227     /** {@code non-null;} instance representing {@code int[]} */
228     public static final Type INT_ARRAY = INT.getArrayType();
229
230     /** {@code non-null;} instance representing {@code long[]} */
231     public static final Type LONG_ARRAY = LONG.getArrayType();
232
233     /** {@code non-null;} instance representing {@code Object[]} */
234     public static final Type OBJECT_ARRAY = OBJECT.getArrayType();
235
236     /** {@code non-null;} instance representing {@code short[]} */
237     public static final Type SHORT_ARRAY = SHORT.getArrayType();
238
239     /** {@code non-null;} field descriptor for the type */
240     private final String descriptor;
241
242     /**
243      * basic type corresponding to this type; one of the
244      * {@code BT_*} constants
245      */
246     private final int basicType;
247
248     /**
249      * {@code >= -1;} for an uninitialized type, bytecode index that this
250      * instance was allocated at; {@code Integer.MAX_VALUE} if it
251      * was an incoming uninitialized instance; {@code -1} if this
252      * is an <i>inititialized</i> instance
253      */
254     private final int newAt;
255
256     /**
257      * {@code null-ok;} the internal-form class name corresponding to
258      * this type, if calculated; only valid if {@code this} is a
259      * reference type and additionally not a return address
260      */
261     private String className;
262
263     /**
264      * {@code null-ok;} the type corresponding to an array of this type, if
265      * calculated
266      */
267     private Type arrayType;
268
269     /**
270      * {@code null-ok;} the type corresponding to elements of this type, if
271      * calculated; only valid if {@code this} is an array type
272      */
273     private Type componentType;
274
275     /**
276      * {@code null-ok;} the type corresponding to the initialized version of
277      * this type, if this instance is in fact an uninitialized type
278      */
279     private Type initializedType;
280
281     /**
282      * Returns the unique instance corresponding to the type with the
283      * given descriptor. See vmspec-2 sec4.3.2 for details on the
284      * field descriptor syntax. This method does <i>not</i> allow
285      * {@code "V"} (that is, type {@code void}) as a valid
286      * descriptor.
287      *
288      * @param descriptor {@code non-null;} the descriptor
289      * @return {@code non-null;} the corresponding instance
290      * @throws IllegalArgumentException thrown if the descriptor has
291      * invalid syntax
292      */
293     public static Type intern(String descriptor) {
294         Type result;
295         synchronized (internTable) {
296             result = internTable.get(descriptor);
297         }
298         if (result != null) {
299             return result;
300         }
301
302         char firstChar;
303         try {
304             firstChar = descriptor.charAt(0);
305         } catch (IndexOutOfBoundsException ex) {
306             // Translate the exception.
307             throw new IllegalArgumentException("descriptor is empty");
308         } catch (NullPointerException ex) {
309             // Elucidate the exception.
310             throw new NullPointerException("descriptor == null");
311         }
312
313         if (firstChar == '[') {
314             /*
315              * Recursively strip away array markers to get at the underlying
316              * type, and build back on to form the result.
317              */
318             result = intern(descriptor.substring(1));
319             return result.getArrayType();
320         }
321
322         /*
323          * If the first character isn't '[' and it wasn't found in the
324          * intern cache, then it had better be the descriptor for a class.
325          */
326
327         int length = descriptor.length();
328         if ((firstChar != 'L') ||
329             (descriptor.charAt(length - 1) != ';')) {
330             throw new IllegalArgumentException("bad descriptor: " + descriptor);
331         }
332
333         /*
334          * Validate the characters of the class name itself. Note that
335          * vmspec-2 does not have a coherent definition for valid
336          * internal-form class names, and the definition here is fairly
337          * liberal: A name is considered valid as long as it doesn't
338          * contain any of '[' ';' '.' '(' ')', and it has no more than one
339          * '/' in a row, and no '/' at either end.
340          */
341
342         int limit = (length - 1); // Skip the final ';'.
343         for (int i = 1; i < limit; i++) {
344             char c = descriptor.charAt(i);
345             switch (c) {
346                 case '[':
347                 case ';':
348                 case '.':
349                 case '(':
350                 case ')': {
351                     throw new IllegalArgumentException("bad descriptor: " + descriptor);
352                 }
353                 case '/': {
354                     if ((i == 1) ||
355                         (i == (length - 1)) ||
356                         (descriptor.charAt(i - 1) == '/')) {
357                         throw new IllegalArgumentException("bad descriptor: " + descriptor);
358                     }
359                     break;
360                 }
361             }
362         }
363
364         result = new Type(descriptor, BT_OBJECT);
365         return putIntern(result);
366     }
367
368     /**
369      * Returns the unique instance corresponding to the type with the
370      * given descriptor, allowing {@code "V"} to return the type
371      * for {@code void}. Other than that one caveat, this method
372      * is identical to {@link #intern}.
373      *
374      * @param descriptor {@code non-null;} the descriptor
375      * @return {@code non-null;} the corresponding instance
376      * @throws IllegalArgumentException thrown if the descriptor has
377      * invalid syntax
378      */
379     public static Type internReturnType(String descriptor) {
380         try {
381             if (descriptor.equals("V")) {
382                 // This is the one special case where void may be returned.
383                 return VOID;
384             }
385         } catch (NullPointerException ex) {
386             // Elucidate the exception.
387             throw new NullPointerException("descriptor == null");
388         }
389
390         return intern(descriptor);
391     }
392
393     /**
394      * Returns the unique instance corresponding to the type of the
395      * class with the given name. Calling this method is equivalent to
396      * calling {@code intern(name)} if {@code name} begins
397      * with {@code "["} and calling {@code intern("L" + name + ";")}
398      * in all other cases.
399      *
400      * @param name {@code non-null;} the name of the class whose type
401      * is desired
402      * @return {@code non-null;} the corresponding type
403      * @throws IllegalArgumentException thrown if the name has
404      * invalid syntax
405      */
406     public static Type internClassName(String name) {
407         if (name == null) {
408             throw new NullPointerException("name == null");
409         }
410
411         if (name.startsWith("[")) {
412             return intern(name);
413         }
414
415         return intern('L' + name + ';');
416     }
417
418     /**
419      * Constructs an instance corresponding to an "uninitialized type."
420      * This is a private constructor; use one of the public static
421      * methods to get instances.
422      *
423      * @param descriptor {@code non-null;} the field descriptor for the type
424      * @param basicType basic type corresponding to this type; one of the
425      * {@code BT_*} constants
426      * @param newAt {@code >= -1;} allocation bytecode index
427      */
428     private Type(String descriptor, int basicType, int newAt) {
429         if (descriptor == null) {
430             throw new NullPointerException("descriptor == null");
431         }
432
433         if ((basicType < 0) || (basicType >= BT_COUNT)) {
434             throw new IllegalArgumentException("bad basicType");
435         }
436
437         if (newAt < -1) {
438             throw new IllegalArgumentException("newAt < -1");
439         }
440
441         this.descriptor = descriptor;
442         this.basicType = basicType;
443         this.newAt = newAt;
444         this.arrayType = null;
445         this.componentType = null;
446         this.initializedType = null;
447     }
448
449     /**
450      * Constructs an instance corresponding to an "initialized type."
451      * This is a private constructor; use one of the public static
452      * methods to get instances.
453      *
454      * @param descriptor {@code non-null;} the field descriptor for the type
455      * @param basicType basic type corresponding to this type; one of the
456      * {@code BT_*} constants
457      */
458     private Type(String descriptor, int basicType) {
459         this(descriptor, basicType, -1);
460     }
461
462     /** {@inheritDoc} */
463     @Override
464     public boolean equals(Object other) {
465         if (this == other) {
466             /*
467              * Since externally-visible types are interned, this check
468              * helps weed out some easy cases.
469              */
470             return true;
471         }
472
473         if (!(other instanceof Type)) {
474             return false;
475         }
476
477         return descriptor.equals(((Type) other).descriptor);
478     }
479
480     /** {@inheritDoc} */
481     @Override
482     public int hashCode() {
483         return descriptor.hashCode();
484     }
485
486     /** {@inheritDoc} */
487     public int compareTo(Type other) {
488         return descriptor.compareTo(other.descriptor);
489     }
490
491     /** {@inheritDoc} */
492     @Override
493     public String toString() {
494         return descriptor;
495     }
496
497     /** {@inheritDoc} */
498     public String toHuman() {
499         switch (basicType) {
500             case BT_VOID:    return "void";
501             case BT_BOOLEAN: return "boolean";
502             case BT_BYTE:    return "byte";
503             case BT_CHAR:    return "char";
504             case BT_DOUBLE:  return "double";
505             case BT_FLOAT:   return "float";
506             case BT_INT:     return "int";
507             case BT_LONG:    return "long";
508             case BT_SHORT:   return "short";
509             case BT_OBJECT:  break;
510             default:         return descriptor;
511         }
512
513         if (isArray()) {
514             return getComponentType().toHuman() + "[]";
515         }
516
517         // Remove the "L...;" around the type and convert "/" to ".".
518         return getClassName().replace("/", ".");
519     }
520
521     /** {@inheritDoc} */
522     public Type getType() {
523         return this;
524     }
525
526     /** {@inheritDoc} */
527     public Type getFrameType() {
528         switch (basicType) {
529             case BT_BOOLEAN:
530             case BT_BYTE:
531             case BT_CHAR:
532             case BT_INT:
533             case BT_SHORT: {
534                 return INT;
535             }
536         }
537
538         return this;
539     }
540
541     /** {@inheritDoc} */
542     public int getBasicType() {
543         return basicType;
544     }
545
546     /** {@inheritDoc} */
547     public int getBasicFrameType() {
548         switch (basicType) {
549             case BT_BOOLEAN:
550             case BT_BYTE:
551             case BT_CHAR:
552             case BT_INT:
553             case BT_SHORT: {
554                 return BT_INT;
555             }
556         }
557
558         return basicType;
559     }
560
561     /** {@inheritDoc} */
562     public boolean isConstant() {
563         return false;
564     }
565
566     /**
567      * Gets the descriptor.
568      *
569      * @return {@code non-null;} the descriptor
570      */
571     public String getDescriptor() {
572         return descriptor;
573     }
574
575     /**
576      * Gets the name of the class this type corresponds to, in internal
577      * form. This method is only valid if this instance is for a
578      * normal reference type (that is, a reference type and
579      * additionally not a return address).
580      *
581      * @return {@code non-null;} the internal-form class name
582      */
583     public String getClassName() {
584         if (className == null) {
585             if (!isReference()) {
586                 throw new IllegalArgumentException("not an object type: " +
587                                                    descriptor);
588             }
589
590             if (descriptor.charAt(0) == '[') {
591                 className = descriptor;
592             } else {
593                 className = descriptor.substring(1, descriptor.length() - 1);
594             }
595         }
596
597         return className;
598     }
599
600     /**
601      * Gets the category. Most instances are category 1. {@code long}
602      * and {@code double} are the only category 2 types.
603      *
604      * @see #isCategory1
605      * @see #isCategory2
606      * @return the category
607      */
608     public int getCategory() {
609         switch (basicType) {
610             case BT_LONG:
611             case BT_DOUBLE: {
612                 return 2;
613             }
614         }
615
616         return 1;
617     }
618
619     /**
620      * Returns whether or not this is a category 1 type.
621      *
622      * @see #getCategory
623      * @see #isCategory2
624      * @return whether or not this is a category 1 type
625      */
626     public boolean isCategory1() {
627         switch (basicType) {
628             case BT_LONG:
629             case BT_DOUBLE: {
630                 return false;
631             }
632         }
633
634         return true;
635     }
636
637     /**
638      * Returns whether or not this is a category 2 type.
639      *
640      * @see #getCategory
641      * @see #isCategory1
642      * @return whether or not this is a category 2 type
643      */
644     public boolean isCategory2() {
645         switch (basicType) {
646             case BT_LONG:
647             case BT_DOUBLE: {
648                 return true;
649             }
650         }
651
652         return false;
653     }
654
655     /**
656      * Gets whether this type is "intlike." An intlike type is one which, when
657      * placed on a stack or in a local, is automatically converted to an
658      * {@code int}.
659      *
660      * @return whether this type is "intlike"
661      */
662     public boolean isIntlike() {
663         switch (basicType) {
664             case BT_BOOLEAN:
665             case BT_BYTE:
666             case BT_CHAR:
667             case BT_INT:
668             case BT_SHORT: {
669                 return true;
670             }
671         }
672
673         return false;
674     }
675
676     /**
677      * Gets whether this type is a primitive type. All types are either
678      * primitive or reference types.
679      *
680      * @return whether this type is primitive
681      */
682     public boolean isPrimitive() {
683         switch (basicType) {
684             case BT_BOOLEAN:
685             case BT_BYTE:
686             case BT_CHAR:
687             case BT_DOUBLE:
688             case BT_FLOAT:
689             case BT_INT:
690             case BT_LONG:
691             case BT_SHORT:
692             case BT_VOID: {
693                 return true;
694             }
695         }
696
697         return false;
698     }
699
700     /**
701      * Gets whether this type is a normal reference type. A normal
702      * reference type is a reference type that is not a return
703      * address. This method is just convenient shorthand for
704      * {@code getBasicType() == Type.BT_OBJECT}.
705      *
706      * @return whether this type is a normal reference type
707      */
708     public boolean isReference() {
709         return (basicType == BT_OBJECT);
710     }
711
712     /**
713      * Gets whether this type is an array type. If this method returns
714      * {@code true}, then it is safe to use {@link #getComponentType}
715      * to determine the component type.
716      *
717      * @return whether this type is an array type
718      */
719     public boolean isArray() {
720         return (descriptor.charAt(0) == '[');
721     }
722
723     /**
724      * Gets whether this type is an array type or is a known-null, and
725      * hence is compatible with array types.
726      *
727      * @return whether this type is an array type
728      */
729     public boolean isArrayOrKnownNull() {
730         return isArray() || equals(KNOWN_NULL);
731     }
732
733     /**
734      * Gets whether this type represents an uninitialized instance. An
735      * uninitialized instance is what one gets back from the {@code new}
736      * opcode, and remains uninitialized until a valid constructor is
737      * invoked on it.
738      *
739      * @return whether this type is "uninitialized"
740      */
741     public boolean isUninitialized() {
742         return (newAt >= 0);
743     }
744
745     /**
746      * Gets the bytecode index at which this uninitialized type was
747      * allocated.  This returns {@code Integer.MAX_VALUE} if this
748      * type is an uninitialized incoming parameter (i.e., the
749      * {@code this} of an {@code <init>} method) or
750      * {@code -1} if this type is in fact <i>initialized</i>.
751      *
752      * @return {@code >= -1;} the allocation bytecode index
753      */
754     public int getNewAt() {
755         return newAt;
756     }
757
758     /**
759      * Gets the initialized type corresponding to this instance, but only
760      * if this instance is in fact an uninitialized object type.
761      *
762      * @return {@code non-null;} the initialized type
763      */
764     public Type getInitializedType() {
765         if (initializedType == null) {
766             throw new IllegalArgumentException("initialized type: " +
767                                                descriptor);
768         }
769
770         return initializedType;
771     }
772
773     /**
774      * Gets the type corresponding to an array of this type.
775      *
776      * @return {@code non-null;} the array type
777      */
778     public Type getArrayType() {
779         if (arrayType == null) {
780             arrayType = putIntern(new Type('[' + descriptor, BT_OBJECT));
781         }
782
783         return arrayType;
784     }
785
786     /**
787      * Gets the component type of this type. This method is only valid on
788      * array types.
789      *
790      * @return {@code non-null;} the component type
791      */
792     public Type getComponentType() {
793         if (componentType == null) {
794             if (descriptor.charAt(0) != '[') {
795                 throw new IllegalArgumentException("not an array type: " +
796                                                    descriptor);
797             }
798             componentType = intern(descriptor.substring(1));
799         }
800
801         return componentType;
802     }
803
804     /**
805      * Returns a new interned instance which is identical to this one, except
806      * it is indicated as uninitialized and allocated at the given bytecode
807      * index. This instance must be an initialized object type.
808      *
809      * @param newAt {@code >= 0;} the allocation bytecode index
810      * @return {@code non-null;} an appropriately-constructed instance
811      */
812     public Type asUninitialized(int newAt) {
813         if (newAt < 0) {
814             throw new IllegalArgumentException("newAt < 0");
815         }
816
817         if (!isReference()) {
818             throw new IllegalArgumentException("not a reference type: " +
819                                                descriptor);
820         }
821
822         if (isUninitialized()) {
823             /*
824              * Dealing with uninitialized types as a starting point is
825              * a pain, and it's not clear that it'd ever be used, so
826              * just disallow it.
827              */
828             throw new IllegalArgumentException("already uninitialized: " +
829                                                descriptor);
830         }
831
832         /*
833          * Create a new descriptor that is unique and shouldn't conflict
834          * with "normal" type descriptors
835          */
836         String newDesc = 'N' + Hex.u2(newAt) + descriptor;
837         Type result = new Type(newDesc, BT_OBJECT, newAt);
838         result.initializedType = this;
839         return putIntern(result);
840     }
841
842     /**
843      * Puts the given instance in the intern table if it's not already
844      * there. If a conflicting value is already in the table, then leave it.
845      * Return the interned value.
846      *
847      * @param type {@code non-null;} instance to make interned
848      * @return {@code non-null;} the actual interned object
849      */
850     private static Type putIntern(Type type) {
851         synchronized (internTable) {
852             String descriptor = type.getDescriptor();
853             Type already = internTable.get(descriptor);
854             if (already != null) {
855                 return already;
856             }
857             internTable.put(descriptor, type);
858             return type;
859         }
860     }
861 }