WASM: Cover frontend issue where unit-type is casted to the non-unit type

This commit is contained in:
Igor Laevsky
2021-09-03 18:44:45 +03:00
committed by TeamCityServer
parent 4299915326
commit ef2970a888
2 changed files with 19 additions and 2 deletions
@@ -5,6 +5,7 @@
package org.jetbrains.kotlin.backend.wasm.lower
import org.jetbrains.kotlin.backend.common.CommonBackendContext
import org.jetbrains.kotlin.backend.common.FileLoweringPass
import org.jetbrains.kotlin.backend.common.IrElementTransformerVoidWithContext
import org.jetbrains.kotlin.backend.common.lower.*
@@ -66,7 +67,7 @@ import org.jetbrains.kotlin.name.Name
// tmp // result
internal class TryCatchCanonicalization(private val ctx: WasmBackendContext) : FileLoweringPass {
internal class TryCatchCanonicalization(private val ctx: CommonBackendContext) : FileLoweringPass {
override fun lower(irFile: IrFile) {
irFile.transformChildrenVoid(CatchMerger(ctx))
@@ -84,7 +85,7 @@ internal class TryCatchCanonicalization(private val ctx: WasmBackendContext) : F
}
}
internal class CatchMerger(private val ctx: WasmBackendContext) : IrElementTransformerVoidWithContext() {
internal class CatchMerger(private val ctx: CommonBackendContext) : IrElementTransformerVoidWithContext() {
override fun visitTry(aTry: IrTry): IrExpression {
// First, handle all nested constructs
aTry.transformChildrenVoid(this)
@@ -168,6 +168,22 @@ class WasmBaseTypeOperatorTransformer(val context: WasmBackendContext) : IrEleme
}
}
// Workaround for the bug in frontend.
// In code like this:
// val p: Int = try {
// 1
// } catch (e: Exception) {
// throw RuntimeException()
// }
// Frontend will emit IMPLICIT_CAST from Unit into Int. Such code can't be correctly compiled to wasm as it is.
// This supposed to only happen in the unreachable code so we emit unreachable intrinsic.
if (fromType == builtIns.unitType && toType !in listOf(builtIns.unitType, builtIns.anyType, builtIns.anyNType)) {
return builder.irComposite(resultType = toType) {
+value
+builder.irCall(symbols.wasmUnreachable)
}
}
// Handled by autoboxing transformer
if (toType.isInlined() && !fromType.isInlined()) {
return builder.irCall(