From ebde1e5491044949f16e315b4bff26c09c30e0a5 Mon Sep 17 00:00:00 2001 From: Igor Laevsky Date: Fri, 23 Jul 2021 20:42:48 +0300 Subject: [PATCH] WASM: Crude println implementation with the wasm-native strings --- .../jetbrains/kotlin/backend/wasm/compiler.kt | 24 ++++++++++--------- .../kotlin/js/test/BasicWasmBoxTest.kt | 4 ++-- libraries/stdlib/wasm/src/kotlin/io.kt | 4 ++-- 3 files changed, 17 insertions(+), 15 deletions(-) diff --git a/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/compiler.kt b/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/compiler.kt index 468bd78d35c..11a9bd2e092 100644 --- a/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/compiler.kt +++ b/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/compiler.kt @@ -95,6 +95,8 @@ fun compileWasm( fun WasmCompiledModuleFragment.generateJs(): String { val runtime = """ + var wasmInstance = null; + const runtime = { String_getChar(str, index) { return str.charCodeAt(index); @@ -130,19 +132,19 @@ fun WasmCompiledModuleFragment.generateJs(): String { return x; }, - println(value) { - console.log(">>> " + value) - }, - - importStringToJs(addr, wasmMem) { - const mem16 = new Uint16Array(wasmMem.buffer); - const mem32 = new Int32Array(wasmMem.buffer); - const len = mem32[addr / 4]; - const str_start_addr = (addr + 4) / 2 - const slice = mem16.slice(str_start_addr, str_start_addr + len); - return String.fromCharCode.apply(null, slice); + println(valueAddr) { + console.log(">>> " + importStringToJs(valueAddr)); } }; + + function importStringToJs(addr) { + const mem16 = new Uint16Array(wasmInstance.exports.memory.buffer); + const mem32 = new Int32Array(wasmInstance.exports.memory.buffer); + const len = mem32[addr / 4]; + const str_start_addr = (addr + 4) / 2; + const slice = mem16.slice(str_start_addr, str_start_addr + len); + return String.fromCharCode.apply(null, slice); + } """.trimIndent() val jsCode = diff --git a/js/js.tests/test/org/jetbrains/kotlin/js/test/BasicWasmBoxTest.kt b/js/js.tests/test/org/jetbrains/kotlin/js/test/BasicWasmBoxTest.kt index 1c66e8a0e3f..62f5dc3db93 100644 --- a/js/js.tests/test/org/jetbrains/kotlin/js/test/BasicWasmBoxTest.kt +++ b/js/js.tests/test/org/jetbrains/kotlin/js/test/BasicWasmBoxTest.kt @@ -149,9 +149,9 @@ abstract class BasicWasmBoxTest( val testRunner = """ const wasmBinary = read(String.raw`${outputWasmFile.absoluteFile}`, 'binary'); const wasmModule = new WebAssembly.Module(wasmBinary); - const wasmInstance = new WebAssembly.Instance(wasmModule, { runtime, js_code }); + wasmInstance = new WebAssembly.Instance(wasmModule, { runtime, js_code }); - const actualResult = runtime.importStringToJs(wasmInstance.exports.$testFunction(), wasmInstance.exports.memory); + const actualResult = importStringToJs(wasmInstance.exports.$testFunction()); if (actualResult !== "OK") throw `Wrong box result '${'$'}{actualResult}'; Expected "OK"`; """.trimIndent() diff --git a/libraries/stdlib/wasm/src/kotlin/io.kt b/libraries/stdlib/wasm/src/kotlin/io.kt index 0d27e864646..502756988ee 100644 --- a/libraries/stdlib/wasm/src/kotlin/io.kt +++ b/libraries/stdlib/wasm/src/kotlin/io.kt @@ -14,7 +14,7 @@ public actual fun println() { /** Prints the given [message] and the line separator to the standard output stream. */ public actual fun println(message: Any?) { - printlnImpl(message.toString()) + printlnImpl(exportStringRet(message.toString())) } /** Prints the given [message] to the standard output stream. */ @@ -27,5 +27,5 @@ public actual fun print(message: Any?) { internal actual interface Serializable @WasmImport("runtime", "println") -private fun printlnImpl(message: String): Unit = +private fun printlnImpl(messageAddr: Int): Unit = implementedAsIntrinsic