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)