Skip to content

Commit

Permalink
Fix compatibility with java 9+ (#43)
Browse files Browse the repository at this point in the history
Java 9 introduced something called "covariant return types". This gets
used in java.nio.ByteBuffer: overriden methods from java.nio.Buffer now
return ByteBuffer instead of more general Buffer. Unfortunately this
breaks bytecode generation for the memory: ByteBuffer::limit cannot be
casted to ByteBuffer.(Int) -> Buffer. It can be casted to
ByteBuffer.(Int) -> ByteBuffer, but not in java 8.

The fix is easy enough: upcast the object to Buffer before calling the
method. In bytecode this corresponds to using Buffer::limit method instead
of ByteBuffer::limit. This works both with older and newer java.

The same applies to Buffer::position
  • Loading branch information
DCNick3 committed Jun 16, 2023
1 parent 11e5701 commit 82a5df2
Showing 1 changed file with 4 additions and 4 deletions.
8 changes: 4 additions & 4 deletions compiler/src/main/kotlin/asmble/compile/jvm/ByteBufferMem.kt
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ open class ByteBufferMem(val direct: Boolean = true) : Mem {
override fun init(func: Func, initial: Int) = func.popExpecting(memType).addInsns(
// Set the limit to initial
(initial * Mem.PAGE_SIZE).const,
forceFnType<ByteBuffer.(Int) -> Buffer>(ByteBuffer::limit).invokeVirtual(),
forceFnType<ByteBuffer.(Int) -> Buffer>(Buffer::limit).invokeVirtual(),
TypeInsnNode(Opcodes.CHECKCAST, ByteBuffer::class.ref.asmName),
// Set it to use little endian
ByteOrder::LITTLE_ENDIAN.getStatic(),
Expand All @@ -45,7 +45,7 @@ open class ByteBufferMem(val direct: Boolean = true) : Mem {
addInsns(ByteBuffer::duplicate.invokeVirtual()).
let(buildOffset).popExpecting(Int::class.ref).
addInsns(
forceFnType<ByteBuffer.(Int) -> Buffer>(ByteBuffer::position).invokeVirtual(),
forceFnType<ByteBuffer.(Int) -> Buffer>(Buffer::position).invokeVirtual(),
TypeInsnNode(Opcodes.CHECKCAST, memType.asmName)
).addInsns(
// We're going to do this as an LDC string in ISO-8859 and read it back at runtime. However,
Expand Down Expand Up @@ -111,7 +111,7 @@ open class ByteBufferMem(val direct: Boolean = true) : Mem {
InsnNode(Opcodes.IRETURN),
okLim, // [lim, mem, newlimL]
InsnNode(Opcodes.L2I), // [lim, mem, newlim]
forceFnType<ByteBuffer.(Int) -> Buffer>(ByteBuffer::limit).invokeVirtual(), // [lim, mem]
forceFnType<ByteBuffer.(Int) -> Buffer>(Buffer::limit).invokeVirtual(), // [lim, mem]
InsnNode(Opcodes.POP), // [lim]
Mem.PAGE_SIZE.const, // [lim, pagesize]
InsnNode(Opcodes.IDIV), // [limpages]
Expand Down Expand Up @@ -261,4 +261,4 @@ open class ByteBufferMem(val direct: Boolean = true) : Mem {
override val storeLeavesMemOnStack get() = true

companion object : ByteBufferMem()
}
}

0 comments on commit 82a5df2

Please sign in to comment.