Reflection: fix callBy for functions with 32 * N parameters
Optimization in 2439c22ff6 introduced an array `absentArguments` with
default values of all parameter types, which is copied in `callBy`
instead of being recomputed each time. Unfortunately, its size was
computed incorrectly: `maskSize` should only take into account
value parameters (see the `parameter.kind == KParameter.Kind.VALUE`
check in `callBy`).
This led to an issue where if the function had 32 * N value parameters
and 1 receiver parameter, `maskSize` was greater by 1 than expected,
which caused an exception due to mismatching argument array sizes.
#KT-61304 Fixed
This commit is contained in:
committed by
Space Team
parent
421cd9929b
commit
34f52aaeda
+12
@@ -45042,6 +45042,12 @@ public class FirLightTreeBlackBoxCodegenTestGenerated extends AbstractFirLightTr
|
||||
runTest("compiler/testData/codegen/box/reflection/callBy/jvmStaticInObject.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("kt61304.kt")
|
||||
public void testKt61304() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/reflection/callBy/kt61304.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("manyArgumentsNoneDefaultConstructor.kt")
|
||||
public void testManyArgumentsNoneDefaultConstructor() throws Exception {
|
||||
@@ -45078,6 +45084,12 @@ public class FirLightTreeBlackBoxCodegenTestGenerated extends AbstractFirLightTr
|
||||
runTest("compiler/testData/codegen/box/reflection/callBy/mfvcFunctionsAndConstructors.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("mfvcKt61304.kt")
|
||||
public void testMfvcKt61304() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/reflection/callBy/mfvcKt61304.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("mfvcMembers.kt")
|
||||
public void testMfvcMembers() throws Exception {
|
||||
|
||||
+12
@@ -45042,6 +45042,12 @@ public class FirLightTreeBlackBoxCodegenWithIrFakeOverrideGeneratorTestGenerated
|
||||
runTest("compiler/testData/codegen/box/reflection/callBy/jvmStaticInObject.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("kt61304.kt")
|
||||
public void testKt61304() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/reflection/callBy/kt61304.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("manyArgumentsNoneDefaultConstructor.kt")
|
||||
public void testManyArgumentsNoneDefaultConstructor() throws Exception {
|
||||
@@ -45078,6 +45084,12 @@ public class FirLightTreeBlackBoxCodegenWithIrFakeOverrideGeneratorTestGenerated
|
||||
runTest("compiler/testData/codegen/box/reflection/callBy/mfvcFunctionsAndConstructors.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("mfvcKt61304.kt")
|
||||
public void testMfvcKt61304() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/reflection/callBy/mfvcKt61304.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("mfvcMembers.kt")
|
||||
public void testMfvcMembers() throws Exception {
|
||||
|
||||
+12
@@ -45042,6 +45042,12 @@ public class FirPsiBlackBoxCodegenTestGenerated extends AbstractFirPsiBlackBoxCo
|
||||
runTest("compiler/testData/codegen/box/reflection/callBy/jvmStaticInObject.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("kt61304.kt")
|
||||
public void testKt61304() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/reflection/callBy/kt61304.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("manyArgumentsNoneDefaultConstructor.kt")
|
||||
public void testManyArgumentsNoneDefaultConstructor() throws Exception {
|
||||
@@ -45078,6 +45084,12 @@ public class FirPsiBlackBoxCodegenTestGenerated extends AbstractFirPsiBlackBoxCo
|
||||
runTest("compiler/testData/codegen/box/reflection/callBy/mfvcFunctionsAndConstructors.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("mfvcKt61304.kt")
|
||||
public void testMfvcKt61304() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/reflection/callBy/mfvcKt61304.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("mfvcMembers.kt")
|
||||
public void testMfvcMembers() throws Exception {
|
||||
|
||||
@@ -0,0 +1,81 @@
|
||||
// TARGET_BACKEND: JVM
|
||||
// WITH_REFLECT
|
||||
|
||||
import kotlin.reflect.full.instanceParameter
|
||||
import kotlin.reflect.full.memberFunctions
|
||||
|
||||
data class DataCopyBug(
|
||||
val f01: Int = 0,
|
||||
val f02: Int = 0,
|
||||
val f03: Int = 0,
|
||||
val f04: Int = 0,
|
||||
val f05: Int = 0,
|
||||
val f06: Int = 0,
|
||||
val f07: Int = 0,
|
||||
val f08: Int = 0,
|
||||
val f09: Int = 0,
|
||||
val f10: Int = 0,
|
||||
val f11: Int = 0,
|
||||
val f12: Int = 0,
|
||||
val f13: Int = 0,
|
||||
val f14: Int = 0,
|
||||
val f15: Int = 0,
|
||||
val f16: Int = 0,
|
||||
val f17: Int = 0,
|
||||
val f18: Int = 0,
|
||||
val f19: Int = 0,
|
||||
val f20: Int = 0,
|
||||
val f21: Int = 0,
|
||||
val f22: Int = 0,
|
||||
val f23: Int = 0,
|
||||
val f24: Int = 0,
|
||||
val f25: Int = 0,
|
||||
val f26: Int = 0,
|
||||
val f27: Int = 0,
|
||||
val f28: Int = 0,
|
||||
val f29: Int = 0,
|
||||
val f30: Int = 0,
|
||||
val f31: Int = 0,
|
||||
val f32: Int = 0,
|
||||
val f33: Int = 0,
|
||||
val f34: Int = 0,
|
||||
val f35: Int = 0,
|
||||
val f36: Int = 0,
|
||||
val f37: Int = 0,
|
||||
val f38: Int = 0,
|
||||
val f39: Int = 0,
|
||||
val f40: Int = 0,
|
||||
val f41: Int = 0,
|
||||
val f42: String = "Fail",
|
||||
val f43: Int = 0,
|
||||
val f44: Int = 0,
|
||||
val f45: Int = 0,
|
||||
val f46: Int = 0,
|
||||
val f47: Int = 0,
|
||||
val f48: Int = 0,
|
||||
val f49: Int = 0,
|
||||
val f50: Int = 0,
|
||||
val f51: Int = 0,
|
||||
val f52: Int = 0,
|
||||
val f53: Int = 0,
|
||||
val f54: Int = 0,
|
||||
val f55: Int = 0,
|
||||
val f56: Int = 0,
|
||||
val f57: Int = 0,
|
||||
val f58: Int = 0,
|
||||
val f59: Int = 0,
|
||||
val f60: Int = 0,
|
||||
val f61: Int = 0,
|
||||
val f62: Int = 0,
|
||||
val f63: Int = 0,
|
||||
val f64: Int = 0,
|
||||
)
|
||||
|
||||
fun box(): String {
|
||||
val copyFun = DataCopyBug::class.memberFunctions.single { it.name == "copy" }
|
||||
val result = copyFun.callBy(mapOf(
|
||||
copyFun.instanceParameter!! to DataCopyBug(),
|
||||
copyFun.parameters.single { it.name == "f42" } to "OK",
|
||||
))
|
||||
return (result as DataCopyBug).f42
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
// TARGET_BACKEND: JVM_IR
|
||||
// WITH_REFLECT
|
||||
// LANGUAGE: +ValueClasses
|
||||
|
||||
import kotlin.reflect.full.instanceParameter
|
||||
import kotlin.reflect.full.memberFunctions
|
||||
|
||||
@JvmInline
|
||||
value class S2(val x: Int, val y: Int)
|
||||
@JvmInline
|
||||
value class S4(val x: S2, val y: S2)
|
||||
@JvmInline
|
||||
value class S8(val x: S4, val y: S4)
|
||||
@JvmInline
|
||||
value class S16(val x: S8, val y: S8)
|
||||
@JvmInline
|
||||
value class S32(val x: S16, val y: S16)
|
||||
@JvmInline
|
||||
value class S64(val x: S32, val y: S32)
|
||||
|
||||
data class D(val s: S64 = createS64())
|
||||
|
||||
fun createS64(): S64 {
|
||||
val s2 = S2(0, 0)
|
||||
val s4 = S4(s2, s2)
|
||||
val s8 = S8(s4, s4)
|
||||
val s16 = S16(s8, s8)
|
||||
val s32 = S32(s16, s16)
|
||||
return S64(s32, s32)
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
val copyFun = D::class.memberFunctions.single { it.name == "copy" }
|
||||
copyFun.callBy(mapOf(copyFun.instanceParameter!! to D()))
|
||||
return "OK"
|
||||
}
|
||||
+6
@@ -42324,6 +42324,12 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
|
||||
runTest("compiler/testData/codegen/box/reflection/callBy/jvmStaticInObject.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("kt61304.kt")
|
||||
public void testKt61304() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/reflection/callBy/kt61304.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("manyArgumentsNoneDefaultConstructor.kt")
|
||||
public void testManyArgumentsNoneDefaultConstructor() throws Exception {
|
||||
|
||||
+12
@@ -45042,6 +45042,12 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
|
||||
runTest("compiler/testData/codegen/box/reflection/callBy/jvmStaticInObject.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("kt61304.kt")
|
||||
public void testKt61304() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/reflection/callBy/kt61304.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("manyArgumentsNoneDefaultConstructor.kt")
|
||||
public void testManyArgumentsNoneDefaultConstructor() throws Exception {
|
||||
@@ -45078,6 +45084,12 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
|
||||
runTest("compiler/testData/codegen/box/reflection/callBy/mfvcFunctionsAndConstructors.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("mfvcKt61304.kt")
|
||||
public void testMfvcKt61304() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/reflection/callBy/mfvcKt61304.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("mfvcMembers.kt")
|
||||
public void testMfvcMembers() throws Exception {
|
||||
|
||||
+12
@@ -45042,6 +45042,12 @@ public class IrBlackBoxCodegenWithIrInlinerTestGenerated extends AbstractIrBlack
|
||||
runTest("compiler/testData/codegen/box/reflection/callBy/jvmStaticInObject.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("kt61304.kt")
|
||||
public void testKt61304() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/reflection/callBy/kt61304.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("manyArgumentsNoneDefaultConstructor.kt")
|
||||
public void testManyArgumentsNoneDefaultConstructor() throws Exception {
|
||||
@@ -45078,6 +45084,12 @@ public class IrBlackBoxCodegenWithIrInlinerTestGenerated extends AbstractIrBlack
|
||||
runTest("compiler/testData/codegen/box/reflection/callBy/mfvcFunctionsAndConstructors.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("mfvcKt61304.kt")
|
||||
public void testMfvcKt61304() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/reflection/callBy/mfvcKt61304.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("mfvcMembers.kt")
|
||||
public void testMfvcMembers() throws Exception {
|
||||
|
||||
+10
@@ -35784,6 +35784,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
|
||||
runTest("compiler/testData/codegen/box/reflection/callBy/jvmStaticInObject.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("kt61304.kt")
|
||||
public void testKt61304() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/reflection/callBy/kt61304.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("manyArgumentsNoneDefaultConstructor.kt")
|
||||
public void testManyArgumentsNoneDefaultConstructor() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/reflection/callBy/manyArgumentsNoneDefaultConstructor.kt");
|
||||
@@ -35814,6 +35819,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
|
||||
runTest("compiler/testData/codegen/box/reflection/callBy/mfvcFunctionsAndConstructors.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("mfvcKt61304.kt")
|
||||
public void testMfvcKt61304() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/reflection/callBy/mfvcKt61304.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("mfvcMembers.kt")
|
||||
public void testMfvcMembers() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/reflection/callBy/mfvcMembers.kt");
|
||||
|
||||
@@ -113,9 +113,16 @@ internal abstract class KCallableImpl<out R> : KCallable<R>, KTypeParameterOwner
|
||||
}
|
||||
|
||||
private val _absentArguments = ReflectProperties.lazySoft {
|
||||
val parameters = parameters
|
||||
val parameterSize = parameters.size + (if (isSuspend) 1 else 0)
|
||||
val flattenedParametersSize =
|
||||
if (parametersNeedMFVCFlattening.value) parameters.sumOf { getParameterTypeSize(it) } else parameters.size
|
||||
if (parametersNeedMFVCFlattening.value) {
|
||||
parameters.sumOf {
|
||||
if (it.kind == KParameter.Kind.VALUE) getParameterTypeSize(it) else 0
|
||||
}
|
||||
} else {
|
||||
parameters.count { it.kind == KParameter.Kind.VALUE }
|
||||
}
|
||||
val maskSize = (flattenedParametersSize + Integer.SIZE - 1) / Integer.SIZE
|
||||
|
||||
// Array containing the actual function arguments, masks, and +1 for DefaultConstructorMarker or MethodHandle.
|
||||
|
||||
Reference in New Issue
Block a user