Add $result to suspend functions' LVT

#KT-28535
This commit is contained in:
Ilmir Usmanov
2019-03-29 18:27:29 +03:00
parent 05937a28ee
commit d2a80e7938
6 changed files with 36 additions and 19 deletions
@@ -62,7 +62,7 @@ abstract class AbstractCoroutineCodegen(
if (languageVersionSettings.isReleaseCoroutines())
createImplMethod(
INVOKE_SUSPEND_METHOD_NAME,
"\$result" to classDescriptor.module.getResult(classDescriptor.builtIns.anyType)
SUSPEND_CALL_RESULT_NAME to classDescriptor.module.getResult(classDescriptor.builtIns.anyType)
)
else
createImplMethod(
@@ -47,6 +47,7 @@ private const val COROUTINES_METADATA_CLASS_NAME_JVM_NAME = "c"
private const val COROUTINES_METADATA_VERSION_JVM_NAME = "v"
const val SUSPEND_FUNCTION_CONTINUATION_PARAMETER = "\$completion"
const val SUSPEND_CALL_RESULT_NAME = "\$result"
class CoroutineTransformerMethodVisitor(
delegate: MethodVisitor,
@@ -315,18 +316,28 @@ class CoroutineTransformerMethodVisitor(
// Warning! This is _continuation_, not _completion_, it can be allocated inside the method, thus, it is incorrect to treat it
// as a parameter
private fun addContinuationToLvt(methodNode: MethodNode, startLabel: LabelNode) {
val endLabel = LabelNode()
methodNode.instructions.insert(methodNode.instructions.last, endLabel)
methodNode.localVariables.add(
LocalVariableNode(
CONTINUATION_VARIABLE_NAME,
languageVersionSettings.continuationAsmType().descriptor,
null,
startLabel,
endLabel,
continuationIndex
)
private fun addContinuationAndResultToLvt(
methodNode: MethodNode,
startLabel: Label,
resultStartLabel: Label
) {
val endLabel = Label()
methodNode.instructions.add(withInstructionAdapter { mark(endLabel) })
methodNode.visitLocalVariable(
CONTINUATION_VARIABLE_NAME,
languageVersionSettings.continuationAsmType().descriptor,
null,
startLabel,
endLabel,
continuationIndex
)
methodNode.visitLocalVariable(
SUSPEND_CALL_RESULT_NAME,
AsmTypes.OBJECT_TYPE.descriptor,
null,
resultStartLabel,
endLabel,
dataIndex
)
}
@@ -454,12 +465,15 @@ class CoroutineTransformerMethodVisitor(
visitLabel(afterCoroutineStateCreated)
addContinuationToLvt(methodNode, LabelNode(afterCoroutineStateCreated))
visitVarInsn(Opcodes.ALOAD, continuationIndex)
getfield(classBuilderForCoroutineState.thisName, languageVersionSettings.dataFieldName(), AsmTypes.OBJECT_TYPE.descriptor)
visitVarInsn(Opcodes.ASTORE, dataIndex)
val resultStartLabel = Label()
visitLabel(resultStartLabel)
addContinuationAndResultToLvt(methodNode, afterCoroutineStateCreated, resultStartLabel)
if (!languageVersionSettings.isReleaseCoroutines()) {
visitVarInsn(Opcodes.ALOAD, continuationIndex)
getfield(classBuilderForCoroutineState.thisName, EXCEPTION_FIELD_NAME, AsmTypes.JAVA_THROWABLE_TYPE.descriptor)
@@ -13,4 +13,5 @@ class A {
// VARIABLE : NAME=this TYPE=LA; INDEX=0
// VARIABLE : NAME=l TYPE=J INDEX=1
// VARIABLE : NAME=$completion TYPE=Lkotlin/coroutines/Continuation; INDEX=3
// VARIABLE : NAME=$continuation TYPE=Lkotlin/coroutines/Continuation; INDEX=5
// VARIABLE : NAME=$continuation TYPE=Lkotlin/coroutines/Continuation; INDEX=5
// VARIABLE : NAME=$result TYPE=Ljava/lang/Object; INDEX=4
@@ -10,4 +10,5 @@ suspend fun foo1(l: Long) {
// METHOD : StaticStateMachineKt.foo1(JLkotlin/coroutines/Continuation;)Ljava/lang/Object;
// VARIABLE : NAME=l TYPE=J INDEX=0
// VARIABLE : NAME=$completion TYPE=Lkotlin/coroutines/Continuation; INDEX=2
// VARIABLE : NAME=$continuation TYPE=Lkotlin/coroutines/Continuation; INDEX=4
// VARIABLE : NAME=$continuation TYPE=Lkotlin/coroutines/Continuation; INDEX=4
// VARIABLE : NAME=$result TYPE=Ljava/lang/Object; INDEX=3
@@ -13,4 +13,5 @@ suspend fun A.foo1(l: Long) {
// VARIABLE : NAME=$this$foo1 TYPE=LA; INDEX=0
// VARIABLE : NAME=l TYPE=J INDEX=1
// VARIABLE : NAME=$completion TYPE=Lkotlin/coroutines/Continuation; INDEX=3
// VARIABLE : NAME=$continuation TYPE=Lkotlin/coroutines/Continuation; INDEX=5
// VARIABLE : NAME=$continuation TYPE=Lkotlin/coroutines/Continuation; INDEX=5
// VARIABLE : NAME=$result TYPE=Ljava/lang/Object; INDEX=4
@@ -22,4 +22,4 @@ class A {
// 1 LOCALVARIABLE a LA; L0 L.* 1
// 1 LOCALVARIABLE s Ljava/lang/String; L0 L.* 2
// 1 LOCALVARIABLE block Lkotlin/jvm/functions/Function2; L0 L.* 3
// 1 LOCALVARIABLE \$continuation Lkotlin/coroutines/Continuation; L2 L7 6
// 1 LOCALVARIABLE \$continuation Lkotlin/coroutines/Continuation; L2 L.* 6