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");
|
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
|
@Test
|
||||||
@TestMetadata("localFunction1.kt")
|
@TestMetadata("localFunction1.kt")
|
||||||
public void testLocalFunction1() throws Exception {
|
public void testLocalFunction1() throws Exception {
|
||||||
|
|||||||
+1
-1
@@ -438,7 +438,7 @@ class MethodSignatureMapper(private val context: JvmBackendContext) {
|
|||||||
mapAsmMethod(findSuperDeclaration(function, isSuperCall))
|
mapAsmMethod(findSuperDeclaration(function, isSuperCall))
|
||||||
|
|
||||||
// Copied from KotlinTypeMapper.findSuperDeclaration.
|
// Copied from KotlinTypeMapper.findSuperDeclaration.
|
||||||
private fun findSuperDeclaration(function: IrSimpleFunction, isSuperCall: Boolean): IrSimpleFunction {
|
internal fun findSuperDeclaration(function: IrSimpleFunction, isSuperCall: Boolean): IrSimpleFunction {
|
||||||
var current = function
|
var current = function
|
||||||
while (current.isFakeOverride) {
|
while (current.isFakeOverride) {
|
||||||
// TODO: probably isJvmInterface instead of isInterface, here and in KotlinTypeMapper
|
// 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 {
|
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
|
val irParentClass = irFun.parent as? IrClass
|
||||||
?: throw AssertionError("Unexpected parent: ${irFun.parent.render()}")
|
?: throw AssertionError("Unexpected parent: ${irFun.parent.render()}")
|
||||||
val owner = codegen.typeMapper.mapOwner(irParentClass)
|
val owner = codegen.typeMapper.mapOwner(irParentClass)
|
||||||
|
|
||||||
val asmMethod = codegen.methodSignatureMapper.mapAsmMethod(irFun)
|
val asmMethod = codegen.methodSignatureMapper.mapAsmMethod(irFun)
|
||||||
|
|
||||||
val handleTag = when {
|
val handleTag = when {
|
||||||
irFun is IrConstructor ->
|
irFun is IrConstructor ->
|
||||||
Opcodes.H_NEWINVOKESPECIAL
|
Opcodes.H_NEWINVOKESPECIAL
|
||||||
@@ -116,6 +129,7 @@ object JvmInvokeDynamic : IntrinsicMethod() {
|
|||||||
else ->
|
else ->
|
||||||
Opcodes.H_INVOKEVIRTUAL
|
Opcodes.H_INVOKEVIRTUAL
|
||||||
}
|
}
|
||||||
|
|
||||||
return Handle(handleTag, owner.internalName, asmMethod.name, asmMethod.descriptor, irParentClass.isJvmInterface)
|
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");
|
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
|
@Test
|
||||||
@TestMetadata("localFunction1.kt")
|
@TestMetadata("localFunction1.kt")
|
||||||
public void testLocalFunction1() throws Exception {
|
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");
|
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
|
@Test
|
||||||
@TestMetadata("localFunction1.kt")
|
@TestMetadata("localFunction1.kt")
|
||||||
public void testLocalFunction1() throws Exception {
|
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");
|
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")
|
@TestMetadata("localFunction1.kt")
|
||||||
public void testLocalFunction1() throws Exception {
|
public void testLocalFunction1() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/invokedynamic/sam/functionRefToJavaInterface/localFunction1.kt");
|
runTest("compiler/testData/codegen/box/invokedynamic/sam/functionRefToJavaInterface/localFunction1.kt");
|
||||||
|
|||||||
Reference in New Issue
Block a user