Kotlin passing string to WebAssembly

Submitted by Dickens A S on Thu, 04/30/2020 - 14:09

From JavaScript as of now we cannot pass string to WebAssembly, therefore the string will be converted to an array of bytes and kept in browser's memory object of the kotlin web assembly framework object kotlinObject

From WebAssembly by calling the JavaScript method for each character, transfer the numeric value

Then convert the numeric value to character and combine to a string in kotlin

This is achieved using below code

JavaScript: string to UTF array utlity

function toUint8Array(value) {
   var buffer = new Uint8Array(value.length);
   for(var i=0;i<value.length;i++)
     buffer[i] = value.charCodeAt(i)
   return buffer;
}

JavaScript: Retrieve single char from arena object of the kotlin web assembly framework

getChar: function (arena, obj, index) {
   var arena = konan_dependencies.env.arenas.get(arena);
   var value = arena[obj][index];
   return value;
}

Kotlin: call the getChar from WebAssembly

fun getString(): String {
   val length = this.getInt("length")
   var result = ""
   for (i in 0 until length) {
       result += getChar(arena, index, i).toChar()
   }
   return result;
}

Here getInt is also a JavaScript callback which is in-built

Konan_js_getInt: function(arenaIndex, objIndex, propertyNamePtr, propertyNameLength) {
     // TODO:  The toUTF16String() is to be resolved by launcher.js runtime.
     var property = toUTF16String(propertyNamePtr, propertyNameLength); 
     var value =  kotlinObject(arenaIndex, objIndex)[property];
     return value;
}

Kotlin main code for the output

package wasm

import kotlinx.interop.wasm.dom.*
import kotlinx.wasm.jsinterop.*
import kotlinx.cinterop.*
import kotlin.text.*
import mymod.*

fun main() {
    mod.wasmReady()
    document.setter("onmouseup") { arguments: ArrayList<JsValue> ->
        val event = ButtonMouseEvent(arguments[0])
        if(event.target.id == "clickme") {
            println("Button clickme is pressed")
            var t1 = document.getElementById("t1").asDOM.value
            var t2 = document.getElementById("t2").asDOM.value
            var sb = StringBuilder(t1 + " " + t2)
            
            document.getElementById("mydiv").asDOM.innerHTML = "Reverse: " + sb.reverse()
        }
    }
    
}

Sample Output

Sample output

In the above two text box I intentionally provided "doog" in the first box "si ananab" in the second box

from web assembly Kotlin code StringBuilder and reverse is used to form the combined reverse of both string and transferred to UI using innerHTML JS callback

GitHub: https://github.com/dickensas/kotlin-gradle-templates/tree/master/sboot-wasm-string

 

 

Add new comment