diff options
author | Lukas Rytz <lukas.rytz@gmail.com> | 2015-01-20 23:20:26 +0100 |
---|---|---|
committer | Lukas Rytz <lukas.rytz@gmail.com> | 2015-03-11 12:53:35 -0700 |
commit | 4e982451decdc3821febfe975e1b8e406a3741e8 (patch) | |
tree | 95438438c6cd166b68418e765d8d599bb6a91573 /test/files/run/bcodeInlinerMixed | |
parent | 37c91654433a12249ae125b9454ba17cef103327 (diff) | |
download | scala-4e982451decdc3821febfe975e1b8e406a3741e8.tar.gz scala-4e982451decdc3821febfe975e1b8e406a3741e8.tar.bz2 scala-4e982451decdc3821febfe975e1b8e406a3741e8.zip |
Don't crash the inliner in mixed compilation
In mixed compilation, the bytecode of Java classes is not availalbe:
the Scala compiler does not produce any, and there are no classfiles
yet.
When inlining a (Scala defined) method that contains an invocation to
a Java method, we need the Java method's bytecode in order to check
whether that invocation can be transplanted to the new location
without causing an IllegalAccessError. If the bytecode cannot be
found, inlining won't be allowed.
Diffstat (limited to 'test/files/run/bcodeInlinerMixed')
-rw-r--r-- | test/files/run/bcodeInlinerMixed/A_1.java | 3 | ||||
-rw-r--r-- | test/files/run/bcodeInlinerMixed/B_1.scala | 20 | ||||
-rw-r--r-- | test/files/run/bcodeInlinerMixed/Test.scala | 16 |
3 files changed, 39 insertions, 0 deletions
diff --git a/test/files/run/bcodeInlinerMixed/A_1.java b/test/files/run/bcodeInlinerMixed/A_1.java new file mode 100644 index 0000000000..44d7d88eeb --- /dev/null +++ b/test/files/run/bcodeInlinerMixed/A_1.java @@ -0,0 +1,3 @@ +public class A_1 { + public static final int bar() { return 100; } +} diff --git a/test/files/run/bcodeInlinerMixed/B_1.scala b/test/files/run/bcodeInlinerMixed/B_1.scala new file mode 100644 index 0000000000..2aadeccb82 --- /dev/null +++ b/test/files/run/bcodeInlinerMixed/B_1.scala @@ -0,0 +1,20 @@ +// Partest does proper mixed compilation: +// 1. scalac *.scala *.java +// 2. javac *.java +// 3. scalc *.scala +// +// In the second scalc round, the classfile for A_1 is on the classpath. +// Therefore the inliner has access to the bytecode of `bar`, which means +// it can verify that the invocation to `bar` can be safely inlined. +// +// So both callsites of `flop` are inlined. +// +// In a single mixed compilation, `flop` cannot be inlined, see JUnit InlinerTest.scala, def mixedCompilationNoInline. + +class B { + @inline final def flop = A_1.bar + def g = flop +} +class C { + def h(b: B) = b.flop +} diff --git a/test/files/run/bcodeInlinerMixed/Test.scala b/test/files/run/bcodeInlinerMixed/Test.scala new file mode 100644 index 0000000000..c8c7a9fe2a --- /dev/null +++ b/test/files/run/bcodeInlinerMixed/Test.scala @@ -0,0 +1,16 @@ +import scala.tools.partest.{BytecodeTest, ASMConverters} +import ASMConverters._ + +object Test extends BytecodeTest { + def show: Unit = { + val gIns = instructionsFromMethod(getMethod(loadClassNode("B"), "g")) + val hIns = instructionsFromMethod(getMethod(loadClassNode("C"), "h")) + // val invocation = Invoke(INVOKESTATIC, A_1, bar, ()I, false) + for (i <- List(gIns, hIns)) { + assert(i exists { + case Invoke(_, _, "bar", "()I", _) => true + case _ => false + }, i mkString "\n") + } + } +} |