Box values of inline class types when passing to function as varargs
This commit is contained in:
@@ -2832,13 +2832,16 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
}
|
||||
}
|
||||
else {
|
||||
return StackValue.operation(type, adapter -> {
|
||||
return StackValue.operation(type, outType, adapter -> {
|
||||
v.iconst(arguments.size());
|
||||
newArrayInstruction(outType);
|
||||
KotlinType elementKotlinType = outType.getConstructor().getBuiltIns().getArrayElementType(outType);
|
||||
for (int i = 0; i != size; ++i) {
|
||||
v.dup();
|
||||
StackValue rightSide = gen(arguments.get(i).getArgumentExpression());
|
||||
StackValue.arrayElement(elementType, StackValue.onStack(type), StackValue.constant(i, Type.INT_TYPE)).store(rightSide, v);
|
||||
StackValue
|
||||
.arrayElement(elementType, elementKotlinType, StackValue.onStack(type, outType), StackValue.constant(i, Type.INT_TYPE))
|
||||
.store(rightSide, v);
|
||||
}
|
||||
return Unit.INSTANCE;
|
||||
});
|
||||
@@ -4056,7 +4059,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
elementJetType,
|
||||
ReifiedTypeInliner.OperationKind.NEW_ARRAY
|
||||
);
|
||||
v.newarray(boxType(asmType(elementJetType)));
|
||||
v.newarray(boxType(typeMapper.mapTypeAsDeclaration(elementJetType)));
|
||||
}
|
||||
else {
|
||||
Type type = typeMapper.mapType(arrayType);
|
||||
@@ -4089,7 +4092,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
StackValue arrayValue = genLazy(array, arrayType);
|
||||
StackValue index = genLazy(indices.get(0), Type.INT_TYPE);
|
||||
|
||||
return StackValue.arrayElement(elementType, arrayValue, index);
|
||||
return StackValue.arrayElement(elementType, null, arrayValue, index);
|
||||
}
|
||||
else {
|
||||
ResolvedCall<FunctionDescriptor> resolvedSetCall = bindingContext.get(INDEXED_LVALUE_SET, expression);
|
||||
|
||||
@@ -584,7 +584,7 @@ public class PropertyCodegen {
|
||||
StackValue.Field array = StackValue.field(
|
||||
Type.getType("[" + K_PROPERTY_TYPE), owner, JvmAbi.DELEGATED_PROPERTIES_ARRAY_NAME, true, StackValue.none()
|
||||
);
|
||||
return StackValue.arrayElement(K_PROPERTY_TYPE, array, StackValue.constant(index, Type.INT_TYPE));
|
||||
return StackValue.arrayElement(K_PROPERTY_TYPE, null, array, StackValue.constant(index, Type.INT_TYPE));
|
||||
}
|
||||
|
||||
private static class DelegatedPropertyAccessorStrategy extends FunctionGenerationStrategy.CodegenBased {
|
||||
|
||||
@@ -279,8 +279,8 @@ public abstract class StackValue {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static StackValue arrayElement(@NotNull Type type, StackValue array, StackValue index) {
|
||||
return new ArrayElement(type, array, index);
|
||||
public static StackValue arrayElement(@NotNull Type type, @Nullable KotlinType kotlinType, StackValue array, StackValue index) {
|
||||
return new ArrayElement(type, kotlinType, array, index);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -1004,8 +1004,8 @@ public abstract class StackValue {
|
||||
private static class ArrayElement extends StackValueWithSimpleReceiver {
|
||||
private final Type type;
|
||||
|
||||
public ArrayElement(Type type, StackValue array, StackValue index) {
|
||||
super(type, null, false, false, new Receiver(Type.LONG_TYPE, array, index), true);
|
||||
public ArrayElement(Type type, KotlinType kotlinType, StackValue array, StackValue index) {
|
||||
super(type, kotlinType, false, false, new Receiver(Type.LONG_TYPE, array, index), true);
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
|
||||
+4
-1
@@ -472,11 +472,14 @@ class ExpressionCodegen(
|
||||
else {
|
||||
mv.iconst(size)
|
||||
newArrayInstruction(expression.type)
|
||||
val elementKotlinType = outType.constructor.builtIns.getArrayElementType(outType)
|
||||
for ((i, element) in expression.elements.withIndex()) {
|
||||
mv.dup()
|
||||
StackValue.constant(i, Type.INT_TYPE).put(Type.INT_TYPE, mv)
|
||||
val rightSide = gen(element, elementType, data)
|
||||
StackValue.arrayElement(elementType, StackValue.onStack(elementType), StackValue.onStack(Type.INT_TYPE)).store(rightSide, mv)
|
||||
StackValue
|
||||
.arrayElement(elementType, elementKotlinType, StackValue.onStack(elementType, outType), StackValue.onStack(Type.INT_TYPE))
|
||||
.store(rightSide, mv)
|
||||
}
|
||||
}
|
||||
return expression.onStack
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
// !LANGUAGE: +InlineClasses
|
||||
|
||||
inline class UInt(val value: Int)
|
||||
|
||||
fun <T> takeVarargs(vararg e: T): T {
|
||||
return e[e.size - 1]
|
||||
}
|
||||
|
||||
fun test(u1: UInt, u2: UInt, u3: UInt?): Int {
|
||||
val a = takeVarargs(u1, u2)
|
||||
val b = takeVarargs(u3) ?: UInt(-1)
|
||||
val c = takeVarargs(u1, u3) ?: UInt(-1)
|
||||
|
||||
return a.value + b.value + c.value
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
val u1 = UInt(0)
|
||||
val u2 = UInt(1)
|
||||
val u3 = UInt(2)
|
||||
if (test(u1, u2, u3) != 1 + 2 + 2) return "fail"
|
||||
|
||||
return "OK"
|
||||
}
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
// !LANGUAGE: +InlineClasses
|
||||
|
||||
inline class UInt(val u: Int)
|
||||
|
||||
fun <T> takeVarargs(vararg e: T) {}
|
||||
|
||||
fun test(u1: UInt, u2: UInt, u3: UInt?) {
|
||||
takeVarargs(u1, u2) // 2 box
|
||||
takeVarargs(u3)
|
||||
takeVarargs(u1, u3) // box
|
||||
}
|
||||
|
||||
// 3 INVOKESTATIC UInt\$Erased.box
|
||||
// 0 INVOKEVIRTUAL UInt.unbox
|
||||
|
||||
// 0 valueOf
|
||||
// 0 intValue
|
||||
Generated
+6
@@ -10491,6 +10491,12 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("passInlineClassAsVararg.kt")
|
||||
public void testPassInlineClassAsVararg() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/inlineClasses/passInlineClassAsVararg.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("referToPropertyInCompanionObjectOfInlineClass.kt")
|
||||
public void testReferToPropertyInCompanionObjectOfInlineClass() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/inlineClasses/referToPropertyInCompanionObjectOfInlineClass.kt");
|
||||
|
||||
+6
@@ -10491,6 +10491,12 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("passInlineClassAsVararg.kt")
|
||||
public void testPassInlineClassAsVararg() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/inlineClasses/passInlineClassAsVararg.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("referToPropertyInCompanionObjectOfInlineClass.kt")
|
||||
public void testReferToPropertyInCompanionObjectOfInlineClass() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/inlineClasses/referToPropertyInCompanionObjectOfInlineClass.kt");
|
||||
|
||||
@@ -1920,6 +1920,12 @@ public class BytecodeTextTestGenerated extends AbstractBytecodeTextTest {
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("boxInlineClassesOnPassingToVarargs.kt")
|
||||
public void testBoxInlineClassesOnPassingToVarargs() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/bytecodeText/inlineClasses/boxInlineClassesOnPassingToVarargs.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("boxResultAfterConstructorCall.kt")
|
||||
public void testBoxResultAfterConstructorCall() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/bytecodeText/inlineClasses/boxResultAfterConstructorCall.kt");
|
||||
|
||||
+6
@@ -10491,6 +10491,12 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("passInlineClassAsVararg.kt")
|
||||
public void testPassInlineClassAsVararg() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/inlineClasses/passInlineClassAsVararg.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("referToPropertyInCompanionObjectOfInlineClass.kt")
|
||||
public void testReferToPropertyInCompanionObjectOfInlineClass() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/inlineClasses/referToPropertyInCompanionObjectOfInlineClass.kt");
|
||||
|
||||
+6
@@ -11475,6 +11475,12 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest {
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("passInlineClassAsVararg.kt")
|
||||
public void testPassInlineClassAsVararg() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/inlineClasses/passInlineClassAsVararg.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("referToPropertyInCompanionObjectOfInlineClass.kt")
|
||||
public void testReferToPropertyInCompanionObjectOfInlineClass() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/inlineClasses/referToPropertyInCompanionObjectOfInlineClass.kt");
|
||||
|
||||
Reference in New Issue
Block a user