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)
|
typeMapper.mapType(parameter.type).descriptor, null, null)
|
||||||
}
|
}
|
||||||
|
|
||||||
val classDescriptor = closureContext.contextDescriptor
|
generateDoResume()
|
||||||
|
|
||||||
// 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)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
functionCodegen.generateMethod(JvmDeclarationOrigin.NO_ORIGIN, funDescriptor,
|
functionCodegen.generateMethod(JvmDeclarationOrigin.NO_ORIGIN, funDescriptor,
|
||||||
object : FunctionGenerationStrategy.CodegenBased(state) {
|
object : FunctionGenerationStrategy.CodegenBased(state) {
|
||||||
@@ -188,17 +146,24 @@ class CoroutineCodegen(
|
|||||||
val mappedType = typeMapper.mapType(parameter.type)
|
val mappedType = typeMapper.mapType(parameter.type)
|
||||||
val newIndex = myFrameMap.enter(parameter, mappedType)
|
val newIndex = myFrameMap.enter(parameter, mappedType)
|
||||||
|
|
||||||
StackValue.field(parameter.getFieldInfoForCoroutineLambdaParameter(), generateThisOrOuter(context.thisDescriptor, false))
|
generateLoadField(parameter.getFieldInfoForCoroutineLambdaParameter())
|
||||||
.put(mappedType, v)
|
|
||||||
v.store(newIndex, mappedType)
|
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() =
|
private fun ValueParameterDescriptor.getFieldInfoForCoroutineLambdaParameter() =
|
||||||
|
createHiddenFieldInfo(type, COROUTINE_LAMBDA_PARAMETER_PREFIX + index)
|
||||||
|
|
||||||
|
private fun createHiddenFieldInfo(type: KotlinType, name: String) =
|
||||||
FieldInfo.createForHiddenField(
|
FieldInfo.createForHiddenField(
|
||||||
typeMapper.mapClass(closureContext.thisDescriptor),
|
typeMapper.mapClass(closureContext.thisDescriptor),
|
||||||
typeMapper.mapType(returnType!!),
|
typeMapper.mapType(type),
|
||||||
COROUTINE_LAMBDA_PARAMETER_PREFIX + index)
|
name
|
||||||
|
)
|
||||||
|
|
||||||
private fun generateExceptionHandlingBlock(codegen: ExpressionCodegen) {
|
private fun generateExceptionHandlingBlock(codegen: ExpressionCodegen) {
|
||||||
val handleExceptionFunction =
|
val handleExceptionFunction =
|
||||||
@@ -220,6 +185,52 @@ class CoroutineCodegen(
|
|||||||
codegen.v.areturn(Type.VOID_TYPE)
|
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) {
|
private fun InstructionAdapter.setLabelValue(value: Int) {
|
||||||
load(0, AsmTypes.OBJECT_TYPE)
|
load(0, AsmTypes.OBJECT_TYPE)
|
||||||
iconst(value)
|
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.KtElement
|
||||||
import org.jetbrains.kotlin.psi.KtExpression
|
import org.jetbrains.kotlin.psi.KtExpression
|
||||||
import org.jetbrains.kotlin.psi.KtPsiFactory
|
import org.jetbrains.kotlin.psi.KtPsiFactory
|
||||||
|
import org.jetbrains.kotlin.psi.ValueArgument
|
||||||
import org.jetbrains.kotlin.resolve.BindingTraceContext
|
import org.jetbrains.kotlin.resolve.BindingTraceContext
|
||||||
import org.jetbrains.kotlin.resolve.DelegatingBindingTrace
|
import org.jetbrains.kotlin.resolve.DelegatingBindingTrace
|
||||||
import org.jetbrains.kotlin.resolve.calls.model.ExpressionValueArgument
|
import org.jetbrains.kotlin.resolve.calls.model.ExpressionValueArgument
|
||||||
@@ -120,24 +121,40 @@ fun createResolvedCallForHandleExceptionCall(
|
|||||||
val exceptionArgument = CallMaker.makeValueArgument(psiFactory.createExpression("exception"))
|
val exceptionArgument = CallMaker.makeValueArgument(psiFactory.createExpression("exception"))
|
||||||
val continuationThisArgument = CallMaker.makeValueArgument(psiFactory.createExpression("this"))
|
val continuationThisArgument = CallMaker.makeValueArgument(psiFactory.createExpression("this"))
|
||||||
|
|
||||||
val valueArguments = listOf(exceptionArgument, continuationThisArgument)
|
val resolvedCall =
|
||||||
val call = CallMaker.makeCall(callElement, null, null, null, valueArguments)
|
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(
|
val resolvedCall = ResolvedCallImpl(
|
||||||
call,
|
call,
|
||||||
handleExceptionFunction,
|
descriptor,
|
||||||
coroutineLambdaDescriptor.extensionReceiverParameter!!.value, null, ExplicitReceiverKind.NO_EXPLICIT_RECEIVER,
|
coroutineLambdaDescriptor.extensionReceiverParameter!!.value, null, ExplicitReceiverKind.NO_EXPLICIT_RECEIVER,
|
||||||
null, DelegatingBindingTrace(BindingTraceContext().bindingContext, "Temporary trace for handleException resolution"),
|
null, DelegatingBindingTrace(BindingTraceContext().bindingContext, "Temporary trace for handleException resolution"),
|
||||||
TracingStrategy.EMPTY, MutableDataFlowInfoForArguments.WithoutArgumentsCheck(DataFlowInfo.EMPTY))
|
TracingStrategy.EMPTY, MutableDataFlowInfoForArguments.WithoutArgumentsCheck(DataFlowInfo.EMPTY))
|
||||||
|
|
||||||
handleExceptionFunction.valueParameters.zip(valueArguments).forEach {
|
descriptor.valueParameters.zip(valueArguments).forEach {
|
||||||
resolvedCall.recordValueArgument(it.first, ExpressionValueArgument(it.second))
|
resolvedCall.recordValueArgument(it.first, ExpressionValueArgument(it.second))
|
||||||
}
|
}
|
||||||
|
|
||||||
resolvedCall.setResultingSubstitutor(TypeSubstitutor.EMPTY)
|
resolvedCall.setResultingSubstitutor(TypeSubstitutor.EMPTY)
|
||||||
|
|
||||||
return HandleResultCallContext(
|
return resolvedCall
|
||||||
resolvedCall, exceptionArgument.getArgumentExpression()!!, continuationThisArgument.getArgumentExpression()!!)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun ResolvedCall<*>.isSuspensionPoint() =
|
fun ResolvedCall<*>.isSuspensionPoint() =
|
||||||
|
|||||||
Reference in New Issue
Block a user