Slightly cleanup coroutine codegen and utilities
Reformat, fix inspections, remove some minor leftovers after dropping experimentail coroutines.
This commit is contained in:
@@ -64,24 +64,23 @@ abstract class AbstractCoroutineCodegen(
|
||||
protected val classDescriptor = closureContext.contextDescriptor
|
||||
protected val languageVersionSettings = outerExpressionCodegen.state.languageVersionSettings
|
||||
|
||||
protected val methodToImplement =
|
||||
createImplMethod(
|
||||
INVOKE_SUSPEND_METHOD_NAME,
|
||||
SUSPEND_CALL_RESULT_NAME to classDescriptor.module.getResult(classDescriptor.builtIns.anyType)
|
||||
)
|
||||
|
||||
private fun createImplMethod(name: String, vararg parameters: Pair<String, KotlinType>) =
|
||||
protected val methodToImplement: FunctionDescriptor =
|
||||
SimpleFunctionDescriptorImpl.create(
|
||||
classDescriptor, Annotations.EMPTY, Name.identifier(name), CallableMemberDescriptor.Kind.DECLARATION,
|
||||
classDescriptor, Annotations.EMPTY, Name.identifier(INVOKE_SUSPEND_METHOD_NAME), CallableMemberDescriptor.Kind.DECLARATION,
|
||||
funDescriptor.source
|
||||
).apply {
|
||||
initialize(
|
||||
null,
|
||||
classDescriptor.thisAsReceiverParameter,
|
||||
emptyList(),
|
||||
parameters.withIndex().map { (index, nameAndType) ->
|
||||
createValueParameterForDoResume(Name.identifier(nameAndType.first), nameAndType.second, index)
|
||||
},
|
||||
listOf(
|
||||
ValueParameterDescriptorImpl(
|
||||
this, null, 0, Annotations.EMPTY, Name.identifier(SUSPEND_CALL_RESULT_NAME),
|
||||
classDescriptor.module.getResult(classDescriptor.builtIns.anyType),
|
||||
declaresDefaultValue = false, isCrossinline = false, isNoinline = false, varargElementType = null,
|
||||
SourceElement.NO_SOURCE
|
||||
)
|
||||
),
|
||||
builtIns.nullableAnyType,
|
||||
Modality.FINAL,
|
||||
DescriptorVisibilities.PUBLIC,
|
||||
@@ -89,15 +88,6 @@ abstract class AbstractCoroutineCodegen(
|
||||
)
|
||||
}
|
||||
|
||||
private fun FunctionDescriptor.createValueParameterForDoResume(name: Name, type: KotlinType, index: Int) =
|
||||
ValueParameterDescriptorImpl(
|
||||
this, null, index, Annotations.EMPTY, name,
|
||||
type,
|
||||
declaresDefaultValue = false, isCrossinline = false,
|
||||
isNoinline = false,
|
||||
varargElementType = null, source = SourceElement.NO_SOURCE
|
||||
)
|
||||
|
||||
override fun generateConstructor(): Method {
|
||||
val args = calculateConstructorParameters(typeMapper, languageVersionSettings, closure, asmType)
|
||||
val argTypes = args.map { it.fieldType }.plus(CONTINUATION_ASM_TYPE).toTypedArray()
|
||||
@@ -119,7 +109,7 @@ abstract class AbstractCoroutineCodegen(
|
||||
iv.iconst(funDescriptor.arity)
|
||||
}
|
||||
|
||||
iv.load(argTypes.map { it.size }.sum(), AsmTypes.OBJECT_TYPE)
|
||||
iv.load(argTypes.sumOf { it.size }, AsmTypes.OBJECT_TYPE)
|
||||
|
||||
val parameters =
|
||||
if (passArityToSuperClass)
|
||||
@@ -392,7 +382,7 @@ class CoroutineCodegenForLambda private constructor(
|
||||
if (generateErasedCreate) {
|
||||
load(allFunctionParameters().size + 1, AsmTypes.OBJECT_TYPE)
|
||||
} else {
|
||||
load(allFunctionParameters().map { typeMapper.mapType(it.type).size }.sum() + 1, AsmTypes.OBJECT_TYPE)
|
||||
load(allFunctionParameters().sumOf { typeMapper.mapType(it.type).size } + 1, AsmTypes.OBJECT_TYPE)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -482,7 +472,9 @@ class CoroutineCodegenForLambda private constructor(
|
||||
|
||||
val name =
|
||||
if (parameter is ReceiverParameterDescriptor)
|
||||
DescriptorAsmUtil.getNameForReceiverParameter(originalSuspendFunctionDescriptor, bindingContext, languageVersionSettings)
|
||||
DescriptorAsmUtil.getNameForReceiverParameter(
|
||||
originalSuspendFunctionDescriptor, bindingContext, languageVersionSettings
|
||||
)
|
||||
else
|
||||
(getNameForDestructuredParameterOrNull(parameter as ValueParameterDescriptor) ?: parameter.name.asString())
|
||||
val label = Label()
|
||||
@@ -705,38 +697,6 @@ class CoroutineCodegenForNamedFunction private constructor(
|
||||
)
|
||||
}
|
||||
|
||||
private fun generateGetLabelMethod() {
|
||||
val mv = v.newMethod(
|
||||
JvmDeclarationOrigin.NO_ORIGIN,
|
||||
Opcodes.ACC_SYNTHETIC or Opcodes.ACC_FINAL or AsmUtil.NO_FLAG_PACKAGE_PRIVATE,
|
||||
"getLabel",
|
||||
Type.getMethodDescriptor(Type.INT_TYPE),
|
||||
null,
|
||||
null
|
||||
)
|
||||
|
||||
mv.visitCode()
|
||||
labelFieldStackValue.put(Type.INT_TYPE, InstructionAdapter(mv))
|
||||
mv.visitInsn(Opcodes.IRETURN)
|
||||
mv.visitEnd()
|
||||
}
|
||||
|
||||
private fun generateSetLabelMethod() {
|
||||
val mv = v.newMethod(
|
||||
JvmDeclarationOrigin.NO_ORIGIN,
|
||||
Opcodes.ACC_SYNTHETIC or Opcodes.ACC_FINAL or AsmUtil.NO_FLAG_PACKAGE_PRIVATE,
|
||||
"setLabel",
|
||||
Type.getMethodDescriptor(Type.VOID_TYPE, Type.INT_TYPE),
|
||||
null,
|
||||
null
|
||||
)
|
||||
|
||||
mv.visitCode()
|
||||
labelFieldStackValue.store(StackValue.local(1, Type.INT_TYPE), InstructionAdapter(mv))
|
||||
mv.visitInsn(Opcodes.RETURN)
|
||||
mv.visitEnd()
|
||||
}
|
||||
|
||||
override fun generateKotlinMetadataAnnotation() {
|
||||
val publicAbi = InlineUtil.isInPublicInlineScope(classDescriptor)
|
||||
writeKotlinMetadata(v, state, KotlinClassHeader.Kind.SYNTHETIC_CLASS, publicAbi, 0) { av ->
|
||||
|
||||
+3
-2
@@ -1110,7 +1110,7 @@ inline fun withInstructionAdapter(block: InstructionAdapter.() -> Unit): InsnLis
|
||||
return tmpMethodNode.instructions
|
||||
}
|
||||
|
||||
fun Type.normalize() =
|
||||
fun Type.normalize(): Type =
|
||||
when (sort) {
|
||||
Type.ARRAY, Type.OBJECT -> AsmTypes.OBJECT_TYPE
|
||||
else -> this
|
||||
@@ -1156,7 +1156,7 @@ internal operator fun List<SuspensionPoint>.contains(insn: AbstractInsnNode): Bo
|
||||
any { insn in it }
|
||||
|
||||
internal fun getLastParameterIndex(desc: String, access: Int) =
|
||||
Type.getArgumentTypes(desc).dropLast(1).map { it.size }.sum() + (if (!isStatic(access)) 1 else 0)
|
||||
Type.getArgumentTypes(desc).dropLast(1).sumOf { it.size } + (if (!isStatic(access)) 1 else 0)
|
||||
|
||||
private fun getParameterTypesForCoroutineConstructor(desc: String, hasDispatchReceiver: Boolean, thisName: String) =
|
||||
listOfNotNull(if (!hasDispatchReceiver) null else Type.getObjectType(thisName)).toTypedArray() +
|
||||
@@ -1192,6 +1192,7 @@ internal fun replaceFakeContinuationsWithRealOnes(methodNode: MethodNode, contin
|
||||
}
|
||||
}
|
||||
|
||||
@Suppress("unused")
|
||||
private fun MethodNode.nodeTextWithLiveness(liveness: List<VariableLivenessFrame>): String =
|
||||
liveness.zip(this.instructions.asSequence().toList()).joinToString("\n") { (a, b) -> "$a|${b.insnText}" }
|
||||
|
||||
|
||||
+3
-7
@@ -12,8 +12,6 @@ import org.jetbrains.kotlin.codegen.inline.addFakeContinuationConstructorCallMar
|
||||
import org.jetbrains.kotlin.codegen.inline.coroutines.FOR_INLINE_SUFFIX
|
||||
import org.jetbrains.kotlin.codegen.inline.preprocessSuspendMarkers
|
||||
import org.jetbrains.kotlin.codegen.state.GenerationState
|
||||
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
||||
import org.jetbrains.kotlin.config.languageVersionSettings
|
||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||
import org.jetbrains.kotlin.psi.KtFunction
|
||||
@@ -37,9 +35,7 @@ class SuspendFunctionGenerationStrategy(
|
||||
private val containingClassInternalName: String,
|
||||
private val functionCodegen: FunctionCodegen
|
||||
) : FunctionGenerationStrategy.CodegenBased(state) {
|
||||
|
||||
private lateinit var codegen: ExpressionCodegen
|
||||
private val languageVersionSettings: LanguageVersionSettings = state.configuration.languageVersionSettings
|
||||
|
||||
private val classBuilderForCoroutineState by lazy {
|
||||
state.factory.newVisitor(
|
||||
@@ -61,7 +57,9 @@ class SuspendFunctionGenerationStrategy(
|
||||
}
|
||||
val stateMachineBuilder = createStateMachineBuilder(mv, access, name, desc)
|
||||
if (originalSuspendDescriptor.isInline) {
|
||||
return SuspendForInlineCopyingMethodVisitor(stateMachineBuilder, access, name, desc, functionCodegen::newMethod, keepAccess = false)
|
||||
return SuspendForInlineCopyingMethodVisitor(
|
||||
stateMachineBuilder, access, name, desc, functionCodegen::newMethod, keepAccess = false
|
||||
)
|
||||
}
|
||||
if (state.bindingContext[CodegenBinding.CAPTURES_CROSSINLINE_LAMBDA, originalSuspendDescriptor] == true) {
|
||||
return AddConstructorCallForCoroutineRegeneration(
|
||||
@@ -70,7 +68,6 @@ class SuspendFunctionGenerationStrategy(
|
||||
containingClassInternalName,
|
||||
originalSuspendDescriptor.dispatchReceiverParameter != null,
|
||||
containingClassInternalNameOrNull(),
|
||||
languageVersionSettings
|
||||
)
|
||||
}
|
||||
return stateMachineBuilder
|
||||
@@ -136,7 +133,6 @@ class SuspendFunctionGenerationStrategy(
|
||||
private val containingClassInternalName: String,
|
||||
private val needDispatchReceiver: Boolean,
|
||||
private val internalNameForDispatchReceiver: String?,
|
||||
private val languageVersionSettings: LanguageVersionSettings
|
||||
) : TransformationMethodVisitor(delegate, access, name, desc, signature, exceptions) {
|
||||
private val classBuilderForCoroutineState: ClassBuilder by lazy(obtainClassBuilderForCoroutineState)
|
||||
override fun performTransformations(methodNode: MethodNode) {
|
||||
|
||||
+7
-6
@@ -17,7 +17,6 @@ import org.jetbrains.kotlin.codegen.binding.CodegenBinding
|
||||
import org.jetbrains.kotlin.codegen.inline.addFakeContinuationMarker
|
||||
import org.jetbrains.kotlin.codegen.state.GenerationState
|
||||
import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper
|
||||
import org.jetbrains.kotlin.config.*
|
||||
import org.jetbrains.kotlin.coroutines.isSuspendLambda
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
||||
@@ -146,9 +145,9 @@ fun ResolvedCall<*>.replaceSuspensionFunctionWithRealDescriptor(
|
||||
ExpressionValueArgument(arguments)
|
||||
)
|
||||
|
||||
val newTypeArguments = newCandidateDescriptor.typeParameters.map {
|
||||
Pair(it, typeArguments[candidateDescriptor.typeParameters[it.index]]!!.asTypeProjection())
|
||||
}.toMap()
|
||||
val newTypeArguments = newCandidateDescriptor.typeParameters.associateWith {
|
||||
typeArguments[candidateDescriptor.typeParameters[it.index]]!!.asTypeProjection()
|
||||
}
|
||||
|
||||
newCall.setSubstitutor(
|
||||
TypeConstructorSubstitution.createByParametersMap(newTypeArguments).buildSubstitutor()
|
||||
@@ -440,7 +439,9 @@ fun FunctionDescriptor.isSuspendLambdaOrLocalFunction() = this.isSuspend && when
|
||||
else -> false
|
||||
}
|
||||
|
||||
fun FunctionDescriptor.isLocalSuspendFunctionNotSuspendLambda() = isSuspendLambdaOrLocalFunction() && this !is AnonymousFunctionDescriptor
|
||||
fun FunctionDescriptor.isLocalSuspendFunctionNotSuspendLambda(): Boolean =
|
||||
isSuspendLambdaOrLocalFunction() && this !is AnonymousFunctionDescriptor
|
||||
|
||||
@JvmField
|
||||
val CONTINUATION_ASM_TYPE = StandardNames.CONTINUATION_INTERFACE_FQ_NAME.topLevelClassAsmType()
|
||||
|
||||
@@ -451,4 +452,4 @@ fun FunctionDescriptor.isInvokeSuspendOfLambda(): Boolean {
|
||||
name.asString() != INVOKE_SUSPEND_METHOD_NAME
|
||||
) return false
|
||||
return containingDeclaration is SyntheticClassDescriptorForLambda
|
||||
}
|
||||
}
|
||||
|
||||
+2
-1
@@ -30,6 +30,7 @@ class CoroutineTransformer(
|
||||
private val superClassName: String
|
||||
) {
|
||||
private val state = inliningContext.state
|
||||
|
||||
// If we inline into inline function, we should generate both method with state-machine for Java interop and method without
|
||||
// state-machine for further transformation/inlining.
|
||||
private val generateForInline = inliningContext.callSiteInfo.isInlineOrInsideInline
|
||||
@@ -152,7 +153,7 @@ class CoroutineTransformer(
|
||||
context.continuationBuilders[continuationClassName] = classBuilder
|
||||
}
|
||||
|
||||
fun unregisterClassBuilder(continuationClassName: String) =
|
||||
private fun unregisterClassBuilder(continuationClassName: String): ClassBuilder? =
|
||||
(inliningContext as RegeneratedClassContext).continuationBuilders.remove(continuationClassName)
|
||||
|
||||
// If tail-call optimization took place, we do not need continuation class anymore, unless it is used by $$forInline method
|
||||
|
||||
Reference in New Issue
Block a user