536 bool nostatics = (code == Bytecodes::_invokestatic) ? false : true; |
536 bool nostatics = (code == Bytecodes::_invokestatic) ? false : true; |
537 resolve_interface_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, true, nostatics, CHECK); |
537 resolve_interface_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, true, nostatics, CHECK); |
538 } |
538 } |
539 } |
539 } |
540 |
540 |
|
541 void LinkResolver::check_method_loader_constraints(methodHandle& resolved_method, |
|
542 KlassHandle resolved_klass, |
|
543 Symbol* method_name, |
|
544 Symbol* method_signature, |
|
545 KlassHandle current_klass, |
|
546 const char* method_type, TRAPS) { |
|
547 Handle loader (THREAD, InstanceKlass::cast(current_klass())->class_loader()); |
|
548 Handle class_loader (THREAD, resolved_method->method_holder()->class_loader()); |
|
549 { |
|
550 ResourceMark rm(THREAD); |
|
551 Symbol* failed_type_symbol = |
|
552 SystemDictionary::check_signature_loaders(method_signature, loader, |
|
553 class_loader, true, CHECK); |
|
554 if (failed_type_symbol != NULL) { |
|
555 const char* msg = "loader constraint violation: when resolving %s" |
|
556 " \"%s\" the class loader (instance of %s) of the current class, %s," |
|
557 " and the class loader (instance of %s) for the method's defining class, %s, have" |
|
558 " different Class objects for the type %s used in the signature"; |
|
559 char* sig = Method::name_and_sig_as_C_string(resolved_klass(), method_name, method_signature); |
|
560 const char* loader1 = SystemDictionary::loader_name(loader()); |
|
561 char* current = InstanceKlass::cast(current_klass())->name()->as_C_string(); |
|
562 const char* loader2 = SystemDictionary::loader_name(class_loader()); |
|
563 char* target = InstanceKlass::cast(resolved_method->method_holder()) |
|
564 ->name()->as_C_string(); |
|
565 char* failed_type_name = failed_type_symbol->as_C_string(); |
|
566 size_t buflen = strlen(msg) + strlen(sig) + strlen(loader1) + |
|
567 strlen(current) + strlen(loader2) + strlen(target) + |
|
568 strlen(failed_type_name) + strlen(method_type) + 1; |
|
569 char* buf = NEW_RESOURCE_ARRAY_IN_THREAD(THREAD, char, buflen); |
|
570 jio_snprintf(buf, buflen, msg, method_type, sig, loader1, current, loader2, |
|
571 target, failed_type_name); |
|
572 THROW_MSG(vmSymbols::java_lang_LinkageError(), buf); |
|
573 } |
|
574 } |
|
575 } |
|
576 |
541 void LinkResolver::resolve_method(methodHandle& resolved_method, KlassHandle resolved_klass, |
577 void LinkResolver::resolve_method(methodHandle& resolved_method, KlassHandle resolved_klass, |
542 Symbol* method_name, Symbol* method_signature, |
578 Symbol* method_name, Symbol* method_signature, |
543 KlassHandle current_klass, bool check_access, |
579 KlassHandle current_klass, bool check_access, |
544 bool require_methodref, TRAPS) { |
580 bool require_methodref, TRAPS) { |
545 |
581 |
592 KlassHandle(THREAD, resolved_method->method_holder()), |
628 KlassHandle(THREAD, resolved_method->method_holder()), |
593 resolved_method, |
629 resolved_method, |
594 CHECK); |
630 CHECK); |
595 |
631 |
596 // check loader constraints |
632 // check loader constraints |
597 Handle loader (THREAD, InstanceKlass::cast(current_klass())->class_loader()); |
633 check_method_loader_constraints(resolved_method, resolved_klass, method_name, |
598 Handle class_loader (THREAD, resolved_method->method_holder()->class_loader()); |
634 method_signature, current_klass, "method", CHECK); |
599 { |
|
600 ResourceMark rm(THREAD); |
|
601 Symbol* failed_type_symbol = |
|
602 SystemDictionary::check_signature_loaders(method_signature, loader, |
|
603 class_loader, true, CHECK); |
|
604 if (failed_type_symbol != NULL) { |
|
605 const char* msg = "loader constraint violation: when resolving method" |
|
606 " \"%s\" the class loader (instance of %s) of the current class, %s," |
|
607 " and the class loader (instance of %s) for the method's defining class, %s, have" |
|
608 " different Class objects for the type %s used in the signature"; |
|
609 char* sig = Method::name_and_sig_as_C_string(resolved_klass(),method_name,method_signature); |
|
610 const char* loader1 = SystemDictionary::loader_name(loader()); |
|
611 char* current = InstanceKlass::cast(current_klass())->name()->as_C_string(); |
|
612 const char* loader2 = SystemDictionary::loader_name(class_loader()); |
|
613 char* target = InstanceKlass::cast(resolved_method->method_holder()) |
|
614 ->name()->as_C_string(); |
|
615 char* failed_type_name = failed_type_symbol->as_C_string(); |
|
616 size_t buflen = strlen(msg) + strlen(sig) + strlen(loader1) + |
|
617 strlen(current) + strlen(loader2) + strlen(target) + |
|
618 strlen(failed_type_name) + 1; |
|
619 char* buf = NEW_RESOURCE_ARRAY_IN_THREAD(THREAD, char, buflen); |
|
620 jio_snprintf(buf, buflen, msg, sig, loader1, current, loader2, |
|
621 target, failed_type_name); |
|
622 THROW_MSG(vmSymbols::java_lang_LinkageError(), buf); |
|
623 } |
|
624 } |
|
625 } |
635 } |
626 } |
636 } |
627 |
637 |
628 void LinkResolver::resolve_interface_method(methodHandle& resolved_method, |
638 void LinkResolver::resolve_interface_method(methodHandle& resolved_method, |
629 KlassHandle resolved_klass, |
639 KlassHandle resolved_klass, |
668 resolved_klass, |
678 resolved_klass, |
669 KlassHandle(THREAD, resolved_method->method_holder()), |
679 KlassHandle(THREAD, resolved_method->method_holder()), |
670 resolved_method, |
680 resolved_method, |
671 CHECK); |
681 CHECK); |
672 |
682 |
673 HandleMark hm(THREAD); |
683 check_method_loader_constraints(resolved_method, resolved_klass, method_name, |
674 Handle loader (THREAD, InstanceKlass::cast(current_klass())->class_loader()); |
684 method_signature, current_klass, "interface method", CHECK); |
675 Handle class_loader (THREAD, resolved_method->method_holder()->class_loader()); |
|
676 { |
|
677 ResourceMark rm(THREAD); |
|
678 Symbol* failed_type_symbol = |
|
679 SystemDictionary::check_signature_loaders(method_signature, loader, |
|
680 class_loader, true, CHECK); |
|
681 if (failed_type_symbol != NULL) { |
|
682 const char* msg = "loader constraint violation: when resolving " |
|
683 "interface method \"%s\" the class loader (instance of %s) of the " |
|
684 "current class, %s, and the class loader (instance of %s) for " |
|
685 "the method's defining class, %s, have different Class objects for the type %s " |
|
686 "used in the signature"; |
|
687 char* sig = Method::name_and_sig_as_C_string(resolved_klass(),method_name,method_signature); |
|
688 const char* loader1 = SystemDictionary::loader_name(loader()); |
|
689 char* current = InstanceKlass::cast(current_klass())->name()->as_C_string(); |
|
690 const char* loader2 = SystemDictionary::loader_name(class_loader()); |
|
691 char* target = InstanceKlass::cast(resolved_method->method_holder()) |
|
692 ->name()->as_C_string(); |
|
693 char* failed_type_name = failed_type_symbol->as_C_string(); |
|
694 size_t buflen = strlen(msg) + strlen(sig) + strlen(loader1) + |
|
695 strlen(current) + strlen(loader2) + strlen(target) + |
|
696 strlen(failed_type_name) + 1; |
|
697 char* buf = NEW_RESOURCE_ARRAY_IN_THREAD(THREAD, char, buflen); |
|
698 jio_snprintf(buf, buflen, msg, sig, loader1, current, loader2, |
|
699 target, failed_type_name); |
|
700 THROW_MSG(vmSymbols::java_lang_LinkageError(), buf); |
|
701 } |
|
702 } |
|
703 } |
685 } |
704 |
686 |
705 if (nostatics && resolved_method->is_static()) { |
687 if (nostatics && resolved_method->is_static()) { |
706 ResourceMark rm(THREAD); |
688 ResourceMark rm(THREAD); |
707 char buf[200]; |
689 char buf[200]; |
1047 ResourceMark rm(THREAD); |
1029 ResourceMark rm(THREAD); |
1048 THROW_MSG(vmSymbols::java_lang_AbstractMethodError(), |
1030 THROW_MSG(vmSymbols::java_lang_AbstractMethodError(), |
1049 Method::name_and_sig_as_C_string(resolved_klass(), |
1031 Method::name_and_sig_as_C_string(resolved_klass(), |
1050 resolved_method->name(), |
1032 resolved_method->name(), |
1051 resolved_method->signature())); |
1033 resolved_method->signature())); |
|
1034 } else if (sel_method() != resolved_method()) { |
|
1035 check_method_loader_constraints(sel_method, resolved_klass, |
|
1036 sel_method->name(), sel_method->signature(), |
|
1037 current_klass, "method", CHECK); |
1052 } |
1038 } |
1053 } |
1039 } |
1054 |
1040 |
1055 // Check that the class of objectref (the receiver) is the current class or interface, |
1041 // Check that the class of objectref (the receiver) is the current class or interface, |
1056 // or a subtype of the current class or interface (the sender), otherwise invokespecial |
1042 // or a subtype of the current class or interface (the sender), otherwise invokespecial |