hotspot/src/share/vm/runtime/reflection.cpp
changeset 46329 53ccc37bda19
parent 46289 1904e7ec236e
child 46388 d7a164ad6b7f
equal deleted inserted replaced
46328:6061df52d610 46329:53ccc37bda19
   706 // Checks that the 'outer' klass has declared 'inner' as being an inner klass. If not,
   706 // Checks that the 'outer' klass has declared 'inner' as being an inner klass. If not,
   707 // throw an incompatible class change exception
   707 // throw an incompatible class change exception
   708 // If inner_is_member, require the inner to be a member of the outer.
   708 // If inner_is_member, require the inner to be a member of the outer.
   709 // If !inner_is_member, require the inner to be anonymous (a non-member).
   709 // If !inner_is_member, require the inner to be anonymous (a non-member).
   710 // Caller is responsible for figuring out in advance which case must be true.
   710 // Caller is responsible for figuring out in advance which case must be true.
   711 void Reflection::check_for_inner_class(instanceKlassHandle outer, instanceKlassHandle inner,
   711 void Reflection::check_for_inner_class(const InstanceKlass* outer, const InstanceKlass* inner,
   712                                        bool inner_is_member, TRAPS) {
   712                                        bool inner_is_member, TRAPS) {
   713   InnerClassesIterator iter(outer);
   713   InnerClassesIterator iter(outer);
   714   constantPoolHandle cp   (THREAD, outer->constants());
   714   constantPoolHandle cp   (THREAD, outer->constants());
   715   for (; !iter.done(); iter.next()) {
   715   for (; !iter.done(); iter.next()) {
   716      int ioff = iter.inner_class_info_index();
   716      int ioff = iter.inner_class_info_index();
   717      int ooff = iter.outer_class_info_index();
   717      int ooff = iter.outer_class_info_index();
   718 
   718 
   719      if (inner_is_member && ioff != 0 && ooff != 0) {
   719      if (inner_is_member && ioff != 0 && ooff != 0) {
   720         Klass* o = cp->klass_at(ooff, CHECK);
   720         Klass* o = cp->klass_at(ooff, CHECK);
   721         if (o == outer()) {
   721         if (o == outer) {
   722           Klass* i = cp->klass_at(ioff, CHECK);
   722           Klass* i = cp->klass_at(ioff, CHECK);
   723           if (i == inner()) {
   723           if (i == inner) {
   724             return;
   724             return;
   725           }
   725           }
   726         }
   726         }
   727      }
   727      }
   728      if (!inner_is_member && ioff != 0 && ooff == 0 &&
   728      if (!inner_is_member && ioff != 0 && ooff == 0 &&
   729          cp->klass_name_at_matches(inner, ioff)) {
   729          cp->klass_name_at_matches(inner, ioff)) {
   730         Klass* i = cp->klass_at(ioff, CHECK);
   730         Klass* i = cp->klass_at(ioff, CHECK);
   731         if (i == inner()) {
   731         if (i == inner) {
   732           return;
   732           return;
   733         }
   733         }
   734      }
   734      }
   735   }
   735   }
   736 
   736 
   800 
   800 
   801 static objArrayHandle get_exception_types(methodHandle method, TRAPS) {
   801 static objArrayHandle get_exception_types(methodHandle method, TRAPS) {
   802   return method->resolved_checked_exceptions(THREAD);
   802   return method->resolved_checked_exceptions(THREAD);
   803 }
   803 }
   804 
   804 
   805 static Handle new_type(Symbol* signature, KlassHandle k, TRAPS) {
   805 static Handle new_type(Symbol* signature, Klass* k, TRAPS) {
   806   // Basic types
   806   // Basic types
   807   BasicType type = vmSymbols::signature_type(signature);
   807   BasicType type = vmSymbols::signature_type(signature);
   808   if (type != T_OBJECT) {
   808   if (type != T_OBJECT) {
   809     return Handle(THREAD, Universe::java_mirror(type));
   809     return Handle(THREAD, Universe::java_mirror(type));
   810   }
   810   }
   827 oop Reflection::new_method(const methodHandle& method, bool for_constant_pool_access, TRAPS) {
   827 oop Reflection::new_method(const methodHandle& method, bool for_constant_pool_access, TRAPS) {
   828   // Allow sun.reflect.ConstantPool to refer to <clinit> methods as java.lang.reflect.Methods.
   828   // Allow sun.reflect.ConstantPool to refer to <clinit> methods as java.lang.reflect.Methods.
   829   assert(!method()->is_initializer() ||
   829   assert(!method()->is_initializer() ||
   830          (for_constant_pool_access && method()->is_static()),
   830          (for_constant_pool_access && method()->is_static()),
   831          "should call new_constructor instead");
   831          "should call new_constructor instead");
   832   instanceKlassHandle holder (THREAD, method->method_holder());
   832   InstanceKlass* holder = method->method_holder();
   833   int slot = method->method_idnum();
   833   int slot = method->method_idnum();
   834 
   834 
   835   Symbol*  signature  = method->signature();
   835   Symbol*  signature  = method->signature();
   836   int parameter_count = ArgumentCount(signature).size();
   836   int parameter_count = ArgumentCount(signature).size();
   837   oop return_type_oop = NULL;
   837   oop return_type_oop = NULL;
   888 
   888 
   889 
   889 
   890 oop Reflection::new_constructor(const methodHandle& method, TRAPS) {
   890 oop Reflection::new_constructor(const methodHandle& method, TRAPS) {
   891   assert(method()->is_initializer(), "should call new_method instead");
   891   assert(method()->is_initializer(), "should call new_method instead");
   892 
   892 
   893   instanceKlassHandle  holder (THREAD, method->method_holder());
   893   InstanceKlass* holder = method->method_holder();
   894   int slot = method->method_idnum();
   894   int slot = method->method_idnum();
   895 
   895 
   896   Symbol*  signature  = method->signature();
   896   Symbol*  signature  = method->signature();
   897   int parameter_count = ArgumentCount(signature).size();
   897   int parameter_count = ArgumentCount(signature).size();
   898   objArrayHandle parameter_types = get_parameter_types(method, parameter_count, NULL, CHECK_NULL);
   898   objArrayHandle parameter_types = get_parameter_types(method, parameter_count, NULL, CHECK_NULL);
   936 oop Reflection::new_field(fieldDescriptor* fd, TRAPS) {
   936 oop Reflection::new_field(fieldDescriptor* fd, TRAPS) {
   937   Symbol*  field_name = fd->name();
   937   Symbol*  field_name = fd->name();
   938   oop name_oop = StringTable::intern(field_name, CHECK_NULL);
   938   oop name_oop = StringTable::intern(field_name, CHECK_NULL);
   939   Handle name = Handle(THREAD, name_oop);
   939   Handle name = Handle(THREAD, name_oop);
   940   Symbol*  signature  = fd->signature();
   940   Symbol*  signature  = fd->signature();
   941   instanceKlassHandle  holder    (THREAD, fd->field_holder());
   941   InstanceKlass* holder = fd->field_holder();
   942   Handle type = new_type(signature, holder, CHECK_NULL);
   942   Handle type = new_type(signature, holder, CHECK_NULL);
   943   Handle rh  = java_lang_reflect_Field::create(CHECK_NULL);
   943   Handle rh  = java_lang_reflect_Field::create(CHECK_NULL);
   944 
   944 
   945   java_lang_reflect_Field::set_clazz(rh(), fd->field_holder()->java_mirror());
   945   java_lang_reflect_Field::set_clazz(rh(), fd->field_holder()->java_mirror());
   946   java_lang_reflect_Field::set_slot(rh(), fd->index());
   946   java_lang_reflect_Field::set_slot(rh(), fd->index());
   983   java_lang_reflect_Parameter::set_index(rh(), index);
   983   java_lang_reflect_Parameter::set_index(rh(), index);
   984   return rh();
   984   return rh();
   985 }
   985 }
   986 
   986 
   987 
   987 
   988 static methodHandle resolve_interface_call(instanceKlassHandle klass,
   988 static methodHandle resolve_interface_call(InstanceKlass* klass,
   989                                            const methodHandle& method,
   989                                            const methodHandle& method,
   990                                            KlassHandle recv_klass,
   990                                            Klass* recv_klass,
   991                                            Handle receiver,
   991                                            Handle receiver,
   992                                            TRAPS) {
   992                                            TRAPS) {
   993 
   993 
   994   assert(!method.is_null() , "method should not be null");
   994   assert(!method.is_null() , "method should not be null");
   995 
   995 
  1033   THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), "argument type mismatch");
  1033   THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), "argument type mismatch");
  1034 }
  1034 }
  1035 
  1035 
  1036 
  1036 
  1037 // Method call (shared by invoke_method and invoke_constructor)
  1037 // Method call (shared by invoke_method and invoke_constructor)
  1038 static oop invoke(instanceKlassHandle klass,
  1038 static oop invoke(InstanceKlass* klass,
  1039                   methodHandle reflected_method,
  1039                   methodHandle reflected_method,
  1040                   Handle receiver,
  1040                   Handle receiver,
  1041                   bool override,
  1041                   bool override,
  1042                   objArrayHandle ptypes,
  1042                   objArrayHandle ptypes,
  1043                   BasicType rtype,
  1043                   BasicType rtype,
  1046                   TRAPS) {
  1046                   TRAPS) {
  1047 
  1047 
  1048   ResourceMark rm(THREAD);
  1048   ResourceMark rm(THREAD);
  1049 
  1049 
  1050   methodHandle method;      // actual method to invoke
  1050   methodHandle method;      // actual method to invoke
  1051   KlassHandle target_klass; // target klass, receiver's klass for non-static
  1051   Klass* target_klass;      // target klass, receiver's klass for non-static
  1052 
  1052 
  1053   // Ensure klass is initialized
  1053   // Ensure klass is initialized
  1054   klass->initialize(CHECK_NULL);
  1054   klass->initialize(CHECK_NULL);
  1055 
  1055 
  1056   bool is_static = reflected_method->is_static();
  1056   bool is_static = reflected_method->is_static();
  1062     // check for null receiver
  1062     // check for null receiver
  1063     if (receiver.is_null()) {
  1063     if (receiver.is_null()) {
  1064       THROW_0(vmSymbols::java_lang_NullPointerException());
  1064       THROW_0(vmSymbols::java_lang_NullPointerException());
  1065     }
  1065     }
  1066     // Check class of receiver against class declaring method
  1066     // Check class of receiver against class declaring method
  1067     if (!receiver->is_a(klass())) {
  1067     if (!receiver->is_a(klass)) {
  1068       THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(), "object is not an instance of declaring class");
  1068       THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(), "object is not an instance of declaring class");
  1069     }
  1069     }
  1070     // target klass is receiver's klass
  1070     // target klass is receiver's klass
  1071     target_klass = KlassHandle(THREAD, receiver->klass());
  1071     target_klass = receiver->klass();
  1072     // no need to resolve if method is private or <init>
  1072     // no need to resolve if method is private or <init>
  1073     if (reflected_method->is_private() || reflected_method->name() == vmSymbols::object_initializer_name()) {
  1073     if (reflected_method->is_private() || reflected_method->name() == vmSymbols::object_initializer_name()) {
  1074       method = reflected_method;
  1074       method = reflected_method;
  1075     } else {
  1075     } else {
  1076       // resolve based on the receiver
  1076       // resolve based on the receiver
  1107           if (method->is_abstract()) {
  1107           if (method->is_abstract()) {
  1108             // new default: 6531596
  1108             // new default: 6531596
  1109             ResourceMark rm(THREAD);
  1109             ResourceMark rm(THREAD);
  1110             Handle h_origexception = Exceptions::new_exception(THREAD,
  1110             Handle h_origexception = Exceptions::new_exception(THREAD,
  1111               vmSymbols::java_lang_AbstractMethodError(),
  1111               vmSymbols::java_lang_AbstractMethodError(),
  1112               Method::name_and_sig_as_C_string(target_klass(),
  1112               Method::name_and_sig_as_C_string(target_klass,
  1113               method->name(),
  1113               method->name(),
  1114               method->signature()));
  1114               method->signature()));
  1115             JavaCallArguments args(h_origexception);
  1115             JavaCallArguments args(h_origexception);
  1116             THROW_ARG_0(vmSymbols::java_lang_reflect_InvocationTargetException(),
  1116             THROW_ARG_0(vmSymbols::java_lang_reflect_InvocationTargetException(),
  1117               vmSymbols::throwable_void_signature(),
  1117               vmSymbols::throwable_void_signature(),
  1125   // I believe this is a ShouldNotGetHere case which requires
  1125   // I believe this is a ShouldNotGetHere case which requires
  1126   // an internal vtable bug. If you ever get this please let Karen know.
  1126   // an internal vtable bug. If you ever get this please let Karen know.
  1127   if (method.is_null()) {
  1127   if (method.is_null()) {
  1128     ResourceMark rm(THREAD);
  1128     ResourceMark rm(THREAD);
  1129     THROW_MSG_0(vmSymbols::java_lang_NoSuchMethodError(),
  1129     THROW_MSG_0(vmSymbols::java_lang_NoSuchMethodError(),
  1130                 Method::name_and_sig_as_C_string(klass(),
  1130                 Method::name_and_sig_as_C_string(klass,
  1131                 reflected_method->name(),
  1131                 reflected_method->name(),
  1132                 reflected_method->signature()));
  1132                 reflected_method->signature()));
  1133   }
  1133   }
  1134 
  1134 
  1135   assert(ptypes->is_objArray(), "just checking");
  1135   assert(ptypes->is_objArray(), "just checking");
  1227     rtype = basic_type_mirror_to_basic_type(return_type_mirror, CHECK_NULL);
  1227     rtype = basic_type_mirror_to_basic_type(return_type_mirror, CHECK_NULL);
  1228   } else {
  1228   } else {
  1229     rtype = T_OBJECT;
  1229     rtype = T_OBJECT;
  1230   }
  1230   }
  1231 
  1231 
  1232   instanceKlassHandle klass(THREAD, java_lang_Class::as_Klass(mirror));
  1232   InstanceKlass* klass = InstanceKlass::cast(java_lang_Class::as_Klass(mirror));
  1233   Method* m = klass->method_with_idnum(slot);
  1233   Method* m = klass->method_with_idnum(slot);
  1234   if (m == NULL) {
  1234   if (m == NULL) {
  1235     THROW_MSG_0(vmSymbols::java_lang_InternalError(), "invoke");
  1235     THROW_MSG_0(vmSymbols::java_lang_InternalError(), "invoke");
  1236   }
  1236   }
  1237   methodHandle method(THREAD, m);
  1237   methodHandle method(THREAD, m);
  1244   oop mirror             = java_lang_reflect_Constructor::clazz(constructor_mirror);
  1244   oop mirror             = java_lang_reflect_Constructor::clazz(constructor_mirror);
  1245   int slot               = java_lang_reflect_Constructor::slot(constructor_mirror);
  1245   int slot               = java_lang_reflect_Constructor::slot(constructor_mirror);
  1246   bool override          = java_lang_reflect_Constructor::override(constructor_mirror) != 0;
  1246   bool override          = java_lang_reflect_Constructor::override(constructor_mirror) != 0;
  1247   objArrayHandle ptypes(THREAD, objArrayOop(java_lang_reflect_Constructor::parameter_types(constructor_mirror)));
  1247   objArrayHandle ptypes(THREAD, objArrayOop(java_lang_reflect_Constructor::parameter_types(constructor_mirror)));
  1248 
  1248 
  1249   instanceKlassHandle klass(THREAD, java_lang_Class::as_Klass(mirror));
  1249   InstanceKlass* klass = InstanceKlass::cast(java_lang_Class::as_Klass(mirror));
  1250   Method* m = klass->method_with_idnum(slot);
  1250   Method* m = klass->method_with_idnum(slot);
  1251   if (m == NULL) {
  1251   if (m == NULL) {
  1252     THROW_MSG_0(vmSymbols::java_lang_InternalError(), "invoke");
  1252     THROW_MSG_0(vmSymbols::java_lang_InternalError(), "invoke");
  1253   }
  1253   }
  1254   methodHandle method(THREAD, m);
  1254   methodHandle method(THREAD, m);