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 7582b76176f..ae8534647e5 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 @@ -405,7 +405,7 @@ class BodyGenerator( body.buildStructGet(context.referenceGcType(irBuiltIns.anyClass), WasmSymbol(1)) val classITableReference = context.referenceClassITableGcType(symbol) - body.buildRefCastStatic(classITableReference) + body.buildRefCastNullStatic(classITableReference) body.buildStructGet(classITableReference, context.referenceClassITableInterfaceSlot(symbol)) val vfSlot = context.getInterfaceMetadata(symbol).methods @@ -430,7 +430,7 @@ class BodyGenerator( private fun generateRefCast(fromType: IrType, toType: IrType) { if (!isDownCastAlwaysSuccessInRuntime(fromType, toType)) { - body.buildRefCastStatic( + body.buildRefCastNullStatic( toType = context.referenceGcType(toType.getRuntimeClass(irBuiltIns).symbol) ) } diff --git a/libraries/stdlib/wasm/internal/kotlin/wasm/internal/ExternalWrapper.kt b/libraries/stdlib/wasm/internal/kotlin/wasm/internal/ExternalWrapper.kt index a326cf5bf6e..334024ba85f 100644 --- a/libraries/stdlib/wasm/internal/kotlin/wasm/internal/ExternalWrapper.kt +++ b/libraries/stdlib/wasm/internal/kotlin/wasm/internal/ExternalWrapper.kt @@ -138,13 +138,16 @@ private fun Any.asWasmExternRef(): ExternalInterfaceType = internal external fun isNullish(ref: ExternalInterfaceType?): Boolean internal fun externRefToAny(ref: ExternalInterfaceType): Any? { - // If ref is an instance of kotlin class -- return it cased to Any + // TODO rewrite it so to get something like: + // block { + // refAsAnyref + // br_on_cast_fail 0 $kotlin.Any + // return + // } + // If ref is an instance of kotlin class -- return it casted to Any val refAsAnyref = ref.externAsWasmAnyref() - if (wasm_ref_is_data(refAsAnyref)) { - val refAsDataRef = wasm_ref_as_data(refAsAnyref) - if (wasm_ref_test(refAsDataRef)) { - return wasm_ref_cast(refAsDataRef) - } + if (wasm_ref_test(refAsAnyref)) { + return wasm_ref_cast(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 d325a136df0..0d28e303637 100644 --- a/libraries/stdlib/wasm/internal/kotlin/wasm/internal/WasmInstructions.kt +++ b/libraries/stdlib/wasm/internal/kotlin/wasm/internal/WasmInstructions.kt @@ -378,17 +378,5 @@ public external fun wasm_i64_ctz(a: Long): Long // Reference type operators -@WasmOp(WasmOp.REF_IS_DATA) -internal external fun wasm_ref_is_data(x: anyref): Boolean - -@WasmOp(WasmOp.REF_IS_I31) -internal external fun wasm_ref_is_i31(x: anyref): Boolean - -@WasmOp(WasmOp.REF_AS_DATA) -internal external fun wasm_ref_as_data(x: anyref): dataref - -@WasmOp(WasmOp.REF_AS_I31) -internal external fun wasm_ref_as_i31(x: anyref): i31ref - @WasmOp(WasmOp.REF_IS_NULL) -internal external fun wasm_externref_is_null(a: ExternalInterfaceType?): Boolean \ No newline at end of file +internal external fun wasm_externref_is_null(a: ExternalInterfaceType?): Boolean diff --git a/libraries/stdlib/wasm/src/generated/_WasmOp.kt b/libraries/stdlib/wasm/src/generated/_WasmOp.kt index 6444fb10b51..361ba9ad895 100644 --- a/libraries/stdlib/wasm/src/generated/_WasmOp.kt +++ b/libraries/stdlib/wasm/src/generated/_WasmOp.kt @@ -254,21 +254,16 @@ 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" const val REF_EQ = "REF_EQ" const val REF_TEST = "REF_TEST" + 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_FAIL = "BR_ON_CAST_FAIL" - const val REF_IS_DATA = "REF_IS_DATA" - const val REF_IS_I31 = "REF_IS_I31" - const val REF_AS_DATA = "REF_AS_DATA" - const val REF_AS_I31 = "REF_AS_I31" - const val BR_ON_DATA = "BR_ON_DATA" - const val BR_ON_I31 = "BR_ON_I31" - const val BR_ON_NON_DATA = "BR_ON_NON_DATA" - const val BR_ON_NON_I31 = "BR_ON_NON_I31" const val EXTERN_INTERNALIZE = "EXTERN_INTERNALIZE" const val EXTERN_EXTERNALIZE = "EXTERN_EXTERNALIZE" const val GET_UNIT = "GET_UNIT" 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 f4f151805ab..17ba95bcb60 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 @@ -361,31 +361,30 @@ enum class WasmOp( ARRAY_GET_S("array.get_s", 0xFB_14, listOf(STRUCT_TYPE_IDX)), ARRAY_GET_U("array.get_u", 0xFB_15, listOf(STRUCT_TYPE_IDX)), ARRAY_SET("array.set", 0xFB_16, listOf(STRUCT_TYPE_IDX)), - ARRAY_LEN("array.len", 0xFB_17, listOf(STRUCT_TYPE_IDX)), + ARRAY_LEN("array.len", 0xFB_19), ARRAY_COPY("array.copy", 0xFB_18, listOf(STRUCT_TYPE_IDX, STRUCT_TYPE_IDX)), ARRAY_NEW_DATA("array.new_data", 0xFB_1D, listOf(STRUCT_TYPE_IDX, DATA_IDX)), ARRAY_NEW_FIXED("array.new_fixed", 0xFB_1A, listOf(STRUCT_TYPE_IDX, CONST_I32)), + ARRAY_NEW_ELEM("array.new_elem", 0xFB_1F, listOf(STRUCT_TYPE_IDX, DATA_IDX)), I31_NEW("i31.new", 0xFB_20), I31_GET_S("i31.get_s", 0xFB_21), I31_GET_U("i31.get_u", 0xFB_22), REF_EQ("ref.eq", 0xD5), - REF_TEST("ref.test", 0xFB_44, STRUCT_TYPE_IDX), - REF_CAST("ref.cast", 0xFB_45, STRUCT_TYPE_IDX), + REF_TEST("ref.test", 0xFB_40, STRUCT_TYPE_IDX), + REF_TEST_NULL("ref.test null", 0xFB_48, STRUCT_TYPE_IDX), + REF_CAST("ref.cast", 0xFB_41, STRUCT_TYPE_IDX), + REF_CAST_NULL("ref.cast null", 0xFB_49, STRUCT_TYPE_IDX), + // TODO remove as soon as V8 support new instructions, see below BR_ON_CAST_FAIL("br_on_cast_fail", 0xfb47, listOf(LABEL_IDX, STRUCT_TYPE_IDX)), - REF_IS_DATA("ref.is_data", 0xfb51), - REF_IS_I31("ref.is_i31", 0xfb52), - REF_AS_DATA("ref.as_data", 0xfb59), - REF_AS_I31("ref.as_i31", 0xfb5a), - - BR_ON_DATA("br_on_data", 0xfb61, listOf(LABEL_IDX)), - BR_ON_I31("br_on_i31", 0xfb62, listOf(LABEL_IDX)), - - BR_ON_NON_DATA("br_on_non_data", 0xfb64, listOf(LABEL_IDX)), - BR_ON_NON_I31("br_on_non_i31", 0xfb65, listOf(LABEL_IDX)), +// Not yet supported by V8 +// BR_ON_CAST("br_on_cast", 0xFB42, listOf(LABEL_IDX, STRUCT_TYPE_IDX)), +// BR_ON_CAST_NULL("br_on_cast null", 0xFB4A, listOf(LABEL_IDX, STRUCT_TYPE_IDX)), +// BR_ON_CAST_FAIL("br_on_cast_fail", 0xFB43, listOf(LABEL_IDX, STRUCT_TYPE_IDX)), +// BR_ON_CAST_FAIL_NULL("br_on_cast_fail null", 0xFB4B, listOf(LABEL_IDX, STRUCT_TYPE_IDX)), EXTERN_INTERNALIZE("extern.internalize", 0xfb70), // externref -> anyref EXTERN_EXTERNALIZE("extern.externalize", 0xfb71), // anyref -> externref 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 00c7189822d..4b0a5b0c600 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 @@ -156,8 +156,8 @@ abstract class WasmExpressionBuilder { ) } - fun buildRefCastStatic(toType: WasmSymbolReadOnly) { - buildInstr(WasmOp.REF_CAST, WasmImmediate.TypeIdx(toType)) + fun buildRefCastNullStatic(toType: WasmSymbolReadOnly) { + buildInstr(WasmOp.REF_CAST_NULL, WasmImmediate.TypeIdx(toType)) } fun buildRefTestStatic(toType: WasmSymbolReadOnly) { @@ -172,4 +172,3 @@ abstract class WasmExpressionBuilder { buildInstr(WasmOp.DROP) } } -