4018 |
4018 |
4019 |
4019 |
4020 #endif |
4020 #endif |
4021 |
4021 |
4022 |
4022 |
4023 //--------------------------------------------------------------------------- |
|
4024 // |
|
4025 // Support for old native code-based reflection (pre-JDK 1.4) |
|
4026 // Disabled by default in the product build. |
|
4027 // |
|
4028 // See reflection.hpp for information on SUPPORT_OLD_REFLECTION |
|
4029 // |
|
4030 //--------------------------------------------------------------------------- |
|
4031 |
|
4032 #ifdef SUPPORT_OLD_REFLECTION |
|
4033 |
|
4034 JVM_ENTRY(jobjectArray, JVM_GetClassFields(JNIEnv *env, jclass cls, jint which)) |
|
4035 JVMWrapper("JVM_GetClassFields"); |
|
4036 JvmtiVMObjectAllocEventCollector oam; |
|
4037 oop mirror = JNIHandles::resolve_non_null(cls); |
|
4038 objArrayOop result = Reflection::reflect_fields(mirror, which, CHECK_NULL); |
|
4039 return (jobjectArray) JNIHandles::make_local(env, result); |
|
4040 JVM_END |
|
4041 |
|
4042 |
|
4043 JVM_ENTRY(jobjectArray, JVM_GetClassMethods(JNIEnv *env, jclass cls, jint which)) |
|
4044 JVMWrapper("JVM_GetClassMethods"); |
|
4045 JvmtiVMObjectAllocEventCollector oam; |
|
4046 oop mirror = JNIHandles::resolve_non_null(cls); |
|
4047 objArrayOop result = Reflection::reflect_methods(mirror, which, CHECK_NULL); |
|
4048 //%note jvm_r4 |
|
4049 return (jobjectArray) JNIHandles::make_local(env, result); |
|
4050 JVM_END |
|
4051 |
|
4052 |
|
4053 JVM_ENTRY(jobjectArray, JVM_GetClassConstructors(JNIEnv *env, jclass cls, jint which)) |
|
4054 JVMWrapper("JVM_GetClassConstructors"); |
|
4055 JvmtiVMObjectAllocEventCollector oam; |
|
4056 oop mirror = JNIHandles::resolve_non_null(cls); |
|
4057 objArrayOop result = Reflection::reflect_constructors(mirror, which, CHECK_NULL); |
|
4058 //%note jvm_r4 |
|
4059 return (jobjectArray) JNIHandles::make_local(env, result); |
|
4060 JVM_END |
|
4061 |
|
4062 |
|
4063 JVM_ENTRY(jobject, JVM_GetClassField(JNIEnv *env, jclass cls, jstring name, jint which)) |
|
4064 JVMWrapper("JVM_GetClassField"); |
|
4065 JvmtiVMObjectAllocEventCollector oam; |
|
4066 if (name == NULL) return NULL; |
|
4067 Handle str (THREAD, JNIHandles::resolve_non_null(name)); |
|
4068 |
|
4069 const char* cstr = java_lang_String::as_utf8_string(str()); |
|
4070 TempNewSymbol field_name = SymbolTable::probe(cstr, (int)strlen(cstr)); |
|
4071 if (field_name == NULL) { |
|
4072 THROW_0(vmSymbols::java_lang_NoSuchFieldException()); |
|
4073 } |
|
4074 |
|
4075 oop mirror = JNIHandles::resolve_non_null(cls); |
|
4076 oop result = Reflection::reflect_field(mirror, field_name, which, CHECK_NULL); |
|
4077 if (result == NULL) { |
|
4078 THROW_0(vmSymbols::java_lang_NoSuchFieldException()); |
|
4079 } |
|
4080 return JNIHandles::make_local(env, result); |
|
4081 JVM_END |
|
4082 |
|
4083 |
|
4084 JVM_ENTRY(jobject, JVM_GetClassMethod(JNIEnv *env, jclass cls, jstring name, jobjectArray types, jint which)) |
|
4085 JVMWrapper("JVM_GetClassMethod"); |
|
4086 JvmtiVMObjectAllocEventCollector oam; |
|
4087 if (name == NULL) { |
|
4088 THROW_0(vmSymbols::java_lang_NullPointerException()); |
|
4089 } |
|
4090 Handle str (THREAD, JNIHandles::resolve_non_null(name)); |
|
4091 |
|
4092 const char* cstr = java_lang_String::as_utf8_string(str()); |
|
4093 TempNewSymbol method_name = SymbolTable::probe(cstr, (int)strlen(cstr)); |
|
4094 if (method_name == NULL) { |
|
4095 THROW_0(vmSymbols::java_lang_NoSuchMethodException()); |
|
4096 } |
|
4097 |
|
4098 oop mirror = JNIHandles::resolve_non_null(cls); |
|
4099 objArrayHandle tarray (THREAD, objArrayOop(JNIHandles::resolve(types))); |
|
4100 oop result = Reflection::reflect_method(mirror, method_name, tarray, |
|
4101 which, CHECK_NULL); |
|
4102 if (result == NULL) { |
|
4103 THROW_0(vmSymbols::java_lang_NoSuchMethodException()); |
|
4104 } |
|
4105 return JNIHandles::make_local(env, result); |
|
4106 JVM_END |
|
4107 |
|
4108 |
|
4109 JVM_ENTRY(jobject, JVM_GetClassConstructor(JNIEnv *env, jclass cls, jobjectArray types, jint which)) |
|
4110 JVMWrapper("JVM_GetClassConstructor"); |
|
4111 JvmtiVMObjectAllocEventCollector oam; |
|
4112 oop mirror = JNIHandles::resolve_non_null(cls); |
|
4113 objArrayHandle tarray (THREAD, objArrayOop(JNIHandles::resolve(types))); |
|
4114 oop result = Reflection::reflect_constructor(mirror, tarray, which, CHECK_NULL); |
|
4115 if (result == NULL) { |
|
4116 THROW_0(vmSymbols::java_lang_NoSuchMethodException()); |
|
4117 } |
|
4118 return (jobject) JNIHandles::make_local(env, result); |
|
4119 JVM_END |
|
4120 |
|
4121 |
|
4122 // Instantiation /////////////////////////////////////////////////////////////////////////////// |
|
4123 |
|
4124 JVM_ENTRY(jobject, JVM_NewInstance(JNIEnv *env, jclass cls)) |
|
4125 JVMWrapper("JVM_NewInstance"); |
|
4126 Handle mirror(THREAD, JNIHandles::resolve_non_null(cls)); |
|
4127 |
|
4128 methodOop resolved_constructor = java_lang_Class::resolved_constructor(mirror()); |
|
4129 if (resolved_constructor == NULL) { |
|
4130 klassOop k = java_lang_Class::as_klassOop(mirror()); |
|
4131 // The java.lang.Class object caches a resolved constructor if all the checks |
|
4132 // below were done successfully and a constructor was found. |
|
4133 |
|
4134 // Do class based checks |
|
4135 if (java_lang_Class::is_primitive(mirror())) { |
|
4136 const char* msg = ""; |
|
4137 if (mirror == Universe::bool_mirror()) msg = "java/lang/Boolean"; |
|
4138 else if (mirror == Universe::char_mirror()) msg = "java/lang/Character"; |
|
4139 else if (mirror == Universe::float_mirror()) msg = "java/lang/Float"; |
|
4140 else if (mirror == Universe::double_mirror()) msg = "java/lang/Double"; |
|
4141 else if (mirror == Universe::byte_mirror()) msg = "java/lang/Byte"; |
|
4142 else if (mirror == Universe::short_mirror()) msg = "java/lang/Short"; |
|
4143 else if (mirror == Universe::int_mirror()) msg = "java/lang/Integer"; |
|
4144 else if (mirror == Universe::long_mirror()) msg = "java/lang/Long"; |
|
4145 THROW_MSG_0(vmSymbols::java_lang_NullPointerException(), msg); |
|
4146 } |
|
4147 |
|
4148 // Check whether we are allowed to instantiate this class |
|
4149 Klass::cast(k)->check_valid_for_instantiation(false, CHECK_NULL); // Array classes get caught here |
|
4150 instanceKlassHandle klass(THREAD, k); |
|
4151 // Make sure class is initialized (also so all methods are rewritten) |
|
4152 klass->initialize(CHECK_NULL); |
|
4153 |
|
4154 // Lookup default constructor |
|
4155 resolved_constructor = klass->find_method(vmSymbols::object_initializer_name(), vmSymbols::void_method_signature()); |
|
4156 if (resolved_constructor == NULL) { |
|
4157 ResourceMark rm(THREAD); |
|
4158 THROW_MSG_0(vmSymbols::java_lang_InstantiationException(), klass->external_name()); |
|
4159 } |
|
4160 |
|
4161 // Cache result in java.lang.Class object. Does not have to be MT safe. |
|
4162 java_lang_Class::set_resolved_constructor(mirror(), resolved_constructor); |
|
4163 } |
|
4164 |
|
4165 assert(resolved_constructor != NULL, "sanity check"); |
|
4166 methodHandle constructor = methodHandle(THREAD, resolved_constructor); |
|
4167 |
|
4168 // We have an initialized instanceKlass with a default constructor |
|
4169 instanceKlassHandle klass(THREAD, java_lang_Class::as_klassOop(JNIHandles::resolve_non_null(cls))); |
|
4170 assert(klass->is_initialized() || klass->is_being_initialized(), "sanity check"); |
|
4171 |
|
4172 // Do security check |
|
4173 klassOop caller_klass = NULL; |
|
4174 if (UsePrivilegedStack) { |
|
4175 caller_klass = thread->security_get_caller_class(2); |
|
4176 |
|
4177 if (!Reflection::verify_class_access(caller_klass, klass(), false) || |
|
4178 !Reflection::verify_field_access(caller_klass, |
|
4179 klass(), |
|
4180 klass(), |
|
4181 constructor->access_flags(), |
|
4182 false, |
|
4183 true)) { |
|
4184 ResourceMark rm(THREAD); |
|
4185 THROW_MSG_0(vmSymbols::java_lang_IllegalAccessException(), klass->external_name()); |
|
4186 } |
|
4187 } |
|
4188 |
|
4189 // Allocate object and call constructor |
|
4190 Handle receiver = klass->allocate_instance_handle(CHECK_NULL); |
|
4191 JavaCalls::call_default_constructor(thread, constructor, receiver, CHECK_NULL); |
|
4192 |
|
4193 jobject res = JNIHandles::make_local(env, receiver()); |
|
4194 if (JvmtiExport::should_post_vm_object_alloc()) { |
|
4195 JvmtiExport::post_vm_object_alloc(JavaThread::current(), receiver()); |
|
4196 } |
|
4197 return res; |
|
4198 JVM_END |
|
4199 |
|
4200 |
|
4201 // Field //////////////////////////////////////////////////////////////////////////////////////////// |
|
4202 |
|
4203 JVM_ENTRY(jobject, JVM_GetField(JNIEnv *env, jobject field, jobject obj)) |
|
4204 JVMWrapper("JVM_GetField"); |
|
4205 JvmtiVMObjectAllocEventCollector oam; |
|
4206 Handle field_mirror(thread, JNIHandles::resolve(field)); |
|
4207 Handle receiver (thread, JNIHandles::resolve(obj)); |
|
4208 fieldDescriptor fd; |
|
4209 Reflection::resolve_field(field_mirror, receiver, &fd, false, CHECK_NULL); |
|
4210 jvalue value; |
|
4211 BasicType type = Reflection::field_get(&value, &fd, receiver); |
|
4212 oop box = Reflection::box(&value, type, CHECK_NULL); |
|
4213 return JNIHandles::make_local(env, box); |
|
4214 JVM_END |
|
4215 |
|
4216 |
|
4217 JVM_ENTRY(jvalue, JVM_GetPrimitiveField(JNIEnv *env, jobject field, jobject obj, unsigned char wCode)) |
|
4218 JVMWrapper("JVM_GetPrimitiveField"); |
|
4219 Handle field_mirror(thread, JNIHandles::resolve(field)); |
|
4220 Handle receiver (thread, JNIHandles::resolve(obj)); |
|
4221 fieldDescriptor fd; |
|
4222 jvalue value; |
|
4223 value.j = 0; |
|
4224 Reflection::resolve_field(field_mirror, receiver, &fd, false, CHECK_(value)); |
|
4225 BasicType type = Reflection::field_get(&value, &fd, receiver); |
|
4226 BasicType wide_type = (BasicType) wCode; |
|
4227 if (type != wide_type) { |
|
4228 Reflection::widen(&value, type, wide_type, CHECK_(value)); |
|
4229 } |
|
4230 return value; |
|
4231 JVM_END // should really be JVM_END, but that doesn't work for union types! |
|
4232 |
|
4233 |
|
4234 JVM_ENTRY(void, JVM_SetField(JNIEnv *env, jobject field, jobject obj, jobject val)) |
|
4235 JVMWrapper("JVM_SetField"); |
|
4236 Handle field_mirror(thread, JNIHandles::resolve(field)); |
|
4237 Handle receiver (thread, JNIHandles::resolve(obj)); |
|
4238 oop box = JNIHandles::resolve(val); |
|
4239 fieldDescriptor fd; |
|
4240 Reflection::resolve_field(field_mirror, receiver, &fd, true, CHECK); |
|
4241 BasicType field_type = fd.field_type(); |
|
4242 jvalue value; |
|
4243 BasicType value_type; |
|
4244 if (field_type == T_OBJECT || field_type == T_ARRAY) { |
|
4245 // Make sure we do no unbox e.g. java/lang/Integer instances when storing into an object array |
|
4246 value_type = Reflection::unbox_for_regular_object(box, &value); |
|
4247 Reflection::field_set(&value, &fd, receiver, field_type, CHECK); |
|
4248 } else { |
|
4249 value_type = Reflection::unbox_for_primitive(box, &value, CHECK); |
|
4250 Reflection::field_set(&value, &fd, receiver, value_type, CHECK); |
|
4251 } |
|
4252 JVM_END |
|
4253 |
|
4254 |
|
4255 JVM_ENTRY(void, JVM_SetPrimitiveField(JNIEnv *env, jobject field, jobject obj, jvalue v, unsigned char vCode)) |
|
4256 JVMWrapper("JVM_SetPrimitiveField"); |
|
4257 Handle field_mirror(thread, JNIHandles::resolve(field)); |
|
4258 Handle receiver (thread, JNIHandles::resolve(obj)); |
|
4259 fieldDescriptor fd; |
|
4260 Reflection::resolve_field(field_mirror, receiver, &fd, true, CHECK); |
|
4261 BasicType value_type = (BasicType) vCode; |
|
4262 Reflection::field_set(&v, &fd, receiver, value_type, CHECK); |
|
4263 JVM_END |
|
4264 |
|
4265 |
|
4266 // Method /////////////////////////////////////////////////////////////////////////////////////////// |
4023 // Method /////////////////////////////////////////////////////////////////////////////////////////// |
4267 |
4024 |
4268 JVM_ENTRY(jobject, JVM_InvokeMethod(JNIEnv *env, jobject method, jobject obj, jobjectArray args0)) |
4025 JVM_ENTRY(jobject, JVM_InvokeMethod(JNIEnv *env, jobject method, jobject obj, jobjectArray args0)) |
4269 JVMWrapper("JVM_InvokeMethod"); |
4026 JVMWrapper("JVM_InvokeMethod"); |
4270 Handle method_handle; |
4027 Handle method_handle; |