Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SI-9403 fix ICodeReader for negative BIPUSH / SIPUSH values #4653

Merged
merged 1 commit into from
Jul 27, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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))

Expand Down
1 change: 1 addition & 0 deletions test/files/run/t9403.flags
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
-Ybackend:GenASM -optimize
5 changes: 5 additions & 0 deletions test/files/run/t9403/C_1.scala
Original file line number Diff line number Diff line change
@@ -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)
}
29 changes: 29 additions & 0 deletions test/files/run/t9403/Test_2.scala
Original file line number Diff line number Diff line change
@@ -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")
}
}