Skip call to the underlying value of inline class
This commit is contained in:
@@ -1672,14 +1672,13 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
if (descriptor instanceof PropertyDescriptor) {
|
||||
PropertyDescriptor propertyDescriptor = (PropertyDescriptor) descriptor;
|
||||
|
||||
// `this` is represented as first parameter of function in erased inline class
|
||||
boolean isThisOfErasedInlineClass =
|
||||
contextKind() == OwnerKind.ERASED_INLINE_CLASS &&
|
||||
boolean isUnderlyingPropertyOfInlineClass =
|
||||
InlineClassesUtilsKt.isInlineClass(propertyDescriptor.getContainingDeclaration()) &&
|
||||
JvmCodegenUtil.hasBackingField(propertyDescriptor, contextKind(), bindingContext);
|
||||
if (isThisOfErasedInlineClass) {
|
||||
Type underlyingRepresentationType = typeMapper.mapType(propertyDescriptor.getType());
|
||||
return StackValue.local(0, underlyingRepresentationType);
|
||||
|
||||
if (isUnderlyingPropertyOfInlineClass) {
|
||||
KotlinType propertyType = propertyDescriptor.getType();
|
||||
return StackValue.underlyingValueOfInlineClass(typeMapper.mapType(propertyType), propertyType, receiver);
|
||||
}
|
||||
|
||||
Collection<ExpressionCodegenExtension> codegenExtensions = ExpressionCodegenExtension.Companion.getInstances(state.getProject());
|
||||
|
||||
@@ -291,6 +291,14 @@ public abstract class StackValue {
|
||||
return new CollectionElement(collectionElementReceiver, type, kotlinType, getter, setter, codegen);
|
||||
}
|
||||
|
||||
public static UnderlyingValueOfInlineClass underlyingValueOfInlineClass(
|
||||
@NotNull Type type,
|
||||
@Nullable KotlinType kotlinType,
|
||||
@NotNull StackValue receiver
|
||||
) {
|
||||
return new UnderlyingValueOfInlineClass(type, kotlinType, receiver);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static Field field(@NotNull Type type, @NotNull Type owner, @NotNull String name, boolean isStatic, @NotNull StackValue receiver) {
|
||||
return field(type, null, owner, name, isStatic, receiver, null);
|
||||
@@ -1004,6 +1012,24 @@ public abstract class StackValue {
|
||||
}
|
||||
}
|
||||
|
||||
public static class UnderlyingValueOfInlineClass extends StackValueWithSimpleReceiver {
|
||||
|
||||
public UnderlyingValueOfInlineClass(
|
||||
@NotNull Type type,
|
||||
@Nullable KotlinType kotlinType,
|
||||
@NotNull StackValue receiver
|
||||
) {
|
||||
super(type, kotlinType, false, false, receiver, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void putSelector(
|
||||
@NotNull Type type, @Nullable KotlinType kotlinType, @NotNull InstructionAdapter v
|
||||
) {
|
||||
coerceTo(type, kotlinType, v);
|
||||
}
|
||||
}
|
||||
|
||||
public static class CollectionElementReceiver extends StackValue {
|
||||
private final Callable callable;
|
||||
private final boolean isGetter;
|
||||
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
// !LANGUAGE: +InlineClasses
|
||||
|
||||
inline class UInt(val value: Int) {
|
||||
operator fun plus(other: UInt) = UInt(value + other.value)
|
||||
fun otherValue(other: UInt) = other.value
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
val a = UInt(10)
|
||||
val b = UInt(20)
|
||||
if (a.otherValue(b) != 20) return "fail 1"
|
||||
|
||||
if ((a + b).value != 30) return "fail 2"
|
||||
|
||||
return "OK"
|
||||
}
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
// !LANGUAGE: +InlineClasses
|
||||
|
||||
inline class UInt(val value: Int)
|
||||
|
||||
fun box(): String {
|
||||
val a = UInt(123)
|
||||
if(a.value != 123) return "fail"
|
||||
|
||||
val c = a.value.hashCode()
|
||||
if (c.hashCode() != 123.hashCode()) return "fail"
|
||||
|
||||
val b = UInt(100).value + a.value
|
||||
if (b != 223) return "faile"
|
||||
|
||||
return "OK"
|
||||
}
|
||||
Vendored
+17
@@ -0,0 +1,17 @@
|
||||
// !LANGUAGE: +InlineClasses
|
||||
|
||||
inline class UInt(val value: Int)
|
||||
|
||||
fun test(u1: UInt, u2: UInt) {
|
||||
val a = u1.value
|
||||
|
||||
val b = u1.value.hashCode() // box int to call hashCode
|
||||
val c = u1.value + u2.value
|
||||
}
|
||||
|
||||
// 0 INVOKESTATIC UInt\$Erased.getValue
|
||||
// 0 INVOKESTATIC UInt\$Erased.box
|
||||
// 0 INVOKEVIRTUAL UInt.unbox
|
||||
|
||||
// 1 valueOf
|
||||
// 0 intValue
|
||||
Generated
+12
@@ -10467,6 +10467,18 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("referToUnderlyingPropertyInsideInlineClass.kt")
|
||||
public void testReferToUnderlyingPropertyInsideInlineClass() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/inlineClasses/referToUnderlyingPropertyInsideInlineClass.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("referToUnderlyingPropertyOfInlineClass.kt")
|
||||
public void testReferToUnderlyingPropertyOfInlineClass() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/inlineClasses/referToUnderlyingPropertyOfInlineClass.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("UIntArraySortExample.kt")
|
||||
public void testUIntArraySortExample() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/inlineClasses/UIntArraySortExample.kt");
|
||||
|
||||
+12
@@ -10467,6 +10467,18 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("referToUnderlyingPropertyInsideInlineClass.kt")
|
||||
public void testReferToUnderlyingPropertyInsideInlineClass() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/inlineClasses/referToUnderlyingPropertyInsideInlineClass.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("referToUnderlyingPropertyOfInlineClass.kt")
|
||||
public void testReferToUnderlyingPropertyOfInlineClass() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/inlineClasses/referToUnderlyingPropertyOfInlineClass.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("UIntArraySortExample.kt")
|
||||
public void testUIntArraySortExample() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/inlineClasses/UIntArraySortExample.kt");
|
||||
|
||||
@@ -1974,6 +1974,12 @@ public class BytecodeTextTestGenerated extends AbstractBytecodeTextTest {
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("skipCallToUnderlyingValueOfInlineClass.kt")
|
||||
public void testSkipCallToUnderlyingValueOfInlineClass() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/bytecodeText/inlineClasses/skipCallToUnderlyingValueOfInlineClass.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("uIntArrayIteratorWithoutBoxing.kt")
|
||||
public void testUIntArrayIteratorWithoutBoxing() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/bytecodeText/inlineClasses/uIntArrayIteratorWithoutBoxing.kt");
|
||||
|
||||
+12
@@ -10467,6 +10467,18 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("referToUnderlyingPropertyInsideInlineClass.kt")
|
||||
public void testReferToUnderlyingPropertyInsideInlineClass() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/inlineClasses/referToUnderlyingPropertyInsideInlineClass.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("referToUnderlyingPropertyOfInlineClass.kt")
|
||||
public void testReferToUnderlyingPropertyOfInlineClass() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/inlineClasses/referToUnderlyingPropertyOfInlineClass.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("UIntArraySortExample.kt")
|
||||
public void testUIntArraySortExample() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/inlineClasses/UIntArraySortExample.kt");
|
||||
|
||||
+12
@@ -11451,6 +11451,18 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest {
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("referToUnderlyingPropertyInsideInlineClass.kt")
|
||||
public void testReferToUnderlyingPropertyInsideInlineClass() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/inlineClasses/referToUnderlyingPropertyInsideInlineClass.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("referToUnderlyingPropertyOfInlineClass.kt")
|
||||
public void testReferToUnderlyingPropertyOfInlineClass() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/inlineClasses/referToUnderlyingPropertyOfInlineClass.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("UIntArraySortExample.kt")
|
||||
public void testUIntArraySortExample() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/inlineClasses/UIntArraySortExample.kt");
|
||||
|
||||
Reference in New Issue
Block a user