From 80140207b52acb0103dcdb02bc71c094cdc9725b Mon Sep 17 00:00:00 2001 From: Igor Laevsky Date: Fri, 30 Jul 2021 18:08:57 +0300 Subject: [PATCH] WASM: Properly handle nullable exported strings --- .../jetbrains/kotlin/backend/wasm/ir2wasm/BodyGenerator.kt | 2 +- .../backend/wasm/ir2wasm/WasmModuleCodegenContextImpl.kt | 3 ++- .../wasm/internal/kotlin/wasm/internal/ImportExport.kt | 5 ++++- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/ir2wasm/BodyGenerator.kt b/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/ir2wasm/BodyGenerator.kt index 7cfb48a1cec..d4ff3e47be0 100644 --- a/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/ir2wasm/BodyGenerator.kt +++ b/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/ir2wasm/BodyGenerator.kt @@ -369,7 +369,7 @@ class BodyGenerator(val context: WasmFunctionCodegenContext) : IrElementVisitorV // Handle complex exported parameters. // TODO: This should live as a separate lowering which creates separate shims for each exported function. if (context.irFunction.isExported(context.backendContext) && - expression.value.type == irBuiltIns.stringType) { + expression.value.type.getClass() == irBuiltIns.stringType.getClass()) { body.buildCall(context.referenceFunction(wasmSymbols.exportString)) } diff --git a/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/ir2wasm/WasmModuleCodegenContextImpl.kt b/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/ir2wasm/WasmModuleCodegenContextImpl.kt index 71be3f66bb1..2f8fa17057b 100644 --- a/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/ir2wasm/WasmModuleCodegenContextImpl.kt +++ b/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/ir2wasm/WasmModuleCodegenContextImpl.kt @@ -16,6 +16,7 @@ import org.jetbrains.kotlin.ir.symbols.IrFunctionSymbol import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol import org.jetbrains.kotlin.ir.types.IrType import org.jetbrains.kotlin.ir.types.defaultType +import org.jetbrains.kotlin.ir.types.getClass import org.jetbrains.kotlin.ir.types.isNothing import org.jetbrains.kotlin.ir.util.isFunction import org.jetbrains.kotlin.ir.util.parentAsClass @@ -59,7 +60,7 @@ class WasmModuleCodegenContextImpl( override fun transformExportedResultType(irType: IrType): WasmType? { // Exported strings are passed as pointers to the raw memory - if (irType == backendContext.irBuiltIns.stringType) + if (irType.getClass() == backendContext.irBuiltIns.stringType.getClass()) return WasmI32 return with(typeTransformer) { irType.toWasmResultType() } } diff --git a/libraries/stdlib/wasm/internal/kotlin/wasm/internal/ImportExport.kt b/libraries/stdlib/wasm/internal/kotlin/wasm/internal/ImportExport.kt index c34bf072e01..944865aa11c 100644 --- a/libraries/stdlib/wasm/internal/kotlin/wasm/internal/ImportExport.kt +++ b/libraries/stdlib/wasm/internal/kotlin/wasm/internal/ImportExport.kt @@ -8,7 +8,10 @@ package kotlin.wasm.internal // This is called when exported function returns a string. It writes [i32 length, [i16 chars ...]] into a temporary raw memory area and // returns pointer to the start of it. // Note: currently there is a single temporary raw memory area so it's not possible to export more than one string at a time. -internal fun exportString(src: String): Int { +internal fun exportString(src: String?): Int { + if (src == null) + throw IllegalArgumentException("Exporting null string") + val retAddr = unsafeGetScratchRawMemory(INT_SIZE_BYTES + src.length * CHAR_SIZE_BYTES) wasm_i32_store(retAddr, src.length) unsafeCharArrayToRawMemory(src.toCharArray(), retAddr + INT_SIZE_BYTES)