Support varargs of inline class types with non-trivial spread
#KT-24880 In Progress
This commit is contained in:
@@ -2898,6 +2898,18 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
KotlinType argumentKotlinType = kotlinType(argumentExpression);
|
||||
if (argument.getSpreadElement() != null) {
|
||||
gen(argumentExpression, OBJECT_TYPE, argumentKotlinType);
|
||||
|
||||
if (argumentKotlinType != null && InlineClassesUtilsKt.isInlineClassType(argumentKotlinType)) {
|
||||
// we're going to pass value of inline class type to j/l/Object, which would result in boxing and then
|
||||
// will cause check cast error on toArray() call. To mitigate this problem, we unbox this value and pass
|
||||
// primitive array to the method. Note that bytecode optimisations will remove box/unbox calls.
|
||||
StackValue.coerce(
|
||||
OBJECT_TYPE, argumentKotlinType,
|
||||
asmType(argumentKotlinType), argumentKotlinType,
|
||||
v
|
||||
);
|
||||
}
|
||||
|
||||
v.invokevirtual(owner, "addSpread", "(Ljava/lang/Object;)V", false);
|
||||
}
|
||||
else {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
// !LANGUAGE: +InlineClasses
|
||||
// !SKIP_METADATA_VERSION_CHECK
|
||||
// WITH_UNSIGNED
|
||||
// IGNORE_BACKEND: JS, JS_IR
|
||||
|
||||
fun uint(vararg us: UInt): UIntArray = us
|
||||
|
||||
@@ -15,11 +16,17 @@ fun box(): String {
|
||||
val uints = uint(1u, 2u, 3u)
|
||||
if (sum(*uints) != 6u) return "Fail 1"
|
||||
|
||||
val complextUInts = uint(4u, *uints, 5u, *uints, 6u)
|
||||
if (sum(*complextUInts) != 27u) return "Fail 2"
|
||||
|
||||
val nullableUInts = nullableUInt(1u, null, 2u, null)
|
||||
if (sum(*nullableUInts) != 3u) return "Fail 2"
|
||||
if (sum(*nullableUInts) != 3u) return "Fail 3"
|
||||
|
||||
val inlinedUInts = inlinedUInt(1u, 3u)
|
||||
if (sum(*inlinedUInts) != 4u) return "Fail 3"
|
||||
if (sum(*inlinedUInts) != 4u) return "Fail 4"
|
||||
|
||||
val complexInlinedUInts = inlinedUInt(*inlinedUInts, 3u, *inlinedUInts)
|
||||
if (sum(*complexInlinedUInts) != 11u) return "Fail 5"
|
||||
|
||||
return "OK"
|
||||
}
|
||||
|
||||
Vendored
+27
@@ -0,0 +1,27 @@
|
||||
// !LANGUAGE: +InlineClasses
|
||||
// !WITH_UNSIGNED
|
||||
// !SKIP_METADATA_VERSION_CHECK
|
||||
|
||||
fun uint(vararg us: UInt): UIntArray = us
|
||||
|
||||
// FILE: NoBoxing.kt
|
||||
|
||||
fun test1(us: UIntArray) {
|
||||
uint(1u, *us, 2u, *us)
|
||||
}
|
||||
|
||||
// @NoBoxingKt.class:
|
||||
// 0 INVOKESTATIC kotlin.UInt\$Erased.box
|
||||
// 0 INVOKEVIRTUAL kotlin.UInt.unbox
|
||||
|
||||
// FILE: Boxing.kt
|
||||
|
||||
fun nullableUInt(vararg us: UInt?) {}
|
||||
|
||||
fun test2(nullable: UInt?, ns: Array<UInt>) {
|
||||
nullableUInt(1u, nullable, 3u, *ns)
|
||||
}
|
||||
|
||||
// @BoxingKt.class:
|
||||
// 2 INVOKESTATIC kotlin.UInt\$Erased.box
|
||||
// 0 INVOKEVIRTUAL kotlin.UInt.unbox
|
||||
@@ -2080,6 +2080,11 @@ public class BytecodeTextTestGenerated extends AbstractBytecodeTextTest {
|
||||
runTest("compiler/testData/codegen/bytecodeText/inlineClasses/noAssertionsForInlineClassesBasedOnNullableTypes.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("noBoxingOperationsOnNonTrivialSpread.kt")
|
||||
public void testNoBoxingOperationsOnNonTrivialSpread() throws Exception {
|
||||
runTest("compiler/testData/codegen/bytecodeText/inlineClasses/noBoxingOperationsOnNonTrivialSpread.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("passInlineClassesWithSpreadOperatorToVarargs.kt")
|
||||
public void testPassInlineClassesWithSpreadOperatorToVarargs() throws Exception {
|
||||
runTest("compiler/testData/codegen/bytecodeText/inlineClasses/passInlineClassesWithSpreadOperatorToVarargs.kt");
|
||||
|
||||
Reference in New Issue
Block a user