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);
|
KotlinType argumentKotlinType = kotlinType(argumentExpression);
|
||||||
if (argument.getSpreadElement() != null) {
|
if (argument.getSpreadElement() != null) {
|
||||||
gen(argumentExpression, OBJECT_TYPE, argumentKotlinType);
|
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);
|
v.invokevirtual(owner, "addSpread", "(Ljava/lang/Object;)V", false);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
// !LANGUAGE: +InlineClasses
|
// !LANGUAGE: +InlineClasses
|
||||||
// !SKIP_METADATA_VERSION_CHECK
|
// !SKIP_METADATA_VERSION_CHECK
|
||||||
// WITH_UNSIGNED
|
// WITH_UNSIGNED
|
||||||
|
// IGNORE_BACKEND: JS, JS_IR
|
||||||
|
|
||||||
fun uint(vararg us: UInt): UIntArray = us
|
fun uint(vararg us: UInt): UIntArray = us
|
||||||
|
|
||||||
@@ -15,11 +16,17 @@ fun box(): String {
|
|||||||
val uints = uint(1u, 2u, 3u)
|
val uints = uint(1u, 2u, 3u)
|
||||||
if (sum(*uints) != 6u) return "Fail 1"
|
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)
|
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)
|
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"
|
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");
|
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")
|
@TestMetadata("passInlineClassesWithSpreadOperatorToVarargs.kt")
|
||||||
public void testPassInlineClassesWithSpreadOperatorToVarargs() throws Exception {
|
public void testPassInlineClassesWithSpreadOperatorToVarargs() throws Exception {
|
||||||
runTest("compiler/testData/codegen/bytecodeText/inlineClasses/passInlineClassesWithSpreadOperatorToVarargs.kt");
|
runTest("compiler/testData/codegen/bytecodeText/inlineClasses/passInlineClassesWithSpreadOperatorToVarargs.kt");
|
||||||
|
|||||||
Reference in New Issue
Block a user