JVM_IR KT-46408 properly map fake overrides in method handles

This commit is contained in:
Dmitry Petrov
2021-04-30 13:24:40 +03:00
committed by TeamCityServer
parent ef2c2c2c9e
commit 83e3a702c5
7 changed files with 82 additions and 2 deletions
@@ -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 {
@@ -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
@@ -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)
}
@@ -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);
}
@@ -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 {
@@ -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 {
@@ -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");