From dbfd20ec4e337e0368b993f1b3d9261cde2271cc Mon Sep 17 00:00:00 2001 From: Igor Yakovlev Date: Sat, 10 Sep 2022 16:16:39 +0200 Subject: [PATCH] [WASM] Add null-checks for external functions with String return type --- .../wasm/lower/JsInteropFunctionsLowering.kt | 27 ++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-) diff --git a/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/lower/JsInteropFunctionsLowering.kt b/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/lower/JsInteropFunctionsLowering.kt index 239868facb0..f67f97b78ed 100644 --- a/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/lower/JsInteropFunctionsLowering.kt +++ b/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/lower/JsInteropFunctionsLowering.kt @@ -259,7 +259,8 @@ class JsInteropFunctionsLowering(val context: WasmBackendContext) : DeclarationT return null when (this) { - builtIns.stringType -> return FunctionBasedAdapter(adapters.jsToKotlinStringAdapter.owner) + builtIns.stringType -> return CheckNotNullAndAdapter(FunctionBasedAdapter(adapters.jsToKotlinStringAdapter.owner)) + builtIns.stringType.makeNullable() -> return NullOrAdapter(FunctionBasedAdapter(adapters.jsToKotlinStringAdapter.owner)) builtIns.anyType -> return FunctionBasedAdapter(adapters.jsToKotlinAnyAdapter.owner) builtIns.byteType -> return FunctionBasedAdapter(adapters.jsToKotlinByteAdapter.owner) builtIns.shortType -> return FunctionBasedAdapter(adapters.jsToKotlinShortAdapter.owner) @@ -597,8 +598,28 @@ class JsInteropFunctionsLowering(val context: WasmBackendContext) : DeclarationT override val toType: IrType = adapter.toType.makeNullable() override fun adapt(expression: IrExpression, builder: IrBuilderWithScope): IrExpression { return builder.irComposite { - val tmp = irTemporary(adapter.adapt(expression, builder)) - +irIfNull(toType, irGet(tmp), irNull(toType), irImplicitCast(irGet(tmp), toType)) + val tmp = irTemporary(expression) + +irIfNull(toType, irGet(tmp), irNull(toType), irImplicitCast(adapter.adapt(irGet(tmp), builder), toType)) + } + } + } + + /** + * Effectively `adapter(value!!)` + */ + inner class CheckNotNullAndAdapter( + val adapter: InteropTypeAdapter + ) : InteropTypeAdapter { + override val fromType: IrType = adapter.fromType.makeNullable() + override val toType: IrType = adapter.toType.makeNotNull() + override fun adapt(expression: IrExpression, builder: IrBuilderWithScope): IrExpression { + return builder.irComposite { + val tmp = irTemporary(expression) + +irCall(context.irBuiltIns.checkNotNullSymbol).also { + it.putValueArgument(0, irGet(tmp)) + it.putTypeArgument(0, fromType) + } + +adapter.adapt(irGet(tmp), builder) } } }