From 86e854a98088fe386a023acfad57fdf7773cc1df Mon Sep 17 00:00:00 2001 From: Zalim Bashorov Date: Thu, 14 Sep 2023 00:38:02 +0200 Subject: [PATCH] Revert "[Wasm] Don't use the new br_on_cast* instructions since they are not supported in Node.js yet" This reverts commit 2d728727 #KT-60828 Fixed --- .../backend/wasm/ir2wasm/BodyGenerator.kt | 42 ++++++++++--------- .../ir2wasm/WasmFunctionCodegenContext.kt | 4 +- .../src/generated/wasm/internal/_WasmOp.kt | 2 + .../org/jetbrains/kotlin/wasm/ir/Operators.kt | 5 +-- 4 files changed, 27 insertions(+), 26 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 a6bab8e28dc..f5d2cd29e0e 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 @@ -542,24 +542,26 @@ class BodyGenerator( val parameterLocal = functionContext.referenceLocal(SyntheticLocalType.IS_INTERFACE_PARAMETER) body.buildSetLocal(parameterLocal, location) body.buildBlock("isInterface", WasmI32) { outerLabel -> - body.buildBlock("isInterface") { innerLabel -> + body.buildBlock("isInterface", WasmRefNullType(WasmHeapType.Simple.Struct)) { innerLabel -> body.buildGetLocal(parameterLocal, location) body.buildStructGet(context.referenceGcType(irBuiltIns.anyClass), WasmSymbol(1), location) - val tmpLocal = functionContext.referenceLocal(SyntheticLocalType.TMP_FOR_BR_ON_CAST_EMULATION) - body.buildInstr(WasmOp.LOCAL_TEE, location, WasmImmediate.LocalIdx(tmpLocal)) - body.buildRefTestStatic(classITable, location) - body.buildInstr(WasmOp.I32_EQZ, location) - body.buildBrIf(innerLabel, location) - - body.buildGetLocal(tmpLocal, location) - body.buildRefCastStatic(classITable, location) + body.buildBrOnCastInstr( + WasmOp.BR_ON_CAST_FAIL, + innerLabel, + fromIsNullable = true, + toIsNullable = false, + from = WasmHeapType.Simple.Struct, + to = WasmHeapType.Type(classITable), + location, + ) body.buildStructGet(classITable, context.referenceClassITableInterfaceSlot(irInterface.symbol), location) body.buildInstr(WasmOp.REF_IS_NULL, location) body.buildInstr(WasmOp.I32_EQZ, location) body.buildBr(outerLabel, location) } + body.buildDrop(location) body.buildConstI32(0, location) } } else { @@ -606,23 +608,23 @@ class BodyGenerator( } wasmSymbols.returnArgumentIfItIsKotlinAny -> { - body.buildBlock("returnIfAny") { innerLabel -> + body.buildBlock("returnIfAny", WasmAnyRef) { innerLabel -> body.buildGetLocal(functionContext.referenceLocal(0), location) body.buildInstr(WasmOp.EXTERN_INTERNALIZE, location) - val tmpLocal = functionContext.referenceLocal(SyntheticLocalType.TMP_FOR_BR_ON_CAST_EMULATION) - body.buildInstr(WasmOp.LOCAL_TEE, location, WasmImmediate.LocalIdx(tmpLocal)) - - val toType = context.referenceGcType(backendContext.irBuiltIns.anyClass) - body.buildRefTestStatic(toType, location) - body.buildInstr(WasmOp.I32_EQZ, location) - body.buildBrIf(innerLabel, location) - - body.buildGetLocal(tmpLocal, location) - body.buildRefCastStatic(toType, location) + body.buildBrOnCastInstr( + WasmOp.BR_ON_CAST_FAIL, + innerLabel, + fromIsNullable = true, + toIsNullable = true, + from = WasmHeapType.Simple.Any, + to = WasmHeapType.Type(context.referenceGcType(backendContext.irBuiltIns.anyClass)), + location, + ) body.buildInstr(WasmOp.RETURN, location) } + body.buildDrop(location) } wasmSymbols.wasmArrayCopy -> { 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 86277994bdf..e38936b6873 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 @@ -15,7 +15,7 @@ import org.jetbrains.kotlin.ir.symbols.IrValueSymbol import org.jetbrains.kotlin.wasm.ir.* enum class LoopLabelType { BREAK, CONTINUE } -enum class SyntheticLocalType { IS_INTERFACE_PARAMETER, TABLE_SWITCH_SELECTOR, TMP_FOR_BR_ON_CAST_EMULATION } +enum class SyntheticLocalType { IS_INTERFACE_PARAMETER, TABLE_SWITCH_SELECTOR } class WasmFunctionCodegenContext( val irFunction: IrFunction, @@ -61,8 +61,6 @@ class WasmFunctionCodegenContext( get() = when (this) { SyntheticLocalType.IS_INTERFACE_PARAMETER -> WasmRefNullType(WasmHeapType.Type(context.referenceGcType(backendContext.irBuiltIns.anyClass))) - SyntheticLocalType.TMP_FOR_BR_ON_CAST_EMULATION -> - WasmRefNullType(WasmHeapType.Simple.Any) SyntheticLocalType.TABLE_SWITCH_SELECTOR -> WasmI32 } diff --git a/libraries/stdlib/wasm/src/generated/wasm/internal/_WasmOp.kt b/libraries/stdlib/wasm/src/generated/wasm/internal/_WasmOp.kt index 50797946ad8..7c208c521a4 100644 --- a/libraries/stdlib/wasm/src/generated/wasm/internal/_WasmOp.kt +++ b/libraries/stdlib/wasm/src/generated/wasm/internal/_WasmOp.kt @@ -251,6 +251,8 @@ internal annotation class WasmOp(val name: String) { const val REF_TEST_NULL = "REF_TEST_NULL" const val REF_CAST = "REF_CAST" const val REF_CAST_NULL = "REF_CAST_NULL" + const val BR_ON_CAST = "BR_ON_CAST" + const val BR_ON_CAST_FAIL = "BR_ON_CAST_FAIL" const val EXTERN_INTERNALIZE = "EXTERN_INTERNALIZE" const val EXTERN_EXTERNALIZE = "EXTERN_EXTERNALIZE" const val PSEUDO_COMMENT_PREVIOUS_INSTR = "PSEUDO_COMMENT_PREVIOUS_INSTR" diff --git a/wasm/wasm.ir/src/org/jetbrains/kotlin/wasm/ir/Operators.kt b/wasm/wasm.ir/src/org/jetbrains/kotlin/wasm/ir/Operators.kt index 37b5d43069e..8301aaad7b6 100644 --- a/wasm/wasm.ir/src/org/jetbrains/kotlin/wasm/ir/Operators.kt +++ b/wasm/wasm.ir/src/org/jetbrains/kotlin/wasm/ir/Operators.kt @@ -381,9 +381,8 @@ enum class WasmOp( REF_CAST("ref.cast", 0xFB_16, HEAP_TYPE), REF_CAST_NULL("ref.cast null", 0xFB_17, HEAP_TYPE), -// TODO: KT-60828 Return br_on_cast_fail usages when it's possible -// BR_ON_CAST("br_on_cast", 0xFB_18, listOf(CONST_U8, LABEL_IDX, HEAP_TYPE, HEAP_TYPE)), -// BR_ON_CAST_FAIL("br_on_cast_fail", 0xFB_19, listOf(CONST_U8, LABEL_IDX, HEAP_TYPE, HEAP_TYPE)), + BR_ON_CAST("br_on_cast", 0xFB_18, listOf(CONST_U8, LABEL_IDX, HEAP_TYPE, HEAP_TYPE)), + BR_ON_CAST_FAIL("br_on_cast_fail", 0xFB_19, listOf(CONST_U8, LABEL_IDX, HEAP_TYPE, HEAP_TYPE)), EXTERN_INTERNALIZE("extern.internalize", 0xFB_1A), // externref -> anyref EXTERN_EXTERNALIZE("extern.externalize", 0xFB_1B), // anyref -> externref