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