1316 if (java_lang_Class::is_primitive(JNIHandles::resolve_non_null(ofClass)) || |
1316 if (java_lang_Class::is_primitive(JNIHandles::resolve_non_null(ofClass)) || |
1317 ! Klass::cast(java_lang_Class::as_klassOop(JNIHandles::resolve_non_null(ofClass)))->oop_is_instance()) { |
1317 ! Klass::cast(java_lang_Class::as_klassOop(JNIHandles::resolve_non_null(ofClass)))->oop_is_instance()) { |
1318 return NULL; |
1318 return NULL; |
1319 } |
1319 } |
1320 |
1320 |
1321 symbolOop simple_name = NULL; |
1321 bool inner_is_member = false; |
1322 klassOop outer_klass |
1322 klassOop outer_klass |
1323 = instanceKlass::cast(java_lang_Class::as_klassOop(JNIHandles::resolve_non_null(ofClass)) |
1323 = instanceKlass::cast(java_lang_Class::as_klassOop(JNIHandles::resolve_non_null(ofClass)) |
1324 )->compute_enclosing_class(simple_name, CHECK_NULL); |
1324 )->compute_enclosing_class(&inner_is_member, CHECK_NULL); |
1325 if (outer_klass == NULL) return NULL; // already a top-level class |
1325 if (outer_klass == NULL) return NULL; // already a top-level class |
1326 if (simple_name == NULL) return NULL; // an anonymous class (inside a method) |
1326 if (!inner_is_member) return NULL; // an anonymous class (inside a method) |
1327 return (jclass) JNIHandles::make_local(env, Klass::cast(outer_klass)->java_mirror()); |
1327 return (jclass) JNIHandles::make_local(env, Klass::cast(outer_klass)->java_mirror()); |
1328 } |
1328 } |
1329 JVM_END |
1329 JVM_END |
1330 |
1330 |
1331 // should be in instanceKlass.cpp, but is here for historical reasons |
1331 // should be in instanceKlass.cpp, but is here for historical reasons |
1332 klassOop instanceKlass::compute_enclosing_class_impl(instanceKlassHandle k, |
1332 klassOop instanceKlass::compute_enclosing_class_impl(instanceKlassHandle k, |
1333 symbolOop& simple_name_result, TRAPS) { |
1333 bool* inner_is_member, |
|
1334 TRAPS) { |
1334 Thread* thread = THREAD; |
1335 Thread* thread = THREAD; |
1335 const int inner_class_info_index = inner_class_inner_class_info_offset; |
1336 const int inner_class_info_index = inner_class_inner_class_info_offset; |
1336 const int outer_class_info_index = inner_class_outer_class_info_offset; |
1337 const int outer_class_info_index = inner_class_outer_class_info_offset; |
1337 |
1338 |
1338 if (k->inner_classes()->length() == 0) { |
1339 if (k->inner_classes()->length() == 0) { |
1345 int i_length = i_icls->length(); |
1346 int i_length = i_icls->length(); |
1346 |
1347 |
1347 bool found = false; |
1348 bool found = false; |
1348 klassOop ok; |
1349 klassOop ok; |
1349 instanceKlassHandle outer_klass; |
1350 instanceKlassHandle outer_klass; |
1350 bool inner_is_member = false; |
1351 *inner_is_member = false; |
1351 int simple_name_index = 0; |
|
1352 |
1352 |
1353 // Find inner_klass attribute |
1353 // Find inner_klass attribute |
1354 for (int i = 0; i < i_length && !found; i += inner_class_next_offset) { |
1354 for (int i = 0; i < i_length && !found; i += inner_class_next_offset) { |
1355 int ioff = i_icls->ushort_at(i + inner_class_info_index); |
1355 int ioff = i_icls->ushort_at(i + inner_class_info_index); |
1356 int ooff = i_icls->ushort_at(i + outer_class_info_index); |
1356 int ooff = i_icls->ushort_at(i + outer_class_info_index); |
1362 klassOop inner_klass = i_cp->klass_at(ioff, CHECK_NULL); |
1362 klassOop inner_klass = i_cp->klass_at(ioff, CHECK_NULL); |
1363 found = (k() == inner_klass); |
1363 found = (k() == inner_klass); |
1364 if (found && ooff != 0) { |
1364 if (found && ooff != 0) { |
1365 ok = i_cp->klass_at(ooff, CHECK_NULL); |
1365 ok = i_cp->klass_at(ooff, CHECK_NULL); |
1366 outer_klass = instanceKlassHandle(thread, ok); |
1366 outer_klass = instanceKlassHandle(thread, ok); |
1367 simple_name_index = noff; |
1367 *inner_is_member = true; |
1368 inner_is_member = true; |
|
1369 } |
1368 } |
1370 } |
1369 } |
1371 } |
1370 } |
1372 } |
1371 } |
1373 |
1372 |
1375 // It may be anonymous; try for that. |
1374 // It may be anonymous; try for that. |
1376 int encl_method_class_idx = k->enclosing_method_class_index(); |
1375 int encl_method_class_idx = k->enclosing_method_class_index(); |
1377 if (encl_method_class_idx != 0) { |
1376 if (encl_method_class_idx != 0) { |
1378 ok = i_cp->klass_at(encl_method_class_idx, CHECK_NULL); |
1377 ok = i_cp->klass_at(encl_method_class_idx, CHECK_NULL); |
1379 outer_klass = instanceKlassHandle(thread, ok); |
1378 outer_klass = instanceKlassHandle(thread, ok); |
1380 inner_is_member = false; |
1379 *inner_is_member = false; |
1381 } |
1380 } |
1382 } |
1381 } |
1383 |
1382 |
1384 // If no inner class attribute found for this class. |
1383 // If no inner class attribute found for this class. |
1385 if (outer_klass.is_null()) return NULL; |
1384 if (outer_klass.is_null()) return NULL; |
1386 |
1385 |
1387 // Throws an exception if outer klass has not declared k as an inner klass |
1386 // Throws an exception if outer klass has not declared k as an inner klass |
1388 // We need evidence that each klass knows about the other, or else |
1387 // We need evidence that each klass knows about the other, or else |
1389 // the system could allow a spoof of an inner class to gain access rights. |
1388 // the system could allow a spoof of an inner class to gain access rights. |
1390 Reflection::check_for_inner_class(outer_klass, k, inner_is_member, CHECK_NULL); |
1389 Reflection::check_for_inner_class(outer_klass, k, *inner_is_member, CHECK_NULL); |
1391 |
|
1392 simple_name_result = (inner_is_member ? i_cp->symbol_at(simple_name_index) : symbolOop(NULL)); |
|
1393 return outer_klass(); |
1390 return outer_klass(); |
1394 } |
1391 } |
1395 |
1392 |
1396 JVM_ENTRY(jstring, JVM_GetClassSignature(JNIEnv *env, jclass cls)) |
1393 JVM_ENTRY(jstring, JVM_GetClassSignature(JNIEnv *env, jclass cls)) |
1397 assert (cls != NULL, "illegal class"); |
1394 assert (cls != NULL, "illegal class"); |