Skip to content

Commit 0e98c59

Browse files
committed
Test warnings when an indy cannot be inlined
There are two cases tested here - An indyLMF where the lambda body method is private - An indy where the bootstrap method is not LMF
1 parent d1f2084 commit 0e98c59

File tree

7 files changed

+79
-0
lines changed

7 files changed

+79
-0
lines changed
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
Test_2.scala:2: warning: A_1::test()Ljava/lang/String; could not be inlined:
2+
The callee A_1::test()Ljava/lang/String; contains the instruction INVOKEDYNAMIC m()LA_1$Fun; [
3+
// handle kind 0x6 : INVOKESTATIC
4+
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;
5+
// arguments:
6+
(Ljava/lang/String;)Ljava/lang/String;,
7+
// handle kind 0x6 : INVOKESTATIC
8+
A_1.lambda$test$0(Ljava/lang/String;)Ljava/lang/String;,
9+
(Ljava/lang/String;)Ljava/lang/String;
10+
]
11+
that would cause an IllegalAccessError when inlined into class Test.
12+
def foo = A_1.test
13+
^
14+
error: No warnings can be incurred under -Xfatal-warnings.
15+
one warning found
16+
one error found
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
-Yopt:l:classpath -Yopt-inline-heuristics:everything -Yopt-warnings:_ -Xfatal-warnings
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
public class A_1 {
2+
interface Fun {
3+
String m(String s);
4+
}
5+
public static final String test() {
6+
Fun f = s -> s.trim();
7+
return f.m(" eh ");
8+
}
9+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
class Test {
2+
def foo = A_1.test
3+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
newSource1.scala:1: warning: A_1::test()Ljava/lang/String; could not be inlined:
2+
Failed to check if A_1::test()Ljava/lang/String; can be safely inlined to T without causing an IllegalAccessError. Checking instruction INVOKEDYNAMIC m()LA_1$Fun; [
3+
// handle kind 0x6 : INVOKESTATIC
4+
not/java/lang/SomeLambdaMetafactory.notAMetaFactoryMethod(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;[Ljava/lang/Object;)Ljava/lang/invoke/CallSite;
5+
// arguments:
6+
(Ljava/lang/String;)Ljava/lang/String;,
7+
// handle kind 0x6 : INVOKESTATIC
8+
A_1.lambda$test$0(Ljava/lang/String;)Ljava/lang/String;,
9+
(Ljava/lang/String;)Ljava/lang/String;
10+
] failed:
11+
The callee contains an InvokeDynamic instruction with an unknown bootstrap method (not a LambdaMetaFactory).
12+
class T { def foo = A_1.test }
13+
^
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
public class A_1 {
2+
interface Fun {
3+
String m(String s);
4+
}
5+
public static final String test() {
6+
Fun f = s -> s.trim();
7+
return f.m(" eh ");
8+
}
9+
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import java.io.File
2+
3+
import scala.collection.convert.decorateAsScala._
4+
import scala.tools.asm.tree.{ClassNode, InvokeDynamicInsnNode}
5+
import scala.tools.asm.{Handle, Opcodes}
6+
import scala.tools.partest.BytecodeTest.modifyClassFile
7+
import scala.tools.partest._
8+
9+
object Test extends DirectTest {
10+
def code = ???
11+
12+
def compileCode(code: String) = {
13+
val classpath = List(sys.props("partest.lib"), testOutput.path) mkString sys.props("path.separator")
14+
compileString(newCompiler("-cp", classpath, "-d", testOutput.path, "-Yopt:l:classpath", "-Yopt-inline-heuristics:everything", "-Yopt-warnings:_"))(code)
15+
}
16+
17+
def show(): Unit = {
18+
val unknownBootstrapMethod = new Handle(Opcodes.H_INVOKESTATIC, "not/java/lang/SomeLambdaMetafactory", "notAMetaFactoryMethod", "(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;[Ljava/lang/Object;)Ljava/lang/invoke/CallSite;")
19+
modifyClassFile(new File(testOutput.toFile, "A_1.class"))((cn: ClassNode) => {
20+
val testMethod = cn.methods.iterator.asScala.find(_.name == "test").head
21+
val indy = testMethod.instructions.iterator.asScala.collect({ case i: InvokeDynamicInsnNode => i }).next()
22+
indy.bsm = unknownBootstrapMethod
23+
cn
24+
})
25+
26+
compileCode("class T { def foo = A_1.test }")
27+
}
28+
}

0 commit comments

Comments
 (0)