Unverified Commit f9444dab authored by Oleksandr Karpovich's avatar Oleksandr Karpovich Committed by GitHub

refactor `toInterop` to avoid unnecessary array copies in js when used withing `withResult` (#465)

Co-authored-by: 's avatarOleksandr Karpovich <oleksandr.karpovich@jetbrains.com>
parent e41633e8
......@@ -23,21 +23,36 @@ fun getPtr(n: Native?): NativePointer = n?._ptr ?: Native.NullPointer
expect class InteropScope() {
fun toInterop(string: String?): InteropPointer
fun toInterop(array: ByteArray?): InteropPointer
fun toInteropForResult(array: ByteArray?): InteropPointer
fun InteropPointer.fromInterop(result: ByteArray)
fun toInterop(array: ShortArray?): InteropPointer
fun toInteropForResult(array: ShortArray?): InteropPointer
fun InteropPointer.fromInterop(result: ShortArray)
fun toInterop(array: IntArray?): InteropPointer
fun toInteropForResult(array: IntArray?): InteropPointer
fun InteropPointer.fromInterop(result: IntArray)
fun toInterop(array: LongArray?): InteropPointer
fun InteropPointer.fromInterop(result: LongArray)
fun toInterop(array: FloatArray?): InteropPointer
fun toInteropForResult(array: FloatArray?): InteropPointer
fun InteropPointer.fromInterop(result: FloatArray)
fun toInterop(array: DoubleArray?): InteropPointer
fun toInteropForResult(array: DoubleArray?): InteropPointer
fun InteropPointer.fromInterop(result: DoubleArray)
fun toInterop(array: NativePointerArray?): InteropPointer
fun toInteropForResult(array: NativePointerArray?): InteropPointer
fun InteropPointer.fromInterop(result: NativePointerArray)
fun toInterop(stringArray: Array<String>?): InteropPointer
fun InteropPointer.fromInteropNativePointerArray(): NativePointerArray
inline fun <reified T> InteropPointer.fromInterop(decoder: ArrayInteropDecoder<T>): Array<T>
fun toInteropForArraysOfPointers(interopPointers: Array<InteropPointer>): InteropPointer
......@@ -62,14 +77,14 @@ expect class InteropScope() {
expect inline fun <T> interopScope(block: InteropScope.() -> T): T
inline fun withResult(result: ByteArray, block: InteropScope.(InteropPointer) -> Unit): ByteArray = interopScope {
val handle = toInterop(result)
val handle = toInteropForResult(result)
block(handle)
handle.fromInterop(result)
result
}
inline fun withNullableResult(result: ByteArray, block: InteropScope.(InteropPointer) -> Boolean): ByteArray? = interopScope {
val handle = toInterop(result)
val handle = toInteropForResult(result)
return if (block(handle)) {
handle.fromInterop(result)
result
......@@ -79,14 +94,14 @@ inline fun withNullableResult(result: ByteArray, block: InteropScope.(InteropPoi
}
inline fun withResult(result: FloatArray, block: InteropScope.(InteropPointer) -> Unit): FloatArray = interopScope {
val handle = toInterop(result)
val handle = toInteropForResult(result)
block(handle)
handle.fromInterop(result)
result
}
inline fun withNullableResult(result: FloatArray, block: InteropScope.(InteropPointer) -> Boolean): FloatArray? = interopScope {
val handle = toInterop(result)
val handle = toInteropForResult(result)
val blockResult = block(handle)
if (blockResult) {
handle.fromInterop(result)
......@@ -97,14 +112,14 @@ inline fun withNullableResult(result: FloatArray, block: InteropScope.(InteropPo
}
inline fun withResult(result: IntArray, block: InteropScope.(InteropPointer) -> Unit): IntArray = interopScope {
val handle = toInterop(result)
val handle = toInteropForResult(result)
block(handle)
handle.fromInterop(result)
result
}
inline fun withNullableResult(result: IntArray, block: InteropScope.(InteropPointer) -> Boolean): IntArray? = interopScope {
val handle = toInterop(result)
val handle = toInteropForResult(result)
return if (block(handle)) {
handle.fromInterop(result)
result
......@@ -114,21 +129,21 @@ inline fun withNullableResult(result: IntArray, block: InteropScope.(InteropPoin
}
inline fun withResult(result: ShortArray, block: InteropScope.(InteropPointer) -> Unit): ShortArray = interopScope {
val handle = toInterop(result)
val handle = toInteropForResult(result)
block(handle)
handle.fromInterop(result)
result
}
inline fun withResult(result: DoubleArray, block: InteropScope.(InteropPointer) -> Unit): DoubleArray = interopScope {
val handle = toInterop(result)
val handle = toInteropForResult(result)
block(handle)
handle.fromInterop(result)
result
}
inline fun withResult(result: NativePointerArray, block: InteropScope.(InteropPointer) -> Unit): NativePointerArray = interopScope {
val handle = toInterop(result)
val handle = toInteropForResult(result)
block(handle)
handle.fromInterop(result)
result
......
......@@ -64,46 +64,65 @@ actual class InteropScope actual constructor() {
}
}
actual fun toInterop(array: ByteArray?): InteropPointer {
private fun toInterop(array: ByteArray?, copyArrayToWasm: Boolean): InteropPointer {
return if (array != null && array.isNotEmpty()) {
val data = _malloc(array.size)
elements.add(data)
toWasm(data, array)
if (copyArrayToWasm) toWasm(data, array)
data
} else {
0
}
}
actual fun toInterop(array: ByteArray?): InteropPointer =
toInterop(array = array, copyArrayToWasm = true)
actual fun toInteropForResult(array: ByteArray?): InteropPointer =
toInterop(array = array, copyArrayToWasm = false)
actual fun InteropPointer.fromInterop(result: ShortArray) {
fromWasm(this@fromInterop, result)
}
actual fun toInterop(array: ShortArray?): InteropPointer {
private fun toInterop(array: ShortArray?, copyArrayToWasm: Boolean): InteropPointer {
return if (array != null && array.isNotEmpty()) {
val data = _malloc(array.size * 2)
elements.add(data)
toWasm(data, array)
if (copyArrayToWasm) toWasm(data, array)
data
} else {
0
}
}
actual fun toInterop(array: ShortArray?): InteropPointer =
toInterop(array = array, copyArrayToWasm = true)
actual fun toInteropForResult(array: ShortArray?): InteropPointer =
toInterop(array = array, copyArrayToWasm = false)
actual fun InteropPointer.fromInterop(result: IntArray) {
fromWasm(this@fromInterop, result)
}
actual fun toInterop(array: IntArray?): InteropPointer {
private fun toInterop(array: IntArray?, copyArrayToWasm: Boolean): InteropPointer {
return if (array != null && array.isNotEmpty()) {
val data = _malloc(array.size * 4)
elements.add(data)
toWasm(data, array)
if (copyArrayToWasm) toWasm(data, array)
data
} else {
0
}
}
actual fun toInterop(array: IntArray?): InteropPointer =
toInterop(array = array, copyArrayToWasm = true)
actual fun toInteropForResult(array: IntArray?): InteropPointer =
toInterop(array = array, copyArrayToWasm = false)
actual fun InteropPointer.fromInterop(result: LongArray) {
TODO("implement wasm fromInterop(LongArray)")
}
......@@ -116,47 +135,65 @@ actual class InteropScope actual constructor() {
fromWasm(this@fromInterop, result)
}
actual fun toInterop(array: FloatArray?): InteropPointer {
private fun toInterop(array: FloatArray?, copyArrayToWasm: Boolean): InteropPointer {
return if (array != null && array.isNotEmpty()) {
val data = _malloc(array.size * 4)
elements.add(data)
toWasm(data, array)
if (copyArrayToWasm) toWasm(data, array)
data
} else {
0
}
}
actual fun toInterop(array: FloatArray?): InteropPointer =
toInterop(array = array, copyArrayToWasm = true)
actual fun toInteropForResult(array: FloatArray?): InteropPointer =
toInterop(array = array, copyArrayToWasm = false)
actual fun InteropPointer.fromInterop(result: DoubleArray) {
fromWasm(this@fromInterop, result)
}
actual fun toInterop(array: DoubleArray?): InteropPointer {
private fun toInterop(array: DoubleArray?, copyArrayToWasm: Boolean): InteropPointer {
return if (array != null && array.isNotEmpty()) {
val data = _malloc(array.size * 8)
elements.add(data)
toWasm(data, array)
if (copyArrayToWasm) toWasm(data, array)
data
} else {
0
}
}
actual fun toInterop(array: DoubleArray?): InteropPointer =
toInterop(array = array, copyArrayToWasm = true)
actual fun toInteropForResult(array: DoubleArray?): InteropPointer =
toInterop(array = array, copyArrayToWasm = false)
actual fun InteropPointer.fromInterop(result: ByteArray) {
fromWasm(this@fromInterop, result)
}
actual fun toInterop(array: NativePointerArray?): InteropPointer {
private fun toInterop(array: NativePointerArray?, copyArrayToWasm: Boolean): InteropPointer {
return if (array != null && array.size > 0) {
val data = _malloc(array.size * 4)
elements.add(data)
toWasm(data, array.backing)
if (copyArrayToWasm) toWasm(data, array.backing)
data
} else {
0
}
}
actual fun toInterop(array: NativePointerArray?): InteropPointer =
toInterop(array = array, copyArrayToWasm = true)
actual fun toInteropForResult(array: NativePointerArray?): InteropPointer =
toInterop(array = array, copyArrayToWasm = false)
actual fun InteropPointer.fromInterop(result: NativePointerArray) {
return fromWasm(this@fromInterop, result.backing)
}
......
......@@ -57,20 +57,34 @@ actual inline fun <T> interopScope(block: InteropScope.() -> T): T {
actual open class InteropScope actual constructor() {
actual fun toInterop(string: String?): InteropPointer = string
actual fun toInterop(array: ByteArray?): InteropPointer = array
actual fun toInteropForResult(array: ByteArray?): InteropPointer = toInterop(array)
actual fun InteropPointer.fromInterop(result: ByteArray) {}
actual fun toInterop(array: ShortArray?): InteropPointer = array
actual fun toInteropForResult(array: ShortArray?): InteropPointer = toInterop(array)
actual fun InteropPointer.fromInterop(result: ShortArray) {}
actual fun toInterop(array: IntArray?): InteropPointer = array
actual fun toInteropForResult(array: IntArray?): InteropPointer = toInterop(array)
actual fun InteropPointer.fromInterop(result: IntArray) {}
actual fun toInterop(array: LongArray?): InteropPointer = array
actual fun InteropPointer.fromInterop(result: LongArray) {}
actual fun toInterop(array: FloatArray?): InteropPointer = array
actual fun toInteropForResult(array: FloatArray?): InteropPointer = toInterop(array)
actual fun InteropPointer.fromInterop(result: FloatArray) {}
actual fun toInterop(array: DoubleArray?): InteropPointer = array
actual fun toInteropForResult(array: DoubleArray?): InteropPointer = toInterop(array)
actual fun InteropPointer.fromInterop(result: DoubleArray) {}
actual fun toInterop(array: NativePointerArray?): InteropPointer = array?.backing
actual fun toInteropForResult(array: NativePointerArray?): InteropPointer = toInterop(array)
actual fun InteropPointer.fromInterop(result: NativePointerArray) {}
actual fun toInterop(stringArray: Array<String>?): InteropPointer = stringArray
actual fun InteropPointer.fromInteropNativePointerArray(): NativePointerArray =
NativePointerArray((this as LongArray).size, this)
......
......@@ -89,6 +89,8 @@ actual class InteropScope actual constructor() {
}
}
actual fun toInteropForResult(array: ByteArray?): InteropPointer = toInterop(array)
actual fun InteropPointer.fromInterop(result: ByteArray) {}
actual fun toInterop(array: ShortArray?): InteropPointer {
......@@ -102,6 +104,8 @@ actual class InteropScope actual constructor() {
}
}
actual fun toInteropForResult(array: ShortArray?): InteropPointer = toInterop(array)
actual fun InteropPointer.fromInterop(result: ShortArray) {}
actual fun toInterop(array: IntArray?): InteropPointer {
......@@ -115,6 +119,8 @@ actual class InteropScope actual constructor() {
}
}
actual fun toInteropForResult(array: IntArray?): InteropPointer = toInterop(array)
actual fun InteropPointer.fromInterop(result: IntArray) {}
actual fun toInterop(array: LongArray?): InteropPointer {
......@@ -141,6 +147,8 @@ actual class InteropScope actual constructor() {
}
}
actual fun toInteropForResult(array: FloatArray?): InteropPointer = toInterop(array)
actual fun InteropPointer.fromInterop(result: FloatArray) {}
actual fun toInterop(array: DoubleArray?): InteropPointer {
......@@ -154,6 +162,8 @@ actual class InteropScope actual constructor() {
}
}
actual fun toInteropForResult(array: DoubleArray?): InteropPointer = toInterop(array)
actual fun InteropPointer.fromInterop(result: DoubleArray) {}
actual fun toInterop(array: NativePointerArray?): InteropPointer {
......@@ -168,6 +178,8 @@ actual class InteropScope actual constructor() {
}
}
actual fun toInteropForResult(array: NativePointerArray?): InteropPointer = toInterop(array)
actual fun InteropPointer.fromInterop(result: NativePointerArray) {}
actual fun toInterop(stringArray: Array<String>?): InteropPointer {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment