225 "tried to access class %s from class %s",
226 sel_klass->external_name(),
227 ref_klass->external_name()
228 );
229 return;
230 }
231 }
232
233 void LinkResolver::resolve_klass(KlassHandle& result, constantPoolHandle pool, int index, TRAPS) {
234 Klass* result_oop = pool->klass_ref_at(index, CHECK);
235 result = KlassHandle(THREAD, result_oop);
236 }
237
238 //------------------------------------------------------------------------------------------------------------------------
239 // Method resolution
240 //
241 // According to JVM spec. $5.4.3c & $5.4.3d
242
243 // Look up method in klasses, including static methods
244 // Then look up local default methods
245 void LinkResolver::lookup_method_in_klasses(methodHandle& result, KlassHandle klass, Symbol* name, Symbol* signature, bool checkpolymorphism, TRAPS) {
246 Method* result_oop = klass->uncached_lookup_method(name, signature);
247 if (result_oop == NULL) {
248 Array<Method*>* default_methods = InstanceKlass::cast(klass())->default_methods();
249 if (default_methods != NULL) {
250 result_oop = InstanceKlass::find_method(default_methods, name, signature);
251 }
252 }
253
254 if (checkpolymorphism && EnableInvokeDynamic && result_oop != NULL) {
255 vmIntrinsics::ID iid = result_oop->intrinsic_id();
256 if (MethodHandles::is_signature_polymorphic(iid)) {
257 // Do not link directly to these. The VM must produce a synthetic one using lookup_polymorphic_method.
258 return;
259 }
260 }
261 result = methodHandle(THREAD, result_oop);
262 }
263
264 // returns first instance method
265 // Looks up method in classes, then looks up local default methods
266 void LinkResolver::lookup_instance_method_in_klasses(methodHandle& result, KlassHandle klass, Symbol* name, Symbol* signature, TRAPS) {
403 err_msg("%d != %d", actual_size_of_params, expected_size_of_params));
404 #endif //ASSERT
405
406 assert(appendix_result_or_null != NULL, "");
407 (*appendix_result_or_null) = appendix;
408 (*method_type_result) = method_type;
409 return;
410 }
411 }
412 }
413 }
414
415 void LinkResolver::check_method_accessability(KlassHandle ref_klass,
416 KlassHandle resolved_klass,
417 KlassHandle sel_klass,
418 methodHandle sel_method,
419 TRAPS) {
420
421 AccessFlags flags = sel_method->access_flags();
422
423 // Special case #1: arrays always override "clone". JVMS 2.15.
424 // If the resolved klass is an array class, and the declaring class
425 // is java.lang.Object and the method is "clone", set the flags
426 // to public.
427 // Special case #2: If the resolved klass is an interface, and
428 // the declaring class is java.lang.Object, and the method is
429 // "clone" or "finalize", set the flags to public. If the
430 // resolved interface does not contain "clone" or "finalize"
431 // methods, the method/interface method resolution looks to
432 // the interface's super class, java.lang.Object. With JDK 8
433 // interface accessability check requirement, special casing
434 // this scenario is necessary to avoid an IAE.
435 //
436 // We'll check for each method name first and then java.lang.Object
437 // to best short-circuit out of these tests.
438 if (((sel_method->name() == vmSymbols::clone_name() &&
439 (resolved_klass->oop_is_array() || resolved_klass->is_interface())) ||
440 (sel_method->name() == vmSymbols::finalize_method_name() &&
441 resolved_klass->is_interface())) &&
442 sel_klass() == SystemDictionary::Object_klass()) {
443 // We need to change "protected" to "public".
444 assert(flags.is_protected(), "clone or finalize not protected?");
445 jint new_flags = flags.as_int();
446 new_flags = new_flags & (~JVM_ACC_PROTECTED);
447 new_flags = new_flags | JVM_ACC_PUBLIC;
448 flags.set_flags(new_flags);
449 }
450 // assert(extra_arg_result_or_null != NULL, "must be able to return extra argument");
451
452 if (!Reflection::verify_field_access(ref_klass(),
453 resolved_klass(),
454 sel_klass(),
455 flags,
456 true)) {
457 ResourceMark rm(THREAD);
458 Exceptions::fthrow(
459 THREAD_AND_LOCATION,
460 vmSymbols::java_lang_IllegalAccessError(),
461 "tried to access method %s.%s%s from class %s",
462 sel_klass->external_name(),
463 sel_method->name()->as_C_string(),
464 sel_method->signature()->as_C_string(),
514 }
515 }
516
517 void LinkResolver::resolve_method(methodHandle& resolved_method, KlassHandle resolved_klass,
518 Symbol* method_name, Symbol* method_signature,
519 KlassHandle current_klass, bool check_access,
520 bool require_methodref, TRAPS) {
521
522 Handle nested_exception;
523
524 // 1. check if methodref required, that resolved_klass is not interfacemethodref
525 if (require_methodref && resolved_klass->is_interface()) {
526 ResourceMark rm(THREAD);
527 char buf[200];
528 jio_snprintf(buf, sizeof(buf), "Found interface %s, but class was expected",
529 resolved_klass()->external_name());
530 THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(), buf);
531 }
532
533 // 2. lookup method in resolved klass and its super klasses
534 lookup_method_in_klasses(resolved_method, resolved_klass, method_name, method_signature, true, CHECK);
535
536 if (resolved_method.is_null()) { // not found in the class hierarchy
537 // 3. lookup method in all the interfaces implemented by the resolved klass
538 lookup_method_in_interfaces(resolved_method, resolved_klass, method_name, method_signature, CHECK);
539
540 if (resolved_method.is_null()) {
541 // JSR 292: see if this is an implicitly generated method MethodHandle.linkToVirtual(*...), etc
542 lookup_polymorphic_method(resolved_method, resolved_klass, method_name, method_signature,
543 current_klass, (Handle*)NULL, (Handle*)NULL, THREAD);
544 if (HAS_PENDING_EXCEPTION) {
545 nested_exception = Handle(THREAD, PENDING_EXCEPTION);
546 CLEAR_PENDING_EXCEPTION;
547 }
548 }
549
550 if (resolved_method.is_null()) {
551 // 4. method lookup failed
552 ResourceMark rm(THREAD);
553 THROW_MSG_CAUSE(vmSymbols::java_lang_NoSuchMethodError(),
554 Method::name_and_sig_as_C_string(resolved_klass(),
611 }
612
613 void LinkResolver::resolve_interface_method(methodHandle& resolved_method,
614 KlassHandle resolved_klass,
615 Symbol* method_name,
616 Symbol* method_signature,
617 KlassHandle current_klass,
618 bool check_access,
619 bool nostatics, TRAPS) {
620
621 // check if klass is interface
622 if (!resolved_klass->is_interface()) {
623 ResourceMark rm(THREAD);
624 char buf[200];
625 jio_snprintf(buf, sizeof(buf), "Found class %s, but interface was expected", resolved_klass()->external_name());
626 THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(), buf);
627 }
628
629 // lookup method in this interface or its super, java.lang.Object
630 // JDK8: also look for static methods
631 lookup_method_in_klasses(resolved_method, resolved_klass, method_name, method_signature, false, CHECK);
632
633 if (resolved_method.is_null()) {
634 // lookup method in all the super-interfaces
635 lookup_method_in_interfaces(resolved_method, resolved_klass, method_name, method_signature, CHECK);
636 if (resolved_method.is_null()) {
637 // no method found
638 ResourceMark rm(THREAD);
639 THROW_MSG(vmSymbols::java_lang_NoSuchMethodError(),
640 Method::name_and_sig_as_C_string(resolved_klass(),
641 method_name,
642 method_signature));
643 }
644 }
645
646 if (nostatics && resolved_method->is_static()) {
647 ResourceMark rm(THREAD);
648 char buf[200];
649 jio_snprintf(buf, sizeof(buf), "Expected instance not static method %s", Method::name_and_sig_as_C_string(resolved_klass(),
650 resolved_method->name(),
651 resolved_method->signature()));
|
225 "tried to access class %s from class %s",
226 sel_klass->external_name(),
227 ref_klass->external_name()
228 );
229 return;
230 }
231 }
232
233 void LinkResolver::resolve_klass(KlassHandle& result, constantPoolHandle pool, int index, TRAPS) {
234 Klass* result_oop = pool->klass_ref_at(index, CHECK);
235 result = KlassHandle(THREAD, result_oop);
236 }
237
238 //------------------------------------------------------------------------------------------------------------------------
239 // Method resolution
240 //
241 // According to JVM spec. $5.4.3c & $5.4.3d
242
243 // Look up method in klasses, including static methods
244 // Then look up local default methods
245 void LinkResolver::lookup_method_in_klasses(methodHandle& result, KlassHandle klass, Symbol* name, Symbol* signature, bool checkpolymorphism, bool in_imethod_resolve, TRAPS) {
246 Method* result_oop = klass->uncached_lookup_method(name, signature);
247
248 // JDK 8, JVMS 5.4.3.4: Interface method resolution should
249 // ignore static and non-public methods of java.lang.Object,
250 // like clone, finalize, registerNatives.
251 if (in_imethod_resolve &&
252 result_oop != NULL &&
253 klass->is_interface() &&
254 (result_oop->is_static() || !result_oop->is_public()) &&
255 result_oop->method_holder() == SystemDictionary::Object_klass()) {
256 result_oop = NULL;
257 }
258
259 if (result_oop == NULL) {
260 Array<Method*>* default_methods = InstanceKlass::cast(klass())->default_methods();
261 if (default_methods != NULL) {
262 result_oop = InstanceKlass::find_method(default_methods, name, signature);
263 }
264 }
265
266 if (checkpolymorphism && EnableInvokeDynamic && result_oop != NULL) {
267 vmIntrinsics::ID iid = result_oop->intrinsic_id();
268 if (MethodHandles::is_signature_polymorphic(iid)) {
269 // Do not link directly to these. The VM must produce a synthetic one using lookup_polymorphic_method.
270 return;
271 }
272 }
273 result = methodHandle(THREAD, result_oop);
274 }
275
276 // returns first instance method
277 // Looks up method in classes, then looks up local default methods
278 void LinkResolver::lookup_instance_method_in_klasses(methodHandle& result, KlassHandle klass, Symbol* name, Symbol* signature, TRAPS) {
415 err_msg("%d != %d", actual_size_of_params, expected_size_of_params));
416 #endif //ASSERT
417
418 assert(appendix_result_or_null != NULL, "");
419 (*appendix_result_or_null) = appendix;
420 (*method_type_result) = method_type;
421 return;
422 }
423 }
424 }
425 }
426
427 void LinkResolver::check_method_accessability(KlassHandle ref_klass,
428 KlassHandle resolved_klass,
429 KlassHandle sel_klass,
430 methodHandle sel_method,
431 TRAPS) {
432
433 AccessFlags flags = sel_method->access_flags();
434
435 // Special case: arrays always override "clone". JVMS 2.15.
436 // If the resolved klass is an array class, and the declaring class
437 // is java.lang.Object and the method is "clone", set the flags
438 // to public.
439 //
440 // We'll check for the method name first, as that's most likely
441 // to be false (so we'll short-circuit out of these tests).
442 if (sel_method->name() == vmSymbols::clone_name() &&
443 sel_klass() == SystemDictionary::Object_klass() &&
444 resolved_klass->oop_is_array()) {
445 // We need to change "protected" to "public".
446 assert(flags.is_protected(), "clone not protected?");
447 jint new_flags = flags.as_int();
448 new_flags = new_flags & (~JVM_ACC_PROTECTED);
449 new_flags = new_flags | JVM_ACC_PUBLIC;
450 flags.set_flags(new_flags);
451 }
452 // assert(extra_arg_result_or_null != NULL, "must be able to return extra argument");
453
454 if (!Reflection::verify_field_access(ref_klass(),
455 resolved_klass(),
456 sel_klass(),
457 flags,
458 true)) {
459 ResourceMark rm(THREAD);
460 Exceptions::fthrow(
461 THREAD_AND_LOCATION,
462 vmSymbols::java_lang_IllegalAccessError(),
463 "tried to access method %s.%s%s from class %s",
464 sel_klass->external_name(),
465 sel_method->name()->as_C_string(),
466 sel_method->signature()->as_C_string(),
516 }
517 }
518
519 void LinkResolver::resolve_method(methodHandle& resolved_method, KlassHandle resolved_klass,
520 Symbol* method_name, Symbol* method_signature,
521 KlassHandle current_klass, bool check_access,
522 bool require_methodref, TRAPS) {
523
524 Handle nested_exception;
525
526 // 1. check if methodref required, that resolved_klass is not interfacemethodref
527 if (require_methodref && resolved_klass->is_interface()) {
528 ResourceMark rm(THREAD);
529 char buf[200];
530 jio_snprintf(buf, sizeof(buf), "Found interface %s, but class was expected",
531 resolved_klass()->external_name());
532 THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(), buf);
533 }
534
535 // 2. lookup method in resolved klass and its super klasses
536 lookup_method_in_klasses(resolved_method, resolved_klass, method_name, method_signature, true, false, CHECK);
537
538 if (resolved_method.is_null()) { // not found in the class hierarchy
539 // 3. lookup method in all the interfaces implemented by the resolved klass
540 lookup_method_in_interfaces(resolved_method, resolved_klass, method_name, method_signature, CHECK);
541
542 if (resolved_method.is_null()) {
543 // JSR 292: see if this is an implicitly generated method MethodHandle.linkToVirtual(*...), etc
544 lookup_polymorphic_method(resolved_method, resolved_klass, method_name, method_signature,
545 current_klass, (Handle*)NULL, (Handle*)NULL, THREAD);
546 if (HAS_PENDING_EXCEPTION) {
547 nested_exception = Handle(THREAD, PENDING_EXCEPTION);
548 CLEAR_PENDING_EXCEPTION;
549 }
550 }
551
552 if (resolved_method.is_null()) {
553 // 4. method lookup failed
554 ResourceMark rm(THREAD);
555 THROW_MSG_CAUSE(vmSymbols::java_lang_NoSuchMethodError(),
556 Method::name_and_sig_as_C_string(resolved_klass(),
613 }
614
615 void LinkResolver::resolve_interface_method(methodHandle& resolved_method,
616 KlassHandle resolved_klass,
617 Symbol* method_name,
618 Symbol* method_signature,
619 KlassHandle current_klass,
620 bool check_access,
621 bool nostatics, TRAPS) {
622
623 // check if klass is interface
624 if (!resolved_klass->is_interface()) {
625 ResourceMark rm(THREAD);
626 char buf[200];
627 jio_snprintf(buf, sizeof(buf), "Found class %s, but interface was expected", resolved_klass()->external_name());
628 THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(), buf);
629 }
630
631 // lookup method in this interface or its super, java.lang.Object
632 // JDK8: also look for static methods
633 lookup_method_in_klasses(resolved_method, resolved_klass, method_name, method_signature, false, true, CHECK);
634
635 if (resolved_method.is_null()) {
636 // lookup method in all the super-interfaces
637 lookup_method_in_interfaces(resolved_method, resolved_klass, method_name, method_signature, CHECK);
638 if (resolved_method.is_null()) {
639 // no method found
640 ResourceMark rm(THREAD);
641 THROW_MSG(vmSymbols::java_lang_NoSuchMethodError(),
642 Method::name_and_sig_as_C_string(resolved_klass(),
643 method_name,
644 method_signature));
645 }
646 }
647
648 if (nostatics && resolved_method->is_static()) {
649 ResourceMark rm(THREAD);
650 char buf[200];
651 jio_snprintf(buf, sizeof(buf), "Expected instance not static method %s", Method::name_and_sig_as_C_string(resolved_klass(),
652 resolved_method->name(),
653 resolved_method->signature()));
|