Minor. Extract several methods in coroutine codegen
This commit is contained in:
@@ -64,49 +64,7 @@ class CoroutineCodegen(
|
||||
typeMapper.mapType(parameter.type).descriptor, null, null)
|
||||
}
|
||||
|
||||
val classDescriptor = closureContext.contextDescriptor
|
||||
|
||||
// protected fun doResume(result, throwable)
|
||||
val doResumeDescriptor =
|
||||
SimpleFunctionDescriptorImpl.create(
|
||||
classDescriptor, Annotations.EMPTY, Name.identifier("doResume"), CallableMemberDescriptor.Kind.DECLARATION,
|
||||
funDescriptor.source
|
||||
).apply doResume@{
|
||||
initialize(
|
||||
/* receiverParameterType = */ null,
|
||||
classDescriptor.thisAsReceiverParameter,
|
||||
/* typeParameters = */ emptyList(),
|
||||
listOf(
|
||||
ValueParameterDescriptorImpl(
|
||||
this@doResume, null, 0, Annotations.EMPTY, Name.identifier("data"),
|
||||
module.builtIns.nullableAnyType,
|
||||
/* isDefault = */ false, /* isCrossinline = */ false,
|
||||
/* isNoinline = */ false, /* isCoroutine = */ false,
|
||||
/* varargElementType = */ null, SourceElement.NO_SOURCE
|
||||
),
|
||||
ValueParameterDescriptorImpl(
|
||||
this@doResume, null, 1, Annotations.EMPTY, Name.identifier("throwable"),
|
||||
module.builtIns.throwable.defaultType.makeNullable(),
|
||||
/* isDefault = */ false, /* isCrossinline = */ false,
|
||||
/* isNoinline = */ false, /* isCoroutine = */ false,
|
||||
/* varargElementType = */ null, SourceElement.NO_SOURCE
|
||||
)
|
||||
),
|
||||
module.builtIns.unitType,
|
||||
Modality.FINAL,
|
||||
Visibilities.PROTECTED
|
||||
)
|
||||
}
|
||||
|
||||
functionCodegen.generateMethod(OtherOrigin(element), doResumeDescriptor,
|
||||
object : FunctionGenerationStrategy.FunctionDefault(state, element as KtDeclarationWithBody) {
|
||||
override fun doGenerateBody(codegen: ExpressionCodegen, signature: JvmMethodSignature) {
|
||||
codegen.v.visitAnnotation(CONTINUATION_METHOD_ANNOTATION_DESC, true).visitEnd()
|
||||
codegen.initializeCoroutineParameters()
|
||||
super.doGenerateBody(codegen, signature)
|
||||
generateExceptionHandlingBlock(codegen)
|
||||
}
|
||||
})
|
||||
generateDoResume()
|
||||
|
||||
functionCodegen.generateMethod(JvmDeclarationOrigin.NO_ORIGIN, funDescriptor,
|
||||
object : FunctionGenerationStrategy.CodegenBased(state) {
|
||||
@@ -188,17 +146,24 @@ class CoroutineCodegen(
|
||||
val mappedType = typeMapper.mapType(parameter.type)
|
||||
val newIndex = myFrameMap.enter(parameter, mappedType)
|
||||
|
||||
StackValue.field(parameter.getFieldInfoForCoroutineLambdaParameter(), generateThisOrOuter(context.thisDescriptor, false))
|
||||
.put(mappedType, v)
|
||||
generateLoadField(parameter.getFieldInfoForCoroutineLambdaParameter())
|
||||
v.store(newIndex, mappedType)
|
||||
}
|
||||
}
|
||||
|
||||
private fun ExpressionCodegen.generateLoadField(fieldInfo: FieldInfo) {
|
||||
StackValue.field(fieldInfo, generateThisOrOuter(context.thisDescriptor, false)).put(fieldInfo.fieldType, v)
|
||||
}
|
||||
|
||||
private fun ValueParameterDescriptor.getFieldInfoForCoroutineLambdaParameter() =
|
||||
createHiddenFieldInfo(type, COROUTINE_LAMBDA_PARAMETER_PREFIX + index)
|
||||
|
||||
private fun createHiddenFieldInfo(type: KotlinType, name: String) =
|
||||
FieldInfo.createForHiddenField(
|
||||
typeMapper.mapClass(closureContext.thisDescriptor),
|
||||
typeMapper.mapType(returnType!!),
|
||||
COROUTINE_LAMBDA_PARAMETER_PREFIX + index)
|
||||
typeMapper.mapType(type),
|
||||
name
|
||||
)
|
||||
|
||||
private fun generateExceptionHandlingBlock(codegen: ExpressionCodegen) {
|
||||
val handleExceptionFunction =
|
||||
@@ -220,6 +185,52 @@ class CoroutineCodegen(
|
||||
codegen.v.areturn(Type.VOID_TYPE)
|
||||
}
|
||||
|
||||
private fun generateDoResume() {
|
||||
val classDescriptor = closureContext.contextDescriptor
|
||||
|
||||
// protected fun doResume(result, throwable)
|
||||
val doResumeDescriptor =
|
||||
SimpleFunctionDescriptorImpl.create(
|
||||
classDescriptor, Annotations.EMPTY, Name.identifier("doResume"), CallableMemberDescriptor.Kind.DECLARATION,
|
||||
funDescriptor.source
|
||||
).apply doResume@{
|
||||
initialize(
|
||||
/* receiverParameterType = */ null,
|
||||
classDescriptor.thisAsReceiverParameter,
|
||||
/* typeParameters = */ emptyList(),
|
||||
listOf(
|
||||
ValueParameterDescriptorImpl(
|
||||
this@doResume, null, 0, Annotations.EMPTY, Name.identifier("data"),
|
||||
module.builtIns.nullableAnyType,
|
||||
/* isDefault = */ false, /* isCrossinline = */ false,
|
||||
/* isNoinline = */ false, /* isCoroutine = */ false,
|
||||
/* varargElementType = */ null, SourceElement.NO_SOURCE
|
||||
),
|
||||
ValueParameterDescriptorImpl(
|
||||
this@doResume, null, 1, Annotations.EMPTY, Name.identifier("throwable"),
|
||||
module.builtIns.throwable.defaultType.makeNullable(),
|
||||
/* isDefault = */ false, /* isCrossinline = */ false,
|
||||
/* isNoinline = */ false, /* isCoroutine = */ false,
|
||||
/* varargElementType = */ null, SourceElement.NO_SOURCE
|
||||
)
|
||||
),
|
||||
module.builtIns.unitType,
|
||||
Modality.FINAL,
|
||||
Visibilities.PROTECTED
|
||||
)
|
||||
}
|
||||
|
||||
functionCodegen.generateMethod(OtherOrigin(element), doResumeDescriptor,
|
||||
object : FunctionGenerationStrategy.FunctionDefault(state, element as KtDeclarationWithBody) {
|
||||
override fun doGenerateBody(codegen: ExpressionCodegen, signature: JvmMethodSignature) {
|
||||
codegen.v.visitAnnotation(CONTINUATION_METHOD_ANNOTATION_DESC, true).visitEnd()
|
||||
codegen.initializeCoroutineParameters()
|
||||
super.doGenerateBody(codegen, signature)
|
||||
generateExceptionHandlingBlock(codegen)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
private fun InstructionAdapter.setLabelValue(value: Int) {
|
||||
load(0, AsmTypes.OBJECT_TYPE)
|
||||
iconst(value)
|
||||
|
||||
+23
-6
@@ -22,6 +22,7 @@ import org.jetbrains.kotlin.descriptors.SimpleFunctionDescriptor
|
||||
import org.jetbrains.kotlin.psi.KtElement
|
||||
import org.jetbrains.kotlin.psi.KtExpression
|
||||
import org.jetbrains.kotlin.psi.KtPsiFactory
|
||||
import org.jetbrains.kotlin.psi.ValueArgument
|
||||
import org.jetbrains.kotlin.resolve.BindingTraceContext
|
||||
import org.jetbrains.kotlin.resolve.DelegatingBindingTrace
|
||||
import org.jetbrains.kotlin.resolve.calls.model.ExpressionValueArgument
|
||||
@@ -120,24 +121,40 @@ fun createResolvedCallForHandleExceptionCall(
|
||||
val exceptionArgument = CallMaker.makeValueArgument(psiFactory.createExpression("exception"))
|
||||
val continuationThisArgument = CallMaker.makeValueArgument(psiFactory.createExpression("this"))
|
||||
|
||||
val valueArguments = listOf(exceptionArgument, continuationThisArgument)
|
||||
val call = CallMaker.makeCall(callElement, null, null, null, valueArguments)
|
||||
val resolvedCall =
|
||||
createFakeResolvedCall(
|
||||
callElement,
|
||||
coroutineLambdaDescriptor,
|
||||
handleExceptionFunction,
|
||||
listOf(exceptionArgument, continuationThisArgument)
|
||||
)
|
||||
|
||||
return HandleResultCallContext(
|
||||
resolvedCall, exceptionArgument.getArgumentExpression()!!, continuationThisArgument.getArgumentExpression()!!)
|
||||
}
|
||||
|
||||
private fun createFakeResolvedCall(
|
||||
element: KtElement,
|
||||
coroutineLambdaDescriptor: FunctionDescriptor,
|
||||
descriptor: SimpleFunctionDescriptor,
|
||||
valueArguments: List<ValueArgument>
|
||||
): ResolvedCallImpl<SimpleFunctionDescriptor> {
|
||||
val call = CallMaker.makeCall(element, null, null, null, valueArguments)
|
||||
|
||||
val resolvedCall = ResolvedCallImpl(
|
||||
call,
|
||||
handleExceptionFunction,
|
||||
descriptor,
|
||||
coroutineLambdaDescriptor.extensionReceiverParameter!!.value, null, ExplicitReceiverKind.NO_EXPLICIT_RECEIVER,
|
||||
null, DelegatingBindingTrace(BindingTraceContext().bindingContext, "Temporary trace for handleException resolution"),
|
||||
TracingStrategy.EMPTY, MutableDataFlowInfoForArguments.WithoutArgumentsCheck(DataFlowInfo.EMPTY))
|
||||
|
||||
handleExceptionFunction.valueParameters.zip(valueArguments).forEach {
|
||||
descriptor.valueParameters.zip(valueArguments).forEach {
|
||||
resolvedCall.recordValueArgument(it.first, ExpressionValueArgument(it.second))
|
||||
}
|
||||
|
||||
resolvedCall.setResultingSubstitutor(TypeSubstitutor.EMPTY)
|
||||
|
||||
return HandleResultCallContext(
|
||||
resolvedCall, exceptionArgument.getArgumentExpression()!!, continuationThisArgument.getArgumentExpression()!!)
|
||||
return resolvedCall
|
||||
}
|
||||
|
||||
fun ResolvedCall<*>.isSuspensionPoint() =
|
||||
|
||||
Reference in New Issue
Block a user