1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/share/vm/runtime/reflection.cpp Sat Dec 01 00:00:00 2007 +0000 1.3 @@ -0,0 +1,1586 @@ 1.4 +/* 1.5 + * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved. 1.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 1.7 + * 1.8 + * This code is free software; you can redistribute it and/or modify it 1.9 + * under the terms of the GNU General Public License version 2 only, as 1.10 + * published by the Free Software Foundation. 1.11 + * 1.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 1.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 1.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 1.15 + * version 2 for more details (a copy is included in the LICENSE file that 1.16 + * accompanied this code). 1.17 + * 1.18 + * You should have received a copy of the GNU General Public License version 1.19 + * 2 along with this work; if not, write to the Free Software Foundation, 1.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 1.21 + * 1.22 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, 1.23 + * CA 95054 USA or visit www.sun.com if you need additional information or 1.24 + * have any questions. 1.25 + * 1.26 + */ 1.27 + 1.28 +#include "incls/_precompiled.incl" 1.29 +#include "incls/_reflection.cpp.incl" 1.30 + 1.31 +#define JAVA_1_5_VERSION 49 1.32 + 1.33 +static void trace_class_resolution(klassOop to_class) { 1.34 + ResourceMark rm; 1.35 + int line_number = -1; 1.36 + const char * source_file = NULL; 1.37 + klassOop caller = NULL; 1.38 + JavaThread* jthread = JavaThread::current(); 1.39 + if (jthread->has_last_Java_frame()) { 1.40 + vframeStream vfst(jthread); 1.41 + // skip over any frames belonging to java.lang.Class 1.42 + while (!vfst.at_end() && 1.43 + instanceKlass::cast(vfst.method()->method_holder())->name() == vmSymbols::java_lang_Class()) { 1.44 + vfst.next(); 1.45 + } 1.46 + if (!vfst.at_end()) { 1.47 + // this frame is a likely suspect 1.48 + caller = vfst.method()->method_holder(); 1.49 + line_number = vfst.method()->line_number_from_bci(vfst.bci()); 1.50 + symbolOop s = instanceKlass::cast(vfst.method()->method_holder())->source_file_name(); 1.51 + if (s != NULL) { 1.52 + source_file = s->as_C_string(); 1.53 + } 1.54 + } 1.55 + } 1.56 + if (caller != NULL) { 1.57 + const char * from = Klass::cast(caller)->external_name(); 1.58 + const char * to = Klass::cast(to_class)->external_name(); 1.59 + // print in a single call to reduce interleaving between threads 1.60 + if (source_file != NULL) { 1.61 + tty->print("RESOLVE %s %s %s:%d (reflection)\n", from, to, source_file, line_number); 1.62 + } else { 1.63 + tty->print("RESOLVE %s %s (reflection)\n", from, to); 1.64 + } 1.65 + } 1.66 +} 1.67 + 1.68 + 1.69 +oop Reflection::box(jvalue* value, BasicType type, TRAPS) { 1.70 + if (type == T_VOID) { 1.71 + return NULL; 1.72 + } 1.73 + if (type == T_OBJECT || type == T_ARRAY) { 1.74 + // regular objects are not boxed 1.75 + return (oop) value->l; 1.76 + } 1.77 + oop result = java_lang_boxing_object::create(type, value, CHECK_NULL); 1.78 + if (result == NULL) { 1.79 + THROW_(vmSymbols::java_lang_IllegalArgumentException(), result); 1.80 + } 1.81 + return result; 1.82 +} 1.83 + 1.84 + 1.85 +BasicType Reflection::unbox_for_primitive(oop box, jvalue* value, TRAPS) { 1.86 + if (box == NULL) { 1.87 + THROW_(vmSymbols::java_lang_IllegalArgumentException(), T_ILLEGAL); 1.88 + } 1.89 + return java_lang_boxing_object::get_value(box, value); 1.90 +} 1.91 + 1.92 +BasicType Reflection::unbox_for_regular_object(oop box, jvalue* value) { 1.93 + // Note: box is really the unboxed oop. It might even be a Short, etc.! 1.94 + value->l = (jobject) box; 1.95 + return T_OBJECT; 1.96 +} 1.97 + 1.98 + 1.99 +void Reflection::widen(jvalue* value, BasicType current_type, BasicType wide_type, TRAPS) { 1.100 + assert(wide_type != current_type, "widen should not be called with identical types"); 1.101 + switch (wide_type) { 1.102 + case T_BOOLEAN: 1.103 + case T_BYTE: 1.104 + case T_CHAR: 1.105 + break; // fail 1.106 + case T_SHORT: 1.107 + switch (current_type) { 1.108 + case T_BYTE: 1.109 + value->s = (jshort) value->b; 1.110 + return; 1.111 + } 1.112 + break; // fail 1.113 + case T_INT: 1.114 + switch (current_type) { 1.115 + case T_BYTE: 1.116 + value->i = (jint) value->b; 1.117 + return; 1.118 + case T_CHAR: 1.119 + value->i = (jint) value->c; 1.120 + return; 1.121 + case T_SHORT: 1.122 + value->i = (jint) value->s; 1.123 + return; 1.124 + } 1.125 + break; // fail 1.126 + case T_LONG: 1.127 + switch (current_type) { 1.128 + case T_BYTE: 1.129 + value->j = (jlong) value->b; 1.130 + return; 1.131 + case T_CHAR: 1.132 + value->j = (jlong) value->c; 1.133 + return; 1.134 + case T_SHORT: 1.135 + value->j = (jlong) value->s; 1.136 + return; 1.137 + case T_INT: 1.138 + value->j = (jlong) value->i; 1.139 + return; 1.140 + } 1.141 + break; // fail 1.142 + case T_FLOAT: 1.143 + switch (current_type) { 1.144 + case T_BYTE: 1.145 + value->f = (jfloat) value->b; 1.146 + return; 1.147 + case T_CHAR: 1.148 + value->f = (jfloat) value->c; 1.149 + return; 1.150 + case T_SHORT: 1.151 + value->f = (jfloat) value->s; 1.152 + return; 1.153 + case T_INT: 1.154 + value->f = (jfloat) value->i; 1.155 + return; 1.156 + case T_LONG: 1.157 + value->f = (jfloat) value->j; 1.158 + return; 1.159 + } 1.160 + break; // fail 1.161 + case T_DOUBLE: 1.162 + switch (current_type) { 1.163 + case T_BYTE: 1.164 + value->d = (jdouble) value->b; 1.165 + return; 1.166 + case T_CHAR: 1.167 + value->d = (jdouble) value->c; 1.168 + return; 1.169 + case T_SHORT: 1.170 + value->d = (jdouble) value->s; 1.171 + return; 1.172 + case T_INT: 1.173 + value->d = (jdouble) value->i; 1.174 + return; 1.175 + case T_FLOAT: 1.176 + value->d = (jdouble) value->f; 1.177 + return; 1.178 + case T_LONG: 1.179 + value->d = (jdouble) value->j; 1.180 + return; 1.181 + } 1.182 + break; // fail 1.183 + default: 1.184 + break; // fail 1.185 + } 1.186 + THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), "argument type mismatch"); 1.187 +} 1.188 + 1.189 + 1.190 +BasicType Reflection::array_get(jvalue* value, arrayOop a, int index, TRAPS) { 1.191 + if (!a->is_within_bounds(index)) { 1.192 + THROW_(vmSymbols::java_lang_ArrayIndexOutOfBoundsException(), T_ILLEGAL); 1.193 + } 1.194 + if (a->is_objArray()) { 1.195 + value->l = (jobject) objArrayOop(a)->obj_at(index); 1.196 + return T_OBJECT; 1.197 + } else { 1.198 + assert(a->is_typeArray(), "just checking"); 1.199 + BasicType type = typeArrayKlass::cast(a->klass())->element_type(); 1.200 + switch (type) { 1.201 + case T_BOOLEAN: 1.202 + value->z = typeArrayOop(a)->bool_at(index); 1.203 + break; 1.204 + case T_CHAR: 1.205 + value->c = typeArrayOop(a)->char_at(index); 1.206 + break; 1.207 + case T_FLOAT: 1.208 + value->f = typeArrayOop(a)->float_at(index); 1.209 + break; 1.210 + case T_DOUBLE: 1.211 + value->d = typeArrayOop(a)->double_at(index); 1.212 + break; 1.213 + case T_BYTE: 1.214 + value->b = typeArrayOop(a)->byte_at(index); 1.215 + break; 1.216 + case T_SHORT: 1.217 + value->s = typeArrayOop(a)->short_at(index); 1.218 + break; 1.219 + case T_INT: 1.220 + value->i = typeArrayOop(a)->int_at(index); 1.221 + break; 1.222 + case T_LONG: 1.223 + value->j = typeArrayOop(a)->long_at(index); 1.224 + break; 1.225 + default: 1.226 + return T_ILLEGAL; 1.227 + } 1.228 + return type; 1.229 + } 1.230 +} 1.231 + 1.232 + 1.233 +void Reflection::array_set(jvalue* value, arrayOop a, int index, BasicType value_type, TRAPS) { 1.234 + if (!a->is_within_bounds(index)) { 1.235 + THROW(vmSymbols::java_lang_ArrayIndexOutOfBoundsException()); 1.236 + } 1.237 + if (a->is_objArray()) { 1.238 + if (value_type == T_OBJECT) { 1.239 + oop obj = (oop) value->l; 1.240 + if (obj != NULL) { 1.241 + klassOop element_klass = objArrayKlass::cast(a->klass())->element_klass(); 1.242 + if (!obj->is_a(element_klass)) { 1.243 + THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), "array element type mismatch"); 1.244 + } 1.245 + } 1.246 + objArrayOop(a)->obj_at_put(index, obj); 1.247 + } 1.248 + } else { 1.249 + assert(a->is_typeArray(), "just checking"); 1.250 + BasicType array_type = typeArrayKlass::cast(a->klass())->element_type(); 1.251 + if (array_type != value_type) { 1.252 + // The widen operation can potentially throw an exception, but cannot block, 1.253 + // so typeArrayOop a is safe if the call succeeds. 1.254 + widen(value, value_type, array_type, CHECK); 1.255 + } 1.256 + switch (array_type) { 1.257 + case T_BOOLEAN: 1.258 + typeArrayOop(a)->bool_at_put(index, value->z); 1.259 + break; 1.260 + case T_CHAR: 1.261 + typeArrayOop(a)->char_at_put(index, value->c); 1.262 + break; 1.263 + case T_FLOAT: 1.264 + typeArrayOop(a)->float_at_put(index, value->f); 1.265 + break; 1.266 + case T_DOUBLE: 1.267 + typeArrayOop(a)->double_at_put(index, value->d); 1.268 + break; 1.269 + case T_BYTE: 1.270 + typeArrayOop(a)->byte_at_put(index, value->b); 1.271 + break; 1.272 + case T_SHORT: 1.273 + typeArrayOop(a)->short_at_put(index, value->s); 1.274 + break; 1.275 + case T_INT: 1.276 + typeArrayOop(a)->int_at_put(index, value->i); 1.277 + break; 1.278 + case T_LONG: 1.279 + typeArrayOop(a)->long_at_put(index, value->j); 1.280 + break; 1.281 + default: 1.282 + THROW(vmSymbols::java_lang_IllegalArgumentException()); 1.283 + } 1.284 + } 1.285 +} 1.286 + 1.287 + 1.288 +klassOop Reflection::basic_type_mirror_to_arrayklass(oop basic_type_mirror, TRAPS) { 1.289 + assert(java_lang_Class::is_primitive(basic_type_mirror), "just checking"); 1.290 + BasicType type = java_lang_Class::primitive_type(basic_type_mirror); 1.291 + if (type == T_VOID) { 1.292 + THROW_0(vmSymbols::java_lang_IllegalArgumentException()); 1.293 + } else { 1.294 + return Universe::typeArrayKlassObj(type); 1.295 + } 1.296 +} 1.297 + 1.298 + 1.299 +oop Reflection:: basic_type_arrayklass_to_mirror(klassOop basic_type_arrayklass, TRAPS) { 1.300 + BasicType type = typeArrayKlass::cast(basic_type_arrayklass)->element_type(); 1.301 + return Universe::java_mirror(type); 1.302 +} 1.303 + 1.304 + 1.305 +arrayOop Reflection::reflect_new_array(oop element_mirror, jint length, TRAPS) { 1.306 + if (element_mirror == NULL) { 1.307 + THROW_0(vmSymbols::java_lang_NullPointerException()); 1.308 + } 1.309 + if (length < 0) { 1.310 + THROW_0(vmSymbols::java_lang_NegativeArraySizeException()); 1.311 + } 1.312 + if (java_lang_Class::is_primitive(element_mirror)) { 1.313 + klassOop tak = basic_type_mirror_to_arrayklass(element_mirror, CHECK_NULL); 1.314 + return typeArrayKlass::cast(tak)->allocate(length, THREAD); 1.315 + } else { 1.316 + klassOop k = java_lang_Class::as_klassOop(element_mirror); 1.317 + if (Klass::cast(k)->oop_is_array() && arrayKlass::cast(k)->dimension() >= MAX_DIM) { 1.318 + THROW_0(vmSymbols::java_lang_IllegalArgumentException()); 1.319 + } 1.320 + return oopFactory::new_objArray(k, length, THREAD); 1.321 + } 1.322 +} 1.323 + 1.324 + 1.325 +arrayOop Reflection::reflect_new_multi_array(oop element_mirror, typeArrayOop dim_array, TRAPS) { 1.326 + assert(dim_array->is_typeArray(), "just checking"); 1.327 + assert(typeArrayKlass::cast(dim_array->klass())->element_type() == T_INT, "just checking"); 1.328 + 1.329 + if (element_mirror == NULL) { 1.330 + THROW_0(vmSymbols::java_lang_NullPointerException()); 1.331 + } 1.332 + 1.333 + int len = dim_array->length(); 1.334 + if (len <= 0 || len > MAX_DIM) { 1.335 + THROW_0(vmSymbols::java_lang_IllegalArgumentException()); 1.336 + } 1.337 + 1.338 + jint dimensions[MAX_DIM]; // C array copy of intArrayOop 1.339 + for (int i = 0; i < len; i++) { 1.340 + int d = dim_array->int_at(i); 1.341 + if (d < 0) { 1.342 + THROW_0(vmSymbols::java_lang_NegativeArraySizeException()); 1.343 + } 1.344 + dimensions[i] = d; 1.345 + } 1.346 + 1.347 + klassOop klass; 1.348 + int dim = len; 1.349 + if (java_lang_Class::is_primitive(element_mirror)) { 1.350 + klass = basic_type_mirror_to_arrayklass(element_mirror, CHECK_NULL); 1.351 + } else { 1.352 + klass = java_lang_Class::as_klassOop(element_mirror); 1.353 + if (Klass::cast(klass)->oop_is_array()) { 1.354 + int k_dim = arrayKlass::cast(klass)->dimension(); 1.355 + if (k_dim + len > MAX_DIM) { 1.356 + THROW_0(vmSymbols::java_lang_IllegalArgumentException()); 1.357 + } 1.358 + dim += k_dim; 1.359 + } 1.360 + } 1.361 + klass = Klass::cast(klass)->array_klass(dim, CHECK_NULL); 1.362 + oop obj = arrayKlass::cast(klass)->multi_allocate(len, dimensions, THREAD); 1.363 + assert(obj->is_array(), "just checking"); 1.364 + return arrayOop(obj); 1.365 +} 1.366 + 1.367 + 1.368 +oop Reflection::array_component_type(oop mirror, TRAPS) { 1.369 + if (java_lang_Class::is_primitive(mirror)) { 1.370 + return NULL; 1.371 + } 1.372 + 1.373 + klassOop klass = java_lang_Class::as_klassOop(mirror); 1.374 + if (!Klass::cast(klass)->oop_is_array()) { 1.375 + return NULL; 1.376 + } 1.377 + 1.378 + oop result = arrayKlass::cast(klass)->component_mirror(); 1.379 +#ifdef ASSERT 1.380 + oop result2 = NULL; 1.381 + if (arrayKlass::cast(klass)->dimension() == 1) { 1.382 + if (Klass::cast(klass)->oop_is_typeArray()) { 1.383 + result2 = basic_type_arrayklass_to_mirror(klass, CHECK_NULL); 1.384 + } else { 1.385 + result2 = Klass::cast(objArrayKlass::cast(klass)->element_klass())->java_mirror(); 1.386 + } 1.387 + } else { 1.388 + klassOop lower_dim = arrayKlass::cast(klass)->lower_dimension(); 1.389 + assert(Klass::cast(lower_dim)->oop_is_array(), "just checking"); 1.390 + result2 = Klass::cast(lower_dim)->java_mirror(); 1.391 + } 1.392 + assert(result == result2, "results must be consistent"); 1.393 +#endif //ASSERT 1.394 + return result; 1.395 +} 1.396 + 1.397 + 1.398 +bool Reflection::reflect_check_access(klassOop field_class, AccessFlags acc, klassOop target_class, bool is_method_invoke, TRAPS) { 1.399 + // field_class : declaring class 1.400 + // acc : declared field access 1.401 + // target_class : for protected 1.402 + 1.403 + // Check if field or method is accessible to client. Throw an 1.404 + // IllegalAccessException and return false if not. 1.405 + 1.406 + // The "client" is the class associated with the nearest real frame 1.407 + // getCallerClass already skips Method.invoke frames, so pass 0 in 1.408 + // that case (same as classic). 1.409 + ResourceMark rm(THREAD); 1.410 + assert(THREAD->is_Java_thread(), "sanity check"); 1.411 + klassOop client_class = ((JavaThread *)THREAD)->security_get_caller_class(is_method_invoke ? 0 : 1); 1.412 + 1.413 + if (client_class != field_class) { 1.414 + if (!verify_class_access(client_class, field_class, false) 1.415 + || !verify_field_access(client_class, 1.416 + field_class, 1.417 + field_class, 1.418 + acc, 1.419 + false)) { 1.420 + THROW_(vmSymbols::java_lang_IllegalAccessException(), false); 1.421 + } 1.422 + } 1.423 + 1.424 + // Additional test for protected members: JLS 6.6.2 1.425 + 1.426 + if (acc.is_protected()) { 1.427 + if (target_class != client_class) { 1.428 + if (!is_same_class_package(client_class, field_class)) { 1.429 + if (!Klass::cast(target_class)->is_subclass_of(client_class)) { 1.430 + THROW_(vmSymbols::java_lang_IllegalAccessException(), false); 1.431 + } 1.432 + } 1.433 + } 1.434 + } 1.435 + 1.436 + // Passed all tests 1.437 + return true; 1.438 +} 1.439 + 1.440 + 1.441 +bool Reflection::verify_class_access(klassOop current_class, klassOop new_class, bool classloader_only) { 1.442 + // Verify that current_class can access new_class. If the classloader_only 1.443 + // flag is set, we automatically allow any accesses in which current_class 1.444 + // doesn't have a classloader. 1.445 + if ((current_class == NULL) || 1.446 + (current_class == new_class) || 1.447 + (instanceKlass::cast(new_class)->is_public()) || 1.448 + is_same_class_package(current_class, new_class)) { 1.449 + return true; 1.450 + } 1.451 + // New (1.4) reflection implementation. Allow all accesses from 1.452 + // sun/reflect/MagicAccessorImpl subclasses to succeed trivially. 1.453 + if ( JDK_Version::is_gte_jdk14x_version() 1.454 + && UseNewReflection 1.455 + && Klass::cast(current_class)->is_subclass_of(SystemDictionary::reflect_magic_klass())) { 1.456 + return true; 1.457 + } 1.458 + 1.459 + return can_relax_access_check_for(current_class, new_class, classloader_only); 1.460 +} 1.461 + 1.462 +bool Reflection::can_relax_access_check_for( 1.463 + klassOop accessor, klassOop accessee, bool classloader_only) { 1.464 + instanceKlass* accessor_ik = instanceKlass::cast(accessor); 1.465 + instanceKlass* accessee_ik = instanceKlass::cast(accessee); 1.466 + if (RelaxAccessControlCheck || 1.467 + (accessor_ik->major_version() < JAVA_1_5_VERSION && 1.468 + accessee_ik->major_version() < JAVA_1_5_VERSION)) { 1.469 + return classloader_only && 1.470 + Verifier::relax_verify_for(accessor_ik->class_loader()) && 1.471 + accessor_ik->protection_domain() == accessee_ik->protection_domain() && 1.472 + accessor_ik->class_loader() == accessee_ik->class_loader(); 1.473 + } else { 1.474 + return false; 1.475 + } 1.476 +} 1.477 + 1.478 +bool Reflection::verify_field_access(klassOop current_class, 1.479 + klassOop resolved_class, 1.480 + klassOop field_class, 1.481 + AccessFlags access, 1.482 + bool classloader_only, 1.483 + bool protected_restriction) { 1.484 + // Verify that current_class can access a field of field_class, where that 1.485 + // field's access bits are "access". We assume that we've already verified 1.486 + // that current_class can access field_class. 1.487 + // 1.488 + // If the classloader_only flag is set, we automatically allow any accesses 1.489 + // in which current_class doesn't have a classloader. 1.490 + // 1.491 + // "resolved_class" is the runtime type of "field_class". Sometimes we don't 1.492 + // need this distinction (e.g. if all we have is the runtime type, or during 1.493 + // class file parsing when we only care about the static type); in that case 1.494 + // callers should ensure that resolved_class == field_class. 1.495 + // 1.496 + if ((current_class == NULL) || 1.497 + (current_class == field_class) || 1.498 + access.is_public()) { 1.499 + return true; 1.500 + } 1.501 + 1.502 + if (access.is_protected()) { 1.503 + if (!protected_restriction) { 1.504 + // See if current_class is a subclass of field_class 1.505 + if (Klass::cast(current_class)->is_subclass_of(field_class)) { 1.506 + if (current_class == resolved_class || 1.507 + field_class == resolved_class || 1.508 + Klass::cast(current_class)->is_subclass_of(resolved_class) || 1.509 + Klass::cast(resolved_class)->is_subclass_of(current_class)) { 1.510 + return true; 1.511 + } 1.512 + } 1.513 + } 1.514 + } 1.515 + 1.516 + if (!access.is_private() && is_same_class_package(current_class, field_class)) { 1.517 + return true; 1.518 + } 1.519 + 1.520 + // New (1.4) reflection implementation. Allow all accesses from 1.521 + // sun/reflect/MagicAccessorImpl subclasses to succeed trivially. 1.522 + if ( JDK_Version::is_gte_jdk14x_version() 1.523 + && UseNewReflection 1.524 + && Klass::cast(current_class)->is_subclass_of(SystemDictionary::reflect_magic_klass())) { 1.525 + return true; 1.526 + } 1.527 + 1.528 + return can_relax_access_check_for( 1.529 + current_class, field_class, classloader_only); 1.530 +} 1.531 + 1.532 + 1.533 +bool Reflection::is_same_class_package(klassOop class1, klassOop class2) { 1.534 + return instanceKlass::cast(class1)->is_same_class_package(class2); 1.535 +} 1.536 + 1.537 + 1.538 +// Checks that the 'outer' klass has declared 'inner' as being an inner klass. If not, 1.539 +// throw an incompatible class change exception 1.540 +void Reflection::check_for_inner_class(instanceKlassHandle outer, instanceKlassHandle inner, TRAPS) { 1.541 + const int inner_class_info_index = 0; 1.542 + const int outer_class_info_index = 1; 1.543 + 1.544 + typeArrayHandle icls (THREAD, outer->inner_classes()); 1.545 + constantPoolHandle cp (THREAD, outer->constants()); 1.546 + for(int i = 0; i < icls->length(); i += 4) { 1.547 + int ioff = icls->ushort_at(i + inner_class_info_index); 1.548 + int ooff = icls->ushort_at(i + outer_class_info_index); 1.549 + 1.550 + if (ioff != 0 && ooff != 0) { 1.551 + klassOop o = cp->klass_at(ooff, CHECK); 1.552 + if (o == outer()) { 1.553 + klassOop i = cp->klass_at(ioff, CHECK); 1.554 + if (i == inner()) { 1.555 + return; 1.556 + } 1.557 + } 1.558 + } 1.559 + } 1.560 + 1.561 + // 'inner' not declared as an inner klass in outer 1.562 + ResourceMark rm(THREAD); 1.563 + Exceptions::fthrow( 1.564 + THREAD_AND_LOCATION, 1.565 + vmSymbolHandles::java_lang_IncompatibleClassChangeError(), 1.566 + "%s and %s disagree on InnerClasses attribute", 1.567 + outer->external_name(), 1.568 + inner->external_name() 1.569 + ); 1.570 +} 1.571 + 1.572 +// Utility method converting a single SignatureStream element into java.lang.Class instance 1.573 + 1.574 +oop get_mirror_from_signature(methodHandle method, SignatureStream* ss, TRAPS) { 1.575 + switch (ss->type()) { 1.576 + default: 1.577 + assert(ss->type() != T_VOID || ss->at_return_type(), "T_VOID should only appear as return type"); 1.578 + return java_lang_Class::primitive_mirror(ss->type()); 1.579 + case T_OBJECT: 1.580 + case T_ARRAY: 1.581 + symbolOop name = ss->as_symbol(CHECK_NULL); 1.582 + oop loader = instanceKlass::cast(method->method_holder())->class_loader(); 1.583 + oop protection_domain = instanceKlass::cast(method->method_holder())->protection_domain(); 1.584 + klassOop k = SystemDictionary::resolve_or_fail( 1.585 + symbolHandle(THREAD, name), 1.586 + Handle(THREAD, loader), 1.587 + Handle(THREAD, protection_domain), 1.588 + true, CHECK_NULL); 1.589 + if (TraceClassResolution) { 1.590 + trace_class_resolution(k); 1.591 + } 1.592 + return k->klass_part()->java_mirror(); 1.593 + }; 1.594 +} 1.595 + 1.596 + 1.597 +objArrayHandle Reflection::get_parameter_types(methodHandle method, int parameter_count, oop* return_type, TRAPS) { 1.598 + // Allocate array holding parameter types (java.lang.Class instances) 1.599 + objArrayOop m = oopFactory::new_objArray(SystemDictionary::class_klass(), parameter_count, CHECK_(objArrayHandle())); 1.600 + objArrayHandle mirrors (THREAD, m); 1.601 + int index = 0; 1.602 + // Collect parameter types 1.603 + symbolHandle signature (THREAD, method->signature()); 1.604 + SignatureStream ss(signature); 1.605 + while (!ss.at_return_type()) { 1.606 + oop mirror = get_mirror_from_signature(method, &ss, CHECK_(objArrayHandle())); 1.607 + mirrors->obj_at_put(index++, mirror); 1.608 + ss.next(); 1.609 + } 1.610 + assert(index == parameter_count, "invalid parameter count"); 1.611 + if (return_type != NULL) { 1.612 + // Collect return type as well 1.613 + assert(ss.at_return_type(), "return type should be present"); 1.614 + *return_type = get_mirror_from_signature(method, &ss, CHECK_(objArrayHandle())); 1.615 + } 1.616 + return mirrors; 1.617 +} 1.618 + 1.619 +objArrayHandle Reflection::get_exception_types(methodHandle method, TRAPS) { 1.620 + return method->resolved_checked_exceptions(CHECK_(objArrayHandle())); 1.621 +} 1.622 + 1.623 + 1.624 +Handle Reflection::new_type(symbolHandle signature, KlassHandle k, TRAPS) { 1.625 + // Basic types 1.626 + BasicType type = vmSymbols::signature_type(signature()); 1.627 + if (type != T_OBJECT) { 1.628 + return Handle(THREAD, Universe::java_mirror(type)); 1.629 + } 1.630 + 1.631 + oop loader = instanceKlass::cast(k())->class_loader(); 1.632 + oop protection_domain = Klass::cast(k())->protection_domain(); 1.633 + klassOop result = SystemDictionary::resolve_or_fail(signature, 1.634 + Handle(THREAD, loader), 1.635 + Handle(THREAD, protection_domain), 1.636 + true, CHECK_(Handle())); 1.637 + 1.638 + if (TraceClassResolution) { 1.639 + trace_class_resolution(result); 1.640 + } 1.641 + 1.642 + oop nt = Klass::cast(result)->java_mirror(); 1.643 + return Handle(THREAD, nt); 1.644 +} 1.645 + 1.646 + 1.647 +oop Reflection::new_method(methodHandle method, bool intern_name, bool for_constant_pool_access, TRAPS) { 1.648 + // In jdk1.2.x, getMethods on an interface erroneously includes <clinit>, thus the complicated assert. 1.649 + // Also allow sun.reflect.ConstantPool to refer to <clinit> methods as java.lang.reflect.Methods. 1.650 + assert(!method()->is_initializer() || 1.651 + (for_constant_pool_access && method()->is_static()) || 1.652 + (method()->name() == vmSymbols::class_initializer_name() 1.653 + && Klass::cast(method()->method_holder())->is_interface() && JDK_Version::is_jdk12x_version()), "should call new_constructor instead"); 1.654 + instanceKlassHandle holder (THREAD, method->method_holder()); 1.655 + int slot = method->method_idnum(); 1.656 + 1.657 + symbolHandle signature (THREAD, method->signature()); 1.658 + int parameter_count = ArgumentCount(signature).size(); 1.659 + oop return_type_oop = NULL; 1.660 + objArrayHandle parameter_types = get_parameter_types(method, parameter_count, &return_type_oop, CHECK_NULL); 1.661 + if (parameter_types.is_null() || return_type_oop == NULL) return NULL; 1.662 + 1.663 + Handle return_type(THREAD, return_type_oop); 1.664 + 1.665 + objArrayHandle exception_types = get_exception_types(method, CHECK_NULL); 1.666 + 1.667 + if (exception_types.is_null()) return NULL; 1.668 + 1.669 + symbolHandle method_name(THREAD, method->name()); 1.670 + Handle name; 1.671 + if (intern_name) { 1.672 + // intern_name is only true with UseNewReflection 1.673 + oop name_oop = StringTable::intern(method_name(), CHECK_NULL); 1.674 + name = Handle(THREAD, name_oop); 1.675 + } else { 1.676 + name = java_lang_String::create_from_symbol(method_name, CHECK_NULL); 1.677 + } 1.678 + if (name.is_null()) return NULL; 1.679 + 1.680 + int modifiers = method->access_flags().as_int() & JVM_RECOGNIZED_METHOD_MODIFIERS; 1.681 + 1.682 + Handle mh = java_lang_reflect_Method::create(CHECK_NULL); 1.683 + 1.684 + java_lang_reflect_Method::set_clazz(mh(), holder->java_mirror()); 1.685 + java_lang_reflect_Method::set_slot(mh(), slot); 1.686 + java_lang_reflect_Method::set_name(mh(), name()); 1.687 + java_lang_reflect_Method::set_return_type(mh(), return_type()); 1.688 + java_lang_reflect_Method::set_parameter_types(mh(), parameter_types()); 1.689 + java_lang_reflect_Method::set_exception_types(mh(), exception_types()); 1.690 + java_lang_reflect_Method::set_modifiers(mh(), modifiers); 1.691 + java_lang_reflect_Method::set_override(mh(), false); 1.692 + if (java_lang_reflect_Method::has_signature_field() && 1.693 + method->generic_signature() != NULL) { 1.694 + symbolHandle gs(THREAD, method->generic_signature()); 1.695 + Handle sig = java_lang_String::create_from_symbol(gs, CHECK_NULL); 1.696 + java_lang_reflect_Method::set_signature(mh(), sig()); 1.697 + } 1.698 + if (java_lang_reflect_Method::has_annotations_field()) { 1.699 + java_lang_reflect_Method::set_annotations(mh(), method->annotations()); 1.700 + } 1.701 + if (java_lang_reflect_Method::has_parameter_annotations_field()) { 1.702 + java_lang_reflect_Method::set_parameter_annotations(mh(), method->parameter_annotations()); 1.703 + } 1.704 + if (java_lang_reflect_Method::has_annotation_default_field()) { 1.705 + java_lang_reflect_Method::set_annotation_default(mh(), method->annotation_default()); 1.706 + } 1.707 + return mh(); 1.708 +} 1.709 + 1.710 + 1.711 +oop Reflection::new_constructor(methodHandle method, TRAPS) { 1.712 + assert(method()->is_initializer(), "should call new_method instead"); 1.713 + 1.714 + instanceKlassHandle holder (THREAD, method->method_holder()); 1.715 + int slot = method->method_idnum(); 1.716 + 1.717 + symbolHandle signature (THREAD, method->signature()); 1.718 + int parameter_count = ArgumentCount(signature).size(); 1.719 + objArrayHandle parameter_types = get_parameter_types(method, parameter_count, NULL, CHECK_NULL); 1.720 + if (parameter_types.is_null()) return NULL; 1.721 + 1.722 + objArrayHandle exception_types = get_exception_types(method, CHECK_NULL); 1.723 + if (exception_types.is_null()) return NULL; 1.724 + 1.725 + int modifiers = method->access_flags().as_int() & JVM_RECOGNIZED_METHOD_MODIFIERS; 1.726 + 1.727 + Handle ch = java_lang_reflect_Constructor::create(CHECK_NULL); 1.728 + 1.729 + java_lang_reflect_Constructor::set_clazz(ch(), holder->java_mirror()); 1.730 + java_lang_reflect_Constructor::set_slot(ch(), slot); 1.731 + java_lang_reflect_Constructor::set_parameter_types(ch(), parameter_types()); 1.732 + java_lang_reflect_Constructor::set_exception_types(ch(), exception_types()); 1.733 + java_lang_reflect_Constructor::set_modifiers(ch(), modifiers); 1.734 + java_lang_reflect_Constructor::set_override(ch(), false); 1.735 + if (java_lang_reflect_Constructor::has_signature_field() && 1.736 + method->generic_signature() != NULL) { 1.737 + symbolHandle gs(THREAD, method->generic_signature()); 1.738 + Handle sig = java_lang_String::create_from_symbol(gs, CHECK_NULL); 1.739 + java_lang_reflect_Constructor::set_signature(ch(), sig()); 1.740 + } 1.741 + if (java_lang_reflect_Constructor::has_annotations_field()) { 1.742 + java_lang_reflect_Constructor::set_annotations(ch(), method->annotations()); 1.743 + } 1.744 + if (java_lang_reflect_Constructor::has_parameter_annotations_field()) { 1.745 + java_lang_reflect_Constructor::set_parameter_annotations(ch(), method->parameter_annotations()); 1.746 + } 1.747 + return ch(); 1.748 +} 1.749 + 1.750 + 1.751 +oop Reflection::new_field(fieldDescriptor* fd, bool intern_name, TRAPS) { 1.752 + symbolHandle field_name(THREAD, fd->name()); 1.753 + Handle name; 1.754 + if (intern_name) { 1.755 + // intern_name is only true with UseNewReflection 1.756 + oop name_oop = StringTable::intern(field_name(), CHECK_NULL); 1.757 + name = Handle(THREAD, name_oop); 1.758 + } else { 1.759 + name = java_lang_String::create_from_symbol(field_name, CHECK_NULL); 1.760 + } 1.761 + symbolHandle signature (THREAD, fd->signature()); 1.762 + KlassHandle holder (THREAD, fd->field_holder()); 1.763 + Handle type = new_type(signature, holder, CHECK_NULL); 1.764 + Handle rh = java_lang_reflect_Field::create(CHECK_NULL); 1.765 + 1.766 + java_lang_reflect_Field::set_clazz(rh(), Klass::cast(fd->field_holder())->java_mirror()); 1.767 + java_lang_reflect_Field::set_slot(rh(), fd->index()); 1.768 + java_lang_reflect_Field::set_name(rh(), name()); 1.769 + java_lang_reflect_Field::set_type(rh(), type()); 1.770 + // Note the ACC_ANNOTATION bit, which is a per-class access flag, is never set here. 1.771 + java_lang_reflect_Field::set_modifiers(rh(), fd->access_flags().as_int() & JVM_RECOGNIZED_FIELD_MODIFIERS); 1.772 + java_lang_reflect_Field::set_override(rh(), false); 1.773 + if (java_lang_reflect_Field::has_signature_field() && 1.774 + fd->generic_signature() != NULL) { 1.775 + symbolHandle gs(THREAD, fd->generic_signature()); 1.776 + Handle sig = java_lang_String::create_from_symbol(gs, CHECK_NULL); 1.777 + java_lang_reflect_Field::set_signature(rh(), sig()); 1.778 + } 1.779 + if (java_lang_reflect_Field::has_annotations_field()) { 1.780 + java_lang_reflect_Field::set_annotations(rh(), fd->annotations()); 1.781 + } 1.782 + return rh(); 1.783 +} 1.784 + 1.785 + 1.786 +//--------------------------------------------------------------------------- 1.787 +// 1.788 +// Supporting routines for old native code-based reflection (pre-JDK 1.4). 1.789 +// 1.790 +// See reflection.hpp for details. 1.791 +// 1.792 +//--------------------------------------------------------------------------- 1.793 + 1.794 +#ifdef SUPPORT_OLD_REFLECTION 1.795 + 1.796 +methodHandle Reflection::resolve_interface_call(instanceKlassHandle klass, methodHandle method, 1.797 + KlassHandle recv_klass, Handle receiver, TRAPS) { 1.798 + assert(!method.is_null() , "method should not be null"); 1.799 + 1.800 + CallInfo info; 1.801 + symbolHandle signature (THREAD, method->signature()); 1.802 + symbolHandle name (THREAD, method->name()); 1.803 + LinkResolver::resolve_interface_call(info, receiver, recv_klass, klass, 1.804 + name, signature, 1.805 + KlassHandle(), false, true, 1.806 + CHECK_(methodHandle())); 1.807 + return info.selected_method(); 1.808 +} 1.809 + 1.810 + 1.811 +oop Reflection::invoke(instanceKlassHandle klass, methodHandle reflected_method, 1.812 + Handle receiver, bool override, objArrayHandle ptypes, 1.813 + BasicType rtype, objArrayHandle args, bool is_method_invoke, TRAPS) { 1.814 + ResourceMark rm(THREAD); 1.815 + 1.816 + methodHandle method; // actual method to invoke 1.817 + KlassHandle target_klass; // target klass, receiver's klass for non-static 1.818 + 1.819 + // Ensure klass is initialized 1.820 + klass->initialize(CHECK_NULL); 1.821 + 1.822 + bool is_static = reflected_method->is_static(); 1.823 + if (is_static) { 1.824 + // ignore receiver argument 1.825 + method = reflected_method; 1.826 + target_klass = klass; 1.827 + } else { 1.828 + // check for null receiver 1.829 + if (receiver.is_null()) { 1.830 + THROW_0(vmSymbols::java_lang_NullPointerException()); 1.831 + } 1.832 + // Check class of receiver against class declaring method 1.833 + if (!receiver->is_a(klass())) { 1.834 + THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(), "object is not an instance of declaring class"); 1.835 + } 1.836 + // target klass is receiver's klass 1.837 + target_klass = KlassHandle(THREAD, receiver->klass()); 1.838 + // no need to resolve if method is private or <init> 1.839 + if (reflected_method->is_private() || reflected_method->name() == vmSymbols::object_initializer_name()) { 1.840 + method = reflected_method; 1.841 + } else { 1.842 + // resolve based on the receiver 1.843 + if (instanceKlass::cast(reflected_method->method_holder())->is_interface()) { 1.844 + // resolve interface call 1.845 + if (ReflectionWrapResolutionErrors) { 1.846 + // new default: 6531596 1.847 + // Match resolution errors with those thrown due to reflection inlining 1.848 + // Linktime resolution & IllegalAccessCheck already done by Class.getMethod() 1.849 + method = resolve_interface_call(klass, reflected_method, target_klass, receiver, THREAD); 1.850 + if (HAS_PENDING_EXCEPTION) { 1.851 + // Method resolution threw an exception; wrap it in an InvocationTargetException 1.852 + oop resolution_exception = PENDING_EXCEPTION; 1.853 + CLEAR_PENDING_EXCEPTION; 1.854 + JavaCallArguments args(Handle(THREAD, resolution_exception)); 1.855 + THROW_ARG_0(vmSymbolHandles::java_lang_reflect_InvocationTargetException(), 1.856 + vmSymbolHandles::throwable_void_signature(), 1.857 + &args); 1.858 + } 1.859 + } else { 1.860 + method = resolve_interface_call(klass, reflected_method, target_klass, receiver, CHECK_(NULL)); 1.861 + } 1.862 + } else { 1.863 + // if the method can be overridden, we resolve using the vtable index. 1.864 + int index = reflected_method->vtable_index(); 1.865 + method = reflected_method; 1.866 + if (index != methodOopDesc::nonvirtual_vtable_index) { 1.867 + // target_klass might be an arrayKlassOop but all vtables start at 1.868 + // the same place. The cast is to avoid virtual call and assertion. 1.869 + instanceKlass* inst = (instanceKlass*)target_klass()->klass_part(); 1.870 + method = methodHandle(THREAD, inst->method_at_vtable(index)); 1.871 + } 1.872 + if (!method.is_null()) { 1.873 + // Check for abstract methods as well 1.874 + if (method->is_abstract()) { 1.875 + // new default: 6531596 1.876 + if (ReflectionWrapResolutionErrors) { 1.877 + ResourceMark rm(THREAD); 1.878 + Handle h_origexception = Exceptions::new_exception(THREAD, 1.879 + vmSymbols::java_lang_AbstractMethodError(), 1.880 + methodOopDesc::name_and_sig_as_C_string(Klass::cast(target_klass()), 1.881 + method->name(), 1.882 + method->signature())); 1.883 + JavaCallArguments args(h_origexception); 1.884 + THROW_ARG_0(vmSymbolHandles::java_lang_reflect_InvocationTargetException(), 1.885 + vmSymbolHandles::throwable_void_signature(), 1.886 + &args); 1.887 + } else { 1.888 + ResourceMark rm(THREAD); 1.889 + THROW_MSG_0(vmSymbols::java_lang_AbstractMethodError(), 1.890 + methodOopDesc::name_and_sig_as_C_string(Klass::cast(target_klass()), 1.891 + method->name(), 1.892 + method->signature())); 1.893 + } 1.894 + } 1.895 + } 1.896 + } 1.897 + } 1.898 + } 1.899 + 1.900 + // I believe this is a ShouldNotGetHere case which requires 1.901 + // an internal vtable bug. If you ever get this please let Karen know. 1.902 + if (method.is_null()) { 1.903 + ResourceMark rm(THREAD); 1.904 + THROW_MSG_0(vmSymbols::java_lang_NoSuchMethodError(), 1.905 + methodOopDesc::name_and_sig_as_C_string(Klass::cast(klass()), 1.906 + reflected_method->name(), 1.907 + reflected_method->signature())); 1.908 + } 1.909 + 1.910 + // In the JDK 1.4 reflection implementation, the security check is 1.911 + // done at the Java level 1.912 + if (!(JDK_Version::is_gte_jdk14x_version() && UseNewReflection)) { 1.913 + 1.914 + // Access checking (unless overridden by Method) 1.915 + if (!override) { 1.916 + if (!(klass->is_public() && reflected_method->is_public())) { 1.917 + bool access = Reflection::reflect_check_access(klass(), reflected_method->access_flags(), target_klass(), is_method_invoke, CHECK_NULL); 1.918 + if (!access) { 1.919 + return NULL; // exception 1.920 + } 1.921 + } 1.922 + } 1.923 + 1.924 + } // !(Universe::is_gte_jdk14x_version() && UseNewReflection) 1.925 + 1.926 + assert(ptypes->is_objArray(), "just checking"); 1.927 + int args_len = args.is_null() ? 0 : args->length(); 1.928 + // Check number of arguments 1.929 + if (ptypes->length() != args_len) { 1.930 + THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(), "wrong number of arguments"); 1.931 + } 1.932 + 1.933 + // Create object to contain parameters for the JavaCall 1.934 + JavaCallArguments java_args(method->size_of_parameters()); 1.935 + 1.936 + if (!is_static) { 1.937 + java_args.push_oop(receiver); 1.938 + } 1.939 + 1.940 + for (int i = 0; i < args_len; i++) { 1.941 + oop type_mirror = ptypes->obj_at(i); 1.942 + oop arg = args->obj_at(i); 1.943 + if (java_lang_Class::is_primitive(type_mirror)) { 1.944 + jvalue value; 1.945 + BasicType ptype = basic_type_mirror_to_basic_type(type_mirror, CHECK_NULL); 1.946 + BasicType atype = unbox_for_primitive(arg, &value, CHECK_NULL); 1.947 + if (ptype != atype) { 1.948 + widen(&value, atype, ptype, CHECK_NULL); 1.949 + } 1.950 + switch (ptype) { 1.951 + case T_BOOLEAN: java_args.push_int(value.z); break; 1.952 + case T_CHAR: java_args.push_int(value.c); break; 1.953 + case T_BYTE: java_args.push_int(value.b); break; 1.954 + case T_SHORT: java_args.push_int(value.s); break; 1.955 + case T_INT: java_args.push_int(value.i); break; 1.956 + case T_LONG: java_args.push_long(value.j); break; 1.957 + case T_FLOAT: java_args.push_float(value.f); break; 1.958 + case T_DOUBLE: java_args.push_double(value.d); break; 1.959 + default: 1.960 + THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(), "argument type mismatch"); 1.961 + } 1.962 + } else { 1.963 + if (arg != NULL) { 1.964 + klassOop k = java_lang_Class::as_klassOop(type_mirror); 1.965 + if (!arg->is_a(k)) { 1.966 + THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(), "argument type mismatch"); 1.967 + } 1.968 + } 1.969 + Handle arg_handle(THREAD, arg); // Create handle for argument 1.970 + java_args.push_oop(arg_handle); // Push handle 1.971 + } 1.972 + } 1.973 + 1.974 + assert(java_args.size_of_parameters() == method->size_of_parameters(), "just checking"); 1.975 + 1.976 + // All oops (including receiver) is passed in as Handles. An potential oop is returned as an 1.977 + // oop (i.e., NOT as an handle) 1.978 + JavaValue result(rtype); 1.979 + JavaCalls::call(&result, method, &java_args, THREAD); 1.980 + 1.981 + if (HAS_PENDING_EXCEPTION) { 1.982 + // Method threw an exception; wrap it in an InvocationTargetException 1.983 + oop target_exception = PENDING_EXCEPTION; 1.984 + CLEAR_PENDING_EXCEPTION; 1.985 + JavaCallArguments args(Handle(THREAD, target_exception)); 1.986 + THROW_ARG_0(vmSymbolHandles::java_lang_reflect_InvocationTargetException(), 1.987 + vmSymbolHandles::throwable_void_signature(), 1.988 + &args); 1.989 + } else { 1.990 + if (rtype == T_BOOLEAN || rtype == T_BYTE || rtype == T_CHAR || rtype == T_SHORT) 1.991 + narrow((jvalue*) result.get_value_addr(), rtype, CHECK_NULL); 1.992 + return box((jvalue*) result.get_value_addr(), rtype, CHECK_NULL); 1.993 + } 1.994 +} 1.995 + 1.996 + 1.997 +void Reflection::narrow(jvalue* value, BasicType narrow_type, TRAPS) { 1.998 + switch (narrow_type) { 1.999 + case T_BOOLEAN: 1.1000 + value->z = (jboolean) value->i; 1.1001 + return; 1.1002 + case T_BYTE: 1.1003 + value->b = (jbyte) value->i; 1.1004 + return; 1.1005 + case T_CHAR: 1.1006 + value->c = (jchar) value->i; 1.1007 + return; 1.1008 + case T_SHORT: 1.1009 + value->s = (jshort) value->i; 1.1010 + return; 1.1011 + default: 1.1012 + break; // fail 1.1013 + } 1.1014 + THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), "argument type mismatch"); 1.1015 +} 1.1016 + 1.1017 + 1.1018 +BasicType Reflection::basic_type_mirror_to_basic_type(oop basic_type_mirror, TRAPS) { 1.1019 + assert(java_lang_Class::is_primitive(basic_type_mirror), "just checking"); 1.1020 + return java_lang_Class::primitive_type(basic_type_mirror); 1.1021 +} 1.1022 + 1.1023 + 1.1024 +bool Reflection::match_parameter_types(methodHandle method, objArrayHandle types, int parameter_count, TRAPS) { 1.1025 + int types_len = types.is_null() ? 0 : types->length(); 1.1026 + if (types_len != parameter_count) return false; 1.1027 + if (parameter_count > 0) { 1.1028 + objArrayHandle method_types = get_parameter_types(method, parameter_count, NULL, CHECK_false); 1.1029 + for (int index = 0; index < parameter_count; index++) { 1.1030 + if (types->obj_at(index) != method_types->obj_at(index)) { 1.1031 + return false; 1.1032 + } 1.1033 + } 1.1034 + } 1.1035 + return true; 1.1036 +} 1.1037 + 1.1038 + 1.1039 +oop Reflection::new_field(FieldStream* st, TRAPS) { 1.1040 + symbolHandle field_name(THREAD, st->name()); 1.1041 + Handle name = java_lang_String::create_from_symbol(field_name, CHECK_NULL); 1.1042 + symbolHandle signature(THREAD, st->signature()); 1.1043 + Handle type = new_type(signature, st->klass(), CHECK_NULL); 1.1044 + Handle rh = java_lang_reflect_Field::create(CHECK_NULL); 1.1045 + oop result = rh(); 1.1046 + 1.1047 + java_lang_reflect_Field::set_clazz(result, st->klass()->java_mirror()); 1.1048 + java_lang_reflect_Field::set_slot(result, st->index()); 1.1049 + java_lang_reflect_Field::set_name(result, name()); 1.1050 + java_lang_reflect_Field::set_type(result, type()); 1.1051 + // Note the ACC_ANNOTATION bit, which is a per-class access flag, is never set here. 1.1052 + java_lang_reflect_Field::set_modifiers(result, st->access_flags().as_int() & JVM_RECOGNIZED_FIELD_MODIFIERS); 1.1053 + java_lang_reflect_Field::set_override(result, false); 1.1054 + return result; 1.1055 +} 1.1056 + 1.1057 + 1.1058 +bool Reflection::resolve_field(Handle field_mirror, Handle& receiver, fieldDescriptor* fd, bool check_final, TRAPS) { 1.1059 + if (field_mirror.is_null()) { 1.1060 + THROW_(vmSymbols::java_lang_NullPointerException(), false); 1.1061 + } 1.1062 + 1.1063 + instanceKlassHandle klass (THREAD, java_lang_Class::as_klassOop(java_lang_reflect_Field::clazz(field_mirror()))); 1.1064 + int slot = java_lang_reflect_Field::slot(field_mirror()); 1.1065 + 1.1066 + // Ensure klass is initialized 1.1067 + klass->initialize(CHECK_false); 1.1068 + fd->initialize(klass(), slot); 1.1069 + 1.1070 + bool is_static = fd->is_static(); 1.1071 + KlassHandle receiver_klass; 1.1072 + 1.1073 + if (is_static) { 1.1074 + receiver = KlassHandle(THREAD, klass()); 1.1075 + receiver_klass = klass; 1.1076 + } else { 1.1077 + // Check object is a non-null instance of declaring class 1.1078 + if (receiver.is_null()) { 1.1079 + THROW_(vmSymbols::java_lang_NullPointerException(), false); 1.1080 + } 1.1081 + if (!receiver->is_a(klass())) { 1.1082 + THROW_MSG_(vmSymbols::java_lang_IllegalArgumentException(), "object is not an instance of declaring class", false); 1.1083 + } 1.1084 + receiver_klass = KlassHandle(THREAD, receiver->klass()); 1.1085 + } 1.1086 + 1.1087 + // Access checking (unless overridden by Field) 1.1088 + if (!java_lang_reflect_Field::override(field_mirror())) { 1.1089 + if (!(klass->is_public() && fd->is_public())) { 1.1090 + bool access_check = reflect_check_access(klass(), fd->access_flags(), receiver_klass(), false, CHECK_false); 1.1091 + if (!access_check) { 1.1092 + return false; // exception 1.1093 + } 1.1094 + } 1.1095 + } 1.1096 + 1.1097 + if (check_final && fd->is_final()) { 1.1098 + // In 1.3 we always throw an error when attempting to set a final field. 1.1099 + // In 1.2.x, this was allowed in the override bit was set by calling Field.setAccessible(true). 1.1100 + // We currently maintain backwards compatibility. See bug 4250960. 1.1101 + bool strict_final_check = !JDK_Version::is_jdk12x_version(); 1.1102 + if (strict_final_check || !java_lang_reflect_Field::override(field_mirror())) { 1.1103 + THROW_MSG_(vmSymbols::java_lang_IllegalAccessException(), "field is final", false); 1.1104 + } 1.1105 + } 1.1106 + return true; 1.1107 +} 1.1108 + 1.1109 + 1.1110 +BasicType Reflection::field_get(jvalue* value, fieldDescriptor* fd, Handle receiver) { 1.1111 + BasicType field_type = fd->field_type(); 1.1112 + int offset = fd->offset(); 1.1113 + switch (field_type) { 1.1114 + case T_BOOLEAN: 1.1115 + value->z = receiver->bool_field(offset); 1.1116 + break; 1.1117 + case T_CHAR: 1.1118 + value->c = receiver->char_field(offset); 1.1119 + break; 1.1120 + case T_FLOAT: 1.1121 + value->f = receiver->float_field(offset); 1.1122 + break; 1.1123 + case T_DOUBLE: 1.1124 + value->d = receiver->double_field(offset); 1.1125 + break; 1.1126 + case T_BYTE: 1.1127 + value->b = receiver->byte_field(offset); 1.1128 + break; 1.1129 + case T_SHORT: 1.1130 + value->s = receiver->short_field(offset); 1.1131 + break; 1.1132 + case T_INT: 1.1133 + value->i = receiver->int_field(offset); 1.1134 + break; 1.1135 + case T_LONG: 1.1136 + value->j = receiver->long_field(offset); 1.1137 + break; 1.1138 + case T_OBJECT: 1.1139 + case T_ARRAY: 1.1140 + value->l = (jobject) receiver->obj_field(offset); 1.1141 + break; 1.1142 + default: 1.1143 + return T_ILLEGAL; 1.1144 + } 1.1145 + return field_type; 1.1146 +} 1.1147 + 1.1148 + 1.1149 +void Reflection::field_set(jvalue* value, fieldDescriptor* fd, Handle receiver, BasicType value_type, TRAPS) { 1.1150 + BasicType field_type = fd->field_type(); 1.1151 + if (field_type != value_type) { 1.1152 + widen(value, value_type, field_type, CHECK); 1.1153 + } 1.1154 + 1.1155 + int offset = fd->offset(); 1.1156 + switch (field_type) { 1.1157 + case T_BOOLEAN: 1.1158 + receiver->bool_field_put(offset, value->z); 1.1159 + break; 1.1160 + case T_CHAR: 1.1161 + receiver->char_field_put(offset, value->c); 1.1162 + break; 1.1163 + case T_FLOAT: 1.1164 + receiver->float_field_put(offset, value->f); 1.1165 + break; 1.1166 + case T_DOUBLE: 1.1167 + receiver->double_field_put(offset, value->d); 1.1168 + break; 1.1169 + case T_BYTE: 1.1170 + receiver->byte_field_put(offset, value->b); 1.1171 + break; 1.1172 + case T_SHORT: 1.1173 + receiver->short_field_put(offset, value->s); 1.1174 + break; 1.1175 + case T_INT: 1.1176 + receiver->int_field_put(offset, value->i); 1.1177 + break; 1.1178 + case T_LONG: 1.1179 + receiver->long_field_put(offset, value->j); 1.1180 + break; 1.1181 + case T_OBJECT: 1.1182 + case T_ARRAY: { 1.1183 + Handle obj(THREAD, (oop) value->l); 1.1184 + if (obj.not_null()) { 1.1185 + symbolHandle signature(THREAD, fd->signature()); 1.1186 + Handle loader (THREAD, fd->loader()); 1.1187 + Handle protect (THREAD, Klass::cast(fd->field_holder())->protection_domain()); 1.1188 + klassOop k = SystemDictionary::resolve_or_fail(signature, loader, protect, true, CHECK); // may block 1.1189 + if (!obj->is_a(k)) { 1.1190 + THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), "field type mismatch"); 1.1191 + } 1.1192 + } 1.1193 + receiver->obj_field_put(offset, obj()); 1.1194 + break; 1.1195 + } 1.1196 + default: 1.1197 + THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), "field type mismatch"); 1.1198 + } 1.1199 +} 1.1200 + 1.1201 + 1.1202 +oop Reflection::reflect_field(oop mirror, symbolOop field_name, jint which, TRAPS) { 1.1203 + // Exclude primitive types and array types 1.1204 + if (java_lang_Class::is_primitive(mirror)) return NULL; 1.1205 + if (Klass::cast(java_lang_Class::as_klassOop(mirror))->oop_is_array()) return NULL; 1.1206 + 1.1207 + instanceKlassHandle k(THREAD, java_lang_Class::as_klassOop(mirror)); 1.1208 + bool local_fields_only = (which == DECLARED); 1.1209 + 1.1210 + // Ensure class is linked 1.1211 + k->link_class(CHECK_NULL); 1.1212 + 1.1213 + // Search class and interface fields 1.1214 + for (FieldStream st(k, local_fields_only, false); !st.eos(); st.next()) { 1.1215 + if (st.name() == field_name) { 1.1216 + if (local_fields_only || st.access_flags().is_public()) { 1.1217 + return new_field(&st, THREAD); 1.1218 + } 1.1219 + } 1.1220 + } 1.1221 + 1.1222 + return NULL; 1.1223 +} 1.1224 + 1.1225 + 1.1226 +objArrayOop Reflection::reflect_fields(oop mirror, jint which, TRAPS) { 1.1227 + // Exclude primitive types and array types 1.1228 + if (java_lang_Class::is_primitive(mirror) 1.1229 + || Klass::cast(java_lang_Class::as_klassOop(mirror))->oop_is_array()) { 1.1230 + symbolHandle name = vmSymbolHandles::java_lang_reflect_Field(); 1.1231 + klassOop klass = SystemDictionary::resolve_or_fail(name, true, CHECK_NULL); 1.1232 + return oopFactory::new_objArray(klass, 0, CHECK_NULL); // Return empty array 1.1233 + } 1.1234 + 1.1235 + instanceKlassHandle k(THREAD, java_lang_Class::as_klassOop(mirror)); 1.1236 + 1.1237 + // Ensure class is linked 1.1238 + k->link_class(CHECK_NULL); 1.1239 + 1.1240 + bool local_fields_only = (which == DECLARED); 1.1241 + int count = 0; 1.1242 + { // Compute fields count for class and interface fields 1.1243 + for (FieldStream st(k, local_fields_only, false); !st.eos(); st.next()) { 1.1244 + if (local_fields_only || st.access_flags().is_public()) { 1.1245 + count++; 1.1246 + } 1.1247 + } 1.1248 + } 1.1249 + 1.1250 + // Allocate result 1.1251 + symbolHandle name = vmSymbolHandles::java_lang_reflect_Field(); 1.1252 + klassOop klass = SystemDictionary::resolve_or_fail(name, true, CHECK_NULL); 1.1253 + objArrayOop r = oopFactory::new_objArray(klass, count, CHECK_NULL); 1.1254 + objArrayHandle result (THREAD, r); 1.1255 + 1.1256 + // Fill in results backwards 1.1257 + { 1.1258 + for (FieldStream st(k, local_fields_only, false); !st.eos(); st.next()) { 1.1259 + if (local_fields_only || st.access_flags().is_public()) { 1.1260 + oop field = new_field(&st, CHECK_NULL); 1.1261 + result->obj_at_put(--count, field); 1.1262 + } 1.1263 + } 1.1264 + assert(count == 0, "just checking"); 1.1265 + } 1.1266 + return result(); 1.1267 +} 1.1268 + 1.1269 + 1.1270 +oop Reflection::reflect_method(oop mirror, symbolHandle method_name, objArrayHandle types, jint which, TRAPS) { 1.1271 + if (java_lang_Class::is_primitive(mirror)) return NULL; 1.1272 + klassOop klass = java_lang_Class::as_klassOop(mirror); 1.1273 + if (Klass::cast(klass)->oop_is_array() && which == MEMBER_DECLARED) return NULL; 1.1274 + 1.1275 + if (Klass::cast(java_lang_Class::as_klassOop(mirror))->oop_is_array()) { 1.1276 + klass = SystemDictionary::object_klass(); 1.1277 + } 1.1278 + instanceKlassHandle h_k(THREAD, klass); 1.1279 + 1.1280 + // Ensure klass is linked (need not be initialized) 1.1281 + h_k->link_class(CHECK_NULL); 1.1282 + 1.1283 + // For interfaces include static initializers under jdk1.2.x (since classic does that) 1.1284 + bool include_clinit = JDK_Version::is_jdk12x_version() && h_k->is_interface(); 1.1285 + 1.1286 + switch (which) { 1.1287 + case MEMBER_PUBLIC: 1.1288 + // First the public non-static methods (works if method holder is an interface) 1.1289 + // Note that we can ignore checks for overridden methods, since we go up the hierarchy. 1.1290 + { 1.1291 + for (MethodStream st(h_k, false, false); !st.eos(); st.next()) { 1.1292 + methodHandle m(THREAD, st.method()); 1.1293 + // For interfaces include static initializers since classic does that! 1.1294 + if (method_name() == m->name() && (include_clinit || (m->is_public() && !m->is_static() && !m->is_initializer()))) { 1.1295 + symbolHandle signature(THREAD, m->signature()); 1.1296 + bool parameter_match = match_parameter_types(m, types, ArgumentCount(signature).size(), CHECK_NULL); 1.1297 + if (parameter_match) { 1.1298 + return new_method(m, false, false, THREAD); 1.1299 + } 1.1300 + } 1.1301 + } 1.1302 + } 1.1303 + // Then the public static methods (works if method holder is an interface) 1.1304 + { 1.1305 + for (MethodStream st(h_k, false, false); !st.eos(); st.next()) { 1.1306 + methodHandle m(THREAD, st.method()); 1.1307 + if (method_name() == m->name() && m->is_public() && m->is_static() && !m->is_initializer()) { 1.1308 + symbolHandle signature(THREAD, m->signature()); 1.1309 + bool parameter_match = match_parameter_types(m, types, ArgumentCount(signature).size(), CHECK_NULL); 1.1310 + if (parameter_match) { 1.1311 + return new_method(m, false, false, THREAD); 1.1312 + } 1.1313 + } 1.1314 + } 1.1315 + } 1.1316 + break; 1.1317 + case MEMBER_DECLARED: 1.1318 + // All local methods 1.1319 + { 1.1320 + for (MethodStream st(h_k, true, true); !st.eos(); st.next()) { 1.1321 + methodHandle m(THREAD, st.method()); 1.1322 + if (method_name() == m->name() && !m->is_initializer()) { 1.1323 + symbolHandle signature(THREAD, m->signature()); 1.1324 + bool parameter_match = match_parameter_types(m, types, ArgumentCount(signature).size(), CHECK_NULL); 1.1325 + if (parameter_match) { 1.1326 + return new_method(m, false, false, THREAD); 1.1327 + } 1.1328 + } 1.1329 + } 1.1330 + } 1.1331 + break; 1.1332 + default: 1.1333 + break; 1.1334 + } 1.1335 + return NULL; 1.1336 +} 1.1337 + 1.1338 + 1.1339 +objArrayOop Reflection::reflect_methods(oop mirror, jint which, TRAPS) { 1.1340 + // Exclude primitive types 1.1341 + if (java_lang_Class::is_primitive(mirror) || 1.1342 + (Klass::cast(java_lang_Class::as_klassOop(mirror))->oop_is_array() && (which == MEMBER_DECLARED))) { 1.1343 + klassOop klass = SystemDictionary::reflect_method_klass(); 1.1344 + return oopFactory::new_objArray(klass, 0, CHECK_NULL); // Return empty array 1.1345 + } 1.1346 + 1.1347 + klassOop klass = java_lang_Class::as_klassOop(mirror); 1.1348 + if (Klass::cast(java_lang_Class::as_klassOop(mirror))->oop_is_array()) { 1.1349 + klass = SystemDictionary::object_klass(); 1.1350 + } 1.1351 + instanceKlassHandle h_k(THREAD, klass); 1.1352 + 1.1353 + // Ensure klass is linked (need not be initialized) 1.1354 + h_k->link_class(CHECK_NULL); 1.1355 + 1.1356 + // We search the (super)interfaces only if h_k is an interface itself 1.1357 + bool is_interface = h_k->is_interface(); 1.1358 + 1.1359 + // For interfaces include static initializers under jdk1.2.x (since classic does that) 1.1360 + bool include_clinit = JDK_Version::is_jdk12x_version() && is_interface; 1.1361 + 1.1362 + switch (which) { 1.1363 + case MEMBER_PUBLIC: 1.1364 + { 1.1365 + 1.1366 + // Count public methods (non-static and static) 1.1367 + int count = 0; 1.1368 + { 1.1369 + for (MethodStream st(h_k, false, false); !st.eos(); st.next()) { 1.1370 + methodOop m = st.method(); 1.1371 + // For interfaces include static initializers since classic does that! 1.1372 + if (include_clinit || (!m->is_initializer() && m->is_public() && !m->is_overridden_in(h_k()))) { 1.1373 + count++; 1.1374 + } 1.1375 + } 1.1376 + } 1.1377 + 1.1378 + // Allocate result 1.1379 + klassOop klass = SystemDictionary::reflect_method_klass(); 1.1380 + objArrayOop r = oopFactory::new_objArray(klass, count, CHECK_NULL); 1.1381 + objArrayHandle h_result (THREAD, r); 1.1382 + 1.1383 + // Fill in results backwards 1.1384 + { 1.1385 + // First the non-static public methods 1.1386 + for (MethodStream st(h_k, false, false); !st.eos(); st.next()) { 1.1387 + methodHandle m (THREAD, st.method()); 1.1388 + if (!m->is_static() && !m->is_initializer() && m->is_public() && !m->is_overridden_in(h_k())) { 1.1389 + oop method = new_method(m, false, false, CHECK_NULL); 1.1390 + if (method == NULL) { 1.1391 + return NULL; 1.1392 + } else { 1.1393 + h_result->obj_at_put(--count, method); 1.1394 + } 1.1395 + } 1.1396 + } 1.1397 + } 1.1398 + { 1.1399 + // Then the static public methods 1.1400 + for (MethodStream st(h_k, false, !is_interface); !st.eos(); st.next()) { 1.1401 + methodHandle m (THREAD, st.method()); 1.1402 + if (m->is_static() && (include_clinit || (!m->is_initializer()) && m->is_public() && !m->is_overridden_in(h_k()))) { 1.1403 + oop method = new_method(m, false, false, CHECK_NULL); 1.1404 + if (method == NULL) { 1.1405 + return NULL; 1.1406 + } else { 1.1407 + h_result->obj_at_put(--count, method); 1.1408 + } 1.1409 + } 1.1410 + } 1.1411 + } 1.1412 + 1.1413 + assert(count == 0, "just checking"); 1.1414 + return h_result(); 1.1415 + } 1.1416 + 1.1417 + case MEMBER_DECLARED: 1.1418 + { 1.1419 + // Count all methods 1.1420 + int count = 0; 1.1421 + { 1.1422 + for (MethodStream st(h_k, true, !is_interface); !st.eos(); st.next()) { 1.1423 + methodOop m = st.method(); 1.1424 + if (!m->is_initializer()) { 1.1425 + count++; 1.1426 + } 1.1427 + } 1.1428 + } 1.1429 + // Allocate result 1.1430 + klassOop klass = SystemDictionary::reflect_method_klass(); 1.1431 + objArrayOop r = oopFactory::new_objArray(klass, count, CHECK_NULL); 1.1432 + objArrayHandle h_result (THREAD, r); 1.1433 + 1.1434 + // Fill in results backwards 1.1435 + { 1.1436 + for (MethodStream st(h_k, true, true); !st.eos(); st.next()) { 1.1437 + methodHandle m (THREAD, st.method()); 1.1438 + if (!m->is_initializer()) { 1.1439 + oop method = new_method(m, false, false, CHECK_NULL); 1.1440 + if (method == NULL) { 1.1441 + return NULL; 1.1442 + } else { 1.1443 + h_result->obj_at_put(--count, method); 1.1444 + } 1.1445 + } 1.1446 + } 1.1447 + } 1.1448 + assert(count == 0, "just checking"); 1.1449 + return h_result(); 1.1450 + } 1.1451 + } 1.1452 + ShouldNotReachHere(); 1.1453 + return NULL; 1.1454 +} 1.1455 + 1.1456 + 1.1457 +oop Reflection::reflect_constructor(oop mirror, objArrayHandle types, jint which, TRAPS) { 1.1458 + 1.1459 + // Exclude primitive, interface and array types 1.1460 + bool prim = java_lang_Class::is_primitive(mirror); 1.1461 + Klass* klass = prim ? NULL : Klass::cast(java_lang_Class::as_klassOop(mirror)); 1.1462 + if (prim || klass->is_interface() || klass->oop_is_array()) return NULL; 1.1463 + 1.1464 + // Must be instance klass 1.1465 + instanceKlassHandle h_k(THREAD, java_lang_Class::as_klassOop(mirror)); 1.1466 + 1.1467 + // Ensure klass is linked (need not be initialized) 1.1468 + h_k->link_class(CHECK_NULL); 1.1469 + 1.1470 + bool local_only = (which == MEMBER_DECLARED); 1.1471 + for (MethodStream st(h_k, true, true); !st.eos(); st.next()) { 1.1472 + methodHandle m(THREAD, st.method()); 1.1473 + if (m->name() == vmSymbols::object_initializer_name() && (local_only || m->is_public())) { 1.1474 + symbolHandle signature(THREAD, m->signature()); 1.1475 + bool parameter_match = match_parameter_types(m, types, ArgumentCount(signature).size(), CHECK_NULL); 1.1476 + if (parameter_match) { 1.1477 + return new_constructor(m, THREAD); 1.1478 + } 1.1479 + } 1.1480 + } 1.1481 + 1.1482 + return NULL; 1.1483 +} 1.1484 + 1.1485 + 1.1486 +objArrayOop Reflection::reflect_constructors(oop mirror, jint which, TRAPS) { 1.1487 + // Exclude primitive, interface and array types 1.1488 + bool prim = java_lang_Class::is_primitive(mirror); 1.1489 + Klass* k = prim ? NULL : Klass::cast(java_lang_Class::as_klassOop(mirror)); 1.1490 + if (prim || k->is_interface() || k->oop_is_array()) { 1.1491 + return oopFactory::new_objArray(SystemDictionary::reflect_constructor_klass(), 0, CHECK_NULL); // Return empty array 1.1492 + } 1.1493 + 1.1494 + // Must be instanceKlass at this point 1.1495 + instanceKlassHandle h_k(THREAD, java_lang_Class::as_klassOop(mirror)); 1.1496 + 1.1497 + // Ensure klass is linked (need not be initialized) 1.1498 + h_k->link_class(CHECK_NULL); 1.1499 + 1.1500 + bool local_only = (which == MEMBER_DECLARED); 1.1501 + int count = 0; 1.1502 + { 1.1503 + for (MethodStream st(h_k, true, true); !st.eos(); st.next()) { 1.1504 + methodOop m = st.method(); 1.1505 + if (m->name() == vmSymbols::object_initializer_name() && (local_only || m->is_public())) { 1.1506 + count++; 1.1507 + } 1.1508 + } 1.1509 + } 1.1510 + 1.1511 + // Allocate result 1.1512 + symbolHandle name = vmSymbolHandles::java_lang_reflect_Constructor(); 1.1513 + klassOop klass = SystemDictionary::resolve_or_fail(name, true, CHECK_NULL); 1.1514 + objArrayOop r = oopFactory::new_objArray(klass, count, CHECK_NULL); 1.1515 + objArrayHandle h_result (THREAD, r); 1.1516 + 1.1517 + // Fill in results backwards 1.1518 + { 1.1519 + for (MethodStream st(h_k, true, true); !st.eos(); st.next()) { 1.1520 + methodHandle m (THREAD, st.method()); 1.1521 + if (m->name() == vmSymbols::object_initializer_name() && (local_only || m->is_public())) { 1.1522 + oop constr = new_constructor(m, CHECK_NULL); 1.1523 + if (constr == NULL) { 1.1524 + return NULL; 1.1525 + } else { 1.1526 + h_result->obj_at_put(--count, constr); 1.1527 + } 1.1528 + } 1.1529 + } 1.1530 + assert(count == 0, "just checking"); 1.1531 + } 1.1532 + return h_result(); 1.1533 +} 1.1534 + 1.1535 + 1.1536 +// This would be nicer if, say, java.lang.reflect.Method was a subclass 1.1537 +// of java.lang.reflect.Constructor 1.1538 + 1.1539 +oop Reflection::invoke_method(oop method_mirror, Handle receiver, objArrayHandle args, TRAPS) { 1.1540 + oop mirror = java_lang_reflect_Method::clazz(method_mirror); 1.1541 + int slot = java_lang_reflect_Method::slot(method_mirror); 1.1542 + bool override = java_lang_reflect_Method::override(method_mirror) != 0; 1.1543 + objArrayHandle ptypes(THREAD, objArrayOop(java_lang_reflect_Method::parameter_types(method_mirror))); 1.1544 + 1.1545 + oop return_type_mirror = java_lang_reflect_Method::return_type(method_mirror); 1.1546 + BasicType rtype; 1.1547 + if (java_lang_Class::is_primitive(return_type_mirror)) { 1.1548 + rtype = basic_type_mirror_to_basic_type(return_type_mirror, CHECK_NULL); 1.1549 + } else { 1.1550 + rtype = T_OBJECT; 1.1551 + } 1.1552 + 1.1553 + instanceKlassHandle klass(THREAD, java_lang_Class::as_klassOop(mirror)); 1.1554 + if (!klass->methods()->is_within_bounds(slot)) { 1.1555 + THROW_MSG_0(vmSymbols::java_lang_InternalError(), "invoke"); 1.1556 + } 1.1557 + methodHandle method(THREAD, methodOop(klass->methods()->obj_at(slot))); 1.1558 + 1.1559 + return invoke(klass, method, receiver, override, ptypes, rtype, args, true, THREAD); 1.1560 +} 1.1561 + 1.1562 + 1.1563 +oop Reflection::invoke_constructor(oop constructor_mirror, objArrayHandle args, TRAPS) { 1.1564 + oop mirror = java_lang_reflect_Constructor::clazz(constructor_mirror); 1.1565 + int slot = java_lang_reflect_Constructor::slot(constructor_mirror); 1.1566 + bool override = java_lang_reflect_Constructor::override(constructor_mirror) != 0; 1.1567 + objArrayHandle ptypes(THREAD, objArrayOop(java_lang_reflect_Constructor::parameter_types(constructor_mirror))); 1.1568 + 1.1569 + instanceKlassHandle klass(THREAD, java_lang_Class::as_klassOop(mirror)); 1.1570 + if (!klass->methods()->is_within_bounds(slot)) { 1.1571 + THROW_MSG_0(vmSymbols::java_lang_InternalError(), "invoke"); 1.1572 + } 1.1573 + methodHandle method(THREAD, methodOop(klass->methods()->obj_at(slot))); 1.1574 + assert(method->name() == vmSymbols::object_initializer_name(), "invalid constructor"); 1.1575 + 1.1576 + // Make sure klass gets initialize 1.1577 + klass->initialize(CHECK_NULL); 1.1578 + 1.1579 + // Create new instance (the receiver) 1.1580 + klass->check_valid_for_instantiation(false, CHECK_NULL); 1.1581 + Handle receiver = klass->allocate_instance_handle(CHECK_NULL); 1.1582 + 1.1583 + // Ignore result from call and return receiver 1.1584 + invoke(klass, method, receiver, override, ptypes, T_VOID, args, false, CHECK_NULL); 1.1585 + return receiver(); 1.1586 +} 1.1587 + 1.1588 + 1.1589 +#endif /* SUPPORT_OLD_REFLECTION */