From 31e4ddafd1de6d7737b10f3ee393f01d93a45f88 Mon Sep 17 00:00:00 2001 From: Ilmir Usmanov Date: Tue, 11 Aug 2020 19:54:29 +0200 Subject: [PATCH] Minor. Add test with boolean parameter --- .../codegen/coroutines/CoroutineCodegen.kt | 7 +- .../coroutines/spilling/booleanParameter.kt | 20 ++++ .../coroutines/spilling/booleanParameter.txt | 102 ++++++++++++++++++ .../spilling/booleanParameter_ir.txt | 102 ++++++++++++++++++ .../dumpDeclarations/suspendLambda.json | 2 +- .../codegen/BytecodeListingTestGenerated.java | 5 + .../ir/IrBytecodeListingTestGenerated.java | 5 + 7 files changed, 241 insertions(+), 2 deletions(-) create mode 100644 compiler/testData/codegen/bytecodeListing/coroutines/spilling/booleanParameter.kt create mode 100644 compiler/testData/codegen/bytecodeListing/coroutines/spilling/booleanParameter.txt create mode 100644 compiler/testData/codegen/bytecodeListing/coroutines/spilling/booleanParameter_ir.txt diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/coroutines/CoroutineCodegen.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/coroutines/CoroutineCodegen.kt index f6d9a566215..73656fda769 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/coroutines/CoroutineCodegen.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/coroutines/CoroutineCodegen.kt @@ -471,11 +471,16 @@ class CoroutineCodegenForLambda private constructor( val fieldStackValue = StackValue.field(fieldForParameter, generateThisOrOuter(context.thisDescriptor, false)) val originalType = typeMapper.mapType(parameter.type) + // If a parameter has reference type, it has prefix L$, + // however, when the type is primitive, its prefix is ${type.descriptor}$. + // In other words, it the type is Boolean, the prefix is Z$. + // This is different from spilled variables, where all int-like primitives have prefix I$. + // This is not a problem, since we do not clean spilled primitives up + // and we do not coerce Int to Boolean, which takes quite a bit of bytecode (see coerceInt). val normalizedType = originalType.normalize() fieldStackValue.put(normalizedType, v) val newIndex = myFrameMap.enter(parameter, originalType) - // FIXME: Coerce int StackValue.coerce(normalizedType, originalType, v) v.store(newIndex, originalType) diff --git a/compiler/testData/codegen/bytecodeListing/coroutines/spilling/booleanParameter.kt b/compiler/testData/codegen/bytecodeListing/coroutines/spilling/booleanParameter.kt new file mode 100644 index 00000000000..9d67eab6ee9 --- /dev/null +++ b/compiler/testData/codegen/bytecodeListing/coroutines/spilling/booleanParameter.kt @@ -0,0 +1,20 @@ +// WITH_RUNTIME +// WITH_COROUTINES + +import helpers.* +import kotlin.coroutines.* + +fun builder(c: suspend () -> Unit) { + c.startCoroutine(EmptyContinuation) +} + +fun box(): String { + var res = "FAIL" + val lambda: suspend (Boolean) -> String = { + if (it) "OK" else "FAIL 1" + } + builder { + res = lambda(true) + } + return res +} \ No newline at end of file diff --git a/compiler/testData/codegen/bytecodeListing/coroutines/spilling/booleanParameter.txt b/compiler/testData/codegen/bytecodeListing/coroutines/spilling/booleanParameter.txt new file mode 100644 index 00000000000..b6225158363 --- /dev/null +++ b/compiler/testData/codegen/bytecodeListing/coroutines/spilling/booleanParameter.txt @@ -0,0 +1,102 @@ +@kotlin.coroutines.jvm.internal.DebugMetadata +@kotlin.Metadata +final class BooleanParameterKt$box$1 { + // source: 'booleanParameter.kt' + synthetic final field $lambda: kotlin.jvm.functions.Function2 + synthetic final field $res: kotlin.jvm.internal.Ref$ObjectRef + field L$0: java.lang.Object + field label: int + inner (anonymous) class BooleanParameterKt$box$1 + method (p0: kotlin.jvm.internal.Ref$ObjectRef, p1: kotlin.jvm.functions.Function2, p2: kotlin.coroutines.Continuation): void + public final @org.jetbrains.annotations.NotNull method create(@org.jetbrains.annotations.NotNull p0: kotlin.coroutines.Continuation): kotlin.coroutines.Continuation + public final method invoke(p0: java.lang.Object): java.lang.Object + public final @org.jetbrains.annotations.Nullable method invokeSuspend(@org.jetbrains.annotations.NotNull p0: java.lang.Object): java.lang.Object +} + +@kotlin.coroutines.jvm.internal.DebugMetadata +@kotlin.Metadata +final class BooleanParameterKt$box$lambda$1 { + // source: 'booleanParameter.kt' + private synthetic field Z$0: boolean + field label: int + inner (anonymous) class BooleanParameterKt$box$lambda$1 + method (p0: kotlin.coroutines.Continuation): void + public final @org.jetbrains.annotations.NotNull method create(@org.jetbrains.annotations.Nullable p0: java.lang.Object, @org.jetbrains.annotations.NotNull p1: kotlin.coroutines.Continuation): kotlin.coroutines.Continuation + public final method invoke(p0: java.lang.Object, p1: java.lang.Object): java.lang.Object + public final @org.jetbrains.annotations.Nullable method invokeSuspend(@org.jetbrains.annotations.NotNull p0: java.lang.Object): java.lang.Object +} + +@kotlin.Metadata +public final class BooleanParameterKt { + // source: 'booleanParameter.kt' + inner (anonymous) class BooleanParameterKt$box$1 + inner (anonymous) class BooleanParameterKt$box$lambda$1 + public final static @org.jetbrains.annotations.NotNull method box(): java.lang.String + public final static method builder(@org.jetbrains.annotations.NotNull p0: kotlin.jvm.functions.Function1): void +} + +@kotlin.Metadata +public abstract class helpers/ContinuationAdapter { + // source: 'CoroutineUtil.kt' + private final @org.jetbrains.annotations.NotNull field context: kotlin.coroutines.CoroutineContext + public method (): void + public @org.jetbrains.annotations.NotNull method getContext(): kotlin.coroutines.CoroutineContext + public abstract method resume(p0: java.lang.Object): void + public method resumeWith(@org.jetbrains.annotations.NotNull p0: java.lang.Object): void + public abstract method resumeWithException(@org.jetbrains.annotations.NotNull p0: java.lang.Throwable): void +} + +@kotlin.Metadata +public final class helpers/CoroutineUtilKt$handleExceptionContinuation$1 { + // source: 'CoroutineUtil.kt' + synthetic final field $x: kotlin.jvm.functions.Function1 + private final @org.jetbrains.annotations.NotNull field context: kotlin.coroutines.EmptyCoroutineContext + inner (anonymous) class helpers/CoroutineUtilKt$handleExceptionContinuation$1 + method (p0: kotlin.jvm.functions.Function1): void + public synthetic bridge method getContext(): kotlin.coroutines.CoroutineContext + public @org.jetbrains.annotations.NotNull method getContext(): kotlin.coroutines.EmptyCoroutineContext + public method resumeWith(@org.jetbrains.annotations.NotNull p0: java.lang.Object): void +} + +@kotlin.Metadata +public final class helpers/CoroutineUtilKt$handleResultContinuation$1 { + // source: 'CoroutineUtil.kt' + synthetic final field $x: kotlin.jvm.functions.Function1 + private final @org.jetbrains.annotations.NotNull field context: kotlin.coroutines.EmptyCoroutineContext + inner (anonymous) class helpers/CoroutineUtilKt$handleResultContinuation$1 + method (p0: kotlin.jvm.functions.Function1): void + public synthetic bridge method getContext(): kotlin.coroutines.CoroutineContext + public @org.jetbrains.annotations.NotNull method getContext(): kotlin.coroutines.EmptyCoroutineContext + public method resumeWith(@org.jetbrains.annotations.NotNull p0: java.lang.Object): void +} + +@kotlin.Metadata +public final class helpers/CoroutineUtilKt { + // source: 'CoroutineUtil.kt' + inner (anonymous) class helpers/CoroutineUtilKt$handleExceptionContinuation$1 + inner (anonymous) class helpers/CoroutineUtilKt$handleResultContinuation$1 + public final static @org.jetbrains.annotations.NotNull method handleExceptionContinuation(@org.jetbrains.annotations.NotNull p0: kotlin.jvm.functions.Function1): kotlin.coroutines.Continuation + public final static @org.jetbrains.annotations.NotNull method handleResultContinuation(@org.jetbrains.annotations.NotNull p0: kotlin.jvm.functions.Function1): kotlin.coroutines.Continuation +} + +@kotlin.Metadata +public final class helpers/EmptyContinuation$Companion { + // source: 'CoroutineUtil.kt' + private method (): void + public synthetic method (p0: kotlin.jvm.internal.DefaultConstructorMarker): void + public final inner class helpers/EmptyContinuation$Companion +} + +@kotlin.Metadata +public class helpers/EmptyContinuation { + // source: 'CoroutineUtil.kt' + public final static @org.jetbrains.annotations.NotNull field Companion: helpers.EmptyContinuation$Companion + private final @org.jetbrains.annotations.NotNull field context: kotlin.coroutines.CoroutineContext + static method (): void + public method (): void + public method (@org.jetbrains.annotations.NotNull p0: kotlin.coroutines.CoroutineContext): void + public synthetic method (p0: kotlin.coroutines.CoroutineContext, p1: int, p2: kotlin.jvm.internal.DefaultConstructorMarker): void + public @org.jetbrains.annotations.NotNull method getContext(): kotlin.coroutines.CoroutineContext + public method resumeWith(@org.jetbrains.annotations.NotNull p0: java.lang.Object): void + public final inner class helpers/EmptyContinuation$Companion +} diff --git a/compiler/testData/codegen/bytecodeListing/coroutines/spilling/booleanParameter_ir.txt b/compiler/testData/codegen/bytecodeListing/coroutines/spilling/booleanParameter_ir.txt new file mode 100644 index 00000000000..2e508f4caf4 --- /dev/null +++ b/compiler/testData/codegen/bytecodeListing/coroutines/spilling/booleanParameter_ir.txt @@ -0,0 +1,102 @@ +@kotlin.coroutines.jvm.internal.DebugMetadata +@kotlin.Metadata +final class BooleanParameterKt$box$1 { + // source: 'booleanParameter.kt' + synthetic final field $lambda: kotlin.jvm.functions.Function2 + synthetic final field $res: kotlin.jvm.internal.Ref$ObjectRef + field L$0: java.lang.Object + field label: int + inner (anonymous) class BooleanParameterKt$box$1 + method (p0: kotlin.jvm.internal.Ref$ObjectRef, p1: kotlin.jvm.functions.Function2, p2: kotlin.coroutines.Continuation): void + public final @org.jetbrains.annotations.NotNull method create(@org.jetbrains.annotations.NotNull p0: kotlin.coroutines.Continuation): kotlin.coroutines.Continuation + public final method invoke(p0: java.lang.Object): java.lang.Object + public final @org.jetbrains.annotations.Nullable method invokeSuspend(@org.jetbrains.annotations.NotNull p0: java.lang.Object): java.lang.Object +} + +@kotlin.coroutines.jvm.internal.DebugMetadata +@kotlin.Metadata +final class BooleanParameterKt$box$lambda$1 { + // source: 'booleanParameter.kt' + synthetic field it: boolean + field label: int + inner (anonymous) class BooleanParameterKt$box$lambda$1 + method (p0: kotlin.coroutines.Continuation): void + public final @org.jetbrains.annotations.NotNull method create(@org.jetbrains.annotations.Nullable p0: java.lang.Object, @org.jetbrains.annotations.NotNull p1: kotlin.coroutines.Continuation): kotlin.coroutines.Continuation + public final method invoke(p0: java.lang.Object, p1: java.lang.Object): java.lang.Object + public final @org.jetbrains.annotations.Nullable method invokeSuspend(@org.jetbrains.annotations.NotNull p0: java.lang.Object): java.lang.Object +} + +@kotlin.Metadata +public final class BooleanParameterKt { + // source: 'booleanParameter.kt' + inner (anonymous) class BooleanParameterKt$box$1 + inner (anonymous) class BooleanParameterKt$box$lambda$1 + public final static @org.jetbrains.annotations.NotNull method box(): java.lang.String + public final static method builder(@org.jetbrains.annotations.NotNull p0: kotlin.jvm.functions.Function1): void +} + +@kotlin.Metadata +public abstract class helpers/ContinuationAdapter { + // source: 'CoroutineUtil.kt' + private final @org.jetbrains.annotations.NotNull field context: kotlin.coroutines.CoroutineContext + public method (): void + public @org.jetbrains.annotations.NotNull method getContext(): kotlin.coroutines.CoroutineContext + public abstract method resume(p0: java.lang.Object): void + public method resumeWith(@org.jetbrains.annotations.NotNull p0: java.lang.Object): void + public abstract method resumeWithException(@org.jetbrains.annotations.NotNull p0: java.lang.Throwable): void +} + +@kotlin.Metadata +public final class helpers/CoroutineUtilKt$handleExceptionContinuation$1 { + // source: 'CoroutineUtil.kt' + private synthetic final field $x: kotlin.jvm.functions.Function1 + private final @org.jetbrains.annotations.NotNull field context: kotlin.coroutines.EmptyCoroutineContext + inner (anonymous) class helpers/CoroutineUtilKt$handleExceptionContinuation$1 + method (p0: kotlin.jvm.functions.Function1): void + public synthetic bridge method getContext(): kotlin.coroutines.CoroutineContext + public @org.jetbrains.annotations.NotNull method getContext(): kotlin.coroutines.EmptyCoroutineContext + public method resumeWith(@org.jetbrains.annotations.NotNull p0: java.lang.Object): void +} + +@kotlin.Metadata +public final class helpers/CoroutineUtilKt$handleResultContinuation$1 { + // source: 'CoroutineUtil.kt' + private synthetic final field $x: kotlin.jvm.functions.Function1 + private final @org.jetbrains.annotations.NotNull field context: kotlin.coroutines.EmptyCoroutineContext + inner (anonymous) class helpers/CoroutineUtilKt$handleResultContinuation$1 + method (p0: kotlin.jvm.functions.Function1): void + public synthetic bridge method getContext(): kotlin.coroutines.CoroutineContext + public @org.jetbrains.annotations.NotNull method getContext(): kotlin.coroutines.EmptyCoroutineContext + public method resumeWith(@org.jetbrains.annotations.NotNull p0: java.lang.Object): void +} + +@kotlin.Metadata +public final class helpers/CoroutineUtilKt { + // source: 'CoroutineUtil.kt' + inner (anonymous) class helpers/CoroutineUtilKt$handleExceptionContinuation$1 + inner (anonymous) class helpers/CoroutineUtilKt$handleResultContinuation$1 + public final static @org.jetbrains.annotations.NotNull method handleExceptionContinuation(@org.jetbrains.annotations.NotNull p0: kotlin.jvm.functions.Function1): kotlin.coroutines.Continuation + public final static @org.jetbrains.annotations.NotNull method handleResultContinuation(@org.jetbrains.annotations.NotNull p0: kotlin.jvm.functions.Function1): kotlin.coroutines.Continuation +} + +@kotlin.Metadata +public final class helpers/EmptyContinuation$Companion { + // source: 'CoroutineUtil.kt' + private method (): void + public synthetic method (p0: kotlin.jvm.internal.DefaultConstructorMarker): void + public final inner class helpers/EmptyContinuation$Companion +} + +@kotlin.Metadata +public class helpers/EmptyContinuation { + // source: 'CoroutineUtil.kt' + public final static @org.jetbrains.annotations.NotNull field Companion: helpers.EmptyContinuation$Companion + private final @org.jetbrains.annotations.NotNull field context: kotlin.coroutines.CoroutineContext + static method (): void + public method (): void + public method (@org.jetbrains.annotations.NotNull p0: kotlin.coroutines.CoroutineContext): void + public synthetic method (p0: kotlin.coroutines.CoroutineContext, p1: int, p2: kotlin.jvm.internal.DefaultConstructorMarker): void + public @org.jetbrains.annotations.NotNull method getContext(): kotlin.coroutines.CoroutineContext + public method resumeWith(@org.jetbrains.annotations.NotNull p0: java.lang.Object): void + public final inner class helpers/EmptyContinuation$Companion +} diff --git a/compiler/testData/codegen/dumpDeclarations/suspendLambda.json b/compiler/testData/codegen/dumpDeclarations/suspendLambda.json index 5e6dc40c27f..9012ea2d097 100644 --- a/compiler/testData/codegen/dumpDeclarations/suspendLambda.json +++ b/compiler/testData/codegen/dumpDeclarations/suspendLambda.json @@ -4,7 +4,7 @@ "visibility": "local", "class": "SuspendLambdaKt$invokeCoroutineBuilder$1", "members": [ - {"visibility": "local", "declaration": "", "name": "p$", "desc": "Ljava/lang/Object;"}, + {"visibility": "local", "declaration": "", "name": "L$0", "desc": "Ljava/lang/Object;"}, {"name": "invokeSuspend", "desc": "(Ljava/lang/Object;)Ljava/lang/Object;"}, {"visibility": "local", "declaration": "final suspend fun kotlin.Any.(): kotlin.Unit", "name": "", "desc": "(Lkotlin/coroutines/Continuation;)V"}, {"name": "label", "desc": "I"}, diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/BytecodeListingTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/BytecodeListingTestGenerated.java index 20aa9adf411..10afb25f346 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/BytecodeListingTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/BytecodeListingTestGenerated.java @@ -353,6 +353,11 @@ public class BytecodeListingTestGenerated extends AbstractBytecodeListingTest { KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/bytecodeListing/coroutines/spilling"), Pattern.compile("^(.+)\\.kt$"), null, true); } + @TestMetadata("booleanParameter.kt") + public void testBooleanParameter() throws Exception { + runTest("compiler/testData/codegen/bytecodeListing/coroutines/spilling/booleanParameter.kt"); + } + @TestMetadata("component1.kt") public void testComponent1() throws Exception { runTest("compiler/testData/codegen/bytecodeListing/coroutines/spilling/component1.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBytecodeListingTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBytecodeListingTestGenerated.java index f51a98240d6..131801aa1e6 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBytecodeListingTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBytecodeListingTestGenerated.java @@ -323,6 +323,11 @@ public class IrBytecodeListingTestGenerated extends AbstractIrBytecodeListingTes KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/bytecodeListing/coroutines/spilling"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true); } + @TestMetadata("booleanParameter.kt") + public void testBooleanParameter() throws Exception { + runTest("compiler/testData/codegen/bytecodeListing/coroutines/spilling/booleanParameter.kt"); + } + @TestMetadata("component1.kt") public void testComponent1() throws Exception { runTest("compiler/testData/codegen/bytecodeListing/coroutines/spilling/component1.kt");