Mercurial > hg > truffle
comparison src/share/vm/classfile/classFileParser.cpp @ 1602:136b78722a08
6939203: JSR 292 needs method handle constants
Summary: Add new CP types CONSTANT_MethodHandle, CONSTANT_MethodType; extend 'ldc' bytecode.
Reviewed-by: twisti, never
author | jrose |
---|---|
date | Wed, 09 Jun 2010 18:50:45 -0700 |
parents | c18cbe5936b8 |
children | 2389669474a6 |
comparison
equal
deleted
inserted
replaced
1585:49fac4acd688 | 1602:136b78722a08 |
---|---|
109 case JVM_CONSTANT_String : | 109 case JVM_CONSTANT_String : |
110 { | 110 { |
111 cfs->guarantee_more(3, CHECK); // string_index, tag/access_flags | 111 cfs->guarantee_more(3, CHECK); // string_index, tag/access_flags |
112 u2 string_index = cfs->get_u2_fast(); | 112 u2 string_index = cfs->get_u2_fast(); |
113 cp->string_index_at_put(index, string_index); | 113 cp->string_index_at_put(index, string_index); |
114 } | |
115 break; | |
116 case JVM_CONSTANT_MethodHandle : | |
117 case JVM_CONSTANT_MethodType : | |
118 if (!EnableMethodHandles || | |
119 _major_version < Verifier::INVOKEDYNAMIC_MAJOR_VERSION) { | |
120 classfile_parse_error( | |
121 (!EnableInvokeDynamic ? | |
122 "This JVM does not support constant tag %u in class file %s" : | |
123 "Class file version does not support constant tag %u in class file %s"), | |
124 tag, CHECK); | |
125 } | |
126 if (tag == JVM_CONSTANT_MethodHandle) { | |
127 cfs->guarantee_more(4, CHECK); // ref_kind, method_index, tag/access_flags | |
128 u1 ref_kind = cfs->get_u1_fast(); | |
129 u2 method_index = cfs->get_u2_fast(); | |
130 cp->method_handle_index_at_put(index, ref_kind, method_index); | |
131 } else if (tag == JVM_CONSTANT_MethodType) { | |
132 cfs->guarantee_more(3, CHECK); // signature_index, tag/access_flags | |
133 u2 signature_index = cfs->get_u2_fast(); | |
134 cp->method_type_index_at_put(index, signature_index); | |
135 } else { | |
136 ShouldNotReachHere(); | |
114 } | 137 } |
115 break; | 138 break; |
116 case JVM_CONSTANT_Integer : | 139 case JVM_CONSTANT_Integer : |
117 { | 140 { |
118 cfs->guarantee_more(5, CHECK); // bytes, tag/access_flags | 141 cfs->guarantee_more(5, CHECK); // bytes, tag/access_flags |
331 string_index, CHECK_(nullHandle)); | 354 string_index, CHECK_(nullHandle)); |
332 symbolOop sym = cp->symbol_at(string_index); | 355 symbolOop sym = cp->symbol_at(string_index); |
333 cp->unresolved_string_at_put(index, sym); | 356 cp->unresolved_string_at_put(index, sym); |
334 } | 357 } |
335 break; | 358 break; |
359 case JVM_CONSTANT_MethodHandle : | |
360 { | |
361 int ref_index = cp->method_handle_index_at(index); | |
362 check_property( | |
363 valid_cp_range(ref_index, length) && | |
364 EnableMethodHandles, | |
365 "Invalid constant pool index %u in class file %s", | |
366 ref_index, CHECK_(nullHandle)); | |
367 constantTag tag = cp->tag_at(ref_index); | |
368 int ref_kind = cp->method_handle_ref_kind_at(index); | |
369 switch (ref_kind) { | |
370 case JVM_REF_getField: | |
371 case JVM_REF_getStatic: | |
372 case JVM_REF_putField: | |
373 case JVM_REF_putStatic: | |
374 check_property( | |
375 tag.is_field(), | |
376 "Invalid constant pool index %u in class file %s (not a field)", | |
377 ref_index, CHECK_(nullHandle)); | |
378 break; | |
379 case JVM_REF_invokeVirtual: | |
380 case JVM_REF_invokeStatic: | |
381 case JVM_REF_invokeSpecial: | |
382 case JVM_REF_newInvokeSpecial: | |
383 check_property( | |
384 tag.is_method(), | |
385 "Invalid constant pool index %u in class file %s (not a method)", | |
386 ref_index, CHECK_(nullHandle)); | |
387 break; | |
388 case JVM_REF_invokeInterface: | |
389 check_property( | |
390 tag.is_interface_method(), | |
391 "Invalid constant pool index %u in class file %s (not an interface method)", | |
392 ref_index, CHECK_(nullHandle)); | |
393 break; | |
394 default: | |
395 classfile_parse_error( | |
396 "Bad method handle kind at constant pool index %u in class file %s", | |
397 index, CHECK_(nullHandle)); | |
398 } | |
399 // Keep the ref_index unchanged. It will be indirected at link-time. | |
400 } | |
401 break; | |
402 case JVM_CONSTANT_MethodType : | |
403 { | |
404 int ref_index = cp->method_type_index_at(index); | |
405 check_property( | |
406 valid_cp_range(ref_index, length) && | |
407 cp->tag_at(ref_index).is_utf8() && | |
408 EnableMethodHandles, | |
409 "Invalid constant pool index %u in class file %s", | |
410 ref_index, CHECK_(nullHandle)); | |
411 } | |
412 break; | |
336 default: | 413 default: |
337 fatal(err_msg("bad constant pool tag value %u", | 414 fatal(err_msg("bad constant pool tag value %u", |
338 cp->tag_at(index).value())); | 415 cp->tag_at(index).value())); |
339 ShouldNotReachHere(); | 416 ShouldNotReachHere(); |
340 break; | 417 break; |
414 } | 491 } |
415 } | 492 } |
416 } | 493 } |
417 break; | 494 break; |
418 } | 495 } |
496 case JVM_CONSTANT_MethodHandle: { | |
497 int ref_index = cp->method_handle_index_at(index); | |
498 int ref_kind = cp->method_handle_ref_kind_at(index); | |
499 switch (ref_kind) { | |
500 case JVM_REF_invokeVirtual: | |
501 case JVM_REF_invokeStatic: | |
502 case JVM_REF_invokeSpecial: | |
503 case JVM_REF_newInvokeSpecial: | |
504 { | |
505 int name_and_type_ref_index = cp->name_and_type_ref_index_at(ref_index); | |
506 int name_ref_index = cp->name_ref_index_at(name_and_type_ref_index); | |
507 symbolHandle name(THREAD, cp->symbol_at(name_ref_index)); | |
508 if (ref_kind == JVM_REF_newInvokeSpecial) { | |
509 if (name() != vmSymbols::object_initializer_name()) { | |
510 classfile_parse_error( | |
511 "Bad constructor name at constant pool index %u in class file %s", | |
512 name_ref_index, CHECK_(nullHandle)); | |
513 } | |
514 } else { | |
515 if (name() == vmSymbols::object_initializer_name()) { | |
516 classfile_parse_error( | |
517 "Bad method name at constant pool index %u in class file %s", | |
518 name_ref_index, CHECK_(nullHandle)); | |
519 } | |
520 } | |
521 } | |
522 break; | |
523 // Other ref_kinds are already fully checked in previous pass. | |
524 } | |
525 break; | |
526 } | |
527 case JVM_CONSTANT_MethodType: { | |
528 symbolHandle no_name = vmSymbolHandles::type_name(); // place holder | |
529 symbolHandle signature(THREAD, cp->method_type_signature_at(index)); | |
530 verify_legal_method_signature(no_name, signature, CHECK_(nullHandle)); | |
531 break; | |
532 } | |
419 } // end of switch | 533 } // end of switch |
420 } // end of for | 534 } // end of for |
421 | 535 |
422 return cp; | 536 return cp; |
423 } | 537 } |
429 switch (cp->tag_at(index).value()) { | 543 switch (cp->tag_at(index).value()) { |
430 | 544 |
431 case JVM_CONSTANT_UnresolvedClass : | 545 case JVM_CONSTANT_UnresolvedClass : |
432 // Patching a class means pre-resolving it. | 546 // Patching a class means pre-resolving it. |
433 // The name in the constant pool is ignored. | 547 // The name in the constant pool is ignored. |
434 if (patch->klass() == SystemDictionary::Class_klass()) { // %%% java_lang_Class::is_instance | 548 if (java_lang_Class::is_instance(patch())) { |
435 guarantee_property(!java_lang_Class::is_primitive(patch()), | 549 guarantee_property(!java_lang_Class::is_primitive(patch()), |
436 "Illegal class patch at %d in class file %s", | 550 "Illegal class patch at %d in class file %s", |
437 index, CHECK); | 551 index, CHECK); |
438 cp->klass_at_put(index, java_lang_Class::as_klassOop(patch())); | 552 cp->klass_at_put(index, java_lang_Class::as_klassOop(patch())); |
439 } else { | 553 } else { |