diff options
author | Grzegorz Kossakowski <grzegorz.kossakowski@gmail.com> | 2013-01-29 16:11:58 -0800 |
---|---|---|
committer | Grzegorz Kossakowski <grzegorz.kossakowski@gmail.com> | 2013-01-29 16:11:58 -0800 |
commit | 8610d7ec063407f62b11df848dd588e4594b3b40 (patch) | |
tree | ecb3af9fbcea35be81f1285be47f2e95d19c46d6 /test/files/jvm | |
parent | eff78b852e8b866badf9b9738f896c2a31c05474 (diff) | |
download | scala-8610d7ec063407f62b11df848dd588e4594b3b40.tar.gz scala-8610d7ec063407f62b11df848dd588e4594b3b40.tar.bz2 scala-8610d7ec063407f62b11df848dd588e4594b3b40.zip |
Add Bytecode test (ASM-based) to partest.
This commit introduces a new kind of test `Bytecode` that allows
one to inspect bytecode generated for given piece of Scala code.
The bytecode inspection is achieved by inspection of ASM trees.
See the included example for details.
NOTE: This commit does not introduce a new category of pratest tests.
Bytecode tests should be run in `jvm` category of partest tests.
Specific list of changes:
* Add BytecodeTest that contains common utilities to partest
* Add asm to classpath when compiling partest. That's not a
new dependency as it's being already done for javac task
we were running while compiling partest.
* Add an example test that shows how to count null checks in
given method.
Diffstat (limited to 'test/files/jvm')
-rw-r--r-- | test/files/jvm/bytecode-test-example.check | 1 | ||||
-rw-r--r-- | test/files/jvm/bytecode-test-example/Foo_1.scala | 9 | ||||
-rw-r--r-- | test/files/jvm/bytecode-test-example/Test.scala | 32 |
3 files changed, 42 insertions, 0 deletions
diff --git a/test/files/jvm/bytecode-test-example.check b/test/files/jvm/bytecode-test-example.check new file mode 100644 index 0000000000..0cfbf08886 --- /dev/null +++ b/test/files/jvm/bytecode-test-example.check @@ -0,0 +1 @@ +2 diff --git a/test/files/jvm/bytecode-test-example/Foo_1.scala b/test/files/jvm/bytecode-test-example/Foo_1.scala new file mode 100644 index 0000000000..4f679d156f --- /dev/null +++ b/test/files/jvm/bytecode-test-example/Foo_1.scala @@ -0,0 +1,9 @@ +class Foo_1 { + def foo(x: AnyRef): Int = { + val bool = x == null + if (x != null) + 1 + else + 0 + } +} diff --git a/test/files/jvm/bytecode-test-example/Test.scala b/test/files/jvm/bytecode-test-example/Test.scala new file mode 100644 index 0000000000..d668059cb7 --- /dev/null +++ b/test/files/jvm/bytecode-test-example/Test.scala @@ -0,0 +1,32 @@ +import scala.tools.partest.BytecodeTest + +import scala.tools.nsc.util.JavaClassPath +import java.io.InputStream +import scala.tools.asm +import asm.ClassReader +import asm.tree.{ClassNode, InsnList} +import scala.collection.JavaConverters._ + +object Test extends BytecodeTest { + def show: Unit = { + val classNode = loadClassNode("Foo_1") + val methodNode = getMethod(classNode, "foo") + println(countNullChecks(methodNode.instructions)) + } + + def countNullChecks(insnList: InsnList): Int = { + /** Is given instruction a null check? + * NOTE + * This will detect direct null compparsion as in + * if (x == null) ... + * and not indirect as in + * val foo = null + * if (x == foo) ... + */ + def isNullCheck(node: asm.tree.AbstractInsnNode): Boolean = { + val opcode = node.getOpcode + (opcode == asm.Opcodes.IFNULL) || (opcode == asm.Opcodes.IFNONNULL) + } + insnList.iterator.asScala.count(isNullCheck) + } +} |