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 062f08c2166..fc5986152f7 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 @@ -211,6 +211,7 @@ class WasmSymbols( val nullableDoubleIeee754Equals = getInternalFunction("nullableDoubleIeee754Equals") val unsafeGetScratchRawMemory = getInternalFunction("unsafeGetScratchRawMemory") + val returnArgumentIfItIsKotlinAny = getInternalFunction("returnArgumentIfItIsKotlinAny") val newJsArray = getInternalFunction("newJsArray") val jsArrayPush = getInternalFunction("jsArrayPush") 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 5da097f4801..3ffa6ce595d 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 @@ -594,11 +594,23 @@ class BodyGenerator( } wasmSymbols.unsafeGetScratchRawMemory -> { - body.buildConstI32Symbol(context.scratchMemAddr, location) } - + wasmSymbols.returnArgumentIfItIsKotlinAny -> { + body.buildBlock("returnIfAny", WasmAnyRef) { innerLabel -> + body.buildGetLocal(functionContext.referenceLocal(0), location) + body.buildInstr(WasmOp.EXTERN_INTERNALIZE, location) + body.buildBrInstr(WasmOp.BR_ON_NON_DATA_DEPRECATED, innerLabel, location) + body.buildBrInstr( + WasmOp.BR_ON_CAST_FAIL_DEPRECATED, + innerLabel, + context.referenceGcType(backendContext.irBuiltIns.anyClass), + location + ) + body.buildInstr(WasmOp.RETURN, location) + } + } wasmSymbols.wasmArrayCopy -> { val immediate = WasmImmediate.GcType( diff --git a/libraries/stdlib/wasm/internal/kotlin/wasm/internal/ExternalWrapper.kt b/libraries/stdlib/wasm/internal/kotlin/wasm/internal/ExternalWrapper.kt index 8d0ddaf7700..7997857f4dd 100644 --- a/libraries/stdlib/wasm/internal/kotlin/wasm/internal/ExternalWrapper.kt +++ b/libraries/stdlib/wasm/internal/kotlin/wasm/internal/ExternalWrapper.kt @@ -139,6 +139,22 @@ private fun Any.asWasmExternRef(): ExternalInterfaceType = @JsFun("(ref) => ref == null") internal external fun isNullish(ref: ExternalInterfaceType?): Boolean +@Suppress("UNUSED_PARAMETER") +@ExcludedFromCodegen +/* +* Compiler generates inplace next code: +* ``` +* block (result anyref) { +* local.get 0 +* extern.internalize +* br_on_non_data_fail 0 +* br_on_cast_fail 0 (type $kotlin.Any) +* return +* } +* ``` +*/ +internal fun returnArgumentIfItIsKotlinAny(ref: ExternalInterfaceType): Unit = implementedAsIntrinsic + internal fun externRefToAny(ref: ExternalInterfaceType): Any? { // TODO rewrite it so to get something like: // block { @@ -147,13 +163,7 @@ internal fun externRefToAny(ref: ExternalInterfaceType): Any? { // return // } // If ref is an instance of kotlin class -- return it casted to Any - val refAsAnyref = ref.externAsWasmAnyref() - if (wasm_ref_is_data_deprecated(refAsAnyref)) { - val refAsDataRef = wasm_ref_as_data_deprecated(refAsAnyref) - if (wasm_ref_test_deprecated(refAsDataRef)) { - return wasm_ref_cast_deprecated(refAsDataRef) - } - } + returnArgumentIfItIsKotlinAny(ref) // If we have Null in notNullRef -- return null // If we already have a box -- return it, diff --git a/libraries/stdlib/wasm/internal/kotlin/wasm/internal/WasmInstructions.kt b/libraries/stdlib/wasm/internal/kotlin/wasm/internal/WasmInstructions.kt index 01d212ffb3b..06db2218dd3 100644 --- a/libraries/stdlib/wasm/internal/kotlin/wasm/internal/WasmInstructions.kt +++ b/libraries/stdlib/wasm/internal/kotlin/wasm/internal/WasmInstructions.kt @@ -387,9 +387,3 @@ internal external fun wasm_i64_ctz(a: Long): Long @WasmOp(WasmOp.REF_IS_NULL) internal external fun wasm_externref_is_null(a: ExternalInterfaceType?): Boolean - -@WasmOp(WasmOp.REF_AS_DATA_DEPRECATED) -internal external fun wasm_ref_as_data_deprecated(x: anyref): dataref - -@WasmOp(WasmOp.REF_IS_DATA_DEPRECATED) -internal external fun wasm_ref_is_data_deprecated(x: anyref): Boolean diff --git a/libraries/stdlib/wasm/src/generated/_WasmOp.kt b/libraries/stdlib/wasm/src/generated/_WasmOp.kt index f9c8999e910..f0fe98b932e 100644 --- a/libraries/stdlib/wasm/src/generated/_WasmOp.kt +++ b/libraries/stdlib/wasm/src/generated/_WasmOp.kt @@ -243,7 +243,6 @@ internal annotation class WasmOp(val name: String) { const val ARRAY_COPY = "ARRAY_COPY" const val ARRAY_NEW_DATA = "ARRAY_NEW_DATA" const val ARRAY_NEW_FIXED = "ARRAY_NEW_FIXED" - const val ARRAY_NEW_ELEM = "ARRAY_NEW_ELEM" const val I31_NEW = "I31_NEW" const val I31_GET_S = "I31_GET_S" const val I31_GET_U = "I31_GET_U" @@ -252,9 +251,11 @@ internal annotation class WasmOp(val name: String) { const val EXTERN_EXTERNALIZE = "EXTERN_EXTERNALIZE" const val REF_TEST_DEPRECATED = "REF_TEST_DEPRECATED" const val REF_CAST_DEPRECATED = "REF_CAST_DEPRECATED" - const val REF_IS_DATA_DEPRECATED = "REF_IS_DATA_DEPRECATED" - const val REF_AS_DATA_DEPRECATED = "REF_AS_DATA_DEPRECATED" const val BR_ON_CAST_FAIL_DEPRECATED = "BR_ON_CAST_FAIL_DEPRECATED" + const val BR_ON_NON_DATA_DEPRECATED = "BR_ON_NON_DATA_DEPRECATED" const val GET_UNIT = "GET_UNIT" + const val PSEUDO_COMMENT_PREVIOUS_INSTR = "PSEUDO_COMMENT_PREVIOUS_INSTR" + const val PSEUDO_COMMENT_GROUP_START = "PSEUDO_COMMENT_GROUP_START" + const val PSEUDO_COMMENT_GROUP_END = "PSEUDO_COMMENT_GROUP_END" } } 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 8499010054c..720f1136412 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 @@ -397,10 +397,8 @@ enum class WasmOp( REF_TEST_DEPRECATED("ref.test", 0xFB_44, STRUCT_TYPE_IDX), REF_CAST_DEPRECATED("ref.cast", 0xFB_45, STRUCT_TYPE_IDX), - REF_IS_DATA_DEPRECATED("ref.is_data", 0xFB_51), - REF_AS_DATA_DEPRECATED("ref.as_data", 0xFB_59), - BR_ON_CAST_FAIL_DEPRECATED("br_on_cast_fail", 0xFB_47, listOf(LABEL_IDX, STRUCT_TYPE_IDX)), + BR_ON_NON_DATA_DEPRECATED("br_on_non_data_fail", 0xFB_64, listOf(LABEL_IDX)), // ============================================================ // Pseudo-instruction, just alias for a normal call. It's used to easily spot get_unit on the wasm level.