Skip to content

Commit bf4c0ed

Browse files
committed
Merge branch '318034-add-precompiled-jdk8-all-lambdas-test' into 'master'
Add a jdk8.AllLambdas test case and fix two missing ASM API checks for invokedynamic. Closes #318034 See merge request asm/asm!434
2 parents ea4c6f1 + 1eda731 commit bf4c0ed

File tree

9 files changed

+311
-6
lines changed

9 files changed

+311
-6
lines changed

asm-commons/src/main/java/org/objectweb/asm/commons/InstructionAdapter.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -544,6 +544,9 @@ public void visitInvokeDynamicInsn(
544544
final String descriptor,
545545
final Handle bootstrapMethodHandle,
546546
final Object... bootstrapMethodArguments) {
547+
if (api < Opcodes.ASM5) {
548+
throw new UnsupportedOperationException("This feature requires ASM5");
549+
}
547550
invokedynamic(name, descriptor, bootstrapMethodHandle, bootstrapMethodArguments);
548551
}
549552

asm-test/src/main/java/org/objectweb/asm/test/AsmTest.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,7 @@ public enum PrecompiledClass {
152152
JDK8_ALL_FRAMES("jdk8.AllFrames", JdkVersion.JDK8),
153153
JDK8_ALL_INSTRUCTIONS("jdk8.AllInstructions", JdkVersion.JDK8),
154154
JDK8_ALL_STRUCTURES("jdk8.AllStructures", JdkVersion.JDK8),
155+
JDK8_ALL_LAMBDAS("jdk8.AllLambdas", JdkVersion.JDK8),
155156
JDK8_ANONYMOUS_INNER_CLASS("jdk8.AllStructures$1", JdkVersion.JDK8),
156157
JDK8_ARTIFICIAL_STRUCTURES("jdk8.Artificial$()$Structures", JdkVersion.JDK8),
157158
JDK8_INNER_CLASS("jdk8.AllStructures$InnerClass", JdkVersion.JDK8),
260 Bytes
Binary file not shown.
2.24 KB
Binary file not shown.
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
// ASM: a very small and fast Java bytecode manipulation framework
2+
// Copyright (c) 2000-2011 INRIA, France Telecom
3+
// All rights reserved.
4+
//
5+
// Redistribution and use in source and binary forms, with or without
6+
// modification, are permitted provided that the following conditions
7+
// are met:
8+
// 1. Redistributions of source code must retain the above copyright
9+
// notice, this list of conditions and the following disclaimer.
10+
// 2. Redistributions in binary form must reproduce the above copyright
11+
// notice, this list of conditions and the following disclaimer in the
12+
// documentation and/or other materials provided with the distribution.
13+
// 3. Neither the name of the copyright holders nor the names of its
14+
// contributors may be used to endorse or promote products derived from
15+
// this software without specific prior written permission.
16+
//
17+
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18+
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19+
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20+
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
21+
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22+
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23+
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24+
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25+
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26+
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
27+
// THE POSSIBILITY OF SUCH DAMAGE.
28+
package jdk8;
29+
30+
import java.io.Serializable;
31+
32+
public class AllLambdas {
33+
public interface InnerClass {
34+
default void inner() {
35+
}
36+
}
37+
38+
public static void normalLambda() {
39+
Runnable runnable = Thread::dumpStack;
40+
}
41+
42+
public static void advancedLambda() {
43+
Runnable runnable = (Runnable & InnerClass) Thread::dumpStack;
44+
}
45+
46+
public static void serializableLambda() {
47+
Runnable runnable = (Runnable & Serializable) Thread::dumpStack;
48+
}
49+
50+
public static void serializableAdvancedLambda() {
51+
Runnable runnable = (Runnable & Serializable & InnerClass) Thread::dumpStack;
52+
}
53+
}
54+

asm-tree/src/main/java/org/objectweb/asm/tree/MethodNode.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -605,6 +605,8 @@ public void check(final int api) {
605605
if (isInterface != (insn.opcode == Opcodes.INVOKEINTERFACE)) {
606606
throw new UnsupportedClassVersionException();
607607
}
608+
} else if (insn instanceof InvokeDynamicInsnNode) {
609+
throw new UnsupportedClassVersionException();
608610
} else if (insn instanceof LdcInsnNode) {
609611
Object value = ((LdcInsnNode) insn).cst;
610612
if (value instanceof Handle
Lines changed: 243 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,243 @@
1+
// class version 52.0 (52)
2+
// access flags 0x21
3+
public class jdk8/AllLambdas {
4+
5+
// compiled from: AllLambdas.java
6+
// access flags 0x609
7+
public static abstract INNERCLASS jdk8/AllLambdas$InnerClass jdk8/AllLambdas InnerClass
8+
// access flags 0x19
9+
public final static INNERCLASS java/lang/invoke/MethodHandles$Lookup java/lang/invoke/MethodHandles Lookup
10+
11+
// access flags 0x1
12+
public <init>()V
13+
L0
14+
LINENUMBER 32 L0
15+
ALOAD 0
16+
INVOKESPECIAL java/lang/Object.<init> ()V
17+
RETURN
18+
MAXSTACK = 1
19+
MAXLOCALS = 1
20+
21+
// access flags 0x9
22+
public static normalLambda()V
23+
L0
24+
LINENUMBER 39 L0
25+
INVOKEDYNAMIC run()Ljava/lang/Runnable; [
26+
// handle kind 0x6 : INVOKESTATIC
27+
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;
28+
// arguments:
29+
()V,
30+
// handle kind 0x6 : INVOKESTATIC
31+
java/lang/Thread.dumpStack()V,
32+
()V
33+
]
34+
ASTORE 0
35+
L1
36+
LINENUMBER 40 L1
37+
RETURN
38+
MAXSTACK = 1
39+
MAXLOCALS = 1
40+
41+
// access flags 0x9
42+
public static advancedLambda()V
43+
L0
44+
LINENUMBER 43 L0
45+
INVOKEDYNAMIC run()Ljava/lang/Runnable; [
46+
// handle kind 0x6 : INVOKESTATIC
47+
java/lang/invoke/LambdaMetafactory.altMetafactory(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;[Ljava/lang/Object;)Ljava/lang/invoke/CallSite;
48+
// arguments:
49+
()V,
50+
// handle kind 0x6 : INVOKESTATIC
51+
java/lang/Thread.dumpStack()V,
52+
()V,
53+
6,
54+
1,
55+
jdk8.AllLambdas$InnerClass.class,
56+
0
57+
]
58+
CHECKCAST jdk8/AllLambdas$InnerClass
59+
CHECKCAST java/lang/Runnable
60+
ASTORE 0
61+
L1
62+
LINENUMBER 44 L1
63+
RETURN
64+
MAXSTACK = 1
65+
MAXLOCALS = 1
66+
67+
// access flags 0x9
68+
public static serializableLambda()V
69+
L0
70+
LINENUMBER 47 L0
71+
INVOKEDYNAMIC run()Ljava/lang/Runnable; [
72+
// handle kind 0x6 : INVOKESTATIC
73+
java/lang/invoke/LambdaMetafactory.altMetafactory(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;[Ljava/lang/Object;)Ljava/lang/invoke/CallSite;
74+
// arguments:
75+
()V,
76+
// handle kind 0x6 : INVOKESTATIC
77+
java/lang/Thread.dumpStack()V,
78+
()V,
79+
5,
80+
0
81+
]
82+
CHECKCAST java/io/Serializable
83+
CHECKCAST java/lang/Runnable
84+
ASTORE 0
85+
L1
86+
LINENUMBER 48 L1
87+
RETURN
88+
MAXSTACK = 1
89+
MAXLOCALS = 1
90+
91+
// access flags 0x9
92+
public static serializableAdvancedLambda()V
93+
L0
94+
LINENUMBER 51 L0
95+
INVOKEDYNAMIC run()Ljava/lang/Runnable; [
96+
// handle kind 0x6 : INVOKESTATIC
97+
java/lang/invoke/LambdaMetafactory.altMetafactory(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;[Ljava/lang/Object;)Ljava/lang/invoke/CallSite;
98+
// arguments:
99+
()V,
100+
// handle kind 0x6 : INVOKESTATIC
101+
java/lang/Thread.dumpStack()V,
102+
()V,
103+
7,
104+
1,
105+
jdk8.AllLambdas$InnerClass.class,
106+
0
107+
]
108+
CHECKCAST java/io/Serializable
109+
CHECKCAST jdk8/AllLambdas$InnerClass
110+
CHECKCAST java/lang/Runnable
111+
ASTORE 0
112+
L1
113+
LINENUMBER 52 L1
114+
RETURN
115+
MAXSTACK = 1
116+
MAXLOCALS = 1
117+
118+
// access flags 0x100A
119+
private static synthetic $deserializeLambda$(Ljava/lang/invoke/SerializedLambda;)Ljava/lang/Object;
120+
L0
121+
LINENUMBER 32 L0
122+
ALOAD 0
123+
INVOKEVIRTUAL java/lang/invoke/SerializedLambda.getImplMethodName ()Ljava/lang/String;
124+
ASTORE 1
125+
ICONST_M1
126+
ISTORE 2
127+
ALOAD 1
128+
INVOKEVIRTUAL java/lang/String.hashCode ()I
129+
LOOKUPSWITCH
130+
-1366118156: L1
131+
default: L2
132+
L1
133+
FRAME APPEND [java/lang/String I]
134+
ALOAD 1
135+
LDC "dumpStack"
136+
INVOKEVIRTUAL java/lang/String.equals (Ljava/lang/Object;)Z
137+
IFEQ L2
138+
ICONST_0
139+
ISTORE 2
140+
L2
141+
FRAME SAME
142+
ILOAD 2
143+
LOOKUPSWITCH
144+
0: L3
145+
default: L4
146+
L3
147+
FRAME SAME
148+
ALOAD 0
149+
INVOKEVIRTUAL java/lang/invoke/SerializedLambda.getImplMethodKind ()I
150+
BIPUSH 6
151+
IF_ICMPNE L5
152+
ALOAD 0
153+
INVOKEVIRTUAL java/lang/invoke/SerializedLambda.getFunctionalInterfaceClass ()Ljava/lang/String;
154+
LDC "java/lang/Runnable"
155+
INVOKEVIRTUAL java/lang/Object.equals (Ljava/lang/Object;)Z
156+
IFEQ L5
157+
ALOAD 0
158+
INVOKEVIRTUAL java/lang/invoke/SerializedLambda.getFunctionalInterfaceMethodName ()Ljava/lang/String;
159+
LDC "run"
160+
INVOKEVIRTUAL java/lang/Object.equals (Ljava/lang/Object;)Z
161+
IFEQ L5
162+
ALOAD 0
163+
INVOKEVIRTUAL java/lang/invoke/SerializedLambda.getFunctionalInterfaceMethodSignature ()Ljava/lang/String;
164+
LDC "()V"
165+
INVOKEVIRTUAL java/lang/Object.equals (Ljava/lang/Object;)Z
166+
IFEQ L5
167+
ALOAD 0
168+
INVOKEVIRTUAL java/lang/invoke/SerializedLambda.getImplClass ()Ljava/lang/String;
169+
LDC "java/lang/Thread"
170+
INVOKEVIRTUAL java/lang/Object.equals (Ljava/lang/Object;)Z
171+
IFEQ L5
172+
ALOAD 0
173+
INVOKEVIRTUAL java/lang/invoke/SerializedLambda.getImplMethodSignature ()Ljava/lang/String;
174+
LDC "()V"
175+
INVOKEVIRTUAL java/lang/Object.equals (Ljava/lang/Object;)Z
176+
IFEQ L5
177+
INVOKEDYNAMIC run()Ljava/lang/Runnable; [
178+
// handle kind 0x6 : INVOKESTATIC
179+
java/lang/invoke/LambdaMetafactory.altMetafactory(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;[Ljava/lang/Object;)Ljava/lang/invoke/CallSite;
180+
// arguments:
181+
()V,
182+
// handle kind 0x6 : INVOKESTATIC
183+
java/lang/Thread.dumpStack()V,
184+
()V,
185+
5,
186+
0
187+
]
188+
ARETURN
189+
L5
190+
FRAME SAME
191+
ALOAD 0
192+
INVOKEVIRTUAL java/lang/invoke/SerializedLambda.getImplMethodKind ()I
193+
BIPUSH 6
194+
IF_ICMPNE L4
195+
ALOAD 0
196+
INVOKEVIRTUAL java/lang/invoke/SerializedLambda.getFunctionalInterfaceClass ()Ljava/lang/String;
197+
LDC "java/lang/Runnable"
198+
INVOKEVIRTUAL java/lang/Object.equals (Ljava/lang/Object;)Z
199+
IFEQ L4
200+
ALOAD 0
201+
INVOKEVIRTUAL java/lang/invoke/SerializedLambda.getFunctionalInterfaceMethodName ()Ljava/lang/String;
202+
LDC "run"
203+
INVOKEVIRTUAL java/lang/Object.equals (Ljava/lang/Object;)Z
204+
IFEQ L4
205+
ALOAD 0
206+
INVOKEVIRTUAL java/lang/invoke/SerializedLambda.getFunctionalInterfaceMethodSignature ()Ljava/lang/String;
207+
LDC "()V"
208+
INVOKEVIRTUAL java/lang/Object.equals (Ljava/lang/Object;)Z
209+
IFEQ L4
210+
ALOAD 0
211+
INVOKEVIRTUAL java/lang/invoke/SerializedLambda.getImplClass ()Ljava/lang/String;
212+
LDC "java/lang/Thread"
213+
INVOKEVIRTUAL java/lang/Object.equals (Ljava/lang/Object;)Z
214+
IFEQ L4
215+
ALOAD 0
216+
INVOKEVIRTUAL java/lang/invoke/SerializedLambda.getImplMethodSignature ()Ljava/lang/String;
217+
LDC "()V"
218+
INVOKEVIRTUAL java/lang/Object.equals (Ljava/lang/Object;)Z
219+
IFEQ L4
220+
INVOKEDYNAMIC run()Ljava/lang/Runnable; [
221+
// handle kind 0x6 : INVOKESTATIC
222+
java/lang/invoke/LambdaMetafactory.altMetafactory(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;[Ljava/lang/Object;)Ljava/lang/invoke/CallSite;
223+
// arguments:
224+
()V,
225+
// handle kind 0x6 : INVOKESTATIC
226+
java/lang/Thread.dumpStack()V,
227+
()V,
228+
7,
229+
1,
230+
jdk8.AllLambdas$InnerClass.class,
231+
0
232+
]
233+
ARETURN
234+
L4
235+
FRAME SAME
236+
NEW java/lang/IllegalArgumentException
237+
DUP
238+
LDC "Invalid lambda deserialization"
239+
INVOKESPECIAL java/lang/IllegalArgumentException.<init> (Ljava/lang/String;)V
240+
ATHROW
241+
MAXSTACK = 3
242+
MAXLOCALS = 3
243+
}

asm/src/test/java/org/objectweb/asm/ClassReaderTest.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -351,9 +351,10 @@ void testAccept_emptyVisitor_skipCode(
351351

352352
// jdk8.ArtificialStructures contains structures which require ASM5, but only inside the method
353353
// code. Here we skip the code, so this class can be read with ASM4. Likewise for
354-
// jdk11.AllInstructions.
354+
// jdk8.AllLambdas and jdk11.AllInstructions.
355355
if (classParameter.isMoreRecentThan(apiParameter)
356356
&& classParameter != PrecompiledClass.JDK8_ARTIFICIAL_STRUCTURES
357+
&& classParameter != PrecompiledClass.JDK8_ALL_LAMBDAS
357358
&& classParameter != PrecompiledClass.JDK11_ALL_INSTRUCTIONS) {
358359
Exception exception = assertThrows(UnsupportedOperationException.class, accept);
359360
assertTrue(exception.getMessage().matches(UNSUPPORTED_OPERATION_MESSAGE_PATTERN));

build.gradle

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -101,8 +101,8 @@ project(':asm-commons') {
101101
project(':asm-test') {
102102
description = "Utilities for testing ${parent.description}"
103103
provides = ['org.objectweb.asm.test']
104-
depends = ['org.junit.jupiter:junit-jupiter-api:5.10.1',
105-
'org.junit.jupiter:junit-jupiter-params:5.10.1']
104+
depends = ['org.junit.jupiter:junit-jupiter-api:5.13.4',
105+
'org.junit.jupiter:junit-jupiter-params:5.13.4']
106106
}
107107

108108
project(':asm-tree') {
@@ -211,9 +211,10 @@ subprojects {
211211
dependencies {
212212
requires.each { projectName -> api project(projectName) }
213213
depends.each { artifactName -> api artifactName }
214-
testImplementation 'org.junit.jupiter:junit-jupiter-api:5.10.1',
215-
'org.junit.jupiter:junit-jupiter-params:5.10.1'
216-
testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.10.1'
214+
testImplementation 'org.junit.jupiter:junit-jupiter-api:5.13.4',
215+
'org.junit.jupiter:junit-jupiter-params:5.13.4'
216+
testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.13.4'
217+
testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
217218
testImplementation project(':asm-test')
218219
}
219220

0 commit comments

Comments
 (0)