From 6ca965af6fc82b02e22e9b656de798c297b7fa67 Mon Sep 17 00:00:00 2001 From: Igor Laevsky Date: Wed, 18 Aug 2021 14:57:14 +0300 Subject: [PATCH] WASM: Generate throw instruction instead of wasmThrow call --- .../kotlin/backend/wasm/WasmLoweringPhases.kt | 7 ---- .../kotlin/backend/wasm/WasmSymbols.kt | 2 - .../backend/wasm/ir2wasm/BodyGenerator.kt | 6 +++ .../ir2wasm/WasmCompiledModuleFragment.kt | 7 +++- .../ir2wasm/WasmFunctionCodegenContext.kt | 3 ++ .../ir2wasm/WasmFunctionCodegenContextImpl.kt | 3 ++ .../wasm/lower/WasmThrowDebugLowering.kt | 37 ------------------- .../kotlin/js/test/BasicWasmBoxTest.kt | 1 + .../internal/kotlin/wasm/internal/Runtime.kt | 5 --- .../kotlin/wasm/ir/WasmExpressionBuilder.kt | 8 ++++ 10 files changed, 26 insertions(+), 53 deletions(-) delete mode 100644 compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/lower/WasmThrowDebugLowering.kt diff --git a/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/WasmLoweringPhases.kt b/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/WasmLoweringPhases.kt index a06f535c4d3..7b0d9f3c914 100644 --- a/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/WasmLoweringPhases.kt +++ b/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/WasmLoweringPhases.kt @@ -340,12 +340,6 @@ private val wasmVarargExpressionLoweringPhase = makeWasmModulePhase( description = "Lower varargs" ) -private val wasmThrowDebugLoweringPhase = makeWasmModulePhase( - ::WasmThrowDebugLowering, - name = "WasmThrowDebugLowering", - description = "Instrument throws with debug print information" -) - private val fieldInitializersLoweringPhase = makeWasmModulePhase( ::FieldInitializersLowering, name = "FieldInitializersLowering", @@ -503,7 +497,6 @@ val wasmPhases = NamedCompilerPhase( builtInsLoweringPhase then virtualDispatchReceiverExtractionPhase then - wasmThrowDebugLoweringPhase then staticMembersLoweringPhase then wasmNullSpecializationLowering then validateIrAfterLowering diff --git a/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/WasmSymbols.kt b/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/WasmSymbols.kt index af92419ae06..ac03bbd3b7e 100644 --- a/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/WasmSymbols.kt +++ b/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/WasmSymbols.kt @@ -138,8 +138,6 @@ class WasmSymbols( val nullableFloatIeee754Equals = getInternalFunction("nullableFloatIeee754Equals") val nullableDoubleIeee754Equals = getInternalFunction("nullableDoubleIeee754Equals") - val wasmThrow = getInternalFunction("wasmThrow") - val exportString = getInternalFunction("exportString") val unsafeGetScratchRawMemory = getInternalFunction("unsafeGetScratchRawMemory") 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 32e2db22c9d..b61cade09a7 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 @@ -23,6 +23,7 @@ import org.jetbrains.kotlin.ir.types.* import org.jetbrains.kotlin.ir.util.* import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid import org.jetbrains.kotlin.ir.visitors.acceptVoid +import org.jetbrains.kotlin.psi2ir.intermediate.generateExpressionValue import org.jetbrains.kotlin.wasm.ir.* class BodyGenerator(val context: WasmFunctionCodegenContext) : IrElementVisitorVoid { @@ -61,6 +62,11 @@ class BodyGenerator(val context: WasmFunctionCodegenContext) : IrElementVisitorV error("Unexpected element of type ${element::class}") } + override fun visitThrow(expression: IrThrow) { + generateExpression(expression.value) + body.buildThrow(context.tagIdx) + } + override fun visitTypeOperator(expression: IrTypeOperatorCall) { when (expression.operator) { IrTypeOperator.REINTERPRET_CAST -> generateExpression(expression.argument) diff --git a/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/ir2wasm/WasmCompiledModuleFragment.kt b/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/ir2wasm/WasmCompiledModuleFragment.kt index 1400b4c1108..19023fbb92f 100644 --- a/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/ir2wasm/WasmCompiledModuleFragment.kt +++ b/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/ir2wasm/WasmCompiledModuleFragment.kt @@ -33,6 +33,8 @@ class WasmCompiledModuleFragment { ReferencableElements() val stringLiteralId = ReferencableElements() + val tagFuncType = WasmFunctionType("ex_handling_tag", listOf(WasmAnyRef), emptyList()) + val tag = WasmTag(tagFuncType) val runtimeTypes = ReferencableAndDefinable() @@ -250,7 +252,7 @@ class WasmCompiledModuleFragment { val sortedRttGlobals = runtimeTypes.elements.sortedBy { (it.type as WasmRtt).depth } val module = WasmModule( - functionTypes = functionTypes.elements, + functionTypes = functionTypes.elements + tagFuncType, gcTypes = gcTypes.elements, importsInOrder = importedFunctions, importedFunctions = importedFunctions, @@ -261,7 +263,8 @@ class WasmCompiledModuleFragment { exports = exports, startFunction = startFunction!!, elements = listOf(elements) + interfaceTableElements, - data = data + data = data, + tags = listOf(tag) ) module.calculateIds() return module diff --git a/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/ir2wasm/WasmFunctionCodegenContext.kt b/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/ir2wasm/WasmFunctionCodegenContext.kt index 86a4023f250..8e0f5b56594 100644 --- a/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/ir2wasm/WasmFunctionCodegenContext.kt +++ b/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/ir2wasm/WasmFunctionCodegenContext.kt @@ -24,5 +24,8 @@ interface WasmFunctionCodegenContext : WasmBaseCodegenContext { fun defineLoopLevel(irLoop: IrLoop, labelType: LoopLabelType, level: Int) fun referenceLoopLevel(irLoop: IrLoop, labelType: LoopLabelType): Int + // So far always a single tag + val tagIdx: Int + val bodyGen: WasmExpressionBuilder } \ No newline at end of file diff --git a/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/ir2wasm/WasmFunctionCodegenContextImpl.kt b/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/ir2wasm/WasmFunctionCodegenContextImpl.kt index fad8a5ef160..53e52207815 100644 --- a/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/ir2wasm/WasmFunctionCodegenContextImpl.kt +++ b/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/ir2wasm/WasmFunctionCodegenContextImpl.kt @@ -23,6 +23,9 @@ class WasmFunctionCodegenContextImpl( override val bodyGen: WasmExpressionBuilder = WasmIrExpressionBuilder(wasmFunction.instructions) + override val tagIdx: Int + get() = 0 + private val wasmLocals = LinkedHashMap() private val loopLevels = LinkedHashMap, Int>() diff --git a/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/lower/WasmThrowDebugLowering.kt b/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/lower/WasmThrowDebugLowering.kt deleted file mode 100644 index 45b21868330..00000000000 --- a/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/lower/WasmThrowDebugLowering.kt +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors. - * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. - */ - -package org.jetbrains.kotlin.backend.wasm.lower - -import org.jetbrains.kotlin.backend.common.FileLoweringPass -import org.jetbrains.kotlin.backend.common.IrElementTransformerVoidWithContext -import org.jetbrains.kotlin.backend.common.lower.createIrBuilder -import org.jetbrains.kotlin.backend.wasm.WasmBackendContext -import org.jetbrains.kotlin.ir.builders.irCall -import org.jetbrains.kotlin.ir.declarations.IrFile -import org.jetbrains.kotlin.ir.expressions.IrExpression -import org.jetbrains.kotlin.ir.expressions.IrThrow -import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid - -/** - * Replace throw expressions with a runtime function call. - * TODO: Remove when full-blown exception handling is implemented - */ -internal class WasmThrowDebugLowering( - private val context: WasmBackendContext -) : FileLoweringPass, IrElementTransformerVoidWithContext() { - override fun lower(irFile: IrFile) { - irFile.transformChildrenVoid(this) - } - - override fun visitThrow(expression: IrThrow): IrExpression { - expression.transformChildrenVoid(this) - val builder = context.createIrBuilder(currentScope!!.scope.scopeOwnerSymbol) - - return builder.irCall(context.wasmSymbols.wasmThrow).apply { - this.putValueArgument(0, expression.value) - } - } -} \ No newline at end of file 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 e28ef6ff214..2fb278870df 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 @@ -86,6 +86,7 @@ abstract class BasicWasmBoxTest( .run( "--experimental-wasm-typed-funcref", "--experimental-wasm-gc", + "--experimental-wasm-eh", outputJsFile ) } diff --git a/libraries/stdlib/wasm/internal/kotlin/wasm/internal/Runtime.kt b/libraries/stdlib/wasm/internal/kotlin/wasm/internal/Runtime.kt index b4b6895def0..1862ec9ca97 100644 --- a/libraries/stdlib/wasm/internal/kotlin/wasm/internal/Runtime.kt +++ b/libraries/stdlib/wasm/internal/kotlin/wasm/internal/Runtime.kt @@ -67,8 +67,3 @@ internal fun boxIntrinsic(x: T): R = @ExcludedFromCodegen internal fun unboxIntrinsic(x: T): R = implementedAsIntrinsic - -internal fun wasmThrow(e: Throwable): Nothing { - println("Kotlin/Wasm exception wasm thrown: ${e.message}") - wasm_unreachable() -} \ No newline at end of file diff --git a/wasm/wasm.ir/src/org/jetbrains/kotlin/wasm/ir/WasmExpressionBuilder.kt b/wasm/wasm.ir/src/org/jetbrains/kotlin/wasm/ir/WasmExpressionBuilder.kt index b2f8cab421c..e9d15ac11d1 100644 --- a/wasm/wasm.ir/src/org/jetbrains/kotlin/wasm/ir/WasmExpressionBuilder.kt +++ b/wasm/wasm.ir/src/org/jetbrains/kotlin/wasm/ir/WasmExpressionBuilder.kt @@ -72,6 +72,14 @@ abstract class WasmExpressionBuilder { buildInstr(WasmOp.BR, WasmImmediate.LabelIdx(relativeLevel)) } + fun buildThrow(tagIdx: Int) { + buildInstr(WasmOp.THROW, WasmImmediate.TagIdx(tagIdx)) + } + + fun buildCatch(tagIdx: Int) { + buildInstr(WasmOp.CATCH, WasmImmediate.TagIdx(tagIdx)) + } + fun buildBrIf(absoluteBlockLevel: Int) { val relativeLevel = numberOfNestedBlocks - absoluteBlockLevel assert(relativeLevel >= 0) { "Negative relative block index" }