Skip to content

Commit f4ac00f

Browse files
Constantin Cebruneton
Constantin C
authored andcommitted
Fix SourceInterpreter wrongly saying that Condy long / doubles are one word elements.
1 parent 97495da commit f4ac00f

File tree

4 files changed

+61
-1
lines changed

4 files changed

+61
-1
lines changed

asm-analysis/src/main/java/org/objectweb/asm/tree/analysis/SourceInterpreter.java

+16-1
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
import java.util.HashSet;
3131
import java.util.List;
3232
import java.util.Set;
33+
import org.objectweb.asm.ConstantDynamic;
3334
import org.objectweb.asm.Opcodes;
3435
import org.objectweb.asm.Type;
3536
import org.objectweb.asm.tree.AbstractInsnNode;
@@ -86,8 +87,22 @@ public SourceValue newOperation(final AbstractInsnNode insn) {
8687
size = 2;
8788
break;
8889
case LDC:
90+
// Values able to be pushed by LDC:
91+
// - int, float, string (object), type (Class, object), type (MethodType, object),
92+
// handle (MethodHandle, object): one word
93+
// - long, double, ConstantDynamic (can produce either single word values, or double word
94+
// values): (up to) two words
8995
Object value = ((LdcInsnNode) insn).cst;
90-
size = value instanceof Long || value instanceof Double ? 2 : 1;
96+
if (value instanceof Long || value instanceof Double) {
97+
// two words guaranteed
98+
size = 2;
99+
} else if (value instanceof ConstantDynamic) {
100+
// might yield two words
101+
size = ((ConstantDynamic) value).getSize();
102+
} else {
103+
// one word guaranteed
104+
size = 1;
105+
}
91106
break;
92107
case GETSTATIC:
93108
size = Type.getType(((FieldInsnNode) insn).desc).getSize();
Binary file not shown.

asm-test/src/resources/java/jdk11/AllInstructions.jasm

+25
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,31 @@ private static Method bsm:"(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/St
8585
lreturn;
8686
}
8787

88+
// Needed to make two since asmtools' jasm doesnt optimize bsm entries the same way we do.
89+
// -> asmtools would generate two bsm methods, ClassWriter would generate one with the input from asmtools.
90+
// -> test fails while technically being correct
91+
private static Method anotherBsm:"(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/Class;)J"
92+
stack 2 locals 3
93+
{
94+
bipush 42;
95+
i2l;
96+
lreturn;
97+
}
98+
99+
public static Method gnarlyCondyPop:"()V"
100+
stack 2 locals 0
101+
{
102+
ldc2_w Dynamic REF_invokeStatic
103+
:jdk11/AllInstructions.anotherBsm
104+
:"(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/Class;)J"
105+
:test
106+
:"J";
107+
// Test that a condy ldc (interpreted as an ldc of a ConstantDynamic object) yields
108+
// a value with the proper size, as indicated by its descriptor (long in this case, 2 words)
109+
pop2;
110+
return;
111+
}
112+
88113
public static Method main:"([Ljava/lang/String;)V"
89114
stack 1 locals 2
90115
{

asm-util/src/test/resources/jdk11.AllInstructions.txt

+20
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,26 @@ public class jdk11/AllInstructions {
5050
MAXSTACK = 2
5151
MAXLOCALS = 3
5252

53+
// access flags 0xA
54+
private static anotherBsm(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/Class;)J
55+
BIPUSH 42
56+
I2L
57+
LRETURN
58+
MAXSTACK = 2
59+
MAXLOCALS = 3
60+
61+
// access flags 0x9
62+
public static gnarlyCondyPop()V
63+
LDC test : J [
64+
// handle kind 0x6 : INVOKESTATIC
65+
jdk11/AllInstructions.anotherBsm(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/Class;)J
66+
// arguments: none
67+
]
68+
POP2
69+
RETURN
70+
MAXSTACK = 2
71+
MAXLOCALS = 0
72+
5373
// access flags 0x9
5474
public static main([Ljava/lang/String;)V
5575
LDC run : Ljava/lang/Runnable; [

0 commit comments

Comments
 (0)