jasm fails to parse a Dynamic constant correctly when the constant has no static arguments but is, itself, nested in a static argument list. I think a "," immediately following the Dynamic constant's name and type should indicate that the static argument list is empty.
The workaround is to use "{}" to indicate an empty static argument list. jdis does not use this workaround, so generates code that isn't properly parsed by jasm.
Original jasm source:
public static Method constantFilled3I:"()[I" stack 1 {
invokedynamic
InvokeDynamic REF_invokeStatic:java/lang/runtime/ArrayCreation.constantFilled
:"(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/reflect/RuntimeType;IILjava/lang/Object;)Ljava/lang/invoke/CallSite;"
:_:"()[I"
{
Dynamic REF_invokeStatic:java/lang/invoke/ConstantBootstraps.primitiveClass
:"(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/Class;)Ljava/lang/Class;"
:I:"Ljava/lang/Class;" {},
int 0, int 3, int -3
};
areturn;
}
Note the use of "{}" to indicate an empty list of static arguments to the Dynamic constant.
Run through jasm and then jdis:
public static Method constantFilled3I:"()[I"
stack 1 locals 0
{
invokedynamic InvokeDynamic REF_invokeStatic:Method java/lang/runtime/ArrayCreation.constantFilled:
"(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/reflect/RuntimeType;IILjava/lang/Object;)Ljava/lang/invoke/CallSite;":
_:"()[I" {
Dynamic REF_invokeStatic:Method java/lang/invoke/ConstantBootstraps.primitiveClass:"(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/Class;)Ljava/lang/Class;":I:"Ljava/lang/Class;",
int 0,
int 3,
int -3
};
areturn;
}
Same code, but the "{}" has been removed.
Run through jasm and then jdis again:
public static Method constantFilled3I:"()[I"
stack 1 locals 0
{
invokedynamic InvokeDynamic REF_invokeStatic:Method java/lang/runtime/ArrayCreation.constantFilled:
"(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/reflect/RuntimeType;IILjava/lang/Object;)Ljava/lang/invoke/CallSite;":
_:"()[I" {
Dynamic REF_invokeStatic:Method java/lang/invoke/ConstantBootstraps.primitiveClass:"(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/Class;)Ljava/lang/Class;":I:"Ljava/lang/Class;" {
int 0,
int 3,
int -3
}
};
areturn;
}
Now the trailing arguments have been applied to the Dynamic constant, not the InvokeDynamic constant.
The workaround is to use "{}" to indicate an empty static argument list. jdis does not use this workaround, so generates code that isn't properly parsed by jasm.
Original jasm source:
public static Method constantFilled3I:"()[I" stack 1 {
invokedynamic
InvokeDynamic REF_invokeStatic:java/lang/runtime/ArrayCreation.constantFilled
:"(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/reflect/RuntimeType;IILjava/lang/Object;)Ljava/lang/invoke/CallSite;"
:_:"()[I"
{
Dynamic REF_invokeStatic:java/lang/invoke/ConstantBootstraps.primitiveClass
:"(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/Class;)Ljava/lang/Class;"
:I:"Ljava/lang/Class;" {},
int 0, int 3, int -3
};
areturn;
}
Note the use of "{}" to indicate an empty list of static arguments to the Dynamic constant.
Run through jasm and then jdis:
public static Method constantFilled3I:"()[I"
stack 1 locals 0
{
invokedynamic InvokeDynamic REF_invokeStatic:Method java/lang/runtime/ArrayCreation.constantFilled:
"(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/reflect/RuntimeType;IILjava/lang/Object;)Ljava/lang/invoke/CallSite;":
_:"()[I" {
Dynamic REF_invokeStatic:Method java/lang/invoke/ConstantBootstraps.primitiveClass:"(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/Class;)Ljava/lang/Class;":I:"Ljava/lang/Class;",
int 0,
int 3,
int -3
};
areturn;
}
Same code, but the "{}" has been removed.
Run through jasm and then jdis again:
public static Method constantFilled3I:"()[I"
stack 1 locals 0
{
invokedynamic InvokeDynamic REF_invokeStatic:Method java/lang/runtime/ArrayCreation.constantFilled:
"(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/reflect/RuntimeType;IILjava/lang/Object;)Ljava/lang/invoke/CallSite;":
_:"()[I" {
Dynamic REF_invokeStatic:Method java/lang/invoke/ConstantBootstraps.primitiveClass:"(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/Class;)Ljava/lang/Class;":I:"Ljava/lang/Class;" {
int 0,
int 3,
int -3
}
};
areturn;
}
Now the trailing arguments have been applied to the Dynamic constant, not the InvokeDynamic constant.