[PATCH][asmtools] Fix incorrect handling of some CPX2 constant pool entries by JDIS
Maxim Degtyarev
mdegtyarev at gmail.com
Mon Mar 12 23:52:50 UTC 2018
The proposed patch (see attached file jdis-cpx2-bug.diff.txt) address
incorrect handling of some constant pool entries represented with CPX2
class by ASMTOOLS JDIS.
JDIS incorrectly assume that field CPX2::value1 is always used to hold
index of constant pool entry of type CONSTANT_CLASS.
This assumption is valid only for entries of type CONSTANT_FIELD,
CONSTANT_METHOD and CONSTANT_INTERFACEMETHOD.
For CONSTANT_NAMEANDTYPE, CONSTANT_METHODHANDLE, CONSTANT_DYNAMIC and
CONSTANT_INVOKEDYNAMIC this assumption is wrong.
As a result asmtools jdis may produce malformed output for valid input.
Example:
public class Test {
// Force `class Test` entry appear in the constant pool before
InvokeDynamic entries.
public Class<?> CLASS = Test.class;
private static Runnable[] workers = {
() -> System.out.println("Test"),
() -> System.out.println("Test"),
() -> System.out.println("Test"),
() -> System.out.println("Test"),
() -> System.out.println("Test"),
() -> System.out.println("Test"),
() -> System.out.println("Test"),
() -> System.out.println("Test"),
() -> System.out.println("Test"),
() -> System.out.println("Test")
};
public static void main(String... args) {
for(Runnable worker : workers) {
worker.run();
}
}
}
One of invokedynamic instructions may be rendered by jdis as
invokedynamic InvokeDynamic run:"()Ljava/lang/Runnable;";
instead of
invokedynamic InvokeDynamic
REF_invokeStatic:java/lang/invoke/LambdaMetafactory.metafactory:"(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;":run:"()Ljava/lang/Runnable;"
MethodType "()V", MethodHandle
REF_invokeStatic:Test.lambda$static$1:"()V", MethodType "()V";
-------------- next part --------------
# HG changeset patch
# User maccimo
# Date 1520880268 -10800
# Mon Mar 12 21:44:28 2018 +0300
# Node ID f5e62b0fae745f3640455513a9824c1d3a59e1be
# Parent 2904229ed97ec1d90a055ad86759f867cdc5296b
Fix incorrect handling of constant pool entries of type CONSTANT_NAMEANDTYPE, CONSTANT_METHODHANDLE, CONSTANT_DYNAMIC and CONSTANT_INVOKEDYNAMIC.
diff --git a/src/org/openjdk/asmtools/jdis/ConstantPool.java b/src/org/openjdk/asmtools/jdis/ConstantPool.java
--- a/src/org/openjdk/asmtools/jdis/ConstantPool.java
+++ b/src/org/openjdk/asmtools/jdis/ConstantPool.java
@@ -500,8 +500,9 @@
* CPX2
*
* Constant entries that contain two constant-pool indices. Usually, this includes:
- * CONSTANT_FIELD CONSTANT_METHOD CONSTANT_INTERFACEMETHOD CONSTANT_NAMEANDTYPE
- * CONSTANT_METHODHANDLE CONSTANT_DYNAMIC CONSTANT_INVOKEDYNAMIC
+ * CONSTANT_NAMEANDTYPE CONSTANT_METHODHANDLE CONSTANT_DYNAMIC CONSTANT_INVOKEDYNAMIC
+ *
+ * For constant entries referencing class members use CPX2_ClassMember instead.
*
*/
class CPX2 extends Constant {
@@ -600,6 +601,23 @@
}
}
+ /**
+ * CPX2_ClassMember
+ *
+ * Specialized subclass of CPX2 class for constant entries that contain two constant-pool indices
+ * with first index pointing to the constant pool entry of type CONSTANT_CLASS.
+ *
+ * Usually, this includes: CONSTANT_FIELD CONSTANT_METHOD CONSTANT_INTERFACEMETHOD
+ *
+ */
+ class CPX2_ClassMember extends CPX2 {
+
+ CPX2_ClassMember(TAG tagval, int cpx1, int cpx2) {
+ super(tagval, cpx1, cpx2);
+ }
+
+ }
+
/* -------------------------------------------------------- */
/* ConstantPool Fields */
/**
@@ -674,6 +692,8 @@
case CONSTANT_FIELD:
case CONSTANT_METHOD:
case CONSTANT_INTERFACEMETHOD:
+ pool.add(i, new CPX2_ClassMember(tagobj, in.readUnsignedShort(), in.readUnsignedShort()));
+ break;
case CONSTANT_NAMEANDTYPE:
case CONSTANT_DYNAMIC:
case CONSTANT_INVOKEDYNAMIC:
@@ -845,13 +865,13 @@
*
* getClassName
*
- * Safely gets a Java class name from a ConstantClass from a CPX2 constant pool
+ * Safely gets a Java class name from a ConstantClass from a CPX2_ClassMember constant pool
* object. (eg. Method/Field/Interface Ref)
*
* Returns either the Java class name, or a CP index reference string.
*
*/
- public String getClassName(CPX2 classConst) {
+ public String getClassName(CPX2_ClassMember classConst) {
return _getClassName(classConst.value1);
}
@@ -998,17 +1018,10 @@
if (cns == null) {
return "#" + cpx;
}
- switch (cns.tag) {
- case CONSTANT_METHODHANDLE:
- case CONSTANT_DYNAMIC:
- case CONSTANT_INVOKEDYNAMIC:
- case CONSTANT_METHOD:
- case CONSTANT_INTERFACEMETHOD:
- case CONSTANT_FIELD: {
- CPX2 cns2 = (CPX2) cns;
- if (cns2.value1 == cd.this_cpx) {
- cpx = cns2.value2;
- }
+ if (cns instanceof CPX2_ClassMember) {
+ CPX2_ClassMember cns2 = (CPX2_ClassMember) cns;
+ if (cns2.value1 == cd.this_cpx) {
+ cpx = cns2.value2;
}
}
return cns.tag.tagname + " " + StringValue(cpx);
More information about the code-tools-dev
mailing list