From e46adbae29dd919546862fd8267a47b138388794 Mon Sep 17 00:00:00 2001 From: Mark Punzalan Date: Wed, 8 Jan 2020 15:31:14 -0800 Subject: [PATCH] [JVM IR] Fix `checkLocalVariablesTableTest/parametersInSuspendLambda` for JVM IR. --- .../kotlin/backend/jvm/JvmSymbols.kt | 24 +++++++++++-------- .../parametersInSuspendLambda/dataClass.kt | 15 ++++++++++-- .../extensionComponents.kt | 19 +++++++++++++-- .../parametersInSuspendLambda/generic.kt | 15 ++++++++++-- .../parametersInSuspendLambda/inline.kt | 2 ++ .../otherParameters.kt | 15 ++++++++++-- .../parametersInSuspendLambda/parameters.kt | 15 ++++++++++-- .../underscoreNames.kt | 15 ++++++++++-- 8 files changed, 98 insertions(+), 22 deletions(-) diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmSymbols.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmSymbols.kt index a7c66c3c235..8c709b9c91a 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmSymbols.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmSymbols.kt @@ -8,6 +8,10 @@ package org.jetbrains.kotlin.backend.jvm import org.jetbrains.kotlin.backend.common.ir.Symbols import org.jetbrains.kotlin.backend.common.ir.createImplicitParameterDeclarationWithWrappedDescriptor import org.jetbrains.kotlin.backend.jvm.intrinsics.IrIntrinsicMethods +import org.jetbrains.kotlin.codegen.coroutines.INVOKE_SUSPEND_METHOD_NAME +import org.jetbrains.kotlin.codegen.coroutines.SUSPEND_CALL_RESULT_NAME +import org.jetbrains.kotlin.codegen.coroutines.SUSPEND_FUNCTION_COMPLETION_PARAMETER_NAME +import org.jetbrains.kotlin.codegen.coroutines.SUSPEND_FUNCTION_CREATE_METHOD_NAME import org.jetbrains.kotlin.descriptors.ClassDescriptor import org.jetbrains.kotlin.descriptors.ClassKind import org.jetbrains.kotlin.descriptors.Modality @@ -218,10 +222,10 @@ class JvmSymbols( val continuationType = continuationClass.typeWith(irBuiltIns.anyNType) klass.superTypes += continuationType klass.addConstructor().apply { - addValueParameter("completion", continuationType.makeNullable()) + addValueParameter(SUSPEND_FUNCTION_COMPLETION_PARAMETER_NAME, continuationType.makeNullable()) } - klass.addFunction("invokeSuspend", irBuiltIns.anyNType, Modality.ABSTRACT).apply { - addValueParameter("result", resultClassStub.typeWith(irBuiltIns.anyNType)) + klass.addFunction(INVOKE_SUSPEND_METHOD_NAME, irBuiltIns.anyNType, Modality.ABSTRACT).apply { + addValueParameter(SUSPEND_CALL_RESULT_NAME, resultClassStub.typeWith(irBuiltIns.anyNType)) } } @@ -238,17 +242,17 @@ class JvmSymbols( klass.superTypes += suspendFunctionInterface.defaultType klass.addConstructor().apply { addValueParameter("arity", irBuiltIns.intType) - addValueParameter("completion", continuationClass.typeWith(irBuiltIns.anyNType).makeNullable()) + addValueParameter(SUSPEND_FUNCTION_COMPLETION_PARAMETER_NAME, continuationClass.typeWith(irBuiltIns.anyNType).makeNullable()) } - klass.addFunction("invokeSuspend", irBuiltIns.anyNType, Modality.ABSTRACT).apply { - addValueParameter("result", resultClassStub.typeWith(irBuiltIns.anyNType)) + klass.addFunction(INVOKE_SUSPEND_METHOD_NAME, irBuiltIns.anyNType, Modality.ABSTRACT).apply { + addValueParameter(SUSPEND_CALL_RESULT_NAME, resultClassStub.typeWith(irBuiltIns.anyNType)) } - klass.addFunction("create", continuationClass.typeWith(irBuiltIns.unitType)).apply { - addValueParameter("completion", continuationClass.typeWith(irBuiltIns.nothingType)) + klass.addFunction(SUSPEND_FUNCTION_CREATE_METHOD_NAME, continuationClass.typeWith(irBuiltIns.unitType)).apply { + addValueParameter(SUSPEND_FUNCTION_COMPLETION_PARAMETER_NAME, continuationClass.typeWith(irBuiltIns.nothingType)) } - klass.addFunction("create", continuationClass.typeWith(irBuiltIns.unitType)).apply { + klass.addFunction(SUSPEND_FUNCTION_CREATE_METHOD_NAME, continuationClass.typeWith(irBuiltIns.unitType)).apply { addValueParameter("value", irBuiltIns.anyNType) - addValueParameter("completion", continuationClass.typeWith(irBuiltIns.nothingType)) + addValueParameter(SUSPEND_FUNCTION_COMPLETION_PARAMETER_NAME, continuationClass.typeWith(irBuiltIns.nothingType)) } } diff --git a/compiler/testData/checkLocalVariablesTable/parametersInSuspendLambda/dataClass.kt b/compiler/testData/checkLocalVariablesTable/parametersInSuspendLambda/dataClass.kt index a58a594579a..55270f96d5d 100644 --- a/compiler/testData/checkLocalVariablesTable/parametersInSuspendLambda/dataClass.kt +++ b/compiler/testData/checkLocalVariablesTable/parametersInSuspendLambda/dataClass.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND: JVM_IR // WITH_RUNTIME data class Data(val x: String, val y: Int) @@ -12,9 +11,21 @@ suspend fun foo(data: Data, body: suspend (Data) -> Unit) { body(data) } +// Parameters (including anonymous destructuring parameters) are moved to fields in the Continuation class for the suspend lambda class. +// However, in non-IR, the fields are first stored in local variables, and they are not read directly (even for destructuring components). +// In IR, the fields are directly read from. + // METHOD : DataClassKt$test$2.invokeSuspend(Ljava/lang/Object;)Ljava/lang/Object; + +// JVM_TEMPLATES // VARIABLE : NAME=$dstr$x_param$y_param TYPE=LData; INDEX=2 // VARIABLE : NAME=x_param TYPE=Ljava/lang/String; INDEX=3 // VARIABLE : NAME=y_param TYPE=I INDEX=4 // VARIABLE : NAME=this TYPE=LDataClassKt$test$2; INDEX=0 -// VARIABLE : NAME=$result TYPE=Ljava/lang/Object; INDEX=1 \ No newline at end of file +// VARIABLE : NAME=$result TYPE=Ljava/lang/Object; INDEX=1 + +// JVM_IR_TEMPLATES +// VARIABLE : NAME=x_param TYPE=Ljava/lang/String; INDEX=2 +// VARIABLE : NAME=y_param TYPE=I INDEX=3 +// VARIABLE : NAME=this TYPE=LDataClassKt$test$2; INDEX=0 +// VARIABLE : NAME=$result TYPE=Ljava/lang/Object; INDEX=1 diff --git a/compiler/testData/checkLocalVariablesTable/parametersInSuspendLambda/extensionComponents.kt b/compiler/testData/checkLocalVariablesTable/parametersInSuspendLambda/extensionComponents.kt index 2cd511fcf95..9e8d8eecfd6 100644 --- a/compiler/testData/checkLocalVariablesTable/parametersInSuspendLambda/extensionComponents.kt +++ b/compiler/testData/checkLocalVariablesTable/parametersInSuspendLambda/extensionComponents.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND: JVM_IR // WITH_RUNTIME class A(val x: String, val y: String, val z: T) @@ -18,10 +17,26 @@ suspend fun B.bar(): String { suspend fun test() = B.bar() +// Local function bodies (i.e., `A.component3()`) are in a separate class (implementing FunctionN) for non-IR, and are static methods +// in the enclosing class for IR. Therefore the ordinal in the suspend lambda class name is different for non-IR (`$3`) vs IR (e.g., `$2`). +// +// Parameters (including anonymous destructuring parameters) are moved to fields in the Continuation class for the suspend lambda class. +// However, in non-IR, the fields are first stored in local variables, and they are not read directly (even for destructuring components). +// In IR, the fields are directly read from. + +// JVM_TEMPLATES // METHOD : ExtensionComponentsKt$bar$3.invokeSuspend(Ljava/lang/Object;)Ljava/lang/Object; // VARIABLE : NAME=$dstr$x_param$y_param$z_param TYPE=LA; INDEX=2 // VARIABLE : NAME=x_param TYPE=Ljava/lang/String; INDEX=3 // VARIABLE : NAME=y_param TYPE=Ljava/lang/String; INDEX=4 // VARIABLE : NAME=z_param TYPE=I INDEX=5 // VARIABLE : NAME=this TYPE=LExtensionComponentsKt$bar$3; INDEX=0 -// VARIABLE : NAME=$result TYPE=Ljava/lang/Object; INDEX=1 \ No newline at end of file +// VARIABLE : NAME=$result TYPE=Ljava/lang/Object; INDEX=1 + +// JVM_IR_TEMPLATES +// METHOD : ExtensionComponentsKt$bar$2.invokeSuspend(Ljava/lang/Object;)Ljava/lang/Object; +// VARIABLE : NAME=x_param TYPE=Ljava/lang/String; INDEX=2 +// VARIABLE : NAME=y_param TYPE=Ljava/lang/String; INDEX=3 +// VARIABLE : NAME=z_param TYPE=I INDEX=4 +// VARIABLE : NAME=this TYPE=LExtensionComponentsKt$bar$2; INDEX=0 +// VARIABLE : NAME=$result TYPE=Ljava/lang/Object; INDEX=1 diff --git a/compiler/testData/checkLocalVariablesTable/parametersInSuspendLambda/generic.kt b/compiler/testData/checkLocalVariablesTable/parametersInSuspendLambda/generic.kt index c887428dcc4..0ef5c3d80da 100644 --- a/compiler/testData/checkLocalVariablesTable/parametersInSuspendLambda/generic.kt +++ b/compiler/testData/checkLocalVariablesTable/parametersInSuspendLambda/generic.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND: JVM_IR // WITH_RUNTIME data class A(val x: T, val y: F) @@ -7,9 +6,21 @@ suspend fun foo(a: A, block: suspend (A) -> String) = block(a suspend fun test() = foo(A("OK", 1)) { (x_param, y_param) -> x_param + (y_param.toString()) } +// Parameters (including anonymous destructuring parameters) are moved to fields in the Continuation class for the suspend lambda class. +// However, in non-IR, the fields are first stored in local variables, and they are not read directly (even for destructuring components). +// In IR, the fields are directly read from. + // METHOD : GenericKt$test$2.invokeSuspend(Ljava/lang/Object;)Ljava/lang/Object; + +// JVM_TEMPLATES // VARIABLE : NAME=$dstr$x_param$y_param TYPE=LA; INDEX=2 // VARIABLE : NAME=x_param TYPE=Ljava/lang/String; INDEX=3 // VARIABLE : NAME=y_param TYPE=I INDEX=4 // VARIABLE : NAME=this TYPE=LGenericKt$test$2; INDEX=0 -// VARIABLE : NAME=$result TYPE=Ljava/lang/Object; INDEX=1 \ No newline at end of file +// VARIABLE : NAME=$result TYPE=Ljava/lang/Object; INDEX=1 + +// JVM_IR_TEMPLATES +// VARIABLE : NAME=x_param TYPE=Ljava/lang/String; INDEX=2 +// VARIABLE : NAME=y_param TYPE=I INDEX=3 +// VARIABLE : NAME=this TYPE=LGenericKt$test$2; INDEX=0 +// VARIABLE : NAME=$result TYPE=Ljava/lang/Object; INDEX=1 diff --git a/compiler/testData/checkLocalVariablesTable/parametersInSuspendLambda/inline.kt b/compiler/testData/checkLocalVariablesTable/parametersInSuspendLambda/inline.kt index 69e8801433b..b970af2f840 100644 --- a/compiler/testData/checkLocalVariablesTable/parametersInSuspendLambda/inline.kt +++ b/compiler/testData/checkLocalVariablesTable/parametersInSuspendLambda/inline.kt @@ -6,6 +6,8 @@ suspend inline fun foo(a: A, block: suspend (A) -> String): String = block(a) suspend fun test() = foo(A("O", "K")) { (x_param, y_param) -> x_param + y_param } +// TODO: Fix this after other issues in inlining suspend lambdas are resolved. + // METHOD : InlineKt.test(Lkotlin/coroutines/Continuation;)Ljava/lang/Object; // VARIABLE : NAME=x_param TYPE=Ljava/lang/String; INDEX=6 // VARIABLE : NAME=y_param TYPE=Ljava/lang/String; INDEX=7 diff --git a/compiler/testData/checkLocalVariablesTable/parametersInSuspendLambda/otherParameters.kt b/compiler/testData/checkLocalVariablesTable/parametersInSuspendLambda/otherParameters.kt index 1e2eeb29571..426b9fdabad 100644 --- a/compiler/testData/checkLocalVariablesTable/parametersInSuspendLambda/otherParameters.kt +++ b/compiler/testData/checkLocalVariablesTable/parametersInSuspendLambda/otherParameters.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND: JVM_IR // WITH_RUNTIME data class A(val x: String, val y: String) @@ -6,11 +5,23 @@ suspend fun foo(a: A, block: suspend (Int, A, String) -> String): String = block suspend fun test() = foo(A("O", "K")) { i_param, (x_param, y_param), v_param -> i_param.toString() + x_param + y_param + v_param } +// Parameters (including anonymous destructuring parameters) are moved to fields in the Continuation class for the suspend lambda class. +// However, in non-IR, the fields are first stored in local variables, and they are not read directly (even for destructuring components). +// In IR, the fields are directly read from. + // METHOD : OtherParametersKt$test$2.invokeSuspend(Ljava/lang/Object;)Ljava/lang/Object; + +// JVM_TEMPLATES // VARIABLE : NAME=i_param TYPE=I INDEX=2 // VARIABLE : NAME=$dstr$x_param$y_param TYPE=LA; INDEX=3 // VARIABLE : NAME=v_param TYPE=Ljava/lang/String; INDEX=4 // VARIABLE : NAME=x_param TYPE=Ljava/lang/String; INDEX=5 // VARIABLE : NAME=y_param TYPE=Ljava/lang/String; INDEX=6 // VARIABLE : NAME=this TYPE=LOtherParametersKt$test$2; INDEX=0 -// VARIABLE : NAME=$result TYPE=Ljava/lang/Object; INDEX=1 \ No newline at end of file +// VARIABLE : NAME=$result TYPE=Ljava/lang/Object; INDEX=1 + +// JVM_IR_TEMPLATES +// VARIABLE : NAME=x_param TYPE=Ljava/lang/String; INDEX=2 +// VARIABLE : NAME=y_param TYPE=Ljava/lang/String; INDEX=3 +// VARIABLE : NAME=this TYPE=LOtherParametersKt$test$2; INDEX=0 +// VARIABLE : NAME=$result TYPE=Ljava/lang/Object; INDEX=1 diff --git a/compiler/testData/checkLocalVariablesTable/parametersInSuspendLambda/parameters.kt b/compiler/testData/checkLocalVariablesTable/parametersInSuspendLambda/parameters.kt index d62823663ef..895f6f67ae2 100644 --- a/compiler/testData/checkLocalVariablesTable/parametersInSuspendLambda/parameters.kt +++ b/compiler/testData/checkLocalVariablesTable/parametersInSuspendLambda/parameters.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND: JVM_IR // WITH_RUNTIME data class Data(val x: String, val y: Int, val z: Int = 0) @@ -12,7 +11,13 @@ suspend fun foo(data: Data, body: suspend Long.(String, Data, Int) -> Unit) { 1L.body("OK", data, 1) } +// Parameters (including anonymous destructuring parameters) are moved to fields in the Continuation class for the suspend lambda class. +// However, in non-IR, the fields are first stored in local variables, and they are not read directly (even for destructuring components). +// In IR, the fields are directly read from. + // METHOD : ParametersKt$test$2.invokeSuspend(Ljava/lang/Object;)Ljava/lang/Object; + +// JVM_TEMPLATES // VARIABLE : NAME=$this$foo TYPE=J INDEX=2 // VARIABLE : NAME=str TYPE=Ljava/lang/String; INDEX=4 // VARIABLE : NAME=$dstr$x$_u24__u24$z TYPE=LData; INDEX=5 @@ -20,4 +25,10 @@ suspend fun foo(data: Data, body: suspend Long.(String, Data, Int) -> Unit) { // VARIABLE : NAME=x TYPE=Ljava/lang/String; INDEX=7 // VARIABLE : NAME=z TYPE=I INDEX=8 // VARIABLE : NAME=this TYPE=LParametersKt$test$2; INDEX=0 -// VARIABLE : NAME=$result TYPE=Ljava/lang/Object; INDEX=1 \ No newline at end of file +// VARIABLE : NAME=$result TYPE=Ljava/lang/Object; INDEX=1 + +// JVM_IR_TEMPLATES +// VARIABLE : NAME=x TYPE=Ljava/lang/String; INDEX=2 +// VARIABLE : NAME=z TYPE=I INDEX=3 +// VARIABLE : NAME=this TYPE=LParametersKt$test$2; INDEX=0 +// VARIABLE : NAME=$result TYPE=Ljava/lang/Object; INDEX=1 diff --git a/compiler/testData/checkLocalVariablesTable/parametersInSuspendLambda/underscoreNames.kt b/compiler/testData/checkLocalVariablesTable/parametersInSuspendLambda/underscoreNames.kt index 369cb1f661b..88d8f116352 100644 --- a/compiler/testData/checkLocalVariablesTable/parametersInSuspendLambda/underscoreNames.kt +++ b/compiler/testData/checkLocalVariablesTable/parametersInSuspendLambda/underscoreNames.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND: JVM_IR // WITH_RUNTIME class A { operator fun component1() = "O" @@ -10,9 +9,21 @@ suspend fun foo(a: A, block: suspend (A) -> String): String = block(a) suspend fun test() = foo(A()) { (x_param, _, y_param) -> x_param + y_param } +// Parameters (including anonymous destructuring parameters) are moved to fields in the Continuation class for the suspend lambda class. +// However, in non-IR, the fields are first stored in local variables, and they are not read directly (even for destructuring components). +// In IR, the fields are directly read from. + // METHOD : UnderscoreNamesKt$test$2.invokeSuspend(Ljava/lang/Object;)Ljava/lang/Object; + +// JVM_TEMPLATES // VARIABLE : NAME=$dstr$x_param$_u24__u24$y_param TYPE=LA; INDEX=2 // VARIABLE : NAME=x_param TYPE=Ljava/lang/String; INDEX=3 // VARIABLE : NAME=y_param TYPE=Ljava/lang/String; INDEX=4 // VARIABLE : NAME=this TYPE=LUnderscoreNamesKt$test$2; INDEX=0 -// VARIABLE : NAME=$result TYPE=Ljava/lang/Object; INDEX=1 \ No newline at end of file +// VARIABLE : NAME=$result TYPE=Ljava/lang/Object; INDEX=1 + +// JVM_IR_TEMPLATES +// VARIABLE : NAME=x_param TYPE=Ljava/lang/String; INDEX=2 +// VARIABLE : NAME=y_param TYPE=Ljava/lang/String; INDEX=3 +// VARIABLE : NAME=this TYPE=LUnderscoreNamesKt$test$2; INDEX=0 +// VARIABLE : NAME=$result TYPE=Ljava/lang/Object; INDEX=1