blob: 535ef2a2e2ea77ae11d04cc5046d5eeab38e8640 (
plain) (
blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
|
import java.io.{FileOutputStream, FileInputStream}
import scala.tools.asm.{ClassWriter, Opcodes, ClassReader}
import scala.tools.asm.tree.{InsnNode, ClassNode}
import scala.tools.nsc.backend.jvm.AsmUtils
import scala.tools.partest.DirectTest
import scala.collection.JavaConverters._
/**
* Test that the ICodeReader does not crash if the bytecode of a method has unreachable code.
*/
object Test extends DirectTest {
def code: String = ???
def show(): Unit = {
// The bytecode of f will be modified using ASM by `addDeadCode`
val aCode =
"""
|package p
|class A {
| @inline final def f = 1
|}
""".stripMargin
val bCode =
"""
|package p
|class B {
| def g = (new A()).f
|}
""".stripMargin
compileString(newCompiler("-usejavacp"))(aCode)
addDeadCode()
// If inlining fails, the compiler will issue an inliner warning that is not present in the
// check file
compileString(newCompiler("-usejavacp", "-optimise", "-Ybackend:GenASM"))(bCode)
}
def readClass(file: String) = {
val cnode = new ClassNode()
val is = new FileInputStream(file)
val reader = new ClassReader(is)
reader.accept(cnode, 0)
is.close()
cnode
}
def writeClass(file: String, cnode: ClassNode): Unit = {
val writer = new ClassWriter(0)
cnode.accept(writer)
val os = new FileOutputStream(file)
os.write(writer.toByteArray)
os.close()
}
def addDeadCode() {
val file = (testOutput / "p" / "A.class").path
val cnode = readClass(file)
val method = cnode.methods.asScala.find(_.name == "f").head
AsmUtils.traceMethod(method)
val insns = method.instructions
val it = insns.iterator()
while (it.hasNext) {
val in = it.next()
if (in.getOpcode == Opcodes.IRETURN) {
// Insert an ATHROW before the IRETURN. The IRETURN will then be dead code.
// The ICodeReader should not crash if there's dead code.
insns.insert(in.getPrevious, new InsnNode(Opcodes.ATHROW))
}
}
AsmUtils.traceMethod(method)
writeClass(file, cnode)
}
}
|