1409 }
1410
1411 /**
1412 * Generate code to invoke the Class.forName with the name of the given
1413 * class to get its Class object at runtime. And also generate code
1414 * to invoke Class.asValueBox if the class is regular value type.
1415 *
1416 * The code is written to the supplied stream. Note that the code generated
1417 * by this method may caused the checked ClassNotFoundException to be thrown.
1418 */
1419 private void codeClassForName(Class<?> cl, DataOutputStream out)
1420 throws IOException
1421 {
1422 code_ldc(cp.getString(cl.getName()), out);
1423
1424 out.writeByte(opc_invokestatic);
1425 out.writeShort(cp.getMethodRef(
1426 "java/lang/Class",
1427 "forName", "(Ljava/lang/String;)Ljava/lang/Class;"));
1428
1429 if (cl.isValue() && cl == cl.asValueType()) {
1430 out.writeByte(opc_invokevirtual);
1431 out.writeShort(cp.getMethodRef(
1432 "java/lang/Class",
1433 "asValueType", "()Ljava/lang/Class;"));
1434 }
1435 }
1436
1437
1438 /*
1439 * ==================== General Utility Methods ====================
1440 */
1441
1442 /**
1443 * Convert a fully qualified class name that uses '.' as the package
1444 * separator, the external representation used by the Java language
1445 * and APIs, to a fully qualified class name that uses '/' as the
1446 * package separator, the representation used in the class file
1447 * format (see JVMS section 4.2).
1448 */
1449 private static String dotToSlash(String name) {
1450 return name.replace('.', '/');
1451 }
1452
1453 /**
1478 }
1479
1480 /**
1481 * Return the "field type" string for the given type, appropriate for
1482 * a field descriptor, a parameter descriptor, or a return descriptor
1483 * other than "void". See JVMS section 4.3.2.
1484 */
1485 private static String getFieldType(Class<?> type) {
1486 if (type.isPrimitive()) {
1487 return PrimitiveTypeInfo.get(type).baseTypeString;
1488 } else if (type.isArray()) {
1489 /*
1490 * According to JLS 20.3.2, the getName() method on Class does
1491 * return the VM type descriptor format for array classes (only);
1492 * using that should be quicker than the otherwise obvious code:
1493 *
1494 * return "[" + getTypeDescriptor(type.getComponentType());
1495 */
1496 return type.getName().replace('.', '/');
1497 } else {
1498 char prefix = type.isValue() && type == type.asValueType() ? 'Q' : 'L';
1499 return prefix + dotToSlash(type.getName()) + ";";
1500 }
1501 }
1502
1503 /**
1504 * Returns a human-readable string representing the signature of a
1505 * method with the given name and parameter types.
1506 */
1507 private static String getFriendlyMethodSignature(String name,
1508 Class<?>[] parameterTypes)
1509 {
1510 StringBuilder sig = new StringBuilder(name);
1511 sig.append('(');
1512 for (int i = 0; i < parameterTypes.length; i++) {
1513 if (i > 0) {
1514 sig.append(',');
1515 }
1516 Class<?> parameterType = parameterTypes[i];
1517 int dimensions = 0;
1518 while (parameterType.isArray()) {
1519 parameterType = parameterType.getComponentType();
|
1409 }
1410
1411 /**
1412 * Generate code to invoke the Class.forName with the name of the given
1413 * class to get its Class object at runtime. And also generate code
1414 * to invoke Class.asValueBox if the class is regular value type.
1415 *
1416 * The code is written to the supplied stream. Note that the code generated
1417 * by this method may caused the checked ClassNotFoundException to be thrown.
1418 */
1419 private void codeClassForName(Class<?> cl, DataOutputStream out)
1420 throws IOException
1421 {
1422 code_ldc(cp.getString(cl.getName()), out);
1423
1424 out.writeByte(opc_invokestatic);
1425 out.writeShort(cp.getMethodRef(
1426 "java/lang/Class",
1427 "forName", "(Ljava/lang/String;)Ljava/lang/Class;"));
1428
1429 if (cl.isInlineClass() && cl == cl.asPrimaryType()) {
1430 out.writeByte(opc_invokevirtual);
1431 out.writeShort(cp.getMethodRef(
1432 "java/lang/Class",
1433 "asPrimaryType", "()Ljava/lang/Class;"));
1434 }
1435 }
1436
1437
1438 /*
1439 * ==================== General Utility Methods ====================
1440 */
1441
1442 /**
1443 * Convert a fully qualified class name that uses '.' as the package
1444 * separator, the external representation used by the Java language
1445 * and APIs, to a fully qualified class name that uses '/' as the
1446 * package separator, the representation used in the class file
1447 * format (see JVMS section 4.2).
1448 */
1449 private static String dotToSlash(String name) {
1450 return name.replace('.', '/');
1451 }
1452
1453 /**
1478 }
1479
1480 /**
1481 * Return the "field type" string for the given type, appropriate for
1482 * a field descriptor, a parameter descriptor, or a return descriptor
1483 * other than "void". See JVMS section 4.3.2.
1484 */
1485 private static String getFieldType(Class<?> type) {
1486 if (type.isPrimitive()) {
1487 return PrimitiveTypeInfo.get(type).baseTypeString;
1488 } else if (type.isArray()) {
1489 /*
1490 * According to JLS 20.3.2, the getName() method on Class does
1491 * return the VM type descriptor format for array classes (only);
1492 * using that should be quicker than the otherwise obvious code:
1493 *
1494 * return "[" + getTypeDescriptor(type.getComponentType());
1495 */
1496 return type.getName().replace('.', '/');
1497 } else {
1498 if (type.isInlineClass()) {
1499 Class<?> primary = type.asPrimaryType();
1500 return (type == primary ? 'Q' : 'L' ) + dotToSlash(primary.getName()) + ";";
1501 } else {
1502 return 'L' + dotToSlash(type.getName()) + ";";
1503 }
1504 }
1505 }
1506
1507 /**
1508 * Returns a human-readable string representing the signature of a
1509 * method with the given name and parameter types.
1510 */
1511 private static String getFriendlyMethodSignature(String name,
1512 Class<?>[] parameterTypes)
1513 {
1514 StringBuilder sig = new StringBuilder(name);
1515 sig.append('(');
1516 for (int i = 0; i < parameterTypes.length; i++) {
1517 if (i > 0) {
1518 sig.append(',');
1519 }
1520 Class<?> parameterType = parameterTypes[i];
1521 int dimensions = 0;
1522 while (parameterType.isArray()) {
1523 parameterType = parameterType.getComponentType();
|