38 * deletion without notice.</b> |
40 * deletion without notice.</b> |
39 */ |
41 */ |
40 public enum TypeTag { |
42 public enum TypeTag { |
41 /** The tag of the basic type `byte'. |
43 /** The tag of the basic type `byte'. |
42 */ |
44 */ |
43 BYTE(1), |
45 BYTE(BYTE_CLASS, BYTE_SUPERCLASSES, |
|
46 TypeTagKind.PRIMITIVE | TypeTagKind.NUMERIC), |
44 |
47 |
45 /** The tag of the basic type `char'. |
48 /** The tag of the basic type `char'. |
46 */ |
49 */ |
47 CHAR(2), |
50 CHAR(CHAR_CLASS, CHAR_SUPERCLASSES, |
|
51 TypeTagKind.PRIMITIVE | TypeTagKind.NUMERIC), |
48 |
52 |
49 /** The tag of the basic type `short'. |
53 /** The tag of the basic type `short'. |
50 */ |
54 */ |
51 SHORT(3), |
55 SHORT(SHORT_CLASS, SHORT_SUPERCLASSES, |
|
56 TypeTagKind.PRIMITIVE | TypeTagKind.NUMERIC), |
52 |
57 |
53 /** The tag of the basic type `int'. |
58 /** The tag of the basic type `int'. |
54 */ |
59 */ |
55 INT(4), |
60 INT(INT_CLASS, INT_SUPERCLASSES, |
|
61 TypeTagKind.PRIMITIVE | TypeTagKind.NUMERIC), |
56 |
62 |
57 /** The tag of the basic type `long'. |
63 /** The tag of the basic type `long'. |
58 */ |
64 */ |
59 LONG(5), |
65 LONG(LONG_CLASS, LONG_SUPERCLASSES, TypeTagKind.PRIMITIVE | TypeTagKind.NUMERIC), |
60 |
66 |
61 /** The tag of the basic type `float'. |
67 /** The tag of the basic type `float'. |
62 */ |
68 */ |
63 FLOAT(6), |
69 FLOAT(FLOAT_CLASS, FLOAT_SUPERCLASSES, TypeTagKind.PRIMITIVE | TypeTagKind.NUMERIC), |
64 |
70 |
65 /** The tag of the basic type `double'. |
71 /** The tag of the basic type `double'. |
66 */ |
72 */ |
67 DOUBLE(7), |
73 DOUBLE(DOUBLE_CLASS, DOUBLE_CLASS, TypeTagKind.PRIMITIVE | TypeTagKind.NUMERIC), |
68 |
74 |
69 /** The tag of the basic type `boolean'. |
75 /** The tag of the basic type `boolean'. |
70 */ |
76 */ |
71 BOOLEAN, |
77 BOOLEAN(TypeTagKind.PRIMITIVE), |
72 |
78 |
73 /** The tag of the type `void'. |
79 /** The tag of the type `void'. |
74 */ |
80 */ |
75 VOID, |
81 VOID(TypeTagKind.VOID), |
76 |
82 |
77 /** The tag of all class and interface types. |
83 /** The tag of all class and interface types. |
78 */ |
84 */ |
79 CLASS, |
85 CLASS(TypeTagKind.REFERENCE), |
80 |
86 |
81 /** The tag of all array types. |
87 /** The tag of all array types. |
82 */ |
88 */ |
83 ARRAY, |
89 ARRAY(TypeTagKind.REFERENCE), |
84 |
90 |
85 /** The tag of all (monomorphic) method types. |
91 /** The tag of all (monomorphic) method types. |
86 */ |
92 */ |
87 METHOD, |
93 METHOD(TypeTagKind.OTHER), |
88 |
94 |
89 /** The tag of all package "types". |
95 /** The tag of all package "types". |
90 */ |
96 */ |
91 PACKAGE, |
97 PACKAGE(TypeTagKind.OTHER), |
92 |
98 |
93 /** The tag of all (source-level) type variables. |
99 /** The tag of all (source-level) type variables. |
94 */ |
100 */ |
95 TYPEVAR, |
101 TYPEVAR(TypeTagKind.REFERENCE), |
96 |
102 |
97 /** The tag of all type arguments. |
103 /** The tag of all type arguments. |
98 */ |
104 */ |
99 WILDCARD, |
105 WILDCARD(TypeTagKind.REFERENCE), |
100 |
106 |
101 /** The tag of all polymorphic (method-) types. |
107 /** The tag of all polymorphic (method-) types. |
102 */ |
108 */ |
103 FORALL, |
109 FORALL(TypeTagKind.OTHER), |
104 |
110 |
105 /** The tag of deferred expression types in method context |
111 /** The tag of deferred expression types in method context |
106 */ |
112 */ |
107 DEFERRED, |
113 DEFERRED(TypeTagKind.OTHER), |
108 |
114 |
109 /** The tag of the bottom type {@code <null>}. |
115 /** The tag of the bottom type {@code <null>}. |
110 */ |
116 */ |
111 BOT, |
117 BOT(TypeTagKind.OTHER), |
112 |
118 |
113 /** The tag of a missing type. |
119 /** The tag of a missing type. |
114 */ |
120 */ |
115 NONE, |
121 NONE(TypeTagKind.OTHER), |
116 |
122 |
117 /** The tag of the error type. |
123 /** The tag of the error type. |
118 */ |
124 */ |
119 ERROR, |
125 ERROR(TypeTagKind.REFERENCE | TypeTagKind.PARTIAL), |
120 |
126 |
121 /** The tag of an unknown type |
127 /** The tag of an unknown type |
122 */ |
128 */ |
123 UNKNOWN, |
129 UNKNOWN(TypeTagKind.PARTIAL), |
124 |
130 |
125 /** The tag of all instantiatable type variables. |
131 /** The tag of all instantiatable type variables. |
126 */ |
132 */ |
127 UNDETVAR, |
133 UNDETVAR(TypeTagKind.PARTIAL), |
128 |
134 |
129 /** Pseudo-types, these are special tags |
135 /** Pseudo-types, these are special tags |
130 */ |
136 */ |
131 UNINITIALIZED_THIS, |
137 UNINITIALIZED_THIS(TypeTagKind.OTHER), |
132 |
138 |
133 UNINITIALIZED_OBJECT; |
139 UNINITIALIZED_OBJECT(TypeTagKind.OTHER); |
134 |
140 |
135 /** This field will only be used for tags related with numeric types for |
141 final boolean isPrimitive; |
136 * optimization reasons. |
142 final boolean isNumeric; |
137 */ |
143 final boolean isPartial; |
138 private final int order; |
144 final boolean isReference; |
139 |
145 final boolean isPrimitiveOrVoid; |
140 private TypeTag() { |
146 final int superClasses; |
141 this(0); |
147 final int numericClass; |
142 } |
148 |
143 |
149 private TypeTag(int kind) { |
144 private TypeTag(int order) { |
150 this(0, 0, kind); |
145 this.order = order; |
151 } |
146 } |
152 |
147 |
153 private TypeTag(int numericClass, int superClasses, int kind) { |
148 private static final int MIN_NUMERIC_TAG_ORDER = 1; |
154 isPrimitive = (kind & TypeTagKind.PRIMITIVE) != 0; |
149 private static final int MAX_NUMERIC_TAG_ORDER = 7; |
155 isNumeric = (kind & TypeTagKind.NUMERIC) != 0; |
|
156 isPartial = (kind & TypeTagKind.PARTIAL) != 0; |
|
157 isReference = (kind & TypeTagKind.REFERENCE) != 0; |
|
158 isPrimitiveOrVoid = ((kind & TypeTagKind.PRIMITIVE) != 0) || |
|
159 ((kind & TypeTagKind.VOID) != 0); |
|
160 this.superClasses = superClasses; |
|
161 this.numericClass = numericClass; |
|
162 } |
|
163 |
|
164 static class TypeTagKind { |
|
165 static final int PRIMITIVE = 1; |
|
166 static final int NUMERIC = 2; |
|
167 static final int REFERENCE = 4; |
|
168 static final int PARTIAL = 8; |
|
169 static final int OTHER = 16; |
|
170 static final int VOID = 32; |
|
171 } |
|
172 |
|
173 public static class NumericClasses { |
|
174 public static final int BYTE_CLASS = 1; |
|
175 public static final int CHAR_CLASS = 2; |
|
176 public static final int SHORT_CLASS = 4; |
|
177 public static final int INT_CLASS = 8; |
|
178 public static final int LONG_CLASS = 16; |
|
179 public static final int FLOAT_CLASS = 32; |
|
180 public static final int DOUBLE_CLASS = 64; |
|
181 |
|
182 static final int BYTE_SUPERCLASSES = BYTE_CLASS | SHORT_CLASS | INT_CLASS | |
|
183 LONG_CLASS | FLOAT_CLASS | DOUBLE_CLASS; |
|
184 |
|
185 static final int CHAR_SUPERCLASSES = CHAR_CLASS | INT_CLASS | |
|
186 LONG_CLASS | FLOAT_CLASS | DOUBLE_CLASS; |
|
187 |
|
188 static final int SHORT_SUPERCLASSES = SHORT_CLASS | INT_CLASS | |
|
189 LONG_CLASS | FLOAT_CLASS | DOUBLE_CLASS; |
|
190 |
|
191 static final int INT_SUPERCLASSES = INT_CLASS | LONG_CLASS | FLOAT_CLASS | DOUBLE_CLASS; |
|
192 |
|
193 static final int LONG_SUPERCLASSES = LONG_CLASS | FLOAT_CLASS | DOUBLE_CLASS; |
|
194 |
|
195 static final int FLOAT_SUPERCLASSES = FLOAT_CLASS | DOUBLE_CLASS; |
|
196 } |
|
197 |
|
198 public boolean isStrictSubRangeOf(TypeTag tag) { |
|
199 /* Please don't change the implementation of this method to call method |
|
200 * isSubRangeOf. Both methods are called from hotspot code, the current |
|
201 * implementation is better performance-wise than the commented modification. |
|
202 */ |
|
203 return (this.superClasses & tag.numericClass) != 0 && this != tag; |
|
204 } |
|
205 |
|
206 public boolean isSubRangeOf(TypeTag tag) { |
|
207 return (this.superClasses & tag.numericClass) != 0; |
|
208 } |
150 |
209 |
151 /** Returns the number of type tags. |
210 /** Returns the number of type tags. |
152 */ |
211 */ |
153 public static int getTypeTagCount() { |
212 public static int getTypeTagCount() { |
154 // last two tags are not included in the total as long as they are pseudo-types |
213 // last two tags are not included in the total as long as they are pseudo-types |
155 return (UNDETVAR.ordinal() + 1); |
214 return (UNDETVAR.ordinal() + 1); |
156 } |
|
157 |
|
158 public boolean isSubRangeOf(TypeTag range) { |
|
159 return (this == range) || isStrictSubRangeOf(range); |
|
160 } |
|
161 |
|
162 public boolean isStrictSubRangeOf(TypeTag range) { |
|
163 if (this.order >= MIN_NUMERIC_TAG_ORDER && this.order <= MAX_NUMERIC_TAG_ORDER && |
|
164 range.order >= MIN_NUMERIC_TAG_ORDER && this.order <= MAX_NUMERIC_TAG_ORDER) { |
|
165 if (this == range) |
|
166 return false; |
|
167 switch (this) { |
|
168 case BYTE: |
|
169 return true; |
|
170 case CHAR: case SHORT: case INT: |
|
171 case LONG: case FLOAT: |
|
172 return this.order < range.order && range.order <= MAX_NUMERIC_TAG_ORDER; |
|
173 default: |
|
174 return false; |
|
175 } |
|
176 } |
|
177 else |
|
178 return false; |
|
179 } |
215 } |
180 |
216 |
181 public Kind getKindLiteral() { |
217 public Kind getKindLiteral() { |
182 switch (this) { |
218 switch (this) { |
183 case INT: |
219 case INT: |