1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.apache.bcel.classfile;
21
22 import static org.junit.jupiter.api.Assertions.assertEquals;
23 import static org.junit.jupiter.api.Assertions.assertNotNull;
24 import static org.junit.jupiter.api.Assertions.assertThrows;
25 import static org.junit.jupiter.api.Assertions.fail;
26
27 import java.io.IOException;
28
29 import org.apache.bcel.AbstractTest;
30 import org.apache.bcel.Const;
31 import org.apache.bcel.generic.ConstantPoolGen;
32 import org.apache.bcel.generic.InstructionHandle;
33 import org.apache.bcel.generic.MethodGen;
34 import org.apache.bcel.util.ClassPath;
35 import org.apache.bcel.util.ClassPathRepository;
36 import org.junit.jupiter.api.Test;
37
38 final class ClassWithDoubleConstantPoolItem {
39 double d = 42;
40 }
41
42 final class ClassWithLongConstantPoolItem {
43 long l = 42;
44 }
45
46 class ConstantPoolTest extends AbstractTest {
47
48 private static InstructionHandle[] getInstructionHandles(final JavaClass clazz, final ConstantPoolGen cp, final Method method) {
49 final MethodGen methodGen = new MethodGen(method, clazz.getClassName(), cp);
50 return methodGen.getInstructionList().getInstructionHandles();
51 }
52
53 @Test
54 void testClassWithDoubleConstantPoolItem() throws ClassNotFoundException, IOException {
55 try (ClassPath cp = new ClassPath("target/test-classes/org/apache/bcel/classfile")) {
56 final ClassWithDoubleConstantPoolItem classWithDoubleConstantPoolItem = new ClassWithDoubleConstantPoolItem();
57 final JavaClass c = new ClassPathRepository(cp).loadClass(classWithDoubleConstantPoolItem.getClass());
58 final Field[] fields = c.getFields();
59 assertNotNull(fields);
60 assertEquals(1, fields.length);
61 assertEquals(ClassWithDoubleConstantPoolItem.class.getDeclaredFields()[0].getName(), fields[0].getName());
62 final ConstantPool pool = c.getConstantPool();
63 for (int i = 1; i < pool.getLength(); i++) {
64 try {
65 final Constant constant = pool.getConstant(i);
66 if (constant instanceof ConstantDouble) {
67 assertEquals(classWithDoubleConstantPoolItem.d, ((ConstantDouble) constant).getBytes());
68
69 i++;
70 }
71 } catch (final Throwable t) {
72 t.printStackTrace();
73 fail();
74 }
75 }
76 }
77 }
78
79 @Test
80 void testClassWithLongConstantPoolItem() throws ClassNotFoundException, IOException {
81 try (ClassPath cp = new ClassPath("target/test-classes/org/apache/bcel/classfile")) {
82 final ClassWithLongConstantPoolItem classWithLongConstantPoolItem = new ClassWithLongConstantPoolItem();
83 final JavaClass c = new ClassPathRepository(cp).loadClass(classWithLongConstantPoolItem.getClass());
84 final Field[] fields = c.getFields();
85 assertNotNull(fields);
86 assertEquals(1, fields.length);
87 assertEquals(ClassWithLongConstantPoolItem.class.getDeclaredFields()[0].getName(), fields[0].getName());
88 final ConstantPool pool = c.getConstantPool();
89 for (int i = 1; i < pool.getLength(); i++) {
90 try {
91 final Constant constant = pool.getConstant(i);
92 if (constant instanceof ConstantLong) {
93 assertEquals(classWithLongConstantPoolItem.l, ((ConstantLong) constant).getBytes());
94
95 i++;
96 }
97 } catch (final Throwable t) {
98 t.printStackTrace();
99 fail();
100 }
101 }
102 }
103 }
104
105 @Test
106 void testConstantToString() throws ClassNotFoundException {
107 final JavaClass clazz = getTestJavaClass(PACKAGE_BASE_NAME + ".data.SimpleClassWithDefaultConstructor");
108 final ConstantPoolGen cp = new ConstantPoolGen(clazz.getConstantPool());
109 final Method[] methods = clazz.getMethods();
110 for (final Method method : methods) {
111 if (method.getName().equals("<init>")) {
112 for (final InstructionHandle instructionHandle : getInstructionHandles(clazz, cp, method)) {
113 final String instruction = instructionHandle.getInstruction().toString(cp.getConstantPool());
114 assertNotNull(instruction);
115 switch (instructionHandle.getPosition()) {
116 case 0:
117 assertEquals("aload_0", instruction);
118 break;
119 case 1:
120 assertEquals("invokespecial java/lang/Object/<init>()V", instruction);
121 break;
122 case 4:
123 assertEquals("return", instruction);
124 break;
125 default:
126 break;
127 }
128 }
129 }
130 }
131 }
132
133 @Test
134 void testTooManyConstants() throws ClassNotFoundException {
135 final JavaClass clazz = getTestJavaClass(PACKAGE_BASE_NAME + ".data.SimpleClassWithDefaultConstructor");
136 final ConstantPoolGen cp = new ConstantPoolGen(clazz.getConstantPool());
137 int i = cp.getSize();
138 while (i < Const.MAX_CP_ENTRIES - 1) {
139 cp.addLong(i);
140 i = cp.getSize();
141 }
142 assertThrows(IllegalStateException.class, () -> cp.addLong(0));
143 }
144 }