growStack(Descriptor.dataSize(desc)); // assume ConstPool#REF_invokeStatic | growStack(Descriptor.dataSize(desc)); // assume ConstPool#REF_invokeStatic | ||||
} | } | ||||
/** | |||||
* Appends DYNAMIC. | |||||
* | |||||
* @param bootstrap an index into the <code>bootstrap_methods</code> array | |||||
* of the bootstrap method table. | |||||
* @param name the method name. | |||||
* @param desc the method descriptor. | |||||
* @see Descriptor#ofMethod(CtClass,CtClass[]) | |||||
* @since 3.17 | |||||
*/ | |||||
public void addDynamic(int bootstrap, String name, String desc) { | |||||
int nt = constPool.addNameAndTypeInfo(name, desc); | |||||
int dyn = constPool.addDynamicInfo(bootstrap, nt); | |||||
add(INVOKEDYNAMIC); | |||||
addIndex(dyn); | |||||
add(0, 0); | |||||
growStack(Descriptor.dataSize(desc)); // assume ConstPool#REF_invokeStatic | |||||
} | |||||
/** | /** | ||||
* Appends LDC or LDC_W. The pushed item is a <code>String</code> | * Appends LDC or LDC_W. The pushed item is a <code>String</code> | ||||
* object. | * object. |
return num++; | return num++; | ||||
} | } | ||||
/** | |||||
* Adds a new <code>CONSTANT_InvokeDynamic_info</code> | |||||
* structure. | |||||
* | |||||
* @param bootstrap <code>bootstrap_method_attr_index</code>. | |||||
* @param nameAndTypeInfo <code>name_and_type_index</code>. | |||||
* @return the index of the added entry. | |||||
* | |||||
* @since 3.17.1 | |||||
*/ | |||||
public int addDynamicInfo(int bootstrap, | |||||
int nameAndTypeInfo) { | |||||
output.write(DynamicInfo.tag); | |||||
output.writeShort(bootstrap); | |||||
output.writeShort(nameAndTypeInfo); | |||||
return num++; | |||||
} | |||||
/** | /** | ||||
* Adds a new <code>CONSTANT_String_info</code> | * Adds a new <code>CONSTANT_String_info</code> | ||||
* structure. | * structure. |
} | } | ||||
/** | /** | ||||
* Adds a new <code>CONSTANT_InvokeDynamic_info</code> structure. | |||||
* Adds a new <code>CONSTANT_Dynamic_info</code> structure. | |||||
* | * | ||||
* @param bootstrap <code>bootstrap_method_attr_index</code>. | * @param bootstrap <code>bootstrap_method_attr_index</code>. | ||||
* @param nameAndType <code>name_and_type_index</code>. | * @param nameAndType <code>name_and_type_index</code>. |
assertEquals("(I)V", cPool2.getUtf8Info(cPool2.getMethodTypeInfo(mtIndex))); | assertEquals("(I)V", cPool2.getUtf8Info(cPool2.getMethodTypeInfo(mtIndex))); | ||||
} | } | ||||
// public void testDynamicInfo() throws Exception { | |||||
// ClassFile cf = new ClassFile(false, "test4.Dyn", null); | |||||
// cf.setInterfaces(new String[] { "java.lang.Cloneable" }); | |||||
// ConstPool cp = cf.getConstPool(); | |||||
// | |||||
// Bytecode code = new Bytecode(cp, 0, 1); | |||||
// code.addAload(0); | |||||
// code.addIconst(9); | |||||
// code.addLdc("nine"); | |||||
// code.addDynamic(0, "call", "I"); | |||||
// code.addOpcode(Opcode.SWAP); | |||||
// code.addOpcode(Opcode.POP); | |||||
// code.addOpcode(Opcode.IRETURN); | |||||
// | |||||
// FieldInfo fieldInfo = new FieldInfo(cp, "test", "S"); | |||||
// fieldInfo.setAccessFlags(AccessFlag.PUBLIC); | |||||
// cf.addField(fieldInfo); | |||||
// | |||||
// String desc | |||||
// = "(Ljava/lang/String;)I"; | |||||
// int mri = cp.addMethodrefInfo(cp.addClassInfo("Dyn"), "boot", desc); | |||||
// int mhi = cp.addMethodHandleInfo(ConstPool.REF_invokeStatic, mri); | |||||
// int[] args = new int[0]; | |||||
// BootstrapMethodsAttribute.BootstrapMethod[] bms | |||||
// = new BootstrapMethodsAttribute.BootstrapMethod[1]; | |||||
// bms[0] = new BootstrapMethodsAttribute.BootstrapMethod(mhi, args); | |||||
// | |||||
// cf.addAttribute(new BootstrapMethodsAttribute(cp, bms)); | |||||
// | |||||
// cf.write(new DataOutputStream(new FileOutputStream("test4/Dyn.class"))); | |||||
// | |||||
// Object obj = make(cf.getName()); | |||||
// | |||||
// assertNotNull(obj); | |||||
// } | |||||
public static Test suite() { | public static Test suite() { | ||||
TestSuite suite = new TestSuite("Bytecode Tests"); | TestSuite suite = new TestSuite("Bytecode Tests"); | ||||
suite.addTestSuite(BytecodeTest.class); | suite.addTestSuite(BytecodeTest.class); |