[Wasm] Do not erase interfaces down to Any type in Wasm signature.
This enables overloading virtual methods with different interface types
This commit is contained in:
+6
@@ -16802,6 +16802,12 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
|
|||||||
runTest("compiler/testData/codegen/box/functions/nothisnoclosure.kt");
|
runTest("compiler/testData/codegen/box/functions/nothisnoclosure.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("overloadByInterfaceType.kt")
|
||||||
|
public void testOverloadByInterfaceType() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/functions/overloadByInterfaceType.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("prefixRecursiveCall.kt")
|
@TestMetadata("prefixRecursiveCall.kt")
|
||||||
public void testPrefixRecursiveCall() throws Exception {
|
public void testPrefixRecursiveCall() throws Exception {
|
||||||
|
|||||||
+2
-2
@@ -255,7 +255,7 @@ class BodyGenerator(val context: WasmFunctionCodegenContext) : IrElementVisitorV
|
|||||||
// Processing it separately
|
// Processing it separately
|
||||||
if (call.symbol == wasmSymbols.boxIntrinsic) {
|
if (call.symbol == wasmSymbols.boxIntrinsic) {
|
||||||
val toType = call.getTypeArgument(0)!!
|
val toType = call.getTypeArgument(0)!!
|
||||||
val klass = toType.erasedUpperBound!!
|
val klass = toType.getRuntimeClass!!
|
||||||
val structTypeName = context.referenceGcType(klass.symbol)
|
val structTypeName = context.referenceGcType(klass.symbol)
|
||||||
val klassId = context.referenceClassId(klass.symbol)
|
val klassId = context.referenceClassId(klass.symbol)
|
||||||
|
|
||||||
@@ -332,7 +332,7 @@ class BodyGenerator(val context: WasmFunctionCodegenContext) : IrElementVisitorV
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun generateTypeRTT(type: IrType) {
|
private fun generateTypeRTT(type: IrType) {
|
||||||
val rtClass = type.erasedUpperBound?.symbol ?: context.backendContext.irBuiltIns.anyClass
|
val rtClass = type.getRuntimeClass?.symbol ?: context.backendContext.irBuiltIns.anyClass
|
||||||
body.buildGetGlobal(context.referenceClassRTT(rtClass))
|
body.buildGetGlobal(context.referenceClassRTT(rtClass))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+6
-3
@@ -47,7 +47,7 @@ class WasmTypeTransformer(
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun IrType.toWasmGcRefType(): WasmType =
|
fun IrType.toWasmGcRefType(): WasmType =
|
||||||
WasmRefNullType(WasmHeapType.Type(context.referenceGcType(erasedUpperBound?.symbol ?: builtIns.anyClass)))
|
WasmRefNullType(WasmHeapType.Type(context.referenceGcType(getRuntimeClass?.symbol ?: builtIns.anyClass)))
|
||||||
|
|
||||||
fun IrType.toBoxedInlineClassType(): WasmType =
|
fun IrType.toBoxedInlineClassType(): WasmType =
|
||||||
toWasmGcRefType()
|
toWasmGcRefType()
|
||||||
@@ -111,7 +111,7 @@ class WasmTypeTransformer(
|
|||||||
|
|
||||||
|
|
||||||
// Return null if upper bound is Any
|
// Return null if upper bound is Any
|
||||||
val IrTypeParameter.erasedUpperBound: IrClass?
|
private val IrTypeParameter.erasedUpperBound: IrClass?
|
||||||
get() {
|
get() {
|
||||||
// Pick the (necessarily unique) non-interface upper bound if it exists
|
// Pick the (necessarily unique) non-interface upper bound if it exists
|
||||||
for (type in superTypes) {
|
for (type in superTypes) {
|
||||||
@@ -126,7 +126,10 @@ val IrType.erasedUpperBound: IrClass?
|
|||||||
is IrClassSymbol -> classifier.owner
|
is IrClassSymbol -> classifier.owner
|
||||||
is IrTypeParameterSymbol -> classifier.owner.erasedUpperBound
|
is IrTypeParameterSymbol -> classifier.owner.erasedUpperBound
|
||||||
else -> throw IllegalStateException()
|
else -> throw IllegalStateException()
|
||||||
}.let {
|
}
|
||||||
|
|
||||||
|
val IrType.getRuntimeClass: IrClass?
|
||||||
|
get() = erasedUpperBound.let {
|
||||||
if (it?.isInterface == true) null
|
if (it?.isInterface == true) null
|
||||||
else it
|
else it
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-3
@@ -13,9 +13,8 @@ import org.jetbrains.kotlin.backend.common.lower.at
|
|||||||
import org.jetbrains.kotlin.backend.common.lower.createIrBuilder
|
import org.jetbrains.kotlin.backend.common.lower.createIrBuilder
|
||||||
import org.jetbrains.kotlin.backend.common.lower.irNot
|
import org.jetbrains.kotlin.backend.common.lower.irNot
|
||||||
import org.jetbrains.kotlin.backend.wasm.WasmBackendContext
|
import org.jetbrains.kotlin.backend.wasm.WasmBackendContext
|
||||||
import org.jetbrains.kotlin.backend.wasm.ir2wasm.erasedUpperBound
|
import org.jetbrains.kotlin.backend.wasm.ir2wasm.getRuntimeClass
|
||||||
import org.jetbrains.kotlin.ir.IrStatement
|
import org.jetbrains.kotlin.ir.IrStatement
|
||||||
import org.jetbrains.kotlin.ir.backend.js.utils.findUnitGetInstanceFunction
|
|
||||||
import org.jetbrains.kotlin.ir.builders.*
|
import org.jetbrains.kotlin.ir.builders.*
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrFile
|
import org.jetbrains.kotlin.ir.declarations.IrFile
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrTypeParameter
|
import org.jetbrains.kotlin.ir.declarations.IrTypeParameter
|
||||||
@@ -100,7 +99,7 @@ class WasmBaseTypeOperatorTransformer(val context: WasmBackendContext) : IrEleme
|
|||||||
context.inlineClassesUtils.isTypeInlined(this)
|
context.inlineClassesUtils.isTypeInlined(this)
|
||||||
|
|
||||||
private val IrType.erasedType: IrType
|
private val IrType.erasedType: IrType
|
||||||
get() = this.erasedUpperBound?.defaultType ?: builtIns.anyType
|
get() = this.getRuntimeClass?.defaultType ?: builtIns.anyType
|
||||||
|
|
||||||
private fun generateTypeCheck(
|
private fun generateTypeCheck(
|
||||||
valueProvider: () -> IrExpression,
|
valueProvider: () -> IrExpression,
|
||||||
|
|||||||
-2
@@ -1,5 +1,3 @@
|
|||||||
// DONT_TARGET_EXACT_BACKEND: WASM
|
|
||||||
// WASM_MUTE_REASON: BRIDGE_ISSUES
|
|
||||||
public open class A<T> {
|
public open class A<T> {
|
||||||
fun foo(x: T) = "O"
|
fun foo(x: T) = "O"
|
||||||
fun foo(x: A<T>) = "K"
|
fun foo(x: A<T>) = "K"
|
||||||
|
|||||||
@@ -0,0 +1,35 @@
|
|||||||
|
interface I1 {
|
||||||
|
fun o(): String
|
||||||
|
}
|
||||||
|
interface I2 {
|
||||||
|
fun k(): String
|
||||||
|
}
|
||||||
|
|
||||||
|
interface I {
|
||||||
|
fun foo(x: I1): I1
|
||||||
|
fun foo(x: I2): I2
|
||||||
|
}
|
||||||
|
|
||||||
|
open class C : I {
|
||||||
|
override fun foo(x: I1): I1 = x
|
||||||
|
override fun foo(x: I2): I2 = x
|
||||||
|
}
|
||||||
|
|
||||||
|
class C2 : C() {
|
||||||
|
override fun foo(x: I1): I1 = x
|
||||||
|
override fun foo(x: I2): I2 = x
|
||||||
|
}
|
||||||
|
|
||||||
|
fun box(): String {
|
||||||
|
val x: I = C2()
|
||||||
|
|
||||||
|
val o = x.foo(object : I1 {
|
||||||
|
override fun o(): String = "O"
|
||||||
|
}).o()
|
||||||
|
|
||||||
|
val k = x.foo(object : I2 {
|
||||||
|
override fun k(): String = "K"
|
||||||
|
}).k()
|
||||||
|
|
||||||
|
return o + k
|
||||||
|
}
|
||||||
+6
@@ -16682,6 +16682,12 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
|
|||||||
runTest("compiler/testData/codegen/box/functions/nothisnoclosure.kt");
|
runTest("compiler/testData/codegen/box/functions/nothisnoclosure.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("overloadByInterfaceType.kt")
|
||||||
|
public void testOverloadByInterfaceType() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/functions/overloadByInterfaceType.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("prefixRecursiveCall.kt")
|
@TestMetadata("prefixRecursiveCall.kt")
|
||||||
public void testPrefixRecursiveCall() throws Exception {
|
public void testPrefixRecursiveCall() throws Exception {
|
||||||
|
|||||||
+6
@@ -16802,6 +16802,12 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
|
|||||||
runTest("compiler/testData/codegen/box/functions/nothisnoclosure.kt");
|
runTest("compiler/testData/codegen/box/functions/nothisnoclosure.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("overloadByInterfaceType.kt")
|
||||||
|
public void testOverloadByInterfaceType() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/functions/overloadByInterfaceType.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("prefixRecursiveCall.kt")
|
@TestMetadata("prefixRecursiveCall.kt")
|
||||||
public void testPrefixRecursiveCall() throws Exception {
|
public void testPrefixRecursiveCall() throws Exception {
|
||||||
|
|||||||
+5
@@ -13774,6 +13774,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
|
|||||||
runTest("compiler/testData/codegen/box/functions/nothisnoclosure.kt");
|
runTest("compiler/testData/codegen/box/functions/nothisnoclosure.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("overloadByInterfaceType.kt")
|
||||||
|
public void testOverloadByInterfaceType() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/functions/overloadByInterfaceType.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("prefixRecursiveCall.kt")
|
@TestMetadata("prefixRecursiveCall.kt")
|
||||||
public void testPrefixRecursiveCall() throws Exception {
|
public void testPrefixRecursiveCall() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/functions/prefixRecursiveCall.kt");
|
runTest("compiler/testData/codegen/box/functions/prefixRecursiveCall.kt");
|
||||||
|
|||||||
js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/es6/semantics/IrJsCodegenBoxES6TestGenerated.java
Generated
+5
@@ -12153,6 +12153,11 @@ public class IrJsCodegenBoxES6TestGenerated extends AbstractIrJsCodegenBoxES6Tes
|
|||||||
runTest("compiler/testData/codegen/box/functions/nothisnoclosure.kt");
|
runTest("compiler/testData/codegen/box/functions/nothisnoclosure.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("overloadByInterfaceType.kt")
|
||||||
|
public void testOverloadByInterfaceType() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/functions/overloadByInterfaceType.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("prefixRecursiveCall.kt")
|
@TestMetadata("prefixRecursiveCall.kt")
|
||||||
public void testPrefixRecursiveCall() throws Exception {
|
public void testPrefixRecursiveCall() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/functions/prefixRecursiveCall.kt");
|
runTest("compiler/testData/codegen/box/functions/prefixRecursiveCall.kt");
|
||||||
|
|||||||
Generated
+5
@@ -11559,6 +11559,11 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest {
|
|||||||
runTest("compiler/testData/codegen/box/functions/nothisnoclosure.kt");
|
runTest("compiler/testData/codegen/box/functions/nothisnoclosure.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("overloadByInterfaceType.kt")
|
||||||
|
public void testOverloadByInterfaceType() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/functions/overloadByInterfaceType.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("prefixRecursiveCall.kt")
|
@TestMetadata("prefixRecursiveCall.kt")
|
||||||
public void testPrefixRecursiveCall() throws Exception {
|
public void testPrefixRecursiveCall() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/functions/prefixRecursiveCall.kt");
|
runTest("compiler/testData/codegen/box/functions/prefixRecursiveCall.kt");
|
||||||
|
|||||||
Generated
+5
@@ -11539,6 +11539,11 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest {
|
|||||||
runTest("compiler/testData/codegen/box/functions/nothisnoclosure.kt");
|
runTest("compiler/testData/codegen/box/functions/nothisnoclosure.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("overloadByInterfaceType.kt")
|
||||||
|
public void testOverloadByInterfaceType() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/functions/overloadByInterfaceType.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("prefixRecursiveCall.kt")
|
@TestMetadata("prefixRecursiveCall.kt")
|
||||||
public void testPrefixRecursiveCall() throws Exception {
|
public void testPrefixRecursiveCall() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/functions/prefixRecursiveCall.kt");
|
runTest("compiler/testData/codegen/box/functions/prefixRecursiveCall.kt");
|
||||||
|
|||||||
js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/wasm/semantics/IrCodegenBoxWasmTestGenerated.java
Generated
+10
@@ -1295,6 +1295,11 @@ public class IrCodegenBoxWasmTestGenerated extends AbstractIrCodegenBoxWasmTest
|
|||||||
runTest("compiler/testData/codegen/box/bridges/substitutionInSuperClass/differentErasureInSuperClass.kt");
|
runTest("compiler/testData/codegen/box/bridges/substitutionInSuperClass/differentErasureInSuperClass.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("differentErasureInSuperClassComplex.kt")
|
||||||
|
public void testDifferentErasureInSuperClassComplex() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/bridges/substitutionInSuperClass/differentErasureInSuperClassComplex.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("enum.kt")
|
@TestMetadata("enum.kt")
|
||||||
public void testEnum() throws Exception {
|
public void testEnum() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/bridges/substitutionInSuperClass/enum.kt");
|
runTest("compiler/testData/codegen/box/bridges/substitutionInSuperClass/enum.kt");
|
||||||
@@ -6628,6 +6633,11 @@ public class IrCodegenBoxWasmTestGenerated extends AbstractIrCodegenBoxWasmTest
|
|||||||
runTest("compiler/testData/codegen/box/functions/nothisnoclosure.kt");
|
runTest("compiler/testData/codegen/box/functions/nothisnoclosure.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("overloadByInterfaceType.kt")
|
||||||
|
public void testOverloadByInterfaceType() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/functions/overloadByInterfaceType.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("prefixRecursiveCall.kt")
|
@TestMetadata("prefixRecursiveCall.kt")
|
||||||
public void testPrefixRecursiveCall() throws Exception {
|
public void testPrefixRecursiveCall() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/functions/prefixRecursiveCall.kt");
|
runTest("compiler/testData/codegen/box/functions/prefixRecursiveCall.kt");
|
||||||
|
|||||||
Reference in New Issue
Block a user