aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRich Bolen <rich.bolen@icg360.com>2019-08-20 10:52:01 -0400
committerRich Bolen <rich.bolen@icg360.com>2019-08-20 10:52:01 -0400
commitc08c21ebd2b636d6bc9e3543aaf980f9e4733a04 (patch)
tree1263c43bc116067b4968f3cc8eeedf26fca99045
parent8f4788e0907278cec2a094af179451824651a515 (diff)
downloadjavassist-c08c21ebd2b636d6bc9e3543aaf980f9e4733a04.tar.gz
javassist-c08c21ebd2b636d6bc9e3543aaf980f9e4733a04.zip
Add support for the new Dynamic constant (17) created in java 11
-rw-r--r--pom.xml6
-rw-r--r--src/main/javassist/bytecode/Bytecode.java19
-rw-r--r--src/main/javassist/bytecode/ClassFileWriter.java20
-rw-r--r--src/main/javassist/bytecode/ConstPool.java217
-rw-r--r--src/test/javassist/bytecode/BytecodeTest.java36
-rw-r--r--src/test/test4/Dyn.java22
6 files changed, 269 insertions, 51 deletions
diff --git a/pom.xml b/pom.xml
index c3bd1990..fc8e2fdf 100644
--- a/pom.xml
+++ b/pom.xml
@@ -7,7 +7,7 @@
Javassist (JAVA programming ASSISTant) makes Java bytecode manipulation
simple. It is a class library for editing bytecodes in Java.
</description>
- <version>3.25.0-GA</version>
+ <version>3.25.1-GA</version>
<name>Javassist</name>
<url>http://www.javassist.org/</url>
@@ -151,8 +151,8 @@
<artifactId>maven-compiler-plugin</artifactId>
<version>3.2</version>
<configuration>
- <source>1.7</source>
- <target>1.7</target>
+ <source>9</source>
+ <target>9</target>
<testSource>11</testSource>
<testTarget>11</testTarget>
<testCompilerArgument>-parameters</testCompilerArgument>
diff --git a/src/main/javassist/bytecode/Bytecode.java b/src/main/javassist/bytecode/Bytecode.java
index 37a6d127..193e3f8a 100644
--- a/src/main/javassist/bytecode/Bytecode.java
+++ b/src/main/javassist/bytecode/Bytecode.java
@@ -1241,6 +1241,25 @@ public class Bytecode extends ByteVector implements Cloneable, Opcode {
}
/**
+ * 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>
* object.
*
diff --git a/src/main/javassist/bytecode/ClassFileWriter.java b/src/main/javassist/bytecode/ClassFileWriter.java
index 931ffcb4..03650b75 100644
--- a/src/main/javassist/bytecode/ClassFileWriter.java
+++ b/src/main/javassist/bytecode/ClassFileWriter.java
@@ -693,7 +693,7 @@ public class ClassFileWriter {
* @since 3.17.1
*/
public int addInvokeDynamicInfo(int bootstrap,
- int nameAndTypeInfo) {
+ int nameAndTypeInfo) {
output.write(InvokeDynamicInfo.tag);
output.writeShort(bootstrap);
output.writeShort(nameAndTypeInfo);
@@ -701,6 +701,24 @@ public class ClassFileWriter {
}
/**
+ * 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>
* structure.
*
diff --git a/src/main/javassist/bytecode/ConstPool.java b/src/main/javassist/bytecode/ConstPool.java
index 0447ece7..08985089 100644
--- a/src/main/javassist/bytecode/ConstPool.java
+++ b/src/main/javassist/bytecode/ConstPool.java
@@ -716,53 +716,99 @@ public final class ConstPool
return mtinfo.descriptor;
}
- /**
- * Reads the <code>bootstrap_method_attr_index</code> field of the
- * <code>CONSTANT_InvokeDynamic_info</code> structure
- * at the given index.
- *
- * @since 3.17
- */
- public int getInvokeDynamicBootstrap(int index)
- {
- InvokeDynamicInfo iv = (InvokeDynamicInfo)getItem(index);
- return iv.bootstrap;
- }
-
- /**
- * Reads the <code>name_and_type_index</code> field of the
- * <code>CONSTANT_InvokeDynamic_info</code> structure
- * at the given index.
- *
- * @since 3.17
- */
- public int getInvokeDynamicNameAndType(int index)
- {
- InvokeDynamicInfo iv = (InvokeDynamicInfo)getItem(index);
- return iv.nameAndType;
- }
-
- /**
- * Reads the <code>descriptor_index</code> field of the
- * <code>CONSTANT_NameAndType_info</code> structure
- * indirectly specified by the given index.
- *
- * @param index an index to a <code>CONSTANT_InvokeDynamic_info</code>.
- * @return the descriptor of the method.
- * @since 3.17
- */
- public String getInvokeDynamicType(int index)
- {
- InvokeDynamicInfo iv = (InvokeDynamicInfo)getItem(index);
- if (iv == null)
- return null;
- NameAndTypeInfo n = (NameAndTypeInfo)getItem(iv.nameAndType);
- if(n == null)
- return null;
- return getUtf8Info(n.typeDescriptor);
- }
-
- /**
+ /**
+ * Reads the <code>bootstrap_method_attr_index</code> field of the
+ * <code>CONSTANT_InvokeDynamic_info</code> structure
+ * at the given index.
+ *
+ * @since 3.17
+ */
+ public int getInvokeDynamicBootstrap(int index)
+ {
+ InvokeDynamicInfo iv = (InvokeDynamicInfo)getItem(index);
+ return iv.bootstrap;
+ }
+
+ /**
+ * Reads the <code>name_and_type_index</code> field of the
+ * <code>CONSTANT_InvokeDynamic_info</code> structure
+ * at the given index.
+ *
+ * @since 3.17
+ */
+ public int getInvokeDynamicNameAndType(int index)
+ {
+ InvokeDynamicInfo iv = (InvokeDynamicInfo)getItem(index);
+ return iv.nameAndType;
+ }
+
+ /**
+ * Reads the <code>descriptor_index</code> field of the
+ * <code>CONSTANT_NameAndType_info</code> structure
+ * indirectly specified by the given index.
+ *
+ * @param index an index to a <code>CONSTANT_InvokeDynamic_info</code>.
+ * @return the descriptor of the method.
+ * @since 3.17
+ */
+ public String getInvokeDynamicType(int index)
+ {
+ InvokeDynamicInfo iv = (InvokeDynamicInfo)getItem(index);
+ if (iv == null)
+ return null;
+ NameAndTypeInfo n = (NameAndTypeInfo)getItem(iv.nameAndType);
+ if(n == null)
+ return null;
+ return getUtf8Info(n.typeDescriptor);
+ }
+
+ /**
+ * Reads the <code>bootstrap_method_attr_index</code> field of the
+ * <code>CONSTANT_Dynamic_info</code> structure
+ * at the given index.
+ *
+ * @since 3.17
+ */
+ public int getDynamicBootstrap(int index)
+ {
+ DynamicInfo iv = (DynamicInfo)getItem(index);
+ return iv.bootstrap;
+ }
+
+ /**
+ * Reads the <code>name_and_type_index</code> field of the
+ * <code>CONSTANT_Dynamic_info</code> structure
+ * at the given index.
+ *
+ * @since 3.17
+ */
+ public int getDynamicNameAndType(int index)
+ {
+ DynamicInfo iv = (DynamicInfo)getItem(index);
+ return iv.nameAndType;
+ }
+
+ /**
+ * Reads the <code>descriptor_index</code> field of the
+ * <code>CONSTANT_NameAndType_info</code> structure
+ * indirectly specified by the given index.
+ *
+ * @param index an index to a <code>CONSTANT_Dynamic_info</code>.
+ * @return the descriptor of the method.
+ * @since 3.17
+ */
+ public String getDynamicType(int index)
+ {
+ DynamicInfo iv = (DynamicInfo)getItem(index);
+ if (iv == null)
+ return null;
+ NameAndTypeInfo n = (NameAndTypeInfo)getItem(iv.nameAndType);
+ if(n == null)
+ return null;
+ return getUtf8Info(n.typeDescriptor);
+ }
+
+ /**
* Reads the <code>name_index</code> field of the
* <code>CONSTANT_Module_info</code> structure at the given index.
*
@@ -1196,6 +1242,18 @@ public final class ConstPool
}
/**
+ * Adds a new <code>CONSTANT_InvokeDynamic_info</code> structure.
+ *
+ * @param bootstrap <code>bootstrap_method_attr_index</code>.
+ * @param nameAndType <code>name_and_type_index</code>.
+ * @return the index of the added entry.
+ * @since 3.17
+ */
+ public int addDynamicInfo(int bootstrap, int nameAndType) {
+ return addItem(new DynamicInfo(bootstrap, nameAndType, numOfItems));
+ }
+
+ /**
* Adds a new <code>CONSTANT_Module_info</code>
* @param nameIndex the index of the Utf8 entry.
* @return the index of the added entry.
@@ -1342,6 +1400,9 @@ public final class ConstPool
case MethodTypeInfo.tag : // 16
info = new MethodTypeInfo(in, numOfItems);
break;
+ case DynamicInfo.tag : // 17
+ info = new DynamicInfo(in, numOfItems);
+ break;
case InvokeDynamicInfo.tag : // 18
info = new InvokeDynamicInfo(in, numOfItems);
break;
@@ -2322,6 +2383,68 @@ class InvokeDynamicInfo extends ConstInfo
}
}
+class DynamicInfo extends ConstInfo {
+
+ static final int tag = 17;
+ int bootstrap, nameAndType;
+
+ public DynamicInfo(int bootstrapMethod,
+ int ntIndex, int index) {
+ super(index);
+ bootstrap = bootstrapMethod;
+ nameAndType = ntIndex;
+ }
+
+ public DynamicInfo(DataInputStream in, int index)
+ throws IOException {
+ super(index);
+ bootstrap = in.readUnsignedShort();
+ nameAndType = in.readUnsignedShort();
+ }
+
+ @Override
+ public int hashCode() {
+ return (bootstrap << 16) ^ nameAndType;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (obj instanceof DynamicInfo) {
+ DynamicInfo iv = (DynamicInfo) obj;
+ return iv.bootstrap == bootstrap
+ && iv.nameAndType == nameAndType;
+ }
+ return false;
+ }
+
+ @Override
+ public int getTag() {
+ return tag;
+ }
+
+ @Override
+ public int copy(ConstPool src, ConstPool dest,
+ Map<String, String> map) {
+ return dest.addDynamicInfo(bootstrap,
+ src.getItem(nameAndType).copy(src, dest, map));
+ }
+
+ @Override
+ public void write(DataOutputStream out) throws IOException {
+ out.writeByte(tag);
+ out.writeShort(bootstrap);
+ out.writeShort(nameAndType);
+ }
+
+ @Override
+ public void print(PrintWriter out) {
+ out.print("Dynamic #");
+ out.print(bootstrap);
+ out.print(", name&type #");
+ out.println(nameAndType);
+ }
+}
+
class ModuleInfo extends ConstInfo
{
static final int tag = 19;
diff --git a/src/test/javassist/bytecode/BytecodeTest.java b/src/test/javassist/bytecode/BytecodeTest.java
index 5ddf5d5b..ec754b56 100644
--- a/src/test/javassist/bytecode/BytecodeTest.java
+++ b/src/test/javassist/bytecode/BytecodeTest.java
@@ -827,6 +827,42 @@ public class BytecodeTest extends TestCase {
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() {
TestSuite suite = new TestSuite("Bytecode Tests");
suite.addTestSuite(BytecodeTest.class);
diff --git a/src/test/test4/Dyn.java b/src/test/test4/Dyn.java
new file mode 100644
index 00000000..83418d47
--- /dev/null
+++ b/src/test/test4/Dyn.java
@@ -0,0 +1,22 @@
+package test4;
+
+public class Dyn {
+
+ public static int test9(int i, String s) {
+ return 9;
+ }
+
+ public int test8(int i, String s) {
+ return 8;
+ }
+
+ public static Integer boot(String numberString)
+ throws NoSuchMethodException, IllegalAccessException {
+ return Integer.valueOf(numberString);
+ }
+
+ public Integer boot2(String numberString)
+ throws NoSuchMethodException, IllegalAccessException {
+ return Integer.valueOf(numberString);
+ }
+}