Foreign Memory.kt implementation #98

Closed
CommanderTvis wants to merge 3 commits from foreign-memory into dev
3 changed files with 121 additions and 0 deletions
Showing only changes of commit 9c2c76e6eb - Show all commits

View File

@ -0,0 +1,51 @@
package scientifik.memory.foreign
import jdk.incubator.foreign.MemoryHandles
import jdk.incubator.foreign.MemorySegment
import scientifik.memory.Memory
import scientifik.memory.MemoryReader
import scientifik.memory.MemoryWriter
import java.lang.invoke.VarHandle
import java.nio.ByteOrder
fun Memory.Companion.allocateForeign(length: Int): Memory {
return ForeignMemory(MemorySegment.allocateNative(length.toLong()))
}
internal class ForeignMemory(val scope: MemorySegment) : Memory, AutoCloseable {
override val size: Int
get() = scope.byteSize().toInt()
private val writer: MemoryWriter = ForeignWriter(this)
private val reader: MemoryReader = ForeignReader(this)
override fun view(offset: Int, length: Int): ForeignMemory =
ForeignMemory(scope.asSlice(offset.toLong(), length.toLong()))
override fun copy(): Memory {
val bytes = scope.toByteArray()
val newScope = MemorySegment.allocateNative(scope.byteSize())!!
var point = newScope.baseAddress()
bytes.forEach {
byteHandle.set(point, it)
point = point.addOffset(1)
}
return ForeignMemory(newScope)
}
override fun reader(): MemoryReader = reader
override fun writer(): MemoryWriter = writer
override fun close(): Unit = scope.close()
internal companion object {
internal val doubleHandle: VarHandle = MemoryHandles.varHandle(java.lang.Double.TYPE, ByteOrder.nativeOrder())!!
internal val floatHandle: VarHandle = MemoryHandles.varHandle(java.lang.Float.TYPE, ByteOrder.nativeOrder())!!
internal val byteHandle: VarHandle = MemoryHandles.varHandle(java.lang.Byte.TYPE, ByteOrder.nativeOrder())!!
internal val shortHandle: VarHandle = MemoryHandles.varHandle(java.lang.Short.TYPE, ByteOrder.nativeOrder())!!
internal val intHandle: VarHandle = MemoryHandles.varHandle(Integer.TYPE, ByteOrder.nativeOrder())!!
internal val longHandle: VarHandle = MemoryHandles.varHandle(java.lang.Long.TYPE, ByteOrder.nativeOrder())!!
}
}

View File

@ -0,0 +1,35 @@
package scientifik.memory.foreign
import jdk.incubator.foreign.MemorySegment
import scientifik.memory.MemoryReader
internal class ForeignReader(override val memory: ForeignMemory) : MemoryReader {
private val scope: MemorySegment
get() = memory.scope.asReadOnly()
override fun readDouble(offset: Int): Double = with(scope) {
ForeignMemory.doubleHandle.get(baseAddress().addOffset(offset.toLong())) as Double
}
override fun readFloat(offset: Int): Float = with(scope) {
ForeignMemory.floatHandle.get(baseAddress().addOffset(offset.toLong())) as Float
}
override fun readByte(offset: Int): Byte = with(scope) {
ForeignMemory.byteHandle.get(baseAddress().addOffset(offset.toLong())) as Byte
}
override fun readShort(offset: Int): Short = with(scope) {
ForeignMemory.shortHandle.get(baseAddress().addOffset(offset.toLong())) as Short
}
override fun readInt(offset: Int): Int = with(scope) {
ForeignMemory.intHandle.get(baseAddress().addOffset(offset.toLong())) as Int
}
override fun readLong(offset: Int): Long = with(scope) {
ForeignMemory.longHandle.get(baseAddress().addOffset(offset.toLong())) as Long
}
override fun release(): Unit = memory.close()
}

View File

@ -0,0 +1,35 @@
package scientifik.memory.foreign
import jdk.incubator.foreign.MemorySegment
import scientifik.memory.MemoryWriter
internal class ForeignWriter(override val memory: ForeignMemory) : MemoryWriter {
private val scope: MemorySegment
get() = memory.scope
override fun writeDouble(offset: Int, value: Double): Unit = with(scope) {
ForeignMemory.doubleHandle.set(baseAddress().addOffset(offset.toLong()), value)
}
override fun writeFloat(offset: Int, value: Float): Unit = with(scope) {
ForeignMemory.floatHandle.set(baseAddress().addOffset(offset.toLong()), value)
}
override fun writeByte(offset: Int, value: Byte): Unit = with(scope) {
ForeignMemory.byteHandle.set(baseAddress().addOffset(offset.toLong()), value)
}
override fun writeShort(offset: Int, value: Short): Unit = with(scope) {
ForeignMemory.shortHandle.set(baseAddress().addOffset(offset.toLong()), value)
}
override fun writeInt(offset: Int, value: Int): Unit = with(scope) {
ForeignMemory.intHandle.set(baseAddress().addOffset(offset.toLong()), value)
}
override fun writeLong(offset: Int, value: Long): Unit = with(scope) {
ForeignMemory.longHandle.set(baseAddress().addOffset(offset.toLong()), value)
}
override fun release(): Unit = memory.close()
}