src/share/vm/runtime/reflection.cpp

changeset 3095
19241ae0d839
parent 2658
c7f3d0b4570f
child 3670
f7c4174b33ba
equal deleted inserted replaced
3094:b27c72d69fd1 3095:19241ae0d839
841 java_lang_reflect_Field::set_annotations(rh(), fd->annotations()); 841 java_lang_reflect_Field::set_annotations(rh(), fd->annotations());
842 } 842 }
843 return rh(); 843 return rh();
844 } 844 }
845 845
846
847 //---------------------------------------------------------------------------
848 //
849 // Supporting routines for old native code-based reflection (pre-JDK 1.4).
850 //
851 // See reflection.hpp for details.
852 //
853 //---------------------------------------------------------------------------
854
855 #ifdef SUPPORT_OLD_REFLECTION
856 846
857 methodHandle Reflection::resolve_interface_call(instanceKlassHandle klass, methodHandle method, 847 methodHandle Reflection::resolve_interface_call(instanceKlassHandle klass, methodHandle method,
858 KlassHandle recv_klass, Handle receiver, TRAPS) { 848 KlassHandle recv_klass, Handle receiver, TRAPS) {
859 assert(!method.is_null() , "method should not be null"); 849 assert(!method.is_null() , "method should not be null");
860 850
1079 BasicType Reflection::basic_type_mirror_to_basic_type(oop basic_type_mirror, TRAPS) { 1069 BasicType Reflection::basic_type_mirror_to_basic_type(oop basic_type_mirror, TRAPS) {
1080 assert(java_lang_Class::is_primitive(basic_type_mirror), "just checking"); 1070 assert(java_lang_Class::is_primitive(basic_type_mirror), "just checking");
1081 return java_lang_Class::primitive_type(basic_type_mirror); 1071 return java_lang_Class::primitive_type(basic_type_mirror);
1082 } 1072 }
1083 1073
1084
1085 bool Reflection::match_parameter_types(methodHandle method, objArrayHandle types, int parameter_count, TRAPS) {
1086 int types_len = types.is_null() ? 0 : types->length();
1087 if (types_len != parameter_count) return false;
1088 if (parameter_count > 0) {
1089 objArrayHandle method_types = get_parameter_types(method, parameter_count, NULL, CHECK_false);
1090 for (int index = 0; index < parameter_count; index++) {
1091 if (types->obj_at(index) != method_types->obj_at(index)) {
1092 return false;
1093 }
1094 }
1095 }
1096 return true;
1097 }
1098
1099
1100 oop Reflection::new_field(FieldStream* st, TRAPS) {
1101 Symbol* field_name = st->name();
1102 Handle name = java_lang_String::create_from_symbol(field_name, CHECK_NULL);
1103 Symbol* signature = st->signature();
1104 Handle type = new_type(signature, st->klass(), CHECK_NULL);
1105 Handle rh = java_lang_reflect_Field::create(CHECK_NULL);
1106 oop result = rh();
1107
1108 java_lang_reflect_Field::set_clazz(result, st->klass()->java_mirror());
1109 java_lang_reflect_Field::set_slot(result, st->index());
1110 java_lang_reflect_Field::set_name(result, name());
1111 java_lang_reflect_Field::set_type(result, type());
1112 // Note the ACC_ANNOTATION bit, which is a per-class access flag, is never set here.
1113 java_lang_reflect_Field::set_modifiers(result, st->access_flags().as_int() & JVM_RECOGNIZED_FIELD_MODIFIERS);
1114 java_lang_reflect_Field::set_override(result, false);
1115 return result;
1116 }
1117
1118
1119 bool Reflection::resolve_field(Handle field_mirror, Handle& receiver, fieldDescriptor* fd, bool check_final, TRAPS) {
1120 if (field_mirror.is_null()) {
1121 THROW_(vmSymbols::java_lang_NullPointerException(), false);
1122 }
1123
1124 instanceKlassHandle klass (THREAD, java_lang_Class::as_klassOop(java_lang_reflect_Field::clazz(field_mirror())));
1125 int slot = java_lang_reflect_Field::slot(field_mirror());
1126
1127 // Ensure klass is initialized
1128 klass->initialize(CHECK_false);
1129 fd->initialize(klass(), slot);
1130
1131 bool is_static = fd->is_static();
1132 KlassHandle receiver_klass;
1133
1134 if (is_static) {
1135 receiver = KlassHandle(THREAD, klass());
1136 receiver_klass = klass;
1137 } else {
1138 // Check object is a non-null instance of declaring class
1139 if (receiver.is_null()) {
1140 THROW_(vmSymbols::java_lang_NullPointerException(), false);
1141 }
1142 if (!receiver->is_a(klass())) {
1143 THROW_MSG_(vmSymbols::java_lang_IllegalArgumentException(), "object is not an instance of declaring class", false);
1144 }
1145 receiver_klass = KlassHandle(THREAD, receiver->klass());
1146 }
1147
1148 // Access checking (unless overridden by Field)
1149 if (!java_lang_reflect_Field::override(field_mirror())) {
1150 if (!(klass->is_public() && fd->is_public())) {
1151 bool access_check = reflect_check_access(klass(), fd->access_flags(), receiver_klass(), false, CHECK_false);
1152 if (!access_check) {
1153 return false; // exception
1154 }
1155 }
1156 }
1157
1158 if (check_final && fd->is_final()) {
1159 // In 1.3 we always throw an error when attempting to set a final field.
1160 // In 1.2.x, this was allowed in the override bit was set by calling Field.setAccessible(true).
1161 // We currently maintain backwards compatibility. See bug 4250960.
1162 bool strict_final_check = !JDK_Version::is_jdk12x_version();
1163 if (strict_final_check || !java_lang_reflect_Field::override(field_mirror())) {
1164 THROW_MSG_(vmSymbols::java_lang_IllegalAccessException(), "field is final", false);
1165 }
1166 }
1167 return true;
1168 }
1169
1170
1171 BasicType Reflection::field_get(jvalue* value, fieldDescriptor* fd, Handle receiver) {
1172 BasicType field_type = fd->field_type();
1173 int offset = fd->offset();
1174 switch (field_type) {
1175 case T_BOOLEAN:
1176 value->z = receiver->bool_field(offset);
1177 break;
1178 case T_CHAR:
1179 value->c = receiver->char_field(offset);
1180 break;
1181 case T_FLOAT:
1182 value->f = receiver->float_field(offset);
1183 break;
1184 case T_DOUBLE:
1185 value->d = receiver->double_field(offset);
1186 break;
1187 case T_BYTE:
1188 value->b = receiver->byte_field(offset);
1189 break;
1190 case T_SHORT:
1191 value->s = receiver->short_field(offset);
1192 break;
1193 case T_INT:
1194 value->i = receiver->int_field(offset);
1195 break;
1196 case T_LONG:
1197 value->j = receiver->long_field(offset);
1198 break;
1199 case T_OBJECT:
1200 case T_ARRAY:
1201 value->l = (jobject) receiver->obj_field(offset);
1202 break;
1203 default:
1204 return T_ILLEGAL;
1205 }
1206 return field_type;
1207 }
1208
1209
1210 void Reflection::field_set(jvalue* value, fieldDescriptor* fd, Handle receiver, BasicType value_type, TRAPS) {
1211 BasicType field_type = fd->field_type();
1212 if (field_type != value_type) {
1213 widen(value, value_type, field_type, CHECK);
1214 }
1215
1216 int offset = fd->offset();
1217 switch (field_type) {
1218 case T_BOOLEAN:
1219 receiver->bool_field_put(offset, value->z);
1220 break;
1221 case T_CHAR:
1222 receiver->char_field_put(offset, value->c);
1223 break;
1224 case T_FLOAT:
1225 receiver->float_field_put(offset, value->f);
1226 break;
1227 case T_DOUBLE:
1228 receiver->double_field_put(offset, value->d);
1229 break;
1230 case T_BYTE:
1231 receiver->byte_field_put(offset, value->b);
1232 break;
1233 case T_SHORT:
1234 receiver->short_field_put(offset, value->s);
1235 break;
1236 case T_INT:
1237 receiver->int_field_put(offset, value->i);
1238 break;
1239 case T_LONG:
1240 receiver->long_field_put(offset, value->j);
1241 break;
1242 case T_OBJECT:
1243 case T_ARRAY: {
1244 Handle obj(THREAD, (oop) value->l);
1245 if (obj.not_null()) {
1246 Symbol* signature = fd->signature();
1247 Handle loader (THREAD, fd->loader());
1248 Handle protect (THREAD, Klass::cast(fd->field_holder())->protection_domain());
1249 klassOop k = SystemDictionary::resolve_or_fail(signature, loader, protect, true, CHECK); // may block
1250 if (!obj->is_a(k)) {
1251 THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), "field type mismatch");
1252 }
1253 }
1254 receiver->obj_field_put(offset, obj());
1255 break;
1256 }
1257 default:
1258 THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), "field type mismatch");
1259 }
1260 }
1261
1262
1263 oop Reflection::reflect_field(oop mirror, Symbol* field_name, jint which, TRAPS) {
1264 // Exclude primitive types and array types
1265 if (java_lang_Class::is_primitive(mirror)) return NULL;
1266 if (Klass::cast(java_lang_Class::as_klassOop(mirror))->oop_is_array()) return NULL;
1267
1268 instanceKlassHandle k(THREAD, java_lang_Class::as_klassOop(mirror));
1269 bool local_fields_only = (which == DECLARED);
1270
1271 // Ensure class is linked
1272 k->link_class(CHECK_NULL);
1273
1274 // Search class and interface fields
1275 for (FieldStream st(k, local_fields_only, false); !st.eos(); st.next()) {
1276 if (st.name() == field_name) {
1277 if (local_fields_only || st.access_flags().is_public()) {
1278 return new_field(&st, THREAD);
1279 }
1280 }
1281 }
1282
1283 return NULL;
1284 }
1285
1286
1287 objArrayOop Reflection::reflect_fields(oop mirror, jint which, TRAPS) {
1288 // Exclude primitive types and array types
1289 if (java_lang_Class::is_primitive(mirror)
1290 || Klass::cast(java_lang_Class::as_klassOop(mirror))->oop_is_array()) {
1291 Symbol* name = vmSymbols::java_lang_reflect_Field();
1292 klassOop klass = SystemDictionary::resolve_or_fail(name, true, CHECK_NULL);
1293 return oopFactory::new_objArray(klass, 0, CHECK_NULL); // Return empty array
1294 }
1295
1296 instanceKlassHandle k(THREAD, java_lang_Class::as_klassOop(mirror));
1297
1298 // Ensure class is linked
1299 k->link_class(CHECK_NULL);
1300
1301 bool local_fields_only = (which == DECLARED);
1302 int count = 0;
1303 { // Compute fields count for class and interface fields
1304 for (FieldStream st(k, local_fields_only, false); !st.eos(); st.next()) {
1305 if (local_fields_only || st.access_flags().is_public()) {
1306 count++;
1307 }
1308 }
1309 }
1310
1311 // Allocate result
1312 Symbol* name = vmSymbols::java_lang_reflect_Field();
1313 klassOop klass = SystemDictionary::resolve_or_fail(name, true, CHECK_NULL);
1314 objArrayOop r = oopFactory::new_objArray(klass, count, CHECK_NULL);
1315 objArrayHandle result (THREAD, r);
1316
1317 // Fill in results backwards
1318 {
1319 for (FieldStream st(k, local_fields_only, false); !st.eos(); st.next()) {
1320 if (local_fields_only || st.access_flags().is_public()) {
1321 oop field = new_field(&st, CHECK_NULL);
1322 result->obj_at_put(--count, field);
1323 }
1324 }
1325 assert(count == 0, "just checking");
1326 }
1327 return result();
1328 }
1329
1330
1331 oop Reflection::reflect_method(oop mirror, Symbol* method_name, objArrayHandle types, jint which, TRAPS) {
1332 if (java_lang_Class::is_primitive(mirror)) return NULL;
1333 klassOop klass = java_lang_Class::as_klassOop(mirror);
1334 if (Klass::cast(klass)->oop_is_array() && which == MEMBER_DECLARED) return NULL;
1335
1336 if (Klass::cast(java_lang_Class::as_klassOop(mirror))->oop_is_array()) {
1337 klass = SystemDictionary::Object_klass();
1338 }
1339 instanceKlassHandle h_k(THREAD, klass);
1340
1341 // Ensure klass is linked (need not be initialized)
1342 h_k->link_class(CHECK_NULL);
1343
1344 // For interfaces include static initializers under jdk1.2.x (since classic does that)
1345 bool include_clinit = JDK_Version::is_jdk12x_version() && h_k->is_interface();
1346
1347 switch (which) {
1348 case MEMBER_PUBLIC:
1349 // First the public non-static methods (works if method holder is an interface)
1350 // Note that we can ignore checks for overridden methods, since we go up the hierarchy.
1351 {
1352 for (MethodStream st(h_k, false, false); !st.eos(); st.next()) {
1353 methodHandle m(THREAD, st.method());
1354 // For interfaces include static initializers since classic does that!
1355 if (method_name == m->name() && (include_clinit || (m->is_public() && !m->is_static() && !m->is_initializer()))) {
1356 Symbol* signature = m->signature();
1357 bool parameter_match = match_parameter_types(m, types, ArgumentCount(signature).size(), CHECK_NULL);
1358 if (parameter_match) {
1359 return new_method(m, false, false, THREAD);
1360 }
1361 }
1362 }
1363 }
1364 // Then the public static methods (works if method holder is an interface)
1365 {
1366 for (MethodStream st(h_k, false, false); !st.eos(); st.next()) {
1367 methodHandle m(THREAD, st.method());
1368 if (method_name == m->name() && m->is_public() && m->is_static() && !m->is_initializer()) {
1369 Symbol* signature = m->signature();
1370 bool parameter_match = match_parameter_types(m, types, ArgumentCount(signature).size(), CHECK_NULL);
1371 if (parameter_match) {
1372 return new_method(m, false, false, THREAD);
1373 }
1374 }
1375 }
1376 }
1377 break;
1378 case MEMBER_DECLARED:
1379 // All local methods
1380 {
1381 for (MethodStream st(h_k, true, true); !st.eos(); st.next()) {
1382 methodHandle m(THREAD, st.method());
1383 if (method_name == m->name() && !m->is_initializer()) {
1384 Symbol* signature = m->signature();
1385 bool parameter_match = match_parameter_types(m, types, ArgumentCount(signature).size(), CHECK_NULL);
1386 if (parameter_match) {
1387 return new_method(m, false, false, THREAD);
1388 }
1389 }
1390 }
1391 }
1392 break;
1393 default:
1394 break;
1395 }
1396 return NULL;
1397 }
1398
1399
1400 objArrayOop Reflection::reflect_methods(oop mirror, jint which, TRAPS) {
1401 // Exclude primitive types
1402 if (java_lang_Class::is_primitive(mirror) ||
1403 (Klass::cast(java_lang_Class::as_klassOop(mirror))->oop_is_array() && (which == MEMBER_DECLARED))) {
1404 klassOop klass = SystemDictionary::reflect_Method_klass();
1405 return oopFactory::new_objArray(klass, 0, CHECK_NULL); // Return empty array
1406 }
1407
1408 klassOop klass = java_lang_Class::as_klassOop(mirror);
1409 if (Klass::cast(java_lang_Class::as_klassOop(mirror))->oop_is_array()) {
1410 klass = SystemDictionary::Object_klass();
1411 }
1412 instanceKlassHandle h_k(THREAD, klass);
1413
1414 // Ensure klass is linked (need not be initialized)
1415 h_k->link_class(CHECK_NULL);
1416
1417 // We search the (super)interfaces only if h_k is an interface itself
1418 bool is_interface = h_k->is_interface();
1419
1420 // For interfaces include static initializers under jdk1.2.x (since classic does that)
1421 bool include_clinit = JDK_Version::is_jdk12x_version() && is_interface;
1422
1423 switch (which) {
1424 case MEMBER_PUBLIC:
1425 {
1426
1427 // Count public methods (non-static and static)
1428 int count = 0;
1429 {
1430 for (MethodStream st(h_k, false, false); !st.eos(); st.next()) {
1431 methodOop m = st.method();
1432 // For interfaces include static initializers since classic does that!
1433 if (include_clinit || (!m->is_initializer() && m->is_public() && !m->is_overridden_in(h_k()))) {
1434 count++;
1435 }
1436 }
1437 }
1438
1439 // Allocate result
1440 klassOop klass = SystemDictionary::reflect_Method_klass();
1441 objArrayOop r = oopFactory::new_objArray(klass, count, CHECK_NULL);
1442 objArrayHandle h_result (THREAD, r);
1443
1444 // Fill in results backwards
1445 {
1446 // First the non-static public methods
1447 for (MethodStream st(h_k, false, false); !st.eos(); st.next()) {
1448 methodHandle m (THREAD, st.method());
1449 if (!m->is_static() && !m->is_initializer() && m->is_public() && !m->is_overridden_in(h_k())) {
1450 oop method = new_method(m, false, false, CHECK_NULL);
1451 if (method == NULL) {
1452 return NULL;
1453 } else {
1454 h_result->obj_at_put(--count, method);
1455 }
1456 }
1457 }
1458 }
1459 {
1460 // Then the static public methods
1461 for (MethodStream st(h_k, false, !is_interface); !st.eos(); st.next()) {
1462 methodHandle m (THREAD, st.method());
1463 if (m->is_static() && (include_clinit || (!m->is_initializer()) && m->is_public() && !m->is_overridden_in(h_k()))) {
1464 oop method = new_method(m, false, false, CHECK_NULL);
1465 if (method == NULL) {
1466 return NULL;
1467 } else {
1468 h_result->obj_at_put(--count, method);
1469 }
1470 }
1471 }
1472 }
1473
1474 assert(count == 0, "just checking");
1475 return h_result();
1476 }
1477
1478 case MEMBER_DECLARED:
1479 {
1480 // Count all methods
1481 int count = 0;
1482 {
1483 for (MethodStream st(h_k, true, !is_interface); !st.eos(); st.next()) {
1484 methodOop m = st.method();
1485 if (!m->is_initializer()) {
1486 count++;
1487 }
1488 }
1489 }
1490 // Allocate result
1491 klassOop klass = SystemDictionary::reflect_Method_klass();
1492 objArrayOop r = oopFactory::new_objArray(klass, count, CHECK_NULL);
1493 objArrayHandle h_result (THREAD, r);
1494
1495 // Fill in results backwards
1496 {
1497 for (MethodStream st(h_k, true, true); !st.eos(); st.next()) {
1498 methodHandle m (THREAD, st.method());
1499 if (!m->is_initializer()) {
1500 oop method = new_method(m, false, false, CHECK_NULL);
1501 if (method == NULL) {
1502 return NULL;
1503 } else {
1504 h_result->obj_at_put(--count, method);
1505 }
1506 }
1507 }
1508 }
1509 assert(count == 0, "just checking");
1510 return h_result();
1511 }
1512 }
1513 ShouldNotReachHere();
1514 return NULL;
1515 }
1516
1517
1518 oop Reflection::reflect_constructor(oop mirror, objArrayHandle types, jint which, TRAPS) {
1519
1520 // Exclude primitive, interface and array types
1521 bool prim = java_lang_Class::is_primitive(mirror);
1522 Klass* klass = prim ? NULL : Klass::cast(java_lang_Class::as_klassOop(mirror));
1523 if (prim || klass->is_interface() || klass->oop_is_array()) return NULL;
1524
1525 // Must be instance klass
1526 instanceKlassHandle h_k(THREAD, java_lang_Class::as_klassOop(mirror));
1527
1528 // Ensure klass is linked (need not be initialized)
1529 h_k->link_class(CHECK_NULL);
1530
1531 bool local_only = (which == MEMBER_DECLARED);
1532 for (MethodStream st(h_k, true, true); !st.eos(); st.next()) {
1533 methodHandle m(THREAD, st.method());
1534 if (m->name() == vmSymbols::object_initializer_name() && (local_only || m->is_public())) {
1535 Symbol* signature = m->signature();
1536 bool parameter_match = match_parameter_types(m, types, ArgumentCount(signature).size(), CHECK_NULL);
1537 if (parameter_match) {
1538 return new_constructor(m, THREAD);
1539 }
1540 }
1541 }
1542
1543 return NULL;
1544 }
1545
1546
1547 objArrayOop Reflection::reflect_constructors(oop mirror, jint which, TRAPS) {
1548 // Exclude primitive, interface and array types
1549 bool prim = java_lang_Class::is_primitive(mirror);
1550 Klass* k = prim ? NULL : Klass::cast(java_lang_Class::as_klassOop(mirror));
1551 if (prim || k->is_interface() || k->oop_is_array()) {
1552 return oopFactory::new_objArray(SystemDictionary::reflect_Constructor_klass(), 0, CHECK_NULL); // Return empty array
1553 }
1554
1555 // Must be instanceKlass at this point
1556 instanceKlassHandle h_k(THREAD, java_lang_Class::as_klassOop(mirror));
1557
1558 // Ensure klass is linked (need not be initialized)
1559 h_k->link_class(CHECK_NULL);
1560
1561 bool local_only = (which == MEMBER_DECLARED);
1562 int count = 0;
1563 {
1564 for (MethodStream st(h_k, true, true); !st.eos(); st.next()) {
1565 methodOop m = st.method();
1566 if (m->name() == vmSymbols::object_initializer_name() && (local_only || m->is_public())) {
1567 count++;
1568 }
1569 }
1570 }
1571
1572 // Allocate result
1573 Symbol* name = vmSymbols::java_lang_reflect_Constructor();
1574 klassOop klass = SystemDictionary::resolve_or_fail(name, true, CHECK_NULL);
1575 objArrayOop r = oopFactory::new_objArray(klass, count, CHECK_NULL);
1576 objArrayHandle h_result (THREAD, r);
1577
1578 // Fill in results backwards
1579 {
1580 for (MethodStream st(h_k, true, true); !st.eos(); st.next()) {
1581 methodHandle m (THREAD, st.method());
1582 if (m->name() == vmSymbols::object_initializer_name() && (local_only || m->is_public())) {
1583 oop constr = new_constructor(m, CHECK_NULL);
1584 if (constr == NULL) {
1585 return NULL;
1586 } else {
1587 h_result->obj_at_put(--count, constr);
1588 }
1589 }
1590 }
1591 assert(count == 0, "just checking");
1592 }
1593 return h_result();
1594 }
1595
1596
1597 // This would be nicer if, say, java.lang.reflect.Method was a subclass 1074 // This would be nicer if, say, java.lang.reflect.Method was a subclass
1598 // of java.lang.reflect.Constructor 1075 // of java.lang.reflect.Constructor
1599 1076
1600 oop Reflection::invoke_method(oop method_mirror, Handle receiver, objArrayHandle args, TRAPS) { 1077 oop Reflection::invoke_method(oop method_mirror, Handle receiver, objArrayHandle args, TRAPS) {
1601 oop mirror = java_lang_reflect_Method::clazz(method_mirror); 1078 oop mirror = java_lang_reflect_Method::clazz(method_mirror);
1645 1122
1646 // Ignore result from call and return receiver 1123 // Ignore result from call and return receiver
1647 invoke(klass, method, receiver, override, ptypes, T_VOID, args, false, CHECK_NULL); 1124 invoke(klass, method, receiver, override, ptypes, T_VOID, args, false, CHECK_NULL);
1648 return receiver(); 1125 return receiver();
1649 } 1126 }
1650
1651
1652 #endif /* SUPPORT_OLD_REFLECTION */

mercurial