diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/FunctionReferenceLowering.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/FunctionReferenceLowering.kt index b04375dce84..3775761ab7d 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/FunctionReferenceLowering.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/FunctionReferenceLowering.kt @@ -91,7 +91,7 @@ internal class FunctionReferenceLowering(private val context: JvmBackendContext) expression.statements.dropLast(1).forEach { it.transform(this, null) } reference.transformChildrenVoid(this) - if (shouldGenerateIndyLambdas && canUseIndySamConversion(reference, reference.type)) { + if (shouldGenerateIndyLambdas && canUseIndySamConversion(reference, reference.type, true)) { return wrapLambdaReferenceWithIndySamConversion(expression, reference) } @@ -139,14 +139,14 @@ internal class FunctionReferenceLowering(private val context: JvmBackendContext) reference.transformChildrenVoid() val samSuperType = expression.typeOperand - return if (shouldGenerateIndySamConversions && canUseIndySamConversion(reference, samSuperType)) { + return if (shouldGenerateIndySamConversions && canUseIndySamConversion(reference, samSuperType, false)) { wrapSamConversionArgumentWithIndySamConversion(expression) } else { FunctionReferenceBuilder(reference, samSuperType).build() } } - private fun canUseIndySamConversion(reference: IrFunctionReference, samSuperType: IrType): Boolean { + private fun canUseIndySamConversion(reference: IrFunctionReference, samSuperType: IrType, plainLambda: Boolean): Boolean { // Can't use JDK LambdaMetafactory for function references by default (because of 'equals'). // TODO special mode that would generate indy everywhere? if (reference.origin != IrStatementOrigin.LAMBDA) @@ -168,6 +168,13 @@ internal class FunctionReferenceLowering(private val context: JvmBackendContext) ) return false + if (plainLambda) { + var parametersCount = target.valueParameters.size + if (target.extensionReceiverParameter != null) ++parametersCount + if (parametersCount > 22) + return false + } + // Can't use indy-based SAM conversion inside inline fun (Ok in inline lambda). if (target.parents.any { it.isInlineFunction() || it.isCrossinlineLambda() }) return false diff --git a/compiler/testData/codegen/box/invokedynamic/lambdas/bigArityFun.kt b/compiler/testData/codegen/box/invokedynamic/lambdas/bigArityFun.kt new file mode 100644 index 00000000000..28f212bd5fb --- /dev/null +++ b/compiler/testData/codegen/box/invokedynamic/lambdas/bigArityFun.kt @@ -0,0 +1,13 @@ +// TARGET_BACKEND: JVM +// IGNORE_LIGHT_ANALYSIS +// JVM_TARGET: 1.8 +// LAMBDAS: INDY + +fun box() = + { p0: String, p1: String, p2: Int, p3: Int, p4: Int, p5: Int, p6: Int, p7: Int, p8: Int, p9: Int, + p10: Int, p11: Int, p12: Int, p13: Int, p14: Int, p15: Int, p16: Int, p17: Int, p18: Int, p19: Int, + p20: Int, p21: Int, p22: Int, p23: Int, p24: Int, p25: Int, p26: Int, p27: Int, p28: Int, p29: Int + -> p0 + p1 + }( + "O", "K", 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29 + ) \ No newline at end of file diff --git a/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java b/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java index 3a4d748d9e1..aaabfa278ce 100644 --- a/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java +++ b/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java @@ -16191,6 +16191,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/invokedynamic/lambdas"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM, true); } + @TestMetadata("bigArityFun.kt") + public void testBigArityFun() throws Exception { + runTest("compiler/testData/codegen/box/invokedynamic/lambdas/bigArityFun.kt"); + } + @TestMetadata("capturedDispatchReceiver.kt") public void testCapturedDispatchReceiver() throws Exception { runTest("compiler/testData/codegen/box/invokedynamic/lambdas/capturedDispatchReceiver.kt");