190 // the 'query' types should technically return 'false' here, if we
191 // allow this to return true, we can perform the test using only
192 // 2 operations rather than 8 (3 masks, 3 compares and 2 logical 'ands').
193 // Since noone should call this on a query type anyway, this is ok.
194 assert(!is_check(), "Must not be a check type (wrong value returned)");
195 return ((_u._data & Category1) != Primitive);
196 // should only return false if it's a primitive, and the category1 flag
197 // is not set.
198 }
199 bool is_category2() const { return ((_u._data & Category2) == Category2); }
200 bool is_category2_2nd() const {
201 return ((_u._data & Category2_2nd) == Category2_2nd);
202 }
203 bool is_reference_check() const { return _u._data == ReferenceQuery; }
204 bool is_category1_check() const { return _u._data == Category1Query; }
205 bool is_category2_check() const { return _u._data == Category2Query; }
206 bool is_category2_2nd_check() const { return _u._data == Category2_2ndQuery; }
207 bool is_check() const { return (_u._data & TypeQuery) == TypeQuery; }
208
209 bool is_x_array(char sig) const {
210 return is_null() || (is_array() && (name()->byte_at(1) == sig));
211 }
212 bool is_int_array() const { return is_x_array('I'); }
213 bool is_byte_array() const { return is_x_array('B'); }
214 bool is_bool_array() const { return is_x_array('Z'); }
215 bool is_char_array() const { return is_x_array('C'); }
216 bool is_short_array() const { return is_x_array('S'); }
217 bool is_long_array() const { return is_x_array('J'); }
218 bool is_float_array() const { return is_x_array('F'); }
219 bool is_double_array() const { return is_x_array('D'); }
220 bool is_object_array() const { return is_x_array('L'); }
221 bool is_array_array() const { return is_x_array('['); }
222 bool is_reference_array() const
223 { return is_object_array() || is_array_array(); }
224 bool is_object() const
225 { return (is_reference() && !is_null() && name()->utf8_length() >= 1 &&
226 name()->byte_at(0) != '['); }
227 bool is_array() const
228 { return (is_reference() && !is_null() && name()->utf8_length() >= 2 &&
229 name()->byte_at(0) == '['); }
230 bool is_uninitialized() const
231 { return ((_u._data & Uninitialized) == Uninitialized); }
232 bool is_uninitialized_this() const
233 { return is_uninitialized() && bci() == BciForThis; }
234
235 VerificationType to_category2_2nd() const {
236 assert(is_category2(), "Must be a double word");
237 return VerificationType(is_long() ? Long_2nd : Double_2nd);
238 }
239
240 u2 bci() const {
241 assert(is_uninitialized(), "Must be uninitialized type");
242 return ((_u._data & BciMask) >> 1 * BitsPerByte);
243 }
244
245 Symbol* name() const {
246 assert(is_reference() && !is_null(), "Must be a non-null reference");
247 return _u._sym;
248 }
249
305 if (equals(from) || is_bogus()) {
306 return true;
307 } else {
308 switch(_u._data) {
309 case Boolean:
310 case Byte:
311 case Char:
312 case Short:
313 return false;
314 default:
315 return is_assignable_from(from, context, from_field_is_protected, CHECK_false);
316 }
317 }
318 }
319
320 VerificationType get_component(ClassVerifier* context, TRAPS) const;
321
322 int dimensions() const {
323 assert(is_array(), "Must be an array");
324 int index = 0;
325 while (name()->byte_at(index) == '[') index++;
326 return index;
327 }
328
329 void print_on(outputStream* st) const;
330
331 private:
332
333 bool is_reference_assignable_from(
334 const VerificationType&, ClassVerifier*, bool from_field_is_protected,
335 TRAPS) const;
336
337 public:
338 static bool resolve_and_check_assignability(InstanceKlass* klass, Symbol* name,
339 Symbol* from_name, bool from_field_is_protected,
340 bool from_is_array, bool from_is_object,
341 TRAPS);
342 };
343
344 #endif // SHARE_VM_CLASSFILE_VERIFICATIONTYPE_HPP
|
190 // the 'query' types should technically return 'false' here, if we
191 // allow this to return true, we can perform the test using only
192 // 2 operations rather than 8 (3 masks, 3 compares and 2 logical 'ands').
193 // Since noone should call this on a query type anyway, this is ok.
194 assert(!is_check(), "Must not be a check type (wrong value returned)");
195 return ((_u._data & Category1) != Primitive);
196 // should only return false if it's a primitive, and the category1 flag
197 // is not set.
198 }
199 bool is_category2() const { return ((_u._data & Category2) == Category2); }
200 bool is_category2_2nd() const {
201 return ((_u._data & Category2_2nd) == Category2_2nd);
202 }
203 bool is_reference_check() const { return _u._data == ReferenceQuery; }
204 bool is_category1_check() const { return _u._data == Category1Query; }
205 bool is_category2_check() const { return _u._data == Category2Query; }
206 bool is_category2_2nd_check() const { return _u._data == Category2_2ndQuery; }
207 bool is_check() const { return (_u._data & TypeQuery) == TypeQuery; }
208
209 bool is_x_array(char sig) const {
210 return is_null() || (is_array() && (name()->char_at(1) == sig));
211 }
212 bool is_int_array() const { return is_x_array('I'); }
213 bool is_byte_array() const { return is_x_array('B'); }
214 bool is_bool_array() const { return is_x_array('Z'); }
215 bool is_char_array() const { return is_x_array('C'); }
216 bool is_short_array() const { return is_x_array('S'); }
217 bool is_long_array() const { return is_x_array('J'); }
218 bool is_float_array() const { return is_x_array('F'); }
219 bool is_double_array() const { return is_x_array('D'); }
220 bool is_object_array() const { return is_x_array('L'); }
221 bool is_array_array() const { return is_x_array('['); }
222 bool is_reference_array() const
223 { return is_object_array() || is_array_array(); }
224 bool is_object() const
225 { return (is_reference() && !is_null() && name()->utf8_length() >= 1 &&
226 name()->char_at(0) != '['); }
227 bool is_array() const
228 { return (is_reference() && !is_null() && name()->utf8_length() >= 2 &&
229 name()->char_at(0) == '['); }
230 bool is_uninitialized() const
231 { return ((_u._data & Uninitialized) == Uninitialized); }
232 bool is_uninitialized_this() const
233 { return is_uninitialized() && bci() == BciForThis; }
234
235 VerificationType to_category2_2nd() const {
236 assert(is_category2(), "Must be a double word");
237 return VerificationType(is_long() ? Long_2nd : Double_2nd);
238 }
239
240 u2 bci() const {
241 assert(is_uninitialized(), "Must be uninitialized type");
242 return ((_u._data & BciMask) >> 1 * BitsPerByte);
243 }
244
245 Symbol* name() const {
246 assert(is_reference() && !is_null(), "Must be a non-null reference");
247 return _u._sym;
248 }
249
305 if (equals(from) || is_bogus()) {
306 return true;
307 } else {
308 switch(_u._data) {
309 case Boolean:
310 case Byte:
311 case Char:
312 case Short:
313 return false;
314 default:
315 return is_assignable_from(from, context, from_field_is_protected, CHECK_false);
316 }
317 }
318 }
319
320 VerificationType get_component(ClassVerifier* context, TRAPS) const;
321
322 int dimensions() const {
323 assert(is_array(), "Must be an array");
324 int index = 0;
325 while (name()->char_at(index) == '[') index++;
326 return index;
327 }
328
329 void print_on(outputStream* st) const;
330
331 private:
332
333 bool is_reference_assignable_from(
334 const VerificationType&, ClassVerifier*, bool from_field_is_protected,
335 TRAPS) const;
336
337 public:
338 static bool resolve_and_check_assignability(InstanceKlass* klass, Symbol* name,
339 Symbol* from_name, bool from_field_is_protected,
340 bool from_is_array, bool from_is_object,
341 TRAPS);
342 };
343
344 #endif // SHARE_VM_CLASSFILE_VERIFICATIONTYPE_HPP
|