diff --git a/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/compiler.kt b/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/compiler.kt index ffb93f9d5cc..342bb4cfe90 100644 --- a/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/compiler.kt +++ b/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/compiler.kt @@ -109,8 +109,8 @@ fun WasmCompiledModuleFragment.generateJs(): String { //language=js val runtime = """ const externrefBoxes = new WeakMap(); + // ref must be non-null function tryGetOrSetExternrefBox(ref, ifNotCached) { - if (ref == null) return null; if (typeof ref !== 'object') return ifNotCached; const cachedBox = externrefBoxes.get(ref); if (cachedBox !== void 0) return cachedBox; 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 ae8534647e5..35e2743a914 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 @@ -461,7 +461,7 @@ class BodyGenerator( call: IrFunctionAccessExpression, function: IrFunction ): Boolean { - if (tryToGenerateWasmOpIntrinsicCall(function)) { + if (tryToGenerateWasmOpIntrinsicCall(call, function)) { return true } @@ -840,7 +840,7 @@ class BodyGenerator( } // Return true if function is recognized as intrinsic. - private fun tryToGenerateWasmOpIntrinsicCall(function: IrFunction): Boolean { + private fun tryToGenerateWasmOpIntrinsicCall(call: IrFunctionAccessExpression, function: IrFunction): Boolean { if (function.hasWasmNoOpCastAnnotation()) { return true } @@ -853,14 +853,19 @@ class BodyGenerator( body.buildInstr(op) } 1 -> { + fun getReferenceGcType(): WasmSymbol { + val type = function.dispatchReceiverParameter?.type ?: call.getTypeArgument(0)!! + return context.referenceGcType(type.classOrNull!!) + } + val immediates = arrayOf( when (val imm = op.immediates[0]) { WasmImmediateKind.MEM_ARG -> WasmImmediate.MemArg(0u, 0u) WasmImmediateKind.STRUCT_TYPE_IDX -> - WasmImmediate.GcType(context.referenceGcType(function.dispatchReceiverParameter!!.type.classOrNull!!)) + WasmImmediate.GcType(getReferenceGcType()) WasmImmediateKind.TYPE_IDX -> - WasmImmediate.TypeIdx(context.referenceGcType(function.dispatchReceiverParameter!!.type.classOrNull!!)) + WasmImmediate.TypeIdx(getReferenceGcType()) else -> error("Immediate $imm is unsupported") diff --git a/libraries/stdlib/wasm/internal/kotlin/wasm/internal/ExternalWrapper.kt b/libraries/stdlib/wasm/internal/kotlin/wasm/internal/ExternalWrapper.kt index 334024ba85f..5cc98403207 100644 --- a/libraries/stdlib/wasm/internal/kotlin/wasm/internal/ExternalWrapper.kt +++ b/libraries/stdlib/wasm/internal/kotlin/wasm/internal/ExternalWrapper.kt @@ -141,13 +141,13 @@ internal fun externRefToAny(ref: ExternalInterfaceType): Any? { // TODO rewrite it so to get something like: // block { // refAsAnyref - // br_on_cast_fail 0 $kotlin.Any + // br_on_cast_fail null 0 $kotlin.Any // return // } // If ref is an instance of kotlin class -- return it casted to Any val refAsAnyref = ref.externAsWasmAnyref() - if (wasm_ref_test(refAsAnyref)) { - return wasm_ref_cast(refAsAnyref) + if (wasm_ref_test_null(refAsAnyref)) { + return wasm_ref_cast_null(refAsAnyref) } // If we have Null in notNullRef -- return null diff --git a/libraries/stdlib/wasm/internal/kotlin/wasm/internal/WasmInstructions.kt b/libraries/stdlib/wasm/internal/kotlin/wasm/internal/WasmInstructions.kt index d1e748804a7..b4a347fe318 100644 --- a/libraries/stdlib/wasm/internal/kotlin/wasm/internal/WasmInstructions.kt +++ b/libraries/stdlib/wasm/internal/kotlin/wasm/internal/WasmInstructions.kt @@ -22,9 +22,19 @@ internal fun wasm_unreachable(): Nothing = internal fun wasm_ref_cast(a: Any?): To = implementedAsIntrinsic +@Suppress("REIFIED_TYPE_PARAMETER_NO_INLINE") +@WasmOp(WasmOp.REF_CAST_NULL) +internal fun wasm_ref_cast_null(a: Any?): To = + implementedAsIntrinsic + internal fun wasm_ref_test(a: Any?): Boolean = implementedAsIntrinsic +@Suppress("REIFIED_TYPE_PARAMETER_NO_INLINE") +@WasmOp(WasmOp.REF_TEST_NULL) +internal fun wasm_ref_test_null(a: Any?): Boolean = + implementedAsIntrinsic + internal fun wasm_array_copy(destination: T, destinationIndex: Int, source: T, sourceIndex: Int, length: Int): Unit = implementedAsIntrinsic