Hi, is there a recommended way to return / accept ...
# webassembly
y
Hi, is there a recommended way to return / accept a String in a WasmExport? I would like to call a wasm function from javascript with some complex input. I can work around it by sending individual bytes back and forth but I would like to avoid that if possible
I built this workaround:
Copy code
@WasmExport
fun wasmBestEvAndMove(writer: Int): Int {
    val request = writers.remove(writer)!!.decodeToString()
    println("wasmCalculateEv($request)")
    val response = Json.encodeToString(EvProvider.Local.bestEvAndMove(Json.decodeFromString(request)))
    println("wasmCalculateEv($request) -> $response")
    return allocate(readers, response.encodeToByteArray())
}

private val writers = mutableMapOf<Int, ByteArray>()
private val readers = mutableMapOf<Int, ByteArray>()

private fun allocate(map: MutableMap<Int, ByteArray>, initialValue: ByteArray): Int {
    while (true) {
        val i = Random.nextInt()
        if (map.containsKey(i)) {
            continue
        }
        map[i] = initialValue
        return i
    }
}

@WasmExport
fun wasmCreateWriter(): Int {
    return allocate(writers, ByteArray(0))
}

@WasmExport
fun wasmWrite(writer: Int, b: Byte) {
    writers[writer] = writers[writer]!! + b
}

@WasmExport
fun wasmRead(reader: Int): Int {
    val arr = readers[reader]!!
    if (arr.isEmpty()) {
        readers.remove(reader)
        return -1
    } else {
        readers[reader] = arr.copyOfRange(1, arr.size)
        return arr[0].toInt() and 0xff
    }
}
ugly but it works, it doesnt need to be fast.
a
Usually you would do that through the linear memory. You would have to serialize your complex input somehow and write it to the linear memory then pass the pointer (and data length) to the Wasm module which would have to read it from the linear memory. With Kotlin there is one complication that you can't implement an exported function like
malloc
to allocate memory and store host data upfront. You can only allocate memory using withScopedMemoryAllocator which only allows allocations within a function call scope so you would have to work around that.
👍 1
y
seems like i would be writing a very similar thing as the above, just with linear memory instead of ByteArrays
m
what is the difference between
@JsExport
and
@WasmExport
? Both can be called from javascript right?
y
well one is for a wasm project and one for a js project
m
I mean I'll still be able to call the @WasmExport function from the JS right?
👌 1