1024 void MethodHandles::verify_method_signature(methodHandle m, |
1027 void MethodHandles::verify_method_signature(methodHandle m, |
1025 Handle mtype, |
1028 Handle mtype, |
1026 int first_ptype_pos, |
1029 int first_ptype_pos, |
1027 KlassHandle insert_ptype, |
1030 KlassHandle insert_ptype, |
1028 TRAPS) { |
1031 TRAPS) { |
|
1032 Handle mhi_type; |
|
1033 if (m->is_method_handle_invoke()) { |
|
1034 // use this more exact typing instead of the symbolic signature: |
|
1035 mhi_type = Handle(THREAD, m->method_handle_type()); |
|
1036 } |
1029 objArrayHandle ptypes(THREAD, java_lang_invoke_MethodType::ptypes(mtype())); |
1037 objArrayHandle ptypes(THREAD, java_lang_invoke_MethodType::ptypes(mtype())); |
1030 int pnum = first_ptype_pos; |
1038 int pnum = first_ptype_pos; |
1031 int pmax = ptypes->length(); |
1039 int pmax = ptypes->length(); |
1032 int mnum = 0; // method argument |
1040 int anum = 0; // method argument |
1033 const char* err = NULL; |
1041 const char* err = NULL; |
1034 ResourceMark rm(THREAD); |
1042 ResourceMark rm(THREAD); |
1035 for (SignatureStream ss(m->signature()); !ss.is_done(); ss.next()) { |
1043 for (SignatureStream ss(m->signature()); !ss.is_done(); ss.next()) { |
1036 oop ptype_oop = NULL; |
1044 oop ptype_oop = NULL; |
1037 if (ss.at_return_type()) { |
1045 if (ss.at_return_type()) { |
1046 else if (insert_ptype.is_null()) |
1054 else if (insert_ptype.is_null()) |
1047 ptype_oop = NULL; |
1055 ptype_oop = NULL; |
1048 else |
1056 else |
1049 ptype_oop = insert_ptype->java_mirror(); |
1057 ptype_oop = insert_ptype->java_mirror(); |
1050 pnum += 1; |
1058 pnum += 1; |
1051 mnum += 1; |
1059 anum += 1; |
1052 } |
1060 } |
1053 klassOop pklass = NULL; |
1061 KlassHandle pklass; |
1054 BasicType ptype = T_OBJECT; |
1062 BasicType ptype = T_OBJECT; |
1055 if (ptype_oop != NULL) |
1063 bool have_ptype = false; |
1056 ptype = java_lang_Class::as_BasicType(ptype_oop, &pklass); |
1064 // missing ptype_oop does not match any non-reference; use Object to report the error |
1057 else |
1065 pklass = SystemDictionaryHandles::Object_klass(); |
1058 // null does not match any non-reference; use Object to report the error |
1066 if (ptype_oop != NULL) { |
1059 pklass = SystemDictionary::Object_klass(); |
1067 have_ptype = true; |
1060 klassOop mklass = NULL; |
1068 klassOop pklass_oop = NULL; |
1061 BasicType mtype = ss.type(); |
1069 ptype = java_lang_Class::as_BasicType(ptype_oop, &pklass_oop); |
1062 if (mtype == T_ARRAY) mtype = T_OBJECT; // fold all refs to T_OBJECT |
1070 pklass = KlassHandle(THREAD, pklass_oop); |
1063 if (mtype == T_OBJECT) { |
1071 } |
1064 if (ptype_oop == NULL) { |
1072 ptype_oop = NULL; //done with this |
|
1073 KlassHandle aklass; |
|
1074 BasicType atype = ss.type(); |
|
1075 if (atype == T_ARRAY) atype = T_OBJECT; // fold all refs to T_OBJECT |
|
1076 if (atype == T_OBJECT) { |
|
1077 if (!have_ptype) { |
1065 // null matches any reference |
1078 // null matches any reference |
1066 continue; |
1079 continue; |
1067 } |
1080 } |
1068 KlassHandle pklass_handle(THREAD, pklass); pklass = NULL; |
1081 if (mhi_type.is_null()) { |
1069 // If we fail to resolve types at this point, we will throw an error. |
1082 // If we fail to resolve types at this point, we will usually throw an error. |
1070 Symbol* name = ss.as_symbol(CHECK); |
1083 TempNewSymbol name = ss.as_symbol_or_null(); |
1071 instanceKlass* mk = instanceKlass::cast(m->method_holder()); |
1084 if (name != NULL) { |
1072 Handle loader(THREAD, mk->class_loader()); |
1085 instanceKlass* mk = instanceKlass::cast(m->method_holder()); |
1073 Handle domain(THREAD, mk->protection_domain()); |
1086 Handle loader(THREAD, mk->class_loader()); |
1074 mklass = SystemDictionary::resolve_or_null(name, loader, domain, CHECK); |
1087 Handle domain(THREAD, mk->protection_domain()); |
1075 pklass = pklass_handle(); |
1088 klassOop aklass_oop = SystemDictionary::resolve_or_null(name, loader, domain, CHECK); |
1076 if (mklass == NULL && pklass != NULL && |
1089 if (aklass_oop != NULL) |
1077 Klass::cast(pklass)->name() == name && |
1090 aklass = KlassHandle(THREAD, aklass_oop); |
1078 m->is_method_handle_invoke()) { |
1091 } |
1079 // Assume a match. We can't really decode the signature of MH.invoke*. |
1092 } else { |
1080 continue; |
1093 // for method handle invokers we don't look at the name in the signature |
|
1094 oop atype_oop; |
|
1095 if (ss.at_return_type()) |
|
1096 atype_oop = java_lang_invoke_MethodType::rtype(mhi_type()); |
|
1097 else |
|
1098 atype_oop = java_lang_invoke_MethodType::ptype(mhi_type(), anum-1); |
|
1099 klassOop aklass_oop = NULL; |
|
1100 atype = java_lang_Class::as_BasicType(atype_oop, &aklass_oop); |
|
1101 aklass = KlassHandle(THREAD, aklass_oop); |
1081 } |
1102 } |
1082 } |
1103 } |
1083 if (!ss.at_return_type()) { |
1104 if (!ss.at_return_type()) { |
1084 err = check_argument_type_change(ptype, pklass, mtype, mklass, mnum); |
1105 err = check_argument_type_change(ptype, pklass(), atype, aklass(), anum); |
1085 } else { |
1106 } else { |
1086 err = check_return_type_change(mtype, mklass, ptype, pklass); // note reversal! |
1107 err = check_return_type_change(atype, aklass(), ptype, pklass()); // note reversal! |
1087 } |
1108 } |
1088 if (err != NULL) break; |
1109 if (err != NULL) break; |
1089 } |
1110 } |
1090 |
1111 |
1091 if (err != NULL) { |
1112 if (err != NULL) { |
|
1113 #ifndef PRODUCT |
|
1114 if (PrintMiscellaneous && (Verbose || WizardMode)) { |
|
1115 tty->print("*** verify_method_signature failed: "); |
|
1116 java_lang_invoke_MethodType::print_signature(mtype(), tty); |
|
1117 tty->cr(); |
|
1118 tty->print_cr(" first_ptype_pos = %d, insert_ptype = "UINTX_FORMAT, first_ptype_pos, insert_ptype()); |
|
1119 tty->print(" Failing method: "); |
|
1120 m->print(); |
|
1121 } |
|
1122 #endif //PRODUCT |
1092 THROW_MSG(vmSymbols::java_lang_InternalError(), err); |
1123 THROW_MSG(vmSymbols::java_lang_InternalError(), err); |
1093 } |
1124 } |
1094 } |
1125 } |
1095 |
1126 |
1096 // Main routine for verifying the MethodHandle.type of a proposed |
1127 // Main routine for verifying the MethodHandle.type of a proposed |
1286 } |
1317 } |
1287 |
1318 |
1288 // format, format, format |
1319 // format, format, format |
1289 const char* src_name = type2name(src_type); |
1320 const char* src_name = type2name(src_type); |
1290 const char* dst_name = type2name(dst_type); |
1321 const char* dst_name = type2name(dst_type); |
1291 if (src_type == T_OBJECT) src_name = Klass::cast(src_klass)->external_name(); |
|
1292 if (dst_type == T_OBJECT) dst_name = Klass::cast(dst_klass)->external_name(); |
|
1293 if (src_name == NULL) src_name = "unknown type"; |
1322 if (src_name == NULL) src_name = "unknown type"; |
1294 if (dst_name == NULL) dst_name = "unknown type"; |
1323 if (dst_name == NULL) dst_name = "unknown type"; |
|
1324 if (src_type == T_OBJECT) |
|
1325 src_name = (src_klass != NULL) ? Klass::cast(src_klass)->external_name() : "an unresolved class"; |
|
1326 if (dst_type == T_OBJECT) |
|
1327 dst_name = (dst_klass != NULL) ? Klass::cast(dst_klass)->external_name() : "an unresolved class"; |
1295 |
1328 |
1296 size_t msglen = strlen(err) + strlen(src_name) + strlen(dst_name) + (argnum < 10 ? 1 : 11); |
1329 size_t msglen = strlen(err) + strlen(src_name) + strlen(dst_name) + (argnum < 10 ? 1 : 11); |
1297 char* msg = NEW_RESOURCE_ARRAY(char, msglen + 1); |
1330 char* msg = NEW_RESOURCE_ARRAY(char, msglen + 1); |
1298 if (argnum >= 0) { |
1331 if (argnum >= 0) { |
1299 assert(strstr(err, "%d") != NULL, ""); |
1332 assert(strstr(err, "%d") != NULL, ""); |