JVM_IR KT-46408 properly map fake overrides in method handles
This commit is contained in:
committed by
TeamCityServer
parent
ef2c2c2c9e
commit
83e3a702c5
+6
@@ -21070,6 +21070,12 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
|
||||
runTest("compiler/testData/codegen/box/invokedynamic/sam/functionRefToJavaInterface/kt45581.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("kt46408.kt")
|
||||
public void testKt46408() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/invokedynamic/sam/functionRefToJavaInterface/kt46408.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("localFunction1.kt")
|
||||
public void testLocalFunction1() throws Exception {
|
||||
|
||||
+1
-1
@@ -438,7 +438,7 @@ class MethodSignatureMapper(private val context: JvmBackendContext) {
|
||||
mapAsmMethod(findSuperDeclaration(function, isSuperCall))
|
||||
|
||||
// Copied from KotlinTypeMapper.findSuperDeclaration.
|
||||
private fun findSuperDeclaration(function: IrSimpleFunction, isSuperCall: Boolean): IrSimpleFunction {
|
||||
internal fun findSuperDeclaration(function: IrSimpleFunction, isSuperCall: Boolean): IrSimpleFunction {
|
||||
var current = function
|
||||
while (current.isFakeOverride) {
|
||||
// TODO: probably isJvmInterface instead of isInterface, here and in KotlinTypeMapper
|
||||
|
||||
+15
-1
@@ -101,11 +101,24 @@ object JvmInvokeDynamic : IntrinsicMethod() {
|
||||
}
|
||||
|
||||
private fun generateMethodHandle(irRawFunctionReference: IrRawFunctionReference, codegen: ExpressionCodegen): Handle {
|
||||
val irFun = irRawFunctionReference.symbol.owner
|
||||
val irFun = when (val irFun0 = irRawFunctionReference.symbol.owner) {
|
||||
is IrConstructor ->
|
||||
irFun0
|
||||
is IrSimpleFunction -> {
|
||||
// Note that if the given function is a fake override, we emit a method handle with explicit super class.
|
||||
// This has the same binary compatibility guarantees as in Java.
|
||||
codegen.methodSignatureMapper.findSuperDeclaration(irFun0, false)
|
||||
}
|
||||
else ->
|
||||
throw java.lang.AssertionError("Simple function or constructor expected: ${irFun0.render()}")
|
||||
}
|
||||
|
||||
val irParentClass = irFun.parent as? IrClass
|
||||
?: throw AssertionError("Unexpected parent: ${irFun.parent.render()}")
|
||||
val owner = codegen.typeMapper.mapOwner(irParentClass)
|
||||
|
||||
val asmMethod = codegen.methodSignatureMapper.mapAsmMethod(irFun)
|
||||
|
||||
val handleTag = when {
|
||||
irFun is IrConstructor ->
|
||||
Opcodes.H_NEWINVOKESPECIAL
|
||||
@@ -116,6 +129,7 @@ object JvmInvokeDynamic : IntrinsicMethod() {
|
||||
else ->
|
||||
Opcodes.H_INVOKEVIRTUAL
|
||||
}
|
||||
|
||||
return Handle(handleTag, owner.internalName, asmMethod.name, asmMethod.descriptor, irParentClass.isJvmInterface)
|
||||
}
|
||||
|
||||
|
||||
+43
@@ -0,0 +1,43 @@
|
||||
// TARGET_BACKEND: JVM
|
||||
// JVM_TARGET: 1.8
|
||||
// SAM_CONVERSIONS: INDY
|
||||
|
||||
// FILE: kt46408.kt
|
||||
|
||||
open class User<IT : Identity> {
|
||||
protected fun processIdentity(identity: IT) {
|
||||
identity.ok = "OK"
|
||||
}
|
||||
}
|
||||
|
||||
class UserAc : User<AcIdentity>() {
|
||||
fun doStuff(data: Container) {
|
||||
data.processEachWith(this::processIdentity)
|
||||
}
|
||||
}
|
||||
|
||||
interface Identity {
|
||||
var ok: String
|
||||
}
|
||||
|
||||
class AcIdentity(override var ok: String) : Identity
|
||||
|
||||
class Container {
|
||||
var id = AcIdentity("xxx")
|
||||
|
||||
fun processEachWith(action: Action<AcIdentity>) {
|
||||
action.execute(id)
|
||||
}
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
val c = Container()
|
||||
UserAc().doStuff(c)
|
||||
return c.id.ok
|
||||
}
|
||||
|
||||
// FILE: Action.java
|
||||
|
||||
public interface Action<T> {
|
||||
void execute(T var1);
|
||||
}
|
||||
+6
@@ -21046,6 +21046,12 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
|
||||
runTest("compiler/testData/codegen/box/invokedynamic/sam/functionRefToJavaInterface/kt45581.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("kt46408.kt")
|
||||
public void testKt46408() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/invokedynamic/sam/functionRefToJavaInterface/kt46408.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("localFunction1.kt")
|
||||
public void testLocalFunction1() throws Exception {
|
||||
|
||||
+6
@@ -21070,6 +21070,12 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
|
||||
runTest("compiler/testData/codegen/box/invokedynamic/sam/functionRefToJavaInterface/kt45581.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("kt46408.kt")
|
||||
public void testKt46408() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/invokedynamic/sam/functionRefToJavaInterface/kt46408.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("localFunction1.kt")
|
||||
public void testLocalFunction1() throws Exception {
|
||||
|
||||
+5
@@ -17598,6 +17598,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
|
||||
runTest("compiler/testData/codegen/box/invokedynamic/sam/functionRefToJavaInterface/kt45581.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("kt46408.kt")
|
||||
public void testKt46408() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/invokedynamic/sam/functionRefToJavaInterface/kt46408.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("localFunction1.kt")
|
||||
public void testLocalFunction1() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/invokedynamic/sam/functionRefToJavaInterface/localFunction1.kt");
|
||||
|
||||
Reference in New Issue
Block a user