summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJason Zaugg <jzaugg@gmail.com>2015-07-27 13:33:16 +1000
committerJason Zaugg <jzaugg@gmail.com>2015-07-27 13:33:16 +1000
commitf682441f6f402cc22a747ea93547631af9cb669d (patch)
treea54803d9231347bfa92e72e94d19fac125b22f22
parentf2d7838d904572b3dd15a9ef223ecfd1a6e14697 (diff)
parent2678d349b2b2738d9db38d890199f32aa39d8c3e (diff)
downloadscala-f682441f6f402cc22a747ea93547631af9cb669d.tar.gz
scala-f682441f6f402cc22a747ea93547631af9cb669d.tar.bz2
scala-f682441f6f402cc22a747ea93547631af9cb669d.zip
Merge pull request #4653 from lrytz/t9403
SI-9403 fix ICodeReader for negative BIPUSH / SIPUSH values
-rw-r--r--src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala3
-rw-r--r--src/compiler/scala/tools/nsc/symtab/classfile/ICodeReader.scala6
-rw-r--r--test/files/run/t9403.flags1
-rw-r--r--test/files/run/t9403/C_1.scala5
-rw-r--r--test/files/run/t9403/Test_2.scala29
5 files changed, 41 insertions, 3 deletions
diff --git a/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala b/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala
index 06a0299d2a..99e61d2482 100644
--- a/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala
+++ b/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala
@@ -84,6 +84,9 @@ abstract class ClassfileParser {
protected final def u2(): Int = in.nextChar.toInt
protected final def u4(): Int = in.nextInt
+ protected final def s1(): Int = in.nextByte.toInt // sign-extend the byte to int
+ protected final def s2(): Int = (in.nextByte.toInt << 8) | u1 // sign-extend and shift the first byte, or with the unsigned second byte
+
private def readInnerClassFlags() = readClassFlags()
private def readClassFlags() = JavaAccFlags classFlags u2
private def readMethodFlags() = JavaAccFlags methodFlags u2
diff --git a/src/compiler/scala/tools/nsc/symtab/classfile/ICodeReader.scala b/src/compiler/scala/tools/nsc/symtab/classfile/ICodeReader.scala
index 438a71061e..b2f5a4119d 100644
--- a/src/compiler/scala/tools/nsc/symtab/classfile/ICodeReader.scala
+++ b/src/compiler/scala/tools/nsc/symtab/classfile/ICodeReader.scala
@@ -326,8 +326,8 @@ abstract class ICodeReader extends ClassfileParser {
case JVM.dconst_0 => code emit CONSTANT(Constant(0.0))
case JVM.dconst_1 => code emit CONSTANT(Constant(1.0))
- case JVM.bipush => code.emit(CONSTANT(Constant(u1))); size += 1
- case JVM.sipush => code.emit(CONSTANT(Constant(u2))); size += 2
+ case JVM.bipush => code.emit(CONSTANT(Constant(s1))); size += 1
+ case JVM.sipush => code.emit(CONSTANT(Constant(s2))); size += 2
case JVM.ldc => code.emit(CONSTANT(pool.getConstant(u1))); size += 1
case JVM.ldc_w => code.emit(CONSTANT(pool.getConstant(u2))); size += 2
case JVM.ldc2_w => code.emit(CONSTANT(pool.getConstant(u2))); size += 2
@@ -466,7 +466,7 @@ abstract class ICodeReader extends ClassfileParser {
size += 2
val local = code.getLocal(u1, INT)
code.emit(LOAD_LOCAL(local))
- code.emit(CONSTANT(Constant(u1)))
+ code.emit(CONSTANT(Constant(s1)))
code.emit(CALL_PRIMITIVE(Arithmetic(ADD, INT)))
code.emit(STORE_LOCAL(local))
diff --git a/test/files/run/t9403.flags b/test/files/run/t9403.flags
new file mode 100644
index 0000000000..307668060c
--- /dev/null
+++ b/test/files/run/t9403.flags
@@ -0,0 +1 @@
+-Ybackend:GenASM -optimize
diff --git a/test/files/run/t9403/C_1.scala b/test/files/run/t9403/C_1.scala
new file mode 100644
index 0000000000..439af1a386
--- /dev/null
+++ b/test/files/run/t9403/C_1.scala
@@ -0,0 +1,5 @@
+package p
+class C {
+ @inline final def f(x: Int): Long = 10L / (if (x < 0) -2 else 2)
+ @inline final def g(x: Int): Long = 3000L / (if (x < 0) -300 else 300)
+}
diff --git a/test/files/run/t9403/Test_2.scala b/test/files/run/t9403/Test_2.scala
new file mode 100644
index 0000000000..fb2777b9a8
--- /dev/null
+++ b/test/files/run/t9403/Test_2.scala
@@ -0,0 +1,29 @@
+import p.C
+import scala.tools.asm.Opcodes
+import scala.tools.partest.BytecodeTest
+import scala.tools.partest.ASMConverters._
+
+
+object Test extends BytecodeTest {
+ def foo(c: C, x: Int) = c.f(x)
+ def goo(c: C, x: Int) = c.g(x)
+
+ def has(i: Instruction, c: String, m: String) = {
+ val cls = loadClassNode(c)
+ val mth = convertMethod(getMethod(cls, m))
+ assert(mth.instructions.contains(i))
+ }
+
+ def show(): Unit = {
+ assert(foo(new C, -2) == -5L)
+ assert(goo(new C, -2) == -10L)
+
+ val bipush2 = IntOp(Opcodes.BIPUSH, -2)
+ has(bipush2, "p.C", "f")
+ has(bipush2, "Test$", "foo")
+
+ val sipush300 = IntOp(Opcodes.SIPUSH, -300)
+ has(sipush300, "p.C", "g")
+ has(sipush300, "Test$", "goo")
+ }
+}