23 */
24
25 #include "precompiled.hpp"
26 #include "jvm.h"
27 #include "classfile/javaClasses.inline.hpp"
28 #include "classfile/moduleEntry.hpp"
29 #include "classfile/packageEntry.hpp"
30 #include "classfile/stringTable.hpp"
31 #include "classfile/systemDictionary.hpp"
32 #include "classfile/verifier.hpp"
33 #include "classfile/vmSymbols.hpp"
34 #include "interpreter/linkResolver.hpp"
35 #include "logging/log.hpp"
36 #include "memory/oopFactory.hpp"
37 #include "memory/resourceArea.hpp"
38 #include "memory/universe.hpp"
39 #include "oops/instanceKlass.hpp"
40 #include "oops/objArrayKlass.hpp"
41 #include "oops/objArrayOop.inline.hpp"
42 #include "oops/oop.inline.hpp"
43 #include "oops/typeArrayOop.inline.hpp"
44 #include "prims/jvmtiExport.hpp"
45 #include "runtime/arguments.hpp"
46 #include "runtime/fieldDescriptor.inline.hpp"
47 #include "runtime/handles.inline.hpp"
48 #include "runtime/javaCalls.hpp"
49 #include "runtime/reflection.hpp"
50 #include "runtime/reflectionUtils.hpp"
51 #include "runtime/signature.hpp"
52 #include "runtime/thread.inline.hpp"
53 #include "runtime/vframe.inline.hpp"
54
55 static void trace_class_resolution(const Klass* to_class) {
56 ResourceMark rm;
57 int line_number = -1;
58 const char * source_file = NULL;
59 Klass* caller = NULL;
60 JavaThread* jthread = JavaThread::current();
61 if (jthread->has_last_Java_frame()) {
62 vframeStream vfst(jthread);
63 // skip over any frames belonging to java.lang.Class
64 while (!vfst.at_end() &&
65 vfst.method()->method_holder()->name() == vmSymbols::java_lang_Class()) {
66 vfst.next();
67 }
68 if (!vfst.at_end()) {
69 // this frame is a likely suspect
70 caller = vfst.method()->method_holder();
71 line_number = vfst.method()->line_number_from_bci(vfst.bci());
72 Symbol* s = vfst.method()->method_holder()->source_file_name();
73 if (s != NULL) {
75 }
76 }
77 }
78 if (caller != NULL) {
79 const char * from = caller->external_name();
80 const char * to = to_class->external_name();
81 // print in a single call to reduce interleaving between threads
82 if (source_file != NULL) {
83 log_debug(class, resolve)("%s %s %s:%d (reflection)", from, to, source_file, line_number);
84 } else {
85 log_debug(class, resolve)("%s %s (reflection)", from, to);
86 }
87 }
88 }
89
90
91 oop Reflection::box(jvalue* value, BasicType type, TRAPS) {
92 if (type == T_VOID) {
93 return NULL;
94 }
95 if (type == T_OBJECT || type == T_ARRAY) {
96 // regular objects are not boxed
97 return (oop) value->l;
98 }
99 oop result = java_lang_boxing_object::create(type, value, CHECK_NULL);
100 if (result == NULL) {
101 THROW_(vmSymbols::java_lang_IllegalArgumentException(), result);
102 }
103 return result;
104 }
105
106
107 BasicType Reflection::unbox_for_primitive(oop box, jvalue* value, TRAPS) {
108 if (box == NULL) {
109 THROW_(vmSymbols::java_lang_IllegalArgumentException(), T_ILLEGAL);
110 }
111 return java_lang_boxing_object::get_value(box, value);
112 }
113
114 BasicType Reflection::unbox_for_regular_object(oop box, jvalue* value) {
115 // Note: box is really the unboxed oop. It might even be a Short, etc.!
325 else {
326 return Universe::typeArrayKlassObj(type);
327 }
328 }
329
330 arrayOop Reflection::reflect_new_array(oop element_mirror, jint length, TRAPS) {
331 if (element_mirror == NULL) {
332 THROW_0(vmSymbols::java_lang_NullPointerException());
333 }
334 if (length < 0) {
335 THROW_MSG_0(vmSymbols::java_lang_NegativeArraySizeException(), err_msg("%d", length));
336 }
337 if (java_lang_Class::is_primitive(element_mirror)) {
338 Klass* tak = basic_type_mirror_to_arrayklass(element_mirror, CHECK_NULL);
339 return TypeArrayKlass::cast(tak)->allocate(length, THREAD);
340 } else {
341 Klass* k = java_lang_Class::as_Klass(element_mirror);
342 if (k->is_array_klass() && ArrayKlass::cast(k)->dimension() >= MAX_DIM) {
343 THROW_0(vmSymbols::java_lang_IllegalArgumentException());
344 }
345 return oopFactory::new_objArray(k, length, THREAD);
346 }
347 }
348
349
350 arrayOop Reflection::reflect_new_multi_array(oop element_mirror, typeArrayOop dim_array, TRAPS) {
351 assert(dim_array->is_typeArray(), "just checking");
352 assert(TypeArrayKlass::cast(dim_array->klass())->element_type() == T_INT, "just checking");
353
354 if (element_mirror == NULL) {
355 THROW_0(vmSymbols::java_lang_NullPointerException());
356 }
357
358 int len = dim_array->length();
359 if (len <= 0 || len > MAX_DIM) {
360 THROW_0(vmSymbols::java_lang_IllegalArgumentException());
361 }
362
363 jint dimensions[MAX_DIM]; // C array copy of intArrayOop
364 for (int i = 0; i < len; i++) {
365 int d = dim_array->int_at(i);
733 if (!inner_is_member && ioff != 0 && ooff == 0 &&
734 cp->klass_name_at_matches(inner, ioff)) {
735 Klass* i = cp->klass_at(ioff, CHECK);
736 if (i == inner) {
737 return;
738 }
739 }
740 }
741
742 // 'inner' not declared as an inner klass in outer
743 ResourceMark rm(THREAD);
744 Exceptions::fthrow(
745 THREAD_AND_LOCATION,
746 vmSymbols::java_lang_IncompatibleClassChangeError(),
747 "%s and %s disagree on InnerClasses attribute",
748 outer->external_name(),
749 inner->external_name()
750 );
751 }
752
753 // Utility method converting a single SignatureStream element into java.lang.Class instance
754 static oop get_mirror_from_signature(const methodHandle& method,
755 SignatureStream* ss,
756 TRAPS) {
757
758
759 if (T_OBJECT == ss->type() || T_ARRAY == ss->type()) {
760 Symbol* name = ss->as_symbol(CHECK_NULL);
761 oop loader = method->method_holder()->class_loader();
762 oop protection_domain = method->method_holder()->protection_domain();
763 const Klass* k = SystemDictionary::resolve_or_fail(name,
764 Handle(THREAD, loader),
765 Handle(THREAD, protection_domain),
766 true,
767 CHECK_NULL);
768 if (log_is_enabled(Debug, class, resolve)) {
769 trace_class_resolution(k);
770 }
771 return k->java_mirror();
772 }
773
774 assert(ss->type() != T_VOID || ss->at_return_type(),
775 "T_VOID should only appear as return type");
776
777 return java_lang_Class::primitive_mirror(ss->type());
778 }
779
780 static objArrayHandle get_parameter_types(const methodHandle& method,
781 int parameter_count,
782 oop* return_type,
783 TRAPS) {
784 // Allocate array holding parameter types (java.lang.Class instances)
785 objArrayOop m = oopFactory::new_objArray(SystemDictionary::Class_klass(), parameter_count, CHECK_(objArrayHandle()));
786 objArrayHandle mirrors(THREAD, m);
787 int index = 0;
788 // Collect parameter types
789 ResourceMark rm(THREAD);
790 Symbol* signature = method->signature();
791 SignatureStream ss(signature);
792 while (!ss.at_return_type()) {
793 oop mirror = get_mirror_from_signature(method, &ss, CHECK_(objArrayHandle()));
794 mirrors->obj_at_put(index++, mirror);
795 ss.next();
796 }
797 assert(index == parameter_count, "invalid parameter count");
798 if (return_type != NULL) {
799 // Collect return type as well
800 assert(ss.at_return_type(), "return type should be present");
801 *return_type = get_mirror_from_signature(method, &ss, CHECK_(objArrayHandle()));
802 }
803 return mirrors;
804 }
805
806 static objArrayHandle get_exception_types(const methodHandle& method, TRAPS) {
807 return method->resolved_checked_exceptions(THREAD);
808 }
809
810 static Handle new_type(Symbol* signature, Klass* k, TRAPS) {
811 // Basic types
812 BasicType type = vmSymbols::signature_type(signature);
813 if (type != T_OBJECT) {
814 return Handle(THREAD, Universe::java_mirror(type));
815 }
816
817 Klass* result =
818 SystemDictionary::resolve_or_fail(signature,
819 Handle(THREAD, k->class_loader()),
820 Handle(THREAD, k->protection_domain()),
821 true, CHECK_(Handle()));
822
823 if (log_is_enabled(Debug, class, resolve)) {
824 trace_class_resolution(result);
825 }
826
827 oop nt = result->java_mirror();
828 return Handle(THREAD, nt);
829 }
830
831
832 oop Reflection::new_method(const methodHandle& method, bool for_constant_pool_access, TRAPS) {
833 // Allow sun.reflect.ConstantPool to refer to <clinit> methods as java.lang.reflect.Methods.
834 assert(!method()->is_initializer() ||
835 (for_constant_pool_access && method()->is_static()),
836 "should call new_constructor instead");
837 InstanceKlass* holder = method->method_holder();
838 int slot = method->method_idnum();
839
840 Symbol* signature = method->signature();
841 int parameter_count = ArgumentCount(signature).size();
842 oop return_type_oop = NULL;
843 objArrayHandle parameter_types = get_parameter_types(method, parameter_count, &return_type_oop, CHECK_NULL);
844 if (parameter_types.is_null() || return_type_oop == NULL) return NULL;
845
846 Handle return_type(THREAD, return_type_oop);
847
915 an_oop = Annotations::make_java_array(method->parameter_annotations(), CHECK_NULL);
916 java_lang_reflect_Constructor::set_parameter_annotations(ch(), an_oop);
917 return ch();
918 }
919
920
921 oop Reflection::new_field(fieldDescriptor* fd, TRAPS) {
922 Symbol* field_name = fd->name();
923 oop name_oop = StringTable::intern(field_name, CHECK_NULL);
924 Handle name = Handle(THREAD, name_oop);
925 Symbol* signature = fd->signature();
926 InstanceKlass* holder = fd->field_holder();
927 Handle type = new_type(signature, holder, CHECK_NULL);
928 Handle rh = java_lang_reflect_Field::create(CHECK_NULL);
929
930 java_lang_reflect_Field::set_clazz(rh(), fd->field_holder()->java_mirror());
931 java_lang_reflect_Field::set_slot(rh(), fd->index());
932 java_lang_reflect_Field::set_name(rh(), name());
933 java_lang_reflect_Field::set_type(rh(), type());
934 // Note the ACC_ANNOTATION bit, which is a per-class access flag, is never set here.
935 java_lang_reflect_Field::set_modifiers(rh(), fd->access_flags().as_int() & JVM_RECOGNIZED_FIELD_MODIFIERS);
936 java_lang_reflect_Field::set_override(rh(), false);
937 if (fd->has_generic_signature()) {
938 Symbol* gs = fd->generic_signature();
939 Handle sig = java_lang_String::create_from_symbol(gs, CHECK_NULL);
940 java_lang_reflect_Field::set_signature(rh(), sig());
941 }
942 typeArrayOop an_oop = Annotations::make_java_array(fd->annotations(), CHECK_NULL);
943 java_lang_reflect_Field::set_annotations(rh(), an_oop);
944 return rh();
945 }
946
947 oop Reflection::new_parameter(Handle method, int index, Symbol* sym,
948 int flags, TRAPS) {
949
950 Handle rh = java_lang_reflect_Parameter::create(CHECK_NULL);
951
952 if(NULL != sym) {
953 Handle name = java_lang_String::create_from_symbol(sym, CHECK_NULL);
954 java_lang_reflect_Parameter::set_name(rh(), name());
955 } else {
1186 if (rtype == T_BOOLEAN || rtype == T_BYTE || rtype == T_CHAR || rtype == T_SHORT) {
1187 narrow((jvalue*)result.get_value_addr(), rtype, CHECK_NULL);
1188 }
1189 return Reflection::box((jvalue*)result.get_value_addr(), rtype, THREAD);
1190 }
1191 }
1192
1193 // This would be nicer if, say, java.lang.reflect.Method was a subclass
1194 // of java.lang.reflect.Constructor
1195
1196 oop Reflection::invoke_method(oop method_mirror, Handle receiver, objArrayHandle args, TRAPS) {
1197 oop mirror = java_lang_reflect_Method::clazz(method_mirror);
1198 int slot = java_lang_reflect_Method::slot(method_mirror);
1199 bool override = java_lang_reflect_Method::override(method_mirror) != 0;
1200 objArrayHandle ptypes(THREAD, objArrayOop(java_lang_reflect_Method::parameter_types(method_mirror)));
1201
1202 oop return_type_mirror = java_lang_reflect_Method::return_type(method_mirror);
1203 BasicType rtype;
1204 if (java_lang_Class::is_primitive(return_type_mirror)) {
1205 rtype = basic_type_mirror_to_basic_type(return_type_mirror, CHECK_NULL);
1206 } else {
1207 rtype = T_OBJECT;
1208 }
1209
1210 InstanceKlass* klass = InstanceKlass::cast(java_lang_Class::as_Klass(mirror));
1211 Method* m = klass->method_with_idnum(slot);
1212 if (m == NULL) {
1213 THROW_MSG_0(vmSymbols::java_lang_InternalError(), "invoke");
1214 }
1215 methodHandle method(THREAD, m);
1216
1217 return invoke(klass, method, receiver, override, ptypes, rtype, args, true, THREAD);
1218 }
1219
1220
1221 oop Reflection::invoke_constructor(oop constructor_mirror, objArrayHandle args, TRAPS) {
1222 oop mirror = java_lang_reflect_Constructor::clazz(constructor_mirror);
1223 int slot = java_lang_reflect_Constructor::slot(constructor_mirror);
1224 bool override = java_lang_reflect_Constructor::override(constructor_mirror) != 0;
1225 objArrayHandle ptypes(THREAD, objArrayOop(java_lang_reflect_Constructor::parameter_types(constructor_mirror)));
|
23 */
24
25 #include "precompiled.hpp"
26 #include "jvm.h"
27 #include "classfile/javaClasses.inline.hpp"
28 #include "classfile/moduleEntry.hpp"
29 #include "classfile/packageEntry.hpp"
30 #include "classfile/stringTable.hpp"
31 #include "classfile/systemDictionary.hpp"
32 #include "classfile/verifier.hpp"
33 #include "classfile/vmSymbols.hpp"
34 #include "interpreter/linkResolver.hpp"
35 #include "logging/log.hpp"
36 #include "memory/oopFactory.hpp"
37 #include "memory/resourceArea.hpp"
38 #include "memory/universe.hpp"
39 #include "oops/instanceKlass.hpp"
40 #include "oops/objArrayKlass.hpp"
41 #include "oops/objArrayOop.inline.hpp"
42 #include "oops/oop.inline.hpp"
43 #include "oops/valueKlass.hpp"
44 #include "oops/typeArrayOop.inline.hpp"
45 #include "prims/jvmtiExport.hpp"
46 #include "runtime/arguments.hpp"
47 #include "runtime/fieldDescriptor.inline.hpp"
48 #include "runtime/handles.inline.hpp"
49 #include "runtime/javaCalls.hpp"
50 #include "runtime/reflection.hpp"
51 #include "runtime/reflectionUtils.hpp"
52 #include "runtime/signature.hpp"
53 #include "runtime/thread.inline.hpp"
54 #include "runtime/vframe.inline.hpp"
55 #include "utilities/globalDefinitions.hpp"
56
57 static void trace_class_resolution(const Klass* to_class) {
58 ResourceMark rm;
59 int line_number = -1;
60 const char * source_file = NULL;
61 Klass* caller = NULL;
62 JavaThread* jthread = JavaThread::current();
63 if (jthread->has_last_Java_frame()) {
64 vframeStream vfst(jthread);
65 // skip over any frames belonging to java.lang.Class
66 while (!vfst.at_end() &&
67 vfst.method()->method_holder()->name() == vmSymbols::java_lang_Class()) {
68 vfst.next();
69 }
70 if (!vfst.at_end()) {
71 // this frame is a likely suspect
72 caller = vfst.method()->method_holder();
73 line_number = vfst.method()->line_number_from_bci(vfst.bci());
74 Symbol* s = vfst.method()->method_holder()->source_file_name();
75 if (s != NULL) {
77 }
78 }
79 }
80 if (caller != NULL) {
81 const char * from = caller->external_name();
82 const char * to = to_class->external_name();
83 // print in a single call to reduce interleaving between threads
84 if (source_file != NULL) {
85 log_debug(class, resolve)("%s %s %s:%d (reflection)", from, to, source_file, line_number);
86 } else {
87 log_debug(class, resolve)("%s %s (reflection)", from, to);
88 }
89 }
90 }
91
92
93 oop Reflection::box(jvalue* value, BasicType type, TRAPS) {
94 if (type == T_VOID) {
95 return NULL;
96 }
97 if (type == T_OBJECT || type == T_ARRAY || type == T_VALUETYPE) {
98 // regular objects are not boxed
99 return (oop) value->l;
100 }
101 oop result = java_lang_boxing_object::create(type, value, CHECK_NULL);
102 if (result == NULL) {
103 THROW_(vmSymbols::java_lang_IllegalArgumentException(), result);
104 }
105 return result;
106 }
107
108
109 BasicType Reflection::unbox_for_primitive(oop box, jvalue* value, TRAPS) {
110 if (box == NULL) {
111 THROW_(vmSymbols::java_lang_IllegalArgumentException(), T_ILLEGAL);
112 }
113 return java_lang_boxing_object::get_value(box, value);
114 }
115
116 BasicType Reflection::unbox_for_regular_object(oop box, jvalue* value) {
117 // Note: box is really the unboxed oop. It might even be a Short, etc.!
327 else {
328 return Universe::typeArrayKlassObj(type);
329 }
330 }
331
332 arrayOop Reflection::reflect_new_array(oop element_mirror, jint length, TRAPS) {
333 if (element_mirror == NULL) {
334 THROW_0(vmSymbols::java_lang_NullPointerException());
335 }
336 if (length < 0) {
337 THROW_MSG_0(vmSymbols::java_lang_NegativeArraySizeException(), err_msg("%d", length));
338 }
339 if (java_lang_Class::is_primitive(element_mirror)) {
340 Klass* tak = basic_type_mirror_to_arrayklass(element_mirror, CHECK_NULL);
341 return TypeArrayKlass::cast(tak)->allocate(length, THREAD);
342 } else {
343 Klass* k = java_lang_Class::as_Klass(element_mirror);
344 if (k->is_array_klass() && ArrayKlass::cast(k)->dimension() >= MAX_DIM) {
345 THROW_0(vmSymbols::java_lang_IllegalArgumentException());
346 }
347 return oopFactory::new_array(k, length, THREAD);
348 }
349 }
350
351
352 arrayOop Reflection::reflect_new_multi_array(oop element_mirror, typeArrayOop dim_array, TRAPS) {
353 assert(dim_array->is_typeArray(), "just checking");
354 assert(TypeArrayKlass::cast(dim_array->klass())->element_type() == T_INT, "just checking");
355
356 if (element_mirror == NULL) {
357 THROW_0(vmSymbols::java_lang_NullPointerException());
358 }
359
360 int len = dim_array->length();
361 if (len <= 0 || len > MAX_DIM) {
362 THROW_0(vmSymbols::java_lang_IllegalArgumentException());
363 }
364
365 jint dimensions[MAX_DIM]; // C array copy of intArrayOop
366 for (int i = 0; i < len; i++) {
367 int d = dim_array->int_at(i);
735 if (!inner_is_member && ioff != 0 && ooff == 0 &&
736 cp->klass_name_at_matches(inner, ioff)) {
737 Klass* i = cp->klass_at(ioff, CHECK);
738 if (i == inner) {
739 return;
740 }
741 }
742 }
743
744 // 'inner' not declared as an inner klass in outer
745 ResourceMark rm(THREAD);
746 Exceptions::fthrow(
747 THREAD_AND_LOCATION,
748 vmSymbols::java_lang_IncompatibleClassChangeError(),
749 "%s and %s disagree on InnerClasses attribute",
750 outer->external_name(),
751 inner->external_name()
752 );
753 }
754
755 // Returns Q-mirror if qtype_if_value is true and k is a ValueKlass;
756 // otherwise returns java_mirror or L-mirror for ValueKlass
757 static oop java_mirror(Klass* k, jboolean qtype_if_value) {
758 if (qtype_if_value && k->is_value()) {
759 ValueKlass* vk = ValueKlass::cast(InstanceKlass::cast(k));
760 return vk->value_mirror();
761 } else {
762 return k->java_mirror();
763 }
764 }
765
766 // Utility method converting a single SignatureStream element into java.lang.Class instance
767 static oop get_mirror_from_signature(const methodHandle& method,
768 SignatureStream* ss,
769 TRAPS) {
770
771 BasicType bt = ss->type();
772 if (T_OBJECT == bt || T_ARRAY == bt || T_VALUETYPE == bt) {
773 Symbol* name = ss->as_symbol(CHECK_NULL);
774 oop loader = method->method_holder()->class_loader();
775 oop protection_domain = method->method_holder()->protection_domain();
776 const Klass* k = SystemDictionary::resolve_or_fail(name,
777 Handle(THREAD, loader),
778 Handle(THREAD, protection_domain),
779 true,
780 CHECK_NULL);
781 if (log_is_enabled(Debug, class, resolve)) {
782 trace_class_resolution(k);
783 }
784 return java_mirror((Klass*)k, bt == T_VALUETYPE);
785 }
786
787 assert(bt != T_VOID || ss->at_return_type(),
788 "T_VOID should only appear as return type");
789
790 return java_lang_Class::primitive_mirror(bt);
791 }
792
793 static objArrayHandle get_parameter_types(const methodHandle& method,
794 int parameter_count,
795 oop* return_type,
796 TRAPS) {
797 // Allocate array holding parameter types (java.lang.Class instances)
798 objArrayOop m = oopFactory::new_objArray(SystemDictionary::Class_klass(), parameter_count, CHECK_(objArrayHandle()));
799 objArrayHandle mirrors(THREAD, m);
800 int index = 0;
801 // Collect parameter types
802 ResourceMark rm(THREAD);
803 Symbol* signature = method->signature();
804 SignatureStream ss(signature);
805 while (!ss.at_return_type()) {
806 oop mirror = get_mirror_from_signature(method, &ss, CHECK_(objArrayHandle()));
807 mirrors->obj_at_put(index++, mirror);
808 ss.next();
809 }
810 assert(index == parameter_count, "invalid parameter count");
811 if (return_type != NULL) {
812 // Collect return type as well
813 assert(ss.at_return_type(), "return type should be present");
814 *return_type = get_mirror_from_signature(method, &ss, CHECK_(objArrayHandle()));
815 }
816 return mirrors;
817 }
818
819 static objArrayHandle get_exception_types(const methodHandle& method, TRAPS) {
820 return method->resolved_checked_exceptions(THREAD);
821 }
822
823 static Handle new_type(Symbol* signature, Klass* k, TRAPS) {
824 // Basic types
825 BasicType type = vmSymbols::signature_type(signature);
826 if (type != T_OBJECT && type != T_VALUETYPE) {
827 return Handle(THREAD, Universe::java_mirror(type));
828 }
829
830 Klass* result =
831 SystemDictionary::resolve_or_fail(signature,
832 Handle(THREAD, k->class_loader()),
833 Handle(THREAD, k->protection_domain()),
834 true, CHECK_(Handle()));
835
836 if (log_is_enabled(Debug, class, resolve)) {
837 trace_class_resolution(result);
838 }
839 oop nt = java_mirror(result, type == T_VALUETYPE);
840 return Handle(THREAD, nt);
841 }
842
843
844 oop Reflection::new_method(const methodHandle& method, bool for_constant_pool_access, TRAPS) {
845 // Allow sun.reflect.ConstantPool to refer to <clinit> methods as java.lang.reflect.Methods.
846 assert(!method()->is_initializer() ||
847 (for_constant_pool_access && method()->is_static()),
848 "should call new_constructor instead");
849 InstanceKlass* holder = method->method_holder();
850 int slot = method->method_idnum();
851
852 Symbol* signature = method->signature();
853 int parameter_count = ArgumentCount(signature).size();
854 oop return_type_oop = NULL;
855 objArrayHandle parameter_types = get_parameter_types(method, parameter_count, &return_type_oop, CHECK_NULL);
856 if (parameter_types.is_null() || return_type_oop == NULL) return NULL;
857
858 Handle return_type(THREAD, return_type_oop);
859
927 an_oop = Annotations::make_java_array(method->parameter_annotations(), CHECK_NULL);
928 java_lang_reflect_Constructor::set_parameter_annotations(ch(), an_oop);
929 return ch();
930 }
931
932
933 oop Reflection::new_field(fieldDescriptor* fd, TRAPS) {
934 Symbol* field_name = fd->name();
935 oop name_oop = StringTable::intern(field_name, CHECK_NULL);
936 Handle name = Handle(THREAD, name_oop);
937 Symbol* signature = fd->signature();
938 InstanceKlass* holder = fd->field_holder();
939 Handle type = new_type(signature, holder, CHECK_NULL);
940 Handle rh = java_lang_reflect_Field::create(CHECK_NULL);
941
942 java_lang_reflect_Field::set_clazz(rh(), fd->field_holder()->java_mirror());
943 java_lang_reflect_Field::set_slot(rh(), fd->index());
944 java_lang_reflect_Field::set_name(rh(), name());
945 java_lang_reflect_Field::set_type(rh(), type());
946 // Note the ACC_ANNOTATION bit, which is a per-class access flag, is never set here.
947 int modifiers = fd->access_flags().as_int() & JVM_RECOGNIZED_FIELD_MODIFIERS;
948 if (fd->is_flattenable()) {
949 modifiers |= JVM_ACC_FLATTENABLE;
950 }
951 if (fd->is_flattened()) {
952 modifiers |= JVM_ACC_FIELD_FLATTENED;
953 }
954 java_lang_reflect_Field::set_modifiers(rh(), modifiers);
955 java_lang_reflect_Field::set_override(rh(), false);
956 if (fd->has_generic_signature()) {
957 Symbol* gs = fd->generic_signature();
958 Handle sig = java_lang_String::create_from_symbol(gs, CHECK_NULL);
959 java_lang_reflect_Field::set_signature(rh(), sig());
960 }
961 typeArrayOop an_oop = Annotations::make_java_array(fd->annotations(), CHECK_NULL);
962 java_lang_reflect_Field::set_annotations(rh(), an_oop);
963 return rh();
964 }
965
966 oop Reflection::new_parameter(Handle method, int index, Symbol* sym,
967 int flags, TRAPS) {
968
969 Handle rh = java_lang_reflect_Parameter::create(CHECK_NULL);
970
971 if(NULL != sym) {
972 Handle name = java_lang_String::create_from_symbol(sym, CHECK_NULL);
973 java_lang_reflect_Parameter::set_name(rh(), name());
974 } else {
1205 if (rtype == T_BOOLEAN || rtype == T_BYTE || rtype == T_CHAR || rtype == T_SHORT) {
1206 narrow((jvalue*)result.get_value_addr(), rtype, CHECK_NULL);
1207 }
1208 return Reflection::box((jvalue*)result.get_value_addr(), rtype, THREAD);
1209 }
1210 }
1211
1212 // This would be nicer if, say, java.lang.reflect.Method was a subclass
1213 // of java.lang.reflect.Constructor
1214
1215 oop Reflection::invoke_method(oop method_mirror, Handle receiver, objArrayHandle args, TRAPS) {
1216 oop mirror = java_lang_reflect_Method::clazz(method_mirror);
1217 int slot = java_lang_reflect_Method::slot(method_mirror);
1218 bool override = java_lang_reflect_Method::override(method_mirror) != 0;
1219 objArrayHandle ptypes(THREAD, objArrayOop(java_lang_reflect_Method::parameter_types(method_mirror)));
1220
1221 oop return_type_mirror = java_lang_reflect_Method::return_type(method_mirror);
1222 BasicType rtype;
1223 if (java_lang_Class::is_primitive(return_type_mirror)) {
1224 rtype = basic_type_mirror_to_basic_type(return_type_mirror, CHECK_NULL);
1225 } else if (java_lang_Class::value_mirror(return_type_mirror) == return_type_mirror) {
1226 rtype = T_VALUETYPE;
1227 } else {
1228 rtype = T_OBJECT;
1229 }
1230
1231 InstanceKlass* klass = InstanceKlass::cast(java_lang_Class::as_Klass(mirror));
1232 Method* m = klass->method_with_idnum(slot);
1233 if (m == NULL) {
1234 THROW_MSG_0(vmSymbols::java_lang_InternalError(), "invoke");
1235 }
1236 methodHandle method(THREAD, m);
1237
1238 return invoke(klass, method, receiver, override, ptypes, rtype, args, true, THREAD);
1239 }
1240
1241
1242 oop Reflection::invoke_constructor(oop constructor_mirror, objArrayHandle args, TRAPS) {
1243 oop mirror = java_lang_reflect_Constructor::clazz(constructor_mirror);
1244 int slot = java_lang_reflect_Constructor::slot(constructor_mirror);
1245 bool override = java_lang_reflect_Constructor::override(constructor_mirror) != 0;
1246 objArrayHandle ptypes(THREAD, objArrayOop(java_lang_reflect_Constructor::parameter_types(constructor_mirror)));
|