diff --git a/.idea/dictionaries/skuzmich.xml b/.idea/dictionaries/skuzmich.xml index d373a954ec6..04438696854 100644 --- a/.idea/dictionaries/skuzmich.xml +++ b/.idea/dictionaries/skuzmich.xml @@ -2,6 +2,7 @@ anyref + dataref ushr wasm 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 b04eedbc032..62e88eef8c3 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 @@ -142,7 +142,7 @@ class BodyGenerator(val context: WasmFunctionCodegenContext) : IrElementVisitorV if (klass.getWasmArrayAnnotation() != null) { require(expression.valueArgumentsCount == 1) { "@WasmArrayOf constructs must have exactly one argument" } generateExpression(expression.getValueArgument(0)!!) - body.buildRttCanon(context.transformType(klass.defaultType)) + body.buildRttCanon(wasmGcType) body.buildInstr( WasmOp.ARRAY_NEW_DEFAULT_WITH_RTT, WasmImmediate.GcType(wasmGcType) @@ -242,7 +242,7 @@ class BodyGenerator(val context: WasmFunctionCodegenContext) : IrElementVisitorV val resT = context.transformResultType(function.returnType) if (resT is WasmRefNullType) { generateTypeRTT(function.returnType) - body.buildRefCast(fromType = WasmEqRef, toType = resT) + body.buildRefCast() } } } @@ -278,10 +278,9 @@ class BodyGenerator(val context: WasmFunctionCodegenContext) : IrElementVisitorV } wasmSymbols.wasmRefCast -> { - val fromType = call.getTypeArgument(0)!! - val toType = call.getTypeArgument(1)!! + val toType = call.getTypeArgument(0)!! generateTypeRTT(toType) - body.buildRefCast(context.transformType(fromType), context.transformType(toType)) + body.buildRefCast() } wasmSymbols.wasmFloatNaN -> { @@ -311,7 +310,7 @@ class BodyGenerator(val context: WasmFunctionCodegenContext) : IrElementVisitorV val field = getInlineClassBackingField(klass) generateTypeRTT(toType) - body.buildRefCast(context.transformType(fromType), context.transformBoxedType(toType)) + body.buildRefCast() generateInstanceFieldAccess(field) } else -> { @@ -500,6 +499,15 @@ class BodyGenerator(val context: WasmFunctionCodegenContext) : IrElementVisitorV var immediates = emptyArray() when (op.immediates.size) { 0 -> { + when (op) { + WasmOp.REF_TEST -> { + val toIrType = call.getTypeArgument(0)!! + // ref.test takes RTT as a second operand + generateTypeRTT(toIrType) + } + else -> { + } + } } 1 -> { immediates = arrayOf( @@ -513,25 +521,6 @@ class BodyGenerator(val context: WasmFunctionCodegenContext) : IrElementVisitorV } ) } - 2 -> { - when (op) { - WasmOp.REF_TEST -> { - val fromIrType = call.getValueArgument(0)!!.type - val fromWasmType = context.transformBoxedType(fromIrType) - val toIrType = call.getTypeArgument(0)!! - val toWasmType = context.transformBoxedType(toIrType) - immediates = arrayOf( - WasmImmediate.HeapType(fromWasmType), - WasmImmediate.HeapType(toWasmType), - ) - - // ref.test takes RTT as a second operand - generateTypeRTT(toIrType) - } - else -> - error("Op $opString is unsupported") - } - } else -> error("Op $opString is unsupported") } diff --git a/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/ir2wasm/DeclarationGenerator.kt b/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/ir2wasm/DeclarationGenerator.kt index a364ab77afe..057650d45d6 100644 --- a/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/ir2wasm/DeclarationGenerator.kt +++ b/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/ir2wasm/DeclarationGenerator.kt @@ -211,7 +211,7 @@ class DeclarationGenerator(val context: WasmModuleCodegenContext) : IrElementVis context.defineGcType(symbol, structType) - var depth = 2 + var depth = 0 val metadata = context.getClassMetadata(symbol) var subMetadata = metadata while (true) { @@ -222,22 +222,21 @@ class DeclarationGenerator(val context: WasmModuleCodegenContext) : IrElementVis val initBody = mutableListOf() val wasmExpressionGenerator = WasmIrExpressionBuilder(initBody) + val wasmGcType = context.referenceGcType(symbol) val superClass = metadata.superClass if (superClass != null) { val superRTT = context.referenceClassRTT(superClass.klass.symbol) wasmExpressionGenerator.buildGetGlobal(superRTT) + wasmExpressionGenerator.buildRttSub(wasmGcType) } else { - wasmExpressionGenerator.buildRttCanon(WasmRefType(WasmHeapType.Simple.Eq)) + wasmExpressionGenerator.buildRttCanon(wasmGcType) } - wasmExpressionGenerator.buildRttSub( - WasmRefType(WasmHeapType.Type(WasmSymbol(structType))) - ) val rtt = WasmGlobal( name = "rtt_of_$nameStr", isMutable = false, - type = WasmRtt(depth, WasmHeapType.Type(WasmSymbol(structType))), + type = WasmRtt(depth, WasmSymbol(structType)), init = initBody ) diff --git a/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/lower/BuiltInsLowering.kt b/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/lower/BuiltInsLowering.kt index 3f5e9397025..c3f82eb9a88 100644 --- a/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/lower/BuiltInsLowering.kt +++ b/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/lower/BuiltInsLowering.kt @@ -84,6 +84,15 @@ class BuiltInsLowering(val context: WasmBackendContext) : FileLoweringPass { } irBuiltins.checkNotNullSymbol -> { + + // Workaround: v8 doesnt support ref.cast-ing unreachable very well. + run { + val arg = call.getValueArgument(0)!! + if (arg.isNullConst()) { + return builder.irCall(symbols.wasmUnreachable, irBuiltins.nothingType) + } + } + return irCall(call, symbols.ensureNotNull).also { it.putTypeArgument(0, call.type) } diff --git a/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/lower/WasmTypeOperatorLowering.kt b/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/lower/WasmTypeOperatorLowering.kt index 9ec7584be63..958906951a7 100644 --- a/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/lower/WasmTypeOperatorLowering.kt +++ b/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/lower/WasmTypeOperatorLowering.kt @@ -194,8 +194,7 @@ class WasmBaseTypeOperatorTransformer(val context: WasmBackendContext) : IrEleme subject = cachedValue(), thenPart = builder.irNull(toType), elsePart = builder.irCall(symbols.wasmRefCast, type = toType).apply { - putTypeArgument(0, fromType) - putTypeArgument(1, toType) + putTypeArgument(0, toType) putValueArgument(0, cachedValue()) } ) @@ -203,8 +202,7 @@ class WasmBaseTypeOperatorTransformer(val context: WasmBackendContext) : IrEleme } return builder.irCall(symbols.wasmRefCast, type = toType).apply { - putTypeArgument(0, fromType) - putTypeArgument(1, toType) + putTypeArgument(0, toType) putValueArgument(0, value) } } diff --git a/js/js.tests/build.gradle.kts b/js/js.tests/build.gradle.kts index 6b83369c0f6..a4c8064b591 100644 --- a/js/js.tests/build.gradle.kts +++ b/js/js.tests/build.gradle.kts @@ -147,7 +147,7 @@ val v8osString = when (currentOsType) { } val v8edition = "rel" // rel or dbg -val v8version = "8.8.104" +val v8version = "9.2.212" val v8fileName = "v8-${v8osString}-${v8edition}-${v8version}" val v8url = "https://storage.googleapis.com/chromium-v8/official/canary/$v8fileName.zip" diff --git a/libraries/stdlib/wasm/internal/kotlin/wasm/internal/WasmInstructions.kt b/libraries/stdlib/wasm/internal/kotlin/wasm/internal/WasmInstructions.kt index 3d5a5a1102a..4b8d1fe7393 100644 --- a/libraries/stdlib/wasm/internal/kotlin/wasm/internal/WasmInstructions.kt +++ b/libraries/stdlib/wasm/internal/kotlin/wasm/internal/WasmInstructions.kt @@ -19,7 +19,7 @@ internal fun wasm_float_nan(): Float = internal fun wasm_double_nan(): Double = implementedAsIntrinsic -internal fun wasm_ref_cast(a: From): To = +internal fun wasm_ref_cast(a: Any?): To = implementedAsIntrinsic @WasmOp(WasmOp.I32_EQ) 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 0026b7f250b..f2c93754ce3 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 @@ -62,7 +62,7 @@ sealed class WasmImmediate { constructor(value: WasmGlobal) : this(WasmSymbol(value)) } - class TypeIdx(val value: WasmSymbol) : WasmImmediate() { + class TypeIdx(val value: WasmSymbolReadOnly) : WasmImmediate() { constructor(value: WasmTypeDeclaration) : this(WasmSymbol(value)) } @@ -352,14 +352,12 @@ enum class WasmOp( I31_GET_S("i31.get_s", 0xFB_21), I31_GET_U("i31.get_u", 0xFB_22), - RTT_CANON("rtt.canon", 0xFB_30, HEAP_TYPE), + RTT_CANON("rtt.canon", 0xFB_30, TYPE_IDX), - // TODO: GC spec also has "depth" and "input heap type" immediates. V8 currently implements without them. - RTT_SUB("rtt.sub", 0xFB_31, HEAP_TYPE), - REF_TEST("ref.test", 0xFB_40, listOf(HEAP_TYPE, HEAP_TYPE)), - REF_CAST("ref.cast", 0xFB_41, listOf(HEAP_TYPE, HEAP_TYPE)), + RTT_SUB("rtt.sub", 0xFB_31, TYPE_IDX), + REF_TEST("ref.test", 0xFB_40), + REF_CAST("ref.cast", 0xFB_41), - // TODO: GC spec also has two heap type immediates. V8 currently implements without them. BR_ON_CAST("br_on_cast", 0xFB_42, listOf(LABEL_IDX)), ; diff --git a/wasm/wasm.ir/src/org/jetbrains/kotlin/wasm/ir/Types.kt b/wasm/wasm.ir/src/org/jetbrains/kotlin/wasm/ir/Types.kt index 1a4d18296dd..1471a629608 100644 --- a/wasm/wasm.ir/src/org/jetbrains/kotlin/wasm/ir/Types.kt +++ b/wasm/wasm.ir/src/org/jetbrains/kotlin/wasm/ir/Types.kt @@ -31,10 +31,10 @@ class WasmRefType(val heapType: WasmHeapType) : WasmType("ref", -0x15) @Suppress("unused") object WasmI31Ref : WasmType("i31ref", -0x16) -class WasmRtt(val depth: Int, val heapType: WasmHeapType) : WasmType("rtt", -0x17) +class WasmRtt(val depth: Int, val type: WasmSymbolReadOnly) : WasmType("rtt", -0x17) @Suppress("unused") -object WasmExnRef : WasmType("exnref", -0x18) +object WasmDataRef : WasmType("dataref", -0x19) sealed class WasmHeapType { class Type(val type: WasmSymbolReadOnly) : WasmHeapType() { 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 1d7e689b884..813f3d42c2c 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 @@ -130,24 +130,20 @@ abstract class WasmExpressionBuilder { } - fun buildRefCast(fromType: WasmType, toType: WasmType) { - buildInstr( - WasmOp.REF_CAST, - WasmImmediate.HeapType(fromType.getHeapType()), - WasmImmediate.HeapType(toType.getHeapType()) - ) + fun buildRefCast() { + buildInstr(WasmOp.REF_CAST) } fun buildRefNull(type: WasmHeapType) { buildInstr(WasmOp.REF_NULL, WasmImmediate.HeapType(WasmRefType(type))) } - fun buildRttSub(heapType: WasmType) { - buildInstr(WasmOp.RTT_SUB, WasmImmediate.HeapType(heapType)) + fun buildRttSub(decl: WasmSymbol) { + buildInstr(WasmOp.RTT_SUB, WasmImmediate.TypeIdx(decl)) } - fun buildRttCanon(heapType: WasmType) { - buildInstr(WasmOp.RTT_CANON, WasmImmediate.HeapType(heapType)) + fun buildRttCanon(decl: WasmSymbol) { + buildInstr(WasmOp.RTT_CANON, WasmImmediate.TypeIdx(decl)) } } diff --git a/wasm/wasm.ir/src/org/jetbrains/kotlin/wasm/ir/convertors/WasmIrToBinary.kt b/wasm/wasm.ir/src/org/jetbrains/kotlin/wasm/ir/convertors/WasmIrToBinary.kt index c1feaf15c8f..125a84e9dce 100644 --- a/wasm/wasm.ir/src/org/jetbrains/kotlin/wasm/ir/convertors/WasmIrToBinary.kt +++ b/wasm/wasm.ir/src/org/jetbrains/kotlin/wasm/ir/convertors/WasmIrToBinary.kt @@ -398,7 +398,7 @@ class WasmIrToBinary(outputStream: OutputStream, val module: WasmModule) { } if (type is WasmRtt) { b.writeVarUInt32(type.depth) - appendHeapType(type.heapType) + appendModuleFieldReference(type.type.owner) } } diff --git a/wasm/wasm.ir/src/org/jetbrains/kotlin/wasm/ir/convertors/WasmIrToText.kt b/wasm/wasm.ir/src/org/jetbrains/kotlin/wasm/ir/convertors/WasmIrToText.kt index 53a38a4d29d..ce67b2d91b5 100644 --- a/wasm/wasm.ir/src/org/jetbrains/kotlin/wasm/ir/convertors/WasmIrToText.kt +++ b/wasm/wasm.ir/src/org/jetbrains/kotlin/wasm/ir/convertors/WasmIrToText.kt @@ -442,7 +442,7 @@ class WasmIrToText : SExpressionBuilder() { is WasmRtt -> sameLineList("rtt") { appendElement(type.depth.toString()) - appendHeapType(type.heapType) + appendModuleFieldReference(type.type.owner) } WasmUnreachableType -> {