13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26 package java.lang.reflect;
27
28 import java.io.ByteArrayOutputStream;
29 import java.io.DataOutputStream;
30 import java.io.File;
31 import java.io.IOException;
32 import java.io.OutputStream;
33 import java.lang.reflect.Array;
34 import java.lang.reflect.Method;
35 import java.nio.file.Files;
36 import java.nio.file.Path;
37 import java.util.ArrayList;
38 import java.util.HashMap;
39 import java.util.LinkedList;
40 import java.util.List;
41 import java.util.ListIterator;
42 import java.util.Map;
43 import sun.security.action.GetBooleanAction;
44
45 /**
46 * ProxyGenerator contains the code to generate a dynamic proxy class
47 * for the java.lang.reflect.Proxy API.
48 *
49 * The external interfaces to ProxyGenerator is the static
50 * "generateProxyClass" method.
51 *
52 * @author Peter Jones
53 * @since 1.3
54 */
1395 * supplied stream.
1396 */
1397 private void code_ipush(int value, DataOutputStream out)
1398 throws IOException
1399 {
1400 if (value >= -1 && value <= 5) {
1401 out.writeByte(opc_iconst_0 + value);
1402 } else if (value >= Byte.MIN_VALUE && value <= Byte.MAX_VALUE) {
1403 out.writeByte(opc_bipush);
1404 out.writeByte(value & 0xFF);
1405 } else if (value >= Short.MIN_VALUE && value <= Short.MAX_VALUE) {
1406 out.writeByte(opc_sipush);
1407 out.writeShort(value & 0xFFFF);
1408 } else {
1409 throw new AssertionError();
1410 }
1411 }
1412
1413 /**
1414 * Generate code to invoke the Class.forName with the name of the given
1415 * class to get its Class object at runtime. The code is written to
1416 * the supplied stream. Note that the code generated by this method
1417 * 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
1430
1431 /*
1432 * ==================== General Utility Methods ====================
1433 */
1434
1435 /**
1436 * Convert a fully qualified class name that uses '.' as the package
1437 * separator, the external representation used by the Java language
1438 * and APIs, to a fully qualified class name that uses '/' as the
1439 * package separator, the representation used in the class file
1440 * format (see JVMS section 4.2).
1441 */
1442 private static String dotToSlash(String name) {
1443 return name.replace('.', '/');
1444 }
1445
1446 /**
1447 * Return the "method descriptor" string for a method with the given
1471 }
1472
1473 /**
1474 * Return the "field type" string for the given type, appropriate for
1475 * a field descriptor, a parameter descriptor, or a return descriptor
1476 * other than "void". See JVMS section 4.3.2.
1477 */
1478 private static String getFieldType(Class<?> type) {
1479 if (type.isPrimitive()) {
1480 return PrimitiveTypeInfo.get(type).baseTypeString;
1481 } else if (type.isArray()) {
1482 /*
1483 * According to JLS 20.3.2, the getName() method on Class does
1484 * return the VM type descriptor format for array classes (only);
1485 * using that should be quicker than the otherwise obvious code:
1486 *
1487 * return "[" + getTypeDescriptor(type.getComponentType());
1488 */
1489 return type.getName().replace('.', '/');
1490 } else {
1491 return "L" + dotToSlash(type.getName()) + ";";
1492 }
1493 }
1494
1495 /**
1496 * Returns a human-readable string representing the signature of a
1497 * method with the given name and parameter types.
1498 */
1499 private static String getFriendlyMethodSignature(String name,
1500 Class<?>[] parameterTypes)
1501 {
1502 StringBuilder sig = new StringBuilder(name);
1503 sig.append('(');
1504 for (int i = 0; i < parameterTypes.length; i++) {
1505 if (i > 0) {
1506 sig.append(',');
1507 }
1508 Class<?> parameterType = parameterTypes[i];
1509 int dimensions = 0;
1510 while (parameterType.isArray()) {
1511 parameterType = parameterType.getComponentType();
|
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26 package java.lang.reflect;
27
28 import java.io.ByteArrayOutputStream;
29 import java.io.DataOutputStream;
30 import java.io.File;
31 import java.io.IOException;
32 import java.io.OutputStream;
33 import java.nio.file.Files;
34 import java.nio.file.Path;
35 import java.util.ArrayList;
36 import java.util.HashMap;
37 import java.util.LinkedList;
38 import java.util.List;
39 import java.util.ListIterator;
40 import java.util.Map;
41 import sun.security.action.GetBooleanAction;
42
43 /**
44 * ProxyGenerator contains the code to generate a dynamic proxy class
45 * for the java.lang.reflect.Proxy API.
46 *
47 * The external interfaces to ProxyGenerator is the static
48 * "generateProxyClass" method.
49 *
50 * @author Peter Jones
51 * @since 1.3
52 */
1393 * supplied stream.
1394 */
1395 private void code_ipush(int value, DataOutputStream out)
1396 throws IOException
1397 {
1398 if (value >= -1 && value <= 5) {
1399 out.writeByte(opc_iconst_0 + value);
1400 } else if (value >= Byte.MIN_VALUE && value <= Byte.MAX_VALUE) {
1401 out.writeByte(opc_bipush);
1402 out.writeByte(value & 0xFF);
1403 } else if (value >= Short.MIN_VALUE && value <= Short.MAX_VALUE) {
1404 out.writeByte(opc_sipush);
1405 out.writeShort(value & 0xFFFF);
1406 } else {
1407 throw new AssertionError();
1408 }
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 /**
1454 * Return the "method descriptor" string for a method with the given
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();
|