[PATCH][asmtools] Fix incorrect handling of some CPX2 constant pool entries by JDIS
Leonid Kuskov
Leonid.Kuskov at Oracle.com
Wed Mar 14 19:04:57 UTC 2018
Hi Maxim,
Thank you for the patch. Indeed it does fix a bug - the fix is correct
but it seems to be overloaded with extra code.
CX2 class contains enough information to split structures into 2 groups:
referencing to CLASS_info
(Fieldref, Methodref and InterfaceMethodref) and all others, hence the
marker class CPX2_ClassMember is not necessary.
There you can just add one method to CX2 as follows:
boolean refersClassMember() {
return tag == CONSTANT_FIELD || tag == CONSTANT_METHOD || tag ==
CONSTANT_INTERFACEMETHOD;
}
and change only 1 line:
-if (cns2.value1 == cd.this_cpx) {
+if ( cns2.value1 == cd.this_cpx && cns2.refersClassMember() ) {
What do you think if I use this shorter fix as your contribution?
Thanks,
Leonid
On 3/12/18 16:52, Maxim Degtyarev wrote:
> 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";
More information about the code-tools-dev
mailing list