'box'/'unbox' methods are called by inline class
This commit is contained in:
@@ -402,25 +402,23 @@ public abstract class StackValue {
|
||||
|
||||
private static void boxInlineClass(@NotNull KotlinType kotlinType, @NotNull InstructionAdapter v) {
|
||||
Type boxedType = KotlinTypeMapper.mapInlineClassTypeAsDeclaration(kotlinType);
|
||||
Type owner = KotlinTypeMapper.mapToErasedInlineClassType(kotlinType);
|
||||
Type underlyingType = KotlinTypeMapper.mapUnderlyingTypeOfInlineClassType(kotlinType);
|
||||
|
||||
if (TypeUtils.isNullableType(kotlinType) && !isPrimitive(underlyingType)) {
|
||||
boxOrUnboxWithNullCheck(v, vv -> invokeBoxMethod(vv, boxedType, owner, underlyingType));
|
||||
boxOrUnboxWithNullCheck(v, vv -> invokeBoxMethod(vv, boxedType, underlyingType));
|
||||
}
|
||||
else {
|
||||
invokeBoxMethod(v, boxedType, owner, underlyingType);
|
||||
invokeBoxMethod(v, boxedType, underlyingType);
|
||||
}
|
||||
}
|
||||
|
||||
private static void invokeBoxMethod(
|
||||
@NotNull InstructionAdapter v,
|
||||
Type boxedType,
|
||||
Type owner,
|
||||
Type underlyingType
|
||||
) {
|
||||
v.invokestatic(
|
||||
owner.getInternalName(),
|
||||
boxedType.getInternalName(),
|
||||
InlineClassDescriptorResolver.BOX_METHOD_NAME.asString(),
|
||||
Type.getMethodDescriptor(boxedType, underlyingType),
|
||||
false
|
||||
|
||||
+1
-2
@@ -237,9 +237,8 @@ private fun AbstractInsnNode.isInlineClassUnboxing(state: GenerationState) =
|
||||
|
||||
private fun MethodInsnNode.isInlineClassBoxingMethodDescriptor(state: GenerationState): Boolean {
|
||||
if (name != InlineClassDescriptorResolver.BOX_METHOD_NAME.asString()) return false
|
||||
if (!owner.endsWith(JvmAbi.ERASED_INLINE_CLASS_SUFFIX)) return false
|
||||
|
||||
val ownerType = Type.getObjectType(owner.removeSuffix(JvmAbi.ERASED_INLINE_CLASS_SUFFIX))
|
||||
val ownerType = Type.getObjectType(owner)
|
||||
val descriptor = state.jvmBackendClassResolver.resolveToClassDescriptors(ownerType).singleOrNull() ?: return false
|
||||
|
||||
if (!descriptor.isInline) return false
|
||||
|
||||
+1
-1
@@ -15,7 +15,7 @@ fun test(u1: UInt, u2: UInt, u3: UInt?) {
|
||||
}
|
||||
|
||||
// @TestKt.class:
|
||||
// 3 INVOKESTATIC UInt\$Erased.box
|
||||
// 3 INVOKESTATIC UInt\.box
|
||||
// 0 INVOKEVIRTUAL UInt.unbox
|
||||
// 0 valueOf
|
||||
// 0 intValue
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
// !LANGUAGE: +InlineClasses
|
||||
|
||||
// FILE: Z.kt
|
||||
inline class Z(val x: Int)
|
||||
|
||||
// FILE: Test.kt
|
||||
fun test(): Any = Z(42)
|
||||
|
||||
// @TestKt.class:
|
||||
// 0 INVOKESTATIC Z\$Erased\.box
|
||||
// 0 INVOKESTATIC Z\-Erased\.box
|
||||
// 1 INVOKESTATIC Z\.box \(I\)LZ;
|
||||
+2
-2
@@ -15,10 +15,10 @@ fun test() {
|
||||
}
|
||||
|
||||
// @TestKt.class:
|
||||
// 1 INVOKESTATIC AsInt\$Erased.box
|
||||
// 1 INVOKESTATIC AsInt\.box
|
||||
// 0 INVOKEVIRTUAL AsInt.unbox
|
||||
|
||||
// 1 INVOKESTATIC AsAny\$Erased.box
|
||||
// 1 INVOKESTATIC AsAny\.box
|
||||
// 0 INVOKEVIRTUAL AsAny.unbox
|
||||
|
||||
// 1 valueOf
|
||||
|
||||
+1
-1
@@ -13,7 +13,7 @@ inline class UInt(val a: Int) {
|
||||
|
||||
fun takeNullable(a: UInt?) {}
|
||||
|
||||
// 2 INVOKESTATIC UInt\$Erased.box
|
||||
// 2 INVOKESTATIC UInt\.box
|
||||
// 0 INVOKEVIRTUAL Foo.unbox
|
||||
|
||||
// 1 valueOf
|
||||
|
||||
Vendored
+1
-1
@@ -25,7 +25,7 @@ fun test(f: Foo) {
|
||||
}
|
||||
|
||||
// @TestKt.class:
|
||||
// 6 INVOKESTATIC Foo\$Erased.box
|
||||
// 6 INVOKESTATIC Foo\.box
|
||||
// 4 INVOKEVIRTUAL Foo.unbox
|
||||
// 0 valueOf
|
||||
// 0 intValue
|
||||
Vendored
+1
@@ -18,6 +18,7 @@ fun test(x: UInt?, y: UInt) {
|
||||
|
||||
// @TestKt.class:
|
||||
// 0 INVOKESTATIC UInt\$Erased.box
|
||||
// 0 INVOKESTATIC UInt\.box
|
||||
// 1 INVOKEVIRTUAL UInt.unbox
|
||||
|
||||
// 0 valueOf
|
||||
|
||||
Vendored
+2
-2
@@ -17,10 +17,10 @@ fun test() {
|
||||
}
|
||||
|
||||
// @TestKt.class:
|
||||
// 1 INVOKESTATIC UInt\$Erased.box
|
||||
// 1 INVOKESTATIC UInt\.box
|
||||
// 2 INVOKEVIRTUAL UInt.unbox
|
||||
|
||||
// 1 INVOKESTATIC ULong\$Erased.box
|
||||
// 1 INVOKESTATIC ULong\.box
|
||||
// 2 INVOKEVIRTUAL ULong.unbox
|
||||
|
||||
// 0 valueOf
|
||||
|
||||
+1
-1
@@ -23,7 +23,7 @@ fun test(f: Foo) {
|
||||
}
|
||||
|
||||
// @TestKt.class:
|
||||
// 2 INVOKESTATIC Foo\$Erased.box
|
||||
// 2 INVOKESTATIC Foo\.box
|
||||
// 1 INVOKEVIRTUAL Foo.unbox
|
||||
// 0 valueOf
|
||||
// 0 intValue
|
||||
+1
-1
@@ -27,7 +27,7 @@ fun labeled(): ULong? {
|
||||
}
|
||||
|
||||
// @TestKt.class:
|
||||
// 2 INVOKESTATIC ULong\$Erased.box
|
||||
// 2 INVOKESTATIC ULong\.box
|
||||
// 0 INVOKEVIRTUAL ULong.unbox
|
||||
|
||||
// 0 valueOf
|
||||
|
||||
+2
-2
@@ -11,7 +11,7 @@ fun test(a: InlineNotNullPrimitive, b: InlineNotNullReference) {
|
||||
testNotNullReference(b, b, b, b) // 2 box
|
||||
}
|
||||
|
||||
// 3 INVOKESTATIC InlineNotNullPrimitive\$Erased.box
|
||||
// 2 INVOKESTATIC InlineNotNullReference\$Erased.box
|
||||
// 3 INVOKESTATIC InlineNotNullPrimitive\.box
|
||||
// 2 INVOKESTATIC InlineNotNullReference\.box
|
||||
|
||||
// 0 valueOf
|
||||
compiler/testData/codegen/bytecodeText/inlineClasses/inlineClassBoxingUnboxingInsideInlinedLambda.kt
Vendored
+1
-1
@@ -29,7 +29,7 @@ fun takeNullableUInt(y: UInt?) {}
|
||||
inline fun <T> T.myLet(f: (T) -> Unit) = f(this)
|
||||
|
||||
// @TestKt.class:
|
||||
// 1 INVOKESTATIC UInt\$Erased.box
|
||||
// 1 INVOKESTATIC UInt\.box
|
||||
// 5 INVOKEVIRTUAL UInt.unbox
|
||||
|
||||
// 0 intValue
|
||||
|
||||
+2
-2
@@ -22,9 +22,9 @@ fun transformToNullableTarget(a: AsInt): AsInt? = a as AsInt? // box
|
||||
fun transformNullableToNullableTarget(a: AsInt?): AsInt? = a as AsInt?
|
||||
|
||||
// @ReferenceKt.class:
|
||||
// 2 INVOKESTATIC AsAny\$Erased.box
|
||||
// 2 INVOKESTATIC AsAny\.box
|
||||
// 1 INVOKEVIRTUAL AsAny.unbox
|
||||
|
||||
// @PrimitiveKt.class:
|
||||
// 2 INVOKESTATIC AsInt\$Erased.box
|
||||
// 2 INVOKESTATIC AsInt\.box
|
||||
// 1 INVOKEVIRTUAL AsInt.unbox
|
||||
|
||||
Vendored
+2
-1
@@ -10,6 +10,7 @@ fun test1(us: UIntArray) {
|
||||
|
||||
// @NoBoxingKt.class:
|
||||
// 0 INVOKESTATIC kotlin.UInt\$Erased.box
|
||||
// 0 INVOKESTATIC kotlin.UInt\.box
|
||||
// 0 INVOKEVIRTUAL kotlin.UInt.unbox
|
||||
|
||||
// FILE: Boxing.kt
|
||||
@@ -21,5 +22,5 @@ fun test2(nullable: UInt?, ns: Array<UInt>) {
|
||||
}
|
||||
|
||||
// @BoxingKt.class:
|
||||
// 2 INVOKESTATIC kotlin.UInt\$Erased.box
|
||||
// 2 INVOKESTATIC kotlin.UInt\.box
|
||||
// 0 INVOKEVIRTUAL kotlin.UInt.unbox
|
||||
compiler/testData/codegen/bytecodeText/inlineClasses/passInlineClassesWithSpreadOperatorToVarargs.kt
Vendored
+1
-1
@@ -14,7 +14,7 @@ fun test(u1: UInt, u2: UInt, us: Array<UInt>) {
|
||||
}
|
||||
|
||||
// @TestKt.class:
|
||||
// 2 INVOKESTATIC UInt\$Erased.box
|
||||
// 2 INVOKESTATIC UInt\.box
|
||||
// 0 INVOKEVIRTUAL UInt.unbox
|
||||
|
||||
// 2 CHECKCAST \[LUInt
|
||||
|
||||
+1
-1
@@ -27,7 +27,7 @@ fun test() {
|
||||
|
||||
fun takeUInt(u: UInt) {}
|
||||
|
||||
// 1 INVOKESTATIC UInt\$Erased.box
|
||||
// 1 INVOKESTATIC UInt\.box
|
||||
// 1 INVOKEVIRTUAL UInt.unbox
|
||||
|
||||
// 0 INVOKEVIRTUAL UIntIterator.iterator
|
||||
|
||||
@@ -23,5 +23,6 @@ fun UIntArray.swap(i: Int, j: Int) {
|
||||
// @TestKt.class:
|
||||
// 0 INVOKEVIRTUAL UInt.unbox
|
||||
// 0 INVOKESTATIC UInt\$Erased.box
|
||||
// 0 INVOKESTATIC UInt\.box
|
||||
// 0 intValue
|
||||
// 0 valueOf
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
// !LANGUAGE: +InlineClasses
|
||||
|
||||
// FILE: Z.kt
|
||||
inline class Z(val x: Int)
|
||||
|
||||
// FILE: Test.kt
|
||||
fun test(xs: List<Z>) = xs[0]
|
||||
|
||||
// @TestKt.class:
|
||||
// 0 INVOKEVIRTUAL Z\$Erased\.unbox
|
||||
// 0 INVOKEVIRTUAL Z\-Erased\.unbox
|
||||
// 1 INVOKEVIRTUAL Z\.unbox \(\)I
|
||||
@@ -2008,6 +2008,11 @@ public class BytecodeTextTestGenerated extends AbstractBytecodeTextTest {
|
||||
runTest("compiler/testData/codegen/bytecodeText/inlineClasses/boxInlineClassesOnPassingToVarargs.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("boxMethodCalledByInlineClass.kt")
|
||||
public void testBoxMethodCalledByInlineClass() throws Exception {
|
||||
runTest("compiler/testData/codegen/bytecodeText/inlineClasses/boxMethodCalledByInlineClass.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("boxResultAfterConstructorCall.kt")
|
||||
public void testBoxResultAfterConstructorCall() throws Exception {
|
||||
runTest("compiler/testData/codegen/bytecodeText/inlineClasses/boxResultAfterConstructorCall.kt");
|
||||
@@ -2197,6 +2202,11 @@ public class BytecodeTextTestGenerated extends AbstractBytecodeTextTest {
|
||||
public void testUnboxInlineClassesAfterSmartCasts() throws Exception {
|
||||
runTest("compiler/testData/codegen/bytecodeText/inlineClasses/unboxInlineClassesAfterSmartCasts.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("unboxMethodCalledByInlineClass.kt")
|
||||
public void testUnboxMethodCalledByInlineClass() throws Exception {
|
||||
runTest("compiler/testData/codegen/bytecodeText/inlineClasses/unboxMethodCalledByInlineClass.kt");
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/codegen/bytecodeText/interfaces")
|
||||
|
||||
Reference in New Issue
Block a user