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