From 82a5df2eace499e7b0fa52258d3cb46be833c92f Mon Sep 17 00:00:00 2001 From: Nickie S Date: Fri, 16 Jun 2023 21:44:12 +0300 Subject: [PATCH] Fix compatibility with java 9+ (#43) 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 --- .../src/main/kotlin/asmble/compile/jvm/ByteBufferMem.kt | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/compiler/src/main/kotlin/asmble/compile/jvm/ByteBufferMem.kt b/compiler/src/main/kotlin/asmble/compile/jvm/ByteBufferMem.kt index 9a1c3ba..b7647eb 100644 --- a/compiler/src/main/kotlin/asmble/compile/jvm/ByteBufferMem.kt +++ b/compiler/src/main/kotlin/asmble/compile/jvm/ByteBufferMem.kt @@ -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 Buffer>(ByteBuffer::limit).invokeVirtual(), + forceFnType Buffer>(Buffer::limit).invokeVirtual(), TypeInsnNode(Opcodes.CHECKCAST, ByteBuffer::class.ref.asmName), // Set it to use little endian ByteOrder::LITTLE_ENDIAN.getStatic(), @@ -45,7 +45,7 @@ open class ByteBufferMem(val direct: Boolean = true) : Mem { addInsns(ByteBuffer::duplicate.invokeVirtual()). let(buildOffset).popExpecting(Int::class.ref). addInsns( - forceFnType Buffer>(ByteBuffer::position).invokeVirtual(), + forceFnType 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, @@ -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 Buffer>(ByteBuffer::limit).invokeVirtual(), // [lim, mem] + forceFnType Buffer>(Buffer::limit).invokeVirtual(), // [lim, mem] InsnNode(Opcodes.POP), // [lim] Mem.PAGE_SIZE.const, // [lim, pagesize] InsnNode(Opcodes.IDIV), // [limpages] @@ -261,4 +261,4 @@ open class ByteBufferMem(val direct: Boolean = true) : Mem { override val storeLeavesMemOnStack get() = true companion object : ByteBufferMem() -} \ No newline at end of file +}