Michael Paus
05/11/2025, 12:43 PM@kotlin.wasm.WasmImport("./libs/c_library.wasm", "count_vowels")
private external fun count_vowels(msg_ptr: UInt, msg_len: UInt): UInt
It is written in C and compiled via Emscripten and has been successfully tested with Chasm, Chicory and GraalVMWasm. It takes the pointer to a byte array (which represents a string) and its length as its parameters and returns the number of vowels found in this string.
I am trying to call it directly from Kotlin/wasmJs like this
@OptIn(UnsafeWasmMemoryApi::class)
private fun Pointer.storeBytes(bytes: ByteArray) {
if (bytes.size > 0) {
this.storeByte(bytes[0])
for (i in 1 until bytes.size) {
Pointer(this.address + i.toUInt()).storeByte(bytes[i])
}
}
}
@OptIn(UnsafeWasmMemoryApi::class)
fun countVowels(message: String): Int {
if (message.length > 0) {
withScopedMemoryAllocator { allocator ->
val msgBytes = message.encodeToByteArray()
val pointer = allocator.allocate(msgBytes.size)
val ptr = pointer.address
val len = msgBytes.size.toUInt()
pointer.storeBytes(msgBytes)
return count_vowels(ptr, len).toInt()
}
} else {
return 0
}
}
but the result is always 0. I verified the arguments on the C side and they were received correctly but the memory pointed to by (char*)msg_ptr
is just all zeros. It seems as if the data has never been written to the linear memory of the Wasm module.
Is there something wrong or did I completely misunderstand the allocator and pointer API?Michael Paus
05/11/2025, 2:10 PMephemient
05/11/2025, 3:18 PMMichael Paus
05/12/2025, 6:24 AMephemient
05/12/2025, 1:16 PMMichael Paus
05/12/2025, 3:37 PM