44 #include "runtime/reflection.hpp" |
44 #include "runtime/reflection.hpp" |
45 #include "runtime/reflectionUtils.hpp" |
45 #include "runtime/reflectionUtils.hpp" |
46 #include "runtime/signature.hpp" |
46 #include "runtime/signature.hpp" |
47 #include "runtime/vframe.hpp" |
47 #include "runtime/vframe.hpp" |
48 |
48 |
49 static void trace_class_resolution(Klass* to_class) { |
49 static void trace_class_resolution(const Klass* to_class) { |
50 ResourceMark rm; |
50 ResourceMark rm; |
51 int line_number = -1; |
51 int line_number = -1; |
52 const char * source_file = NULL; |
52 const char * source_file = NULL; |
53 Klass* caller = NULL; |
53 Klass* caller = NULL; |
54 JavaThread* jthread = JavaThread::current(); |
54 JavaThread* jthread = JavaThread::current(); |
298 THROW(vmSymbols::java_lang_IllegalArgumentException()); |
298 THROW(vmSymbols::java_lang_IllegalArgumentException()); |
299 } |
299 } |
300 } |
300 } |
301 } |
301 } |
302 |
302 |
303 |
303 static Klass* basic_type_mirror_to_arrayklass(oop basic_type_mirror, TRAPS) { |
304 Klass* Reflection::basic_type_mirror_to_arrayklass(oop basic_type_mirror, TRAPS) { |
|
305 assert(java_lang_Class::is_primitive(basic_type_mirror), "just checking"); |
304 assert(java_lang_Class::is_primitive(basic_type_mirror), "just checking"); |
306 BasicType type = java_lang_Class::primitive_type(basic_type_mirror); |
305 BasicType type = java_lang_Class::primitive_type(basic_type_mirror); |
307 if (type == T_VOID) { |
306 if (type == T_VOID) { |
308 THROW_0(vmSymbols::java_lang_IllegalArgumentException()); |
307 THROW_0(vmSymbols::java_lang_IllegalArgumentException()); |
309 } else { |
308 } |
|
309 else { |
310 return Universe::typeArrayKlassObj(type); |
310 return Universe::typeArrayKlassObj(type); |
311 } |
311 } |
312 } |
312 } |
313 |
313 |
314 |
314 #ifdef ASSERT |
315 oop Reflection:: basic_type_arrayklass_to_mirror(Klass* basic_type_arrayklass, TRAPS) { |
315 static oop basic_type_arrayklass_to_mirror(Klass* basic_type_arrayklass, TRAPS) { |
316 BasicType type = TypeArrayKlass::cast(basic_type_arrayklass)->element_type(); |
316 BasicType type = TypeArrayKlass::cast(basic_type_arrayklass)->element_type(); |
317 return Universe::java_mirror(type); |
317 return Universe::java_mirror(type); |
318 } |
318 } |
319 |
319 #endif |
320 |
320 |
321 arrayOop Reflection::reflect_new_array(oop element_mirror, jint length, TRAPS) { |
321 arrayOop Reflection::reflect_new_array(oop element_mirror, jint length, TRAPS) { |
322 if (element_mirror == NULL) { |
322 if (element_mirror == NULL) { |
323 THROW_0(vmSymbols::java_lang_NullPointerException()); |
323 THROW_0(vmSymbols::java_lang_NullPointerException()); |
324 } |
324 } |
408 assert(result == result2, "results must be consistent"); |
408 assert(result == result2, "results must be consistent"); |
409 #endif //ASSERT |
409 #endif //ASSERT |
410 return result; |
410 return result; |
411 } |
411 } |
412 |
412 |
413 |
413 static bool under_host_klass(const InstanceKlass* ik, const Klass* host_klass) { |
414 bool Reflection::verify_class_access(Klass* current_class, Klass* new_class, bool classloader_only) { |
414 DEBUG_ONLY(int inf_loop_check = 1000 * 1000 * 1000); |
|
415 for (;;) { |
|
416 const Klass* hc = (const Klass*)ik->host_klass(); |
|
417 if (hc == NULL) return false; |
|
418 if (hc == host_klass) return true; |
|
419 ik = InstanceKlass::cast(hc); |
|
420 |
|
421 // There's no way to make a host class loop short of patching memory. |
|
422 // Therefore there cannot be a loop here unless there's another bug. |
|
423 // Still, let's check for it. |
|
424 assert(--inf_loop_check > 0, "no host_klass loop"); |
|
425 } |
|
426 } |
|
427 |
|
428 static bool can_relax_access_check_for(const Klass* accessor, |
|
429 const Klass* accessee, |
|
430 bool classloader_only) { |
|
431 |
|
432 const InstanceKlass* accessor_ik = InstanceKlass::cast(accessor); |
|
433 const InstanceKlass* accessee_ik = InstanceKlass::cast(accessee); |
|
434 |
|
435 // If either is on the other's host_klass chain, access is OK, |
|
436 // because one is inside the other. |
|
437 if (under_host_klass(accessor_ik, accessee) || |
|
438 under_host_klass(accessee_ik, accessor)) |
|
439 return true; |
|
440 |
|
441 if ((RelaxAccessControlCheck && |
|
442 accessor_ik->major_version() < Verifier::NO_RELAX_ACCESS_CTRL_CHECK_VERSION && |
|
443 accessee_ik->major_version() < Verifier::NO_RELAX_ACCESS_CTRL_CHECK_VERSION) || |
|
444 (accessor_ik->major_version() < Verifier::STRICTER_ACCESS_CTRL_CHECK_VERSION && |
|
445 accessee_ik->major_version() < Verifier::STRICTER_ACCESS_CTRL_CHECK_VERSION)) { |
|
446 return classloader_only && |
|
447 Verifier::relax_verify_for(accessor_ik->class_loader()) && |
|
448 accessor_ik->protection_domain() == accessee_ik->protection_domain() && |
|
449 accessor_ik->class_loader() == accessee_ik->class_loader(); |
|
450 } |
|
451 |
|
452 return false; |
|
453 } |
|
454 |
|
455 bool Reflection::verify_class_access(const Klass* current_class, |
|
456 const Klass* new_class, |
|
457 bool classloader_only) { |
415 // Verify that current_class can access new_class. If the classloader_only |
458 // Verify that current_class can access new_class. If the classloader_only |
416 // flag is set, we automatically allow any accesses in which current_class |
459 // flag is set, we automatically allow any accesses in which current_class |
417 // doesn't have a classloader. |
460 // doesn't have a classloader. |
418 if ((current_class == NULL) || |
461 if ((current_class == NULL) || |
419 (current_class == new_class) || |
462 (current_class == new_class) || |
428 } |
471 } |
429 |
472 |
430 return can_relax_access_check_for(current_class, new_class, classloader_only); |
473 return can_relax_access_check_for(current_class, new_class, classloader_only); |
431 } |
474 } |
432 |
475 |
433 static bool under_host_klass(InstanceKlass* ik, Klass* host_klass) { |
476 bool Reflection::verify_field_access(const Klass* current_class, |
434 DEBUG_ONLY(int inf_loop_check = 1000 * 1000 * 1000); |
477 const Klass* resolved_class, |
435 for (;;) { |
478 const Klass* field_class, |
436 Klass* hc = (Klass*) ik->host_klass(); |
|
437 if (hc == NULL) return false; |
|
438 if (hc == host_klass) return true; |
|
439 ik = InstanceKlass::cast(hc); |
|
440 |
|
441 // There's no way to make a host class loop short of patching memory. |
|
442 // Therefore there cannot be a loop here unless there's another bug. |
|
443 // Still, let's check for it. |
|
444 assert(--inf_loop_check > 0, "no host_klass loop"); |
|
445 } |
|
446 } |
|
447 |
|
448 bool Reflection::can_relax_access_check_for( |
|
449 Klass* accessor, Klass* accessee, bool classloader_only) { |
|
450 InstanceKlass* accessor_ik = InstanceKlass::cast(accessor); |
|
451 InstanceKlass* accessee_ik = InstanceKlass::cast(accessee); |
|
452 |
|
453 // If either is on the other's host_klass chain, access is OK, |
|
454 // because one is inside the other. |
|
455 if (under_host_klass(accessor_ik, accessee) || |
|
456 under_host_klass(accessee_ik, accessor)) |
|
457 return true; |
|
458 |
|
459 if ((RelaxAccessControlCheck && |
|
460 accessor_ik->major_version() < Verifier::NO_RELAX_ACCESS_CTRL_CHECK_VERSION && |
|
461 accessee_ik->major_version() < Verifier::NO_RELAX_ACCESS_CTRL_CHECK_VERSION) || |
|
462 (accessor_ik->major_version() < Verifier::STRICTER_ACCESS_CTRL_CHECK_VERSION && |
|
463 accessee_ik->major_version() < Verifier::STRICTER_ACCESS_CTRL_CHECK_VERSION)) { |
|
464 return classloader_only && |
|
465 Verifier::relax_verify_for(accessor_ik->class_loader()) && |
|
466 accessor_ik->protection_domain() == accessee_ik->protection_domain() && |
|
467 accessor_ik->class_loader() == accessee_ik->class_loader(); |
|
468 } else { |
|
469 return false; |
|
470 } |
|
471 } |
|
472 |
|
473 bool Reflection::verify_field_access(Klass* current_class, |
|
474 Klass* resolved_class, |
|
475 Klass* field_class, |
|
476 AccessFlags access, |
479 AccessFlags access, |
477 bool classloader_only, |
480 bool classloader_only, |
478 bool protected_restriction) { |
481 bool protected_restriction) { |
479 // Verify that current_class can access a field of field_class, where that |
482 // Verify that current_class can access a field of field_class, where that |
480 // field's access bits are "access". We assume that we've already verified |
483 // field's access bits are "access". We assume that we've already verified |
492 (current_class == field_class) || |
495 (current_class == field_class) || |
493 access.is_public()) { |
496 access.is_public()) { |
494 return true; |
497 return true; |
495 } |
498 } |
496 |
499 |
497 Klass* host_class = current_class; |
500 const Klass* host_class = current_class; |
498 while (host_class->is_instance_klass() && |
501 while (host_class->is_instance_klass() && |
499 InstanceKlass::cast(host_class)->is_anonymous()) { |
502 InstanceKlass::cast(host_class)->is_anonymous()) { |
500 Klass* next_host_class = InstanceKlass::cast(host_class)->host_klass(); |
503 const Klass* next_host_class = InstanceKlass::cast(host_class)->host_klass(); |
501 if (next_host_class == NULL) break; |
504 if (next_host_class == NULL) break; |
502 host_class = next_host_class; |
505 host_class = next_host_class; |
503 } |
506 } |
504 if (host_class == field_class) { |
507 if (host_class == field_class) { |
505 return true; |
508 return true; |
533 |
536 |
534 return can_relax_access_check_for( |
537 return can_relax_access_check_for( |
535 current_class, field_class, classloader_only); |
538 current_class, field_class, classloader_only); |
536 } |
539 } |
537 |
540 |
538 |
541 bool Reflection::is_same_class_package(const Klass* class1, const Klass* class2) { |
539 bool Reflection::is_same_class_package(Klass* class1, Klass* class2) { |
|
540 return InstanceKlass::cast(class1)->is_same_class_package(class2); |
542 return InstanceKlass::cast(class1)->is_same_class_package(class2); |
541 } |
543 } |
542 |
|
543 bool Reflection::is_same_package_member(Klass* class1, Klass* class2, TRAPS) { |
|
544 return InstanceKlass::cast(class1)->is_same_package_member(class2, THREAD); |
|
545 } |
|
546 |
|
547 |
544 |
548 // Checks that the 'outer' klass has declared 'inner' as being an inner klass. If not, |
545 // Checks that the 'outer' klass has declared 'inner' as being an inner klass. If not, |
549 // throw an incompatible class change exception |
546 // throw an incompatible class change exception |
550 // If inner_is_member, require the inner to be a member of the outer. |
547 // If inner_is_member, require the inner to be a member of the outer. |
551 // If !inner_is_member, require the inner to be anonymous (a non-member). |
548 // If !inner_is_member, require the inner to be anonymous (a non-member). |
586 inner->external_name() |
583 inner->external_name() |
587 ); |
584 ); |
588 } |
585 } |
589 |
586 |
590 // Utility method converting a single SignatureStream element into java.lang.Class instance |
587 // Utility method converting a single SignatureStream element into java.lang.Class instance |
591 |
588 static oop get_mirror_from_signature(methodHandle method, |
592 oop get_mirror_from_signature(methodHandle method, SignatureStream* ss, TRAPS) { |
589 SignatureStream* ss, |
593 switch (ss->type()) { |
590 TRAPS) { |
594 default: |
591 |
595 assert(ss->type() != T_VOID || ss->at_return_type(), "T_VOID should only appear as return type"); |
592 |
596 return java_lang_Class::primitive_mirror(ss->type()); |
593 if (T_OBJECT == ss->type() || T_ARRAY == ss->type()) { |
597 case T_OBJECT: |
594 Symbol* name = ss->as_symbol(CHECK_NULL); |
598 case T_ARRAY: |
595 oop loader = method->method_holder()->class_loader(); |
599 Symbol* name = ss->as_symbol(CHECK_NULL); |
596 oop protection_domain = method->method_holder()->protection_domain(); |
600 oop loader = method->method_holder()->class_loader(); |
597 const Klass* k = SystemDictionary::resolve_or_fail(name, |
601 oop protection_domain = method->method_holder()->protection_domain(); |
598 Handle(THREAD, loader), |
602 Klass* k = SystemDictionary::resolve_or_fail( |
599 Handle(THREAD, protection_domain), |
603 name, |
600 true, |
604 Handle(THREAD, loader), |
601 CHECK_NULL); |
605 Handle(THREAD, protection_domain), |
602 if (TraceClassResolution) { |
606 true, CHECK_NULL); |
603 trace_class_resolution(k); |
607 if (TraceClassResolution) { |
604 } |
608 trace_class_resolution(k); |
605 return k->java_mirror(); |
609 } |
606 } |
610 return k->java_mirror(); |
607 |
611 }; |
608 assert(ss->type() != T_VOID || ss->at_return_type(), |
612 } |
609 "T_VOID should only appear as return type"); |
613 |
610 |
614 |
611 return java_lang_Class::primitive_mirror(ss->type()); |
615 objArrayHandle Reflection::get_parameter_types(const methodHandle& method, int parameter_count, oop* return_type, TRAPS) { |
612 } |
|
613 |
|
614 static objArrayHandle get_parameter_types(methodHandle method, |
|
615 int parameter_count, |
|
616 oop* return_type, |
|
617 TRAPS) { |
616 // Allocate array holding parameter types (java.lang.Class instances) |
618 // Allocate array holding parameter types (java.lang.Class instances) |
617 objArrayOop m = oopFactory::new_objArray(SystemDictionary::Class_klass(), parameter_count, CHECK_(objArrayHandle())); |
619 objArrayOop m = oopFactory::new_objArray(SystemDictionary::Class_klass(), parameter_count, CHECK_(objArrayHandle())); |
618 objArrayHandle mirrors (THREAD, m); |
620 objArrayHandle mirrors(THREAD, m); |
619 int index = 0; |
621 int index = 0; |
620 // Collect parameter types |
622 // Collect parameter types |
621 ResourceMark rm(THREAD); |
623 ResourceMark rm(THREAD); |
622 Symbol* signature = method->signature(); |
624 Symbol* signature = method->signature(); |
623 SignatureStream ss(signature); |
625 SignatureStream ss(signature); |
624 while (!ss.at_return_type()) { |
626 while (!ss.at_return_type()) { |
625 oop mirror = get_mirror_from_signature(method, &ss, CHECK_(objArrayHandle())); |
627 oop mirror = get_mirror_from_signature(method, &ss, CHECK_(objArrayHandle())); |
626 mirrors->obj_at_put(index++, mirror); |
628 mirrors->obj_at_put(index++, mirror); |
627 ss.next(); |
629 ss.next(); |
633 *return_type = get_mirror_from_signature(method, &ss, CHECK_(objArrayHandle())); |
635 *return_type = get_mirror_from_signature(method, &ss, CHECK_(objArrayHandle())); |
634 } |
636 } |
635 return mirrors; |
637 return mirrors; |
636 } |
638 } |
637 |
639 |
638 objArrayHandle Reflection::get_exception_types(const methodHandle& method, TRAPS) { |
640 static objArrayHandle get_exception_types(methodHandle method, TRAPS) { |
639 return method->resolved_checked_exceptions(THREAD); |
641 return method->resolved_checked_exceptions(THREAD); |
640 } |
642 } |
641 |
643 |
642 |
644 static Handle new_type(Symbol* signature, KlassHandle k, TRAPS) { |
643 Handle Reflection::new_type(Symbol* signature, KlassHandle k, TRAPS) { |
|
644 // Basic types |
645 // Basic types |
645 BasicType type = vmSymbols::signature_type(signature); |
646 BasicType type = vmSymbols::signature_type(signature); |
646 if (type != T_OBJECT) { |
647 if (type != T_OBJECT) { |
647 return Handle(THREAD, Universe::java_mirror(type)); |
648 return Handle(THREAD, Universe::java_mirror(type)); |
648 } |
649 } |
649 |
650 |
650 Klass* result = SystemDictionary::resolve_or_fail(signature, |
651 Klass* result = |
651 Handle(THREAD, k->class_loader()), |
652 SystemDictionary::resolve_or_fail(signature, |
652 Handle(THREAD, k->protection_domain()), |
653 Handle(THREAD, k->class_loader()), |
653 true, CHECK_(Handle())); |
654 Handle(THREAD, k->protection_domain()), |
|
655 true, CHECK_(Handle())); |
654 |
656 |
655 if (TraceClassResolution) { |
657 if (TraceClassResolution) { |
656 trace_class_resolution(result); |
658 trace_class_resolution(result); |
657 } |
659 } |
658 |
660 |
684 Symbol* method_name = method->name(); |
686 Symbol* method_name = method->name(); |
685 oop name_oop = StringTable::intern(method_name, CHECK_NULL); |
687 oop name_oop = StringTable::intern(method_name, CHECK_NULL); |
686 Handle name = Handle(THREAD, name_oop); |
688 Handle name = Handle(THREAD, name_oop); |
687 if (name == NULL) return NULL; |
689 if (name == NULL) return NULL; |
688 |
690 |
689 int modifiers = method->access_flags().as_int() & JVM_RECOGNIZED_METHOD_MODIFIERS; |
691 const int modifiers = method->access_flags().as_int() & JVM_RECOGNIZED_METHOD_MODIFIERS; |
690 |
692 |
691 Handle mh = java_lang_reflect_Method::create(CHECK_NULL); |
693 Handle mh = java_lang_reflect_Method::create(CHECK_NULL); |
692 |
694 |
693 java_lang_reflect_Method::set_clazz(mh(), holder->java_mirror()); |
695 java_lang_reflect_Method::set_clazz(mh(), holder->java_mirror()); |
694 java_lang_reflect_Method::set_slot(mh(), slot); |
696 java_lang_reflect_Method::set_slot(mh(), slot); |
736 if (parameter_types.is_null()) return NULL; |
738 if (parameter_types.is_null()) return NULL; |
737 |
739 |
738 objArrayHandle exception_types = get_exception_types(method, CHECK_NULL); |
740 objArrayHandle exception_types = get_exception_types(method, CHECK_NULL); |
739 if (exception_types.is_null()) return NULL; |
741 if (exception_types.is_null()) return NULL; |
740 |
742 |
741 int modifiers = method->access_flags().as_int() & JVM_RECOGNIZED_METHOD_MODIFIERS; |
743 const int modifiers = method->access_flags().as_int() & JVM_RECOGNIZED_METHOD_MODIFIERS; |
742 |
744 |
743 Handle ch = java_lang_reflect_Constructor::create(CHECK_NULL); |
745 Handle ch = java_lang_reflect_Constructor::create(CHECK_NULL); |
744 |
746 |
745 java_lang_reflect_Constructor::set_clazz(ch(), holder->java_mirror()); |
747 java_lang_reflect_Constructor::set_clazz(ch(), holder->java_mirror()); |
746 java_lang_reflect_Constructor::set_slot(ch(), slot); |
748 java_lang_reflect_Constructor::set_slot(ch(), slot); |
820 java_lang_reflect_Parameter::set_index(rh(), index); |
822 java_lang_reflect_Parameter::set_index(rh(), index); |
821 return rh(); |
823 return rh(); |
822 } |
824 } |
823 |
825 |
824 |
826 |
825 methodHandle Reflection::resolve_interface_call(instanceKlassHandle klass, const methodHandle& method, |
827 static methodHandle resolve_interface_call(instanceKlassHandle klass, |
826 KlassHandle recv_klass, Handle receiver, TRAPS) { |
828 const methodHandle& method, |
|
829 KlassHandle recv_klass, |
|
830 Handle receiver, |
|
831 TRAPS) { |
|
832 |
827 assert(!method.is_null() , "method should not be null"); |
833 assert(!method.is_null() , "method should not be null"); |
828 |
834 |
829 CallInfo info; |
835 CallInfo info; |
830 Symbol* signature = method->signature(); |
836 Symbol* signature = method->signature(); |
831 Symbol* name = method->name(); |
837 Symbol* name = method->name(); |
834 true, |
840 true, |
835 CHECK_(methodHandle())); |
841 CHECK_(methodHandle())); |
836 return info.selected_method(); |
842 return info.selected_method(); |
837 } |
843 } |
838 |
844 |
839 |
845 // Conversion |
840 oop Reflection::invoke(instanceKlassHandle klass, const methodHandle& reflected_method, |
846 static BasicType basic_type_mirror_to_basic_type(oop basic_type_mirror, TRAPS) { |
841 Handle receiver, bool override, objArrayHandle ptypes, |
847 assert(java_lang_Class::is_primitive(basic_type_mirror), |
842 BasicType rtype, objArrayHandle args, bool is_method_invoke, TRAPS) { |
848 "just checking"); |
|
849 return java_lang_Class::primitive_type(basic_type_mirror); |
|
850 } |
|
851 |
|
852 // Narrowing of basic types. Used to create correct jvalues for |
|
853 // boolean, byte, char and short return return values from interpreter |
|
854 // which are returned as ints. Throws IllegalArgumentException. |
|
855 static void narrow(jvalue* value, BasicType narrow_type, TRAPS) { |
|
856 switch (narrow_type) { |
|
857 case T_BOOLEAN: |
|
858 value->z = (jboolean)value->i; |
|
859 return; |
|
860 case T_BYTE: |
|
861 value->b = (jbyte)value->i; |
|
862 return; |
|
863 case T_CHAR: |
|
864 value->c = (jchar)value->i; |
|
865 return; |
|
866 case T_SHORT: |
|
867 value->s = (jshort)value->i; |
|
868 return; |
|
869 default: |
|
870 break; // fail |
|
871 } |
|
872 THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), "argument type mismatch"); |
|
873 } |
|
874 |
|
875 |
|
876 // Method call (shared by invoke_method and invoke_constructor) |
|
877 static oop invoke(instanceKlassHandle klass, |
|
878 methodHandle reflected_method, |
|
879 Handle receiver, |
|
880 bool override, |
|
881 objArrayHandle ptypes, |
|
882 BasicType rtype, |
|
883 objArrayHandle args, |
|
884 bool is_method_invoke, |
|
885 TRAPS) { |
|
886 |
843 ResourceMark rm(THREAD); |
887 ResourceMark rm(THREAD); |
844 |
888 |
845 methodHandle method; // actual method to invoke |
889 methodHandle method; // actual method to invoke |
846 KlassHandle target_klass; // target klass, receiver's klass for non-static |
890 KlassHandle target_klass; // target klass, receiver's klass for non-static |
847 |
891 |
874 // |
918 // |
875 // Match resolution errors with those thrown due to reflection inlining |
919 // Match resolution errors with those thrown due to reflection inlining |
876 // Linktime resolution & IllegalAccessCheck already done by Class.getMethod() |
920 // Linktime resolution & IllegalAccessCheck already done by Class.getMethod() |
877 method = resolve_interface_call(klass, reflected_method, target_klass, receiver, THREAD); |
921 method = resolve_interface_call(klass, reflected_method, target_klass, receiver, THREAD); |
878 if (HAS_PENDING_EXCEPTION) { |
922 if (HAS_PENDING_EXCEPTION) { |
879 // Method resolution threw an exception; wrap it in an InvocationTargetException |
923 // Method resolution threw an exception; wrap it in an InvocationTargetException |
880 oop resolution_exception = PENDING_EXCEPTION; |
924 oop resolution_exception = PENDING_EXCEPTION; |
881 CLEAR_PENDING_EXCEPTION; |
925 CLEAR_PENDING_EXCEPTION; |
882 // JVMTI has already reported the pending exception |
926 // JVMTI has already reported the pending exception |
883 // JVMTI internal flag reset is needed in order to report InvocationTargetException |
927 // JVMTI internal flag reset is needed in order to report InvocationTargetException |
884 if (THREAD->is_Java_thread()) { |
928 if (THREAD->is_Java_thread()) { |
885 JvmtiExport::clear_detected_exception((JavaThread*) THREAD); |
929 JvmtiExport::clear_detected_exception((JavaThread*)THREAD); |
886 } |
930 } |
887 JavaCallArguments args(Handle(THREAD, resolution_exception)); |
931 JavaCallArguments args(Handle(THREAD, resolution_exception)); |
888 THROW_ARG_0(vmSymbols::java_lang_reflect_InvocationTargetException(), |
932 THROW_ARG_0(vmSymbols::java_lang_reflect_InvocationTargetException(), |
889 vmSymbols::throwable_void_signature(), |
933 vmSymbols::throwable_void_signature(), |
890 &args); |
934 &args); |
891 } |
935 } |
892 } else { |
936 } else { |
893 // if the method can be overridden, we resolve using the vtable index. |
937 // if the method can be overridden, we resolve using the vtable index. |
894 assert(!reflected_method->has_itable_index(), ""); |
938 assert(!reflected_method->has_itable_index(), ""); |
895 int index = reflected_method->vtable_index(); |
939 int index = reflected_method->vtable_index(); |
904 // Check for abstract methods as well |
948 // Check for abstract methods as well |
905 if (method->is_abstract()) { |
949 if (method->is_abstract()) { |
906 // new default: 6531596 |
950 // new default: 6531596 |
907 ResourceMark rm(THREAD); |
951 ResourceMark rm(THREAD); |
908 Handle h_origexception = Exceptions::new_exception(THREAD, |
952 Handle h_origexception = Exceptions::new_exception(THREAD, |
909 vmSymbols::java_lang_AbstractMethodError(), |
953 vmSymbols::java_lang_AbstractMethodError(), |
910 Method::name_and_sig_as_C_string(target_klass(), |
954 Method::name_and_sig_as_C_string(target_klass(), |
911 method->name(), |
955 method->name(), |
912 method->signature())); |
956 method->signature())); |
913 JavaCallArguments args(h_origexception); |
957 JavaCallArguments args(h_origexception); |
914 THROW_ARG_0(vmSymbols::java_lang_reflect_InvocationTargetException(), |
958 THROW_ARG_0(vmSymbols::java_lang_reflect_InvocationTargetException(), |
915 vmSymbols::throwable_void_signature(), |
959 vmSymbols::throwable_void_signature(), |
916 &args); |
960 &args); |
917 } |
961 } |
924 // an internal vtable bug. If you ever get this please let Karen know. |
968 // an internal vtable bug. If you ever get this please let Karen know. |
925 if (method.is_null()) { |
969 if (method.is_null()) { |
926 ResourceMark rm(THREAD); |
970 ResourceMark rm(THREAD); |
927 THROW_MSG_0(vmSymbols::java_lang_NoSuchMethodError(), |
971 THROW_MSG_0(vmSymbols::java_lang_NoSuchMethodError(), |
928 Method::name_and_sig_as_C_string(klass(), |
972 Method::name_and_sig_as_C_string(klass(), |
929 reflected_method->name(), |
973 reflected_method->name(), |
930 reflected_method->signature())); |
974 reflected_method->signature())); |
931 } |
975 } |
932 |
976 |
933 assert(ptypes->is_objArray(), "just checking"); |
977 assert(ptypes->is_objArray(), "just checking"); |
934 int args_len = args.is_null() ? 0 : args->length(); |
978 int args_len = args.is_null() ? 0 : args->length(); |
935 // Check number of arguments |
979 // Check number of arguments |
936 if (ptypes->length() != args_len) { |
980 if (ptypes->length() != args_len) { |
937 THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(), "wrong number of arguments"); |
981 THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(), |
|
982 "wrong number of arguments"); |
938 } |
983 } |
939 |
984 |
940 // Create object to contain parameters for the JavaCall |
985 // Create object to contain parameters for the JavaCall |
941 JavaCallArguments java_args(method->size_of_parameters()); |
986 JavaCallArguments java_args(method->size_of_parameters()); |
942 |
987 |
948 oop type_mirror = ptypes->obj_at(i); |
993 oop type_mirror = ptypes->obj_at(i); |
949 oop arg = args->obj_at(i); |
994 oop arg = args->obj_at(i); |
950 if (java_lang_Class::is_primitive(type_mirror)) { |
995 if (java_lang_Class::is_primitive(type_mirror)) { |
951 jvalue value; |
996 jvalue value; |
952 BasicType ptype = basic_type_mirror_to_basic_type(type_mirror, CHECK_NULL); |
997 BasicType ptype = basic_type_mirror_to_basic_type(type_mirror, CHECK_NULL); |
953 BasicType atype = unbox_for_primitive(arg, &value, CHECK_NULL); |
998 BasicType atype = Reflection::unbox_for_primitive(arg, &value, CHECK_NULL); |
954 if (ptype != atype) { |
999 if (ptype != atype) { |
955 widen(&value, atype, ptype, CHECK_NULL); |
1000 Reflection::widen(&value, atype, ptype, CHECK_NULL); |
956 } |
1001 } |
957 switch (ptype) { |
1002 switch (ptype) { |
958 case T_BOOLEAN: java_args.push_int(value.z); break; |
1003 case T_BOOLEAN: java_args.push_int(value.z); break; |
959 case T_CHAR: java_args.push_int(value.c); break; |
1004 case T_CHAR: java_args.push_int(value.c); break; |
960 case T_BYTE: java_args.push_int(value.b); break; |
1005 case T_BYTE: java_args.push_int(value.b); break; |
968 } |
1013 } |
969 } else { |
1014 } else { |
970 if (arg != NULL) { |
1015 if (arg != NULL) { |
971 Klass* k = java_lang_Class::as_Klass(type_mirror); |
1016 Klass* k = java_lang_Class::as_Klass(type_mirror); |
972 if (!arg->is_a(k)) { |
1017 if (!arg->is_a(k)) { |
973 THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(), "argument type mismatch"); |
1018 THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(), |
|
1019 "argument type mismatch"); |
974 } |
1020 } |
975 } |
1021 } |
976 Handle arg_handle(THREAD, arg); // Create handle for argument |
1022 Handle arg_handle(THREAD, arg); // Create handle for argument |
977 java_args.push_oop(arg_handle); // Push handle |
1023 java_args.push_oop(arg_handle); // Push handle |
978 } |
1024 } |
979 } |
1025 } |
980 |
1026 |
981 assert(java_args.size_of_parameters() == method->size_of_parameters(), "just checking"); |
1027 assert(java_args.size_of_parameters() == method->size_of_parameters(), |
|
1028 "just checking"); |
982 |
1029 |
983 // All oops (including receiver) is passed in as Handles. An potential oop is returned as an |
1030 // All oops (including receiver) is passed in as Handles. An potential oop is returned as an |
984 // oop (i.e., NOT as an handle) |
1031 // oop (i.e., NOT as an handle) |
985 JavaValue result(rtype); |
1032 JavaValue result(rtype); |
986 JavaCalls::call(&result, method, &java_args, THREAD); |
1033 JavaCalls::call(&result, method, &java_args, THREAD); |
990 oop target_exception = PENDING_EXCEPTION; |
1037 oop target_exception = PENDING_EXCEPTION; |
991 CLEAR_PENDING_EXCEPTION; |
1038 CLEAR_PENDING_EXCEPTION; |
992 // JVMTI has already reported the pending exception |
1039 // JVMTI has already reported the pending exception |
993 // JVMTI internal flag reset is needed in order to report InvocationTargetException |
1040 // JVMTI internal flag reset is needed in order to report InvocationTargetException |
994 if (THREAD->is_Java_thread()) { |
1041 if (THREAD->is_Java_thread()) { |
995 JvmtiExport::clear_detected_exception((JavaThread*) THREAD); |
1042 JvmtiExport::clear_detected_exception((JavaThread*)THREAD); |
996 } |
1043 } |
997 |
1044 |
998 JavaCallArguments args(Handle(THREAD, target_exception)); |
1045 JavaCallArguments args(Handle(THREAD, target_exception)); |
999 THROW_ARG_0(vmSymbols::java_lang_reflect_InvocationTargetException(), |
1046 THROW_ARG_0(vmSymbols::java_lang_reflect_InvocationTargetException(), |
1000 vmSymbols::throwable_void_signature(), |
1047 vmSymbols::throwable_void_signature(), |
1001 &args); |
1048 &args); |
1002 } else { |
1049 } else { |
1003 if (rtype == T_BOOLEAN || rtype == T_BYTE || rtype == T_CHAR || rtype == T_SHORT) { |
1050 if (rtype == T_BOOLEAN || rtype == T_BYTE || rtype == T_CHAR || rtype == T_SHORT) { |
1004 narrow((jvalue*) result.get_value_addr(), rtype, CHECK_NULL); |
1051 narrow((jvalue*)result.get_value_addr(), rtype, CHECK_NULL); |
1005 } |
1052 } |
1006 return box((jvalue*) result.get_value_addr(), rtype, THREAD); |
1053 return Reflection::box((jvalue*)result.get_value_addr(), rtype, THREAD); |
1007 } |
1054 } |
1008 } |
|
1009 |
|
1010 |
|
1011 void Reflection::narrow(jvalue* value, BasicType narrow_type, TRAPS) { |
|
1012 switch (narrow_type) { |
|
1013 case T_BOOLEAN: |
|
1014 value->z = (jboolean) value->i; |
|
1015 return; |
|
1016 case T_BYTE: |
|
1017 value->b = (jbyte) value->i; |
|
1018 return; |
|
1019 case T_CHAR: |
|
1020 value->c = (jchar) value->i; |
|
1021 return; |
|
1022 case T_SHORT: |
|
1023 value->s = (jshort) value->i; |
|
1024 return; |
|
1025 default: |
|
1026 break; // fail |
|
1027 } |
|
1028 THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), "argument type mismatch"); |
|
1029 } |
|
1030 |
|
1031 |
|
1032 BasicType Reflection::basic_type_mirror_to_basic_type(oop basic_type_mirror, TRAPS) { |
|
1033 assert(java_lang_Class::is_primitive(basic_type_mirror), "just checking"); |
|
1034 return java_lang_Class::primitive_type(basic_type_mirror); |
|
1035 } |
1055 } |
1036 |
1056 |
1037 // This would be nicer if, say, java.lang.reflect.Method was a subclass |
1057 // This would be nicer if, say, java.lang.reflect.Method was a subclass |
1038 // of java.lang.reflect.Constructor |
1058 // of java.lang.reflect.Constructor |
1039 |
1059 |