From 0dd8a135569b8f3f63d9c87fb5ad684d263db9f1 Mon Sep 17 00:00:00 2001 From: Felix Mulder Date: Wed, 18 May 2016 10:49:11 +0200 Subject: Add tests for primitive construction as well as reference and boxed unit arrays --- test/test/AsmConverters.scala | 2 +- test/test/DottyBytecodeTest.scala | 18 +++++++++ test/test/DottyBytecodeTests.scala | 83 +++++++++++++++++++++++++++++++++++++- 3 files changed, 100 insertions(+), 3 deletions(-) (limited to 'test') diff --git a/test/test/AsmConverters.scala b/test/test/AsmConverters.scala index a870b8fe7..5734e8660 100644 --- a/test/test/AsmConverters.scala +++ b/test/test/AsmConverters.scala @@ -5,7 +5,7 @@ import asm._ import asm.tree._ import scala.collection.JavaConverters._ -/** Makes using ASM from ByteCodeTests more convenient. +/** Makes using ASM from tests more convenient. * * Wraps ASM instructions in case classes so that equals and toString work * for the purpose of bytecode diffing and pretty printing. diff --git a/test/test/DottyBytecodeTest.scala b/test/test/DottyBytecodeTest.scala index 1acb85cbf..f2218d4b6 100644 --- a/test/test/DottyBytecodeTest.scala +++ b/test/test/DottyBytecodeTest.scala @@ -27,6 +27,24 @@ trait DottyBytecodeTest extends DottyTest { import AsmNode._ import ASMConverters._ + protected object Opcode { + val newarray = 188 + val anewarray = 189 + val multianewarray = 197 + + val boolean = 4 + val char = 5 + val float = 6 + val double = 7 + val byte = 8 + val short = 9 + val int = 10 + val long = 11 + + val boxedUnit = "scala/runtime/BoxedUnit" + val javaString = "java/lang/String" + } + private def bCodeCheckingComp(phase: TestGenBCode)(check: Directory => Unit) = new Compiler { override def phases = { diff --git a/test/test/DottyBytecodeTests.scala b/test/test/DottyBytecodeTests.scala index 717c8527a..5b5989474 100644 --- a/test/test/DottyBytecodeTests.scala +++ b/test/test/DottyBytecodeTests.scala @@ -86,7 +86,7 @@ class TestBCode extends DottyBytecodeTest { /** Make sure that creating multidim arrays reduces to "multinewarray" * instruction */ - @Test def multidimArrays = { + @Test def multidimArraysFromOfDim = { val source = """ |object Arr { | def arr = Array.ofDim[Int](2, 1) @@ -98,7 +98,10 @@ class TestBCode extends DottyBytecodeTest { val hadCorrectInstr = instructionsFromMethod(method) - .collect { case x @ NewArray(op, _, dims) if op == 197 && dims == 2 => x } + .collect { + case x @ NewArray(op, _, dims) + if op == Opcode.multianewarray && dims == 2 => x + } .length > 0 assert(hadCorrectInstr, @@ -106,4 +109,80 @@ class TestBCode extends DottyBytecodeTest { instructionsFromMethod(method).mkString("\n")) } } + + @Test def arraysFromOfDim = { + val source = """ + |object Arr { + | def arr1 = Array.ofDim[Int](2) + | def arr2 = Array.ofDim[Unit](2) + | def arr3 = Array.ofDim[String](2) + | def arr4 = Array.ofDim[Map[String, String]](2) + |}""".stripMargin + checkBCode(source) { dir => + val moduleIn = dir.lookupName("Arr$.class", directory = false) + val moduleNode = loadClassNode(moduleIn.input) + val arr1 = getMethod(moduleNode, "arr1") + val arr2 = getMethod(moduleNode, "arr2") + val arr3 = getMethod(moduleNode, "arr3") + + val arr1CorrectInstr = + instructionsFromMethod(arr1) + .collect { + case x @ IntOp(op, oprnd) + if op == Opcode.newarray && oprnd == Opcode.int => x + } + .length > 0 + + assert(arr1CorrectInstr, + "Did not contain \"multianewarray\" instruction in:\n" + + instructionsFromMethod(arr1).mkString("\n")) + + val arr2CorrectInstr = + instructionsFromMethod(arr2) + .collect { + case x @ TypeOp(op, oprnd) + if op == Opcode.anewarray && oprnd == Opcode.boxedUnit => x + } + .length > 0 + + assert(arr2CorrectInstr, + "arr2 bytecode did not contain correct `anewarray` instruction:\n" + + instructionsFromMethod(arr2)mkString("\n")) + + val arr3CorrectInstr = + instructionsFromMethod(arr3) + .collect { + case x @ TypeOp(op, oprnd) + if op == Opcode.anewarray && oprnd == Opcode.javaString => x + } + .length > 0 + + assert(arr3CorrectInstr, + "arr3 bytecode did not contain correct `anewarray` instruction:\n" + + instructionsFromMethod(arr3).mkString("\n")) + } + } + + @Test def arraysFromDimAndFromNewEqual = { + val source = """ + |object Arr { + | def arr1 = Array.ofDim[Int](2) + | def arr2 = new Array[Int](2) + |}""".stripMargin + + checkBCode(source) { dir => + val moduleIn = dir.lookupName("Arr$.class", directory = false) + val moduleNode = loadClassNode(moduleIn.input) + val arr1 = getMethod(moduleNode, "arr1") + val arr2 = getMethod(moduleNode, "arr2") + + // First two instructions of `arr1` fetch the static reference to `Array` + val instructions1 = instructionsFromMethod(arr1).drop(2) + val instructions2 = instructionsFromMethod(arr2) + + assert(instructions1 == instructions2, + "Creating arrays using `Array.ofDim[Int](2)` did not equal bytecode for `new Array[Int](2)`\n" + + diffInstructions(instructions1, instructions2)) + } + } } -- cgit v1.2.3