Minor. Reformat CoroutineCodegen.kt
This commit is contained in:
+203
-197
@@ -20,7 +20,10 @@ import org.jetbrains.kotlin.descriptors.impl.SimpleFunctionDescriptorImpl
|
|||||||
import org.jetbrains.kotlin.descriptors.impl.ValueParameterDescriptorImpl
|
import org.jetbrains.kotlin.descriptors.impl.ValueParameterDescriptorImpl
|
||||||
import org.jetbrains.kotlin.load.kotlin.header.KotlinClassHeader
|
import org.jetbrains.kotlin.load.kotlin.header.KotlinClassHeader
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
import org.jetbrains.kotlin.psi.*
|
import org.jetbrains.kotlin.psi.KtCallableReferenceExpression
|
||||||
|
import org.jetbrains.kotlin.psi.KtDeclarationWithBody
|
||||||
|
import org.jetbrains.kotlin.psi.KtElement
|
||||||
|
import org.jetbrains.kotlin.psi.KtFunction
|
||||||
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||||
import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns
|
import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns
|
||||||
import org.jetbrains.kotlin.resolve.descriptorUtil.module
|
import org.jetbrains.kotlin.resolve.descriptorUtil.module
|
||||||
@@ -41,48 +44,48 @@ import org.jetbrains.org.objectweb.asm.commons.Method
|
|||||||
|
|
||||||
|
|
||||||
abstract class AbstractCoroutineCodegen(
|
abstract class AbstractCoroutineCodegen(
|
||||||
outerExpressionCodegen: ExpressionCodegen,
|
outerExpressionCodegen: ExpressionCodegen,
|
||||||
element: KtElement,
|
element: KtElement,
|
||||||
closureContext: ClosureContext,
|
closureContext: ClosureContext,
|
||||||
classBuilder: ClassBuilder,
|
classBuilder: ClassBuilder,
|
||||||
userDataForDoResume: Map<out FunctionDescriptor.UserDataKey<*>, *>? = null
|
userDataForDoResume: Map<out FunctionDescriptor.UserDataKey<*>, *>? = null
|
||||||
) : ClosureCodegen(
|
) : ClosureCodegen(
|
||||||
outerExpressionCodegen.state,
|
outerExpressionCodegen.state,
|
||||||
element, null, closureContext, null,
|
element, null, closureContext, null,
|
||||||
FailingFunctionGenerationStrategy,
|
FailingFunctionGenerationStrategy,
|
||||||
outerExpressionCodegen.parentCodegen, classBuilder
|
outerExpressionCodegen.parentCodegen, classBuilder
|
||||||
) {
|
) {
|
||||||
protected val classDescriptor = closureContext.contextDescriptor
|
protected val classDescriptor = closureContext.contextDescriptor
|
||||||
protected val languageVersionSettings = outerExpressionCodegen.state.languageVersionSettings
|
protected val languageVersionSettings = outerExpressionCodegen.state.languageVersionSettings
|
||||||
|
|
||||||
protected val doResumeDescriptor =
|
protected val doResumeDescriptor =
|
||||||
SimpleFunctionDescriptorImpl.create(
|
SimpleFunctionDescriptorImpl.create(
|
||||||
classDescriptor, Annotations.EMPTY, Name.identifier(DO_RESUME_METHOD_NAME), CallableMemberDescriptor.Kind.DECLARATION,
|
classDescriptor, Annotations.EMPTY, Name.identifier(DO_RESUME_METHOD_NAME), CallableMemberDescriptor.Kind.DECLARATION,
|
||||||
funDescriptor.source
|
funDescriptor.source
|
||||||
).apply doResume@{
|
).apply doResume@{
|
||||||
initialize(
|
initialize(
|
||||||
null,
|
null,
|
||||||
classDescriptor.thisAsReceiverParameter,
|
classDescriptor.thisAsReceiverParameter,
|
||||||
emptyList(),
|
emptyList(),
|
||||||
listOf(
|
listOf(
|
||||||
createValueParameterForDoResume(Name.identifier("data"), builtIns.nullableAnyType, 0),
|
createValueParameterForDoResume(Name.identifier("data"), builtIns.nullableAnyType, 0),
|
||||||
createValueParameterForDoResume(Name.identifier("throwable"), builtIns.throwable.defaultType.makeNullable(), 1)
|
createValueParameterForDoResume(Name.identifier("throwable"), builtIns.throwable.defaultType.makeNullable(), 1)
|
||||||
),
|
),
|
||||||
builtIns.nullableAnyType,
|
builtIns.nullableAnyType,
|
||||||
Modality.FINAL,
|
Modality.FINAL,
|
||||||
Visibilities.PUBLIC,
|
Visibilities.PUBLIC,
|
||||||
userDataForDoResume
|
userDataForDoResume
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun FunctionDescriptor.createValueParameterForDoResume(name: Name, type: KotlinType, index: Int) =
|
private fun FunctionDescriptor.createValueParameterForDoResume(name: Name, type: KotlinType, index: Int) =
|
||||||
ValueParameterDescriptorImpl(
|
ValueParameterDescriptorImpl(
|
||||||
this, null, index, Annotations.EMPTY, name,
|
this, null, index, Annotations.EMPTY, name,
|
||||||
type,
|
type,
|
||||||
false, false,
|
false, false,
|
||||||
false,
|
false,
|
||||||
null, SourceElement.NO_SOURCE
|
null, SourceElement.NO_SOURCE
|
||||||
)
|
)
|
||||||
|
|
||||||
override fun generateConstructor(): Method {
|
override fun generateConstructor(): Method {
|
||||||
val args = calculateConstructorParameters(typeMapper, closure, asmType)
|
val args = calculateConstructorParameters(typeMapper, closure, asmType)
|
||||||
@@ -90,8 +93,8 @@ abstract class AbstractCoroutineCodegen(
|
|||||||
|
|
||||||
val constructor = Method("<init>", Type.VOID_TYPE, argTypes)
|
val constructor = Method("<init>", Type.VOID_TYPE, argTypes)
|
||||||
val mv = v.newMethod(
|
val mv = v.newMethod(
|
||||||
OtherOrigin(element, funDescriptor), visibilityFlag, "<init>", constructor.descriptor, null,
|
OtherOrigin(element, funDescriptor), visibilityFlag, "<init>", constructor.descriptor, null,
|
||||||
ArrayUtil.EMPTY_STRING_ARRAY
|
ArrayUtil.EMPTY_STRING_ARRAY
|
||||||
)
|
)
|
||||||
|
|
||||||
if (state.classBuilderMode.generateBodies) {
|
if (state.classBuilderMode.generateBodies) {
|
||||||
@@ -123,15 +126,15 @@ abstract class AbstractCoroutineCodegen(
|
|||||||
}
|
}
|
||||||
|
|
||||||
class CoroutineCodegenForLambda private constructor(
|
class CoroutineCodegenForLambda private constructor(
|
||||||
outerExpressionCodegen: ExpressionCodegen,
|
outerExpressionCodegen: ExpressionCodegen,
|
||||||
element: KtElement,
|
element: KtElement,
|
||||||
private val closureContext: ClosureContext,
|
private val closureContext: ClosureContext,
|
||||||
classBuilder: ClassBuilder,
|
classBuilder: ClassBuilder,
|
||||||
private val originalSuspendFunctionDescriptor: FunctionDescriptor,
|
private val originalSuspendFunctionDescriptor: FunctionDescriptor,
|
||||||
private val forInline: Boolean
|
private val forInline: Boolean
|
||||||
) : AbstractCoroutineCodegen(
|
) : AbstractCoroutineCodegen(
|
||||||
outerExpressionCodegen, element, closureContext, classBuilder,
|
outerExpressionCodegen, element, closureContext, classBuilder,
|
||||||
userDataForDoResume = mapOf(INITIAL_SUSPEND_DESCRIPTOR_FOR_DO_RESUME to originalSuspendFunctionDescriptor)
|
userDataForDoResume = mapOf(INITIAL_SUSPEND_DESCRIPTOR_FOR_DO_RESUME to originalSuspendFunctionDescriptor)
|
||||||
) {
|
) {
|
||||||
private val builtIns = funDescriptor.builtIns
|
private val builtIns = funDescriptor.builtIns
|
||||||
|
|
||||||
@@ -164,10 +167,10 @@ class CoroutineCodegenForLambda private constructor(
|
|||||||
for (parameter in allFunctionParameters()) {
|
for (parameter in allFunctionParameters()) {
|
||||||
val fieldInfo = parameter.getFieldInfoForCoroutineLambdaParameter()
|
val fieldInfo = parameter.getFieldInfoForCoroutineLambdaParameter()
|
||||||
v.newField(
|
v.newField(
|
||||||
OtherOrigin(parameter),
|
OtherOrigin(parameter),
|
||||||
Opcodes.ACC_PRIVATE,
|
Opcodes.ACC_PRIVATE,
|
||||||
fieldInfo.fieldName,
|
fieldInfo.fieldName,
|
||||||
fieldInfo.fieldType.descriptor, null, null
|
fieldInfo.fieldType.descriptor, null, null
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -207,19 +210,19 @@ class CoroutineCodegenForLambda private constructor(
|
|||||||
// this
|
// this
|
||||||
load(0, AsmTypes.OBJECT_TYPE)
|
load(0, AsmTypes.OBJECT_TYPE)
|
||||||
val parameterTypes = signature.valueParameters.map { it.asmType }
|
val parameterTypes = signature.valueParameters.map { it.asmType }
|
||||||
parameterTypes.withVariableIndices().forEach {
|
parameterTypes.withVariableIndices().forEach { (index, type) ->
|
||||||
(index, type) -> load(index + 1, type)
|
load(index + 1, type)
|
||||||
}
|
}
|
||||||
|
|
||||||
// this.create(..)
|
// this.create(..)
|
||||||
invokevirtual(
|
invokevirtual(
|
||||||
v.thisName,
|
v.thisName,
|
||||||
createCoroutineDescriptor.name.identifier,
|
createCoroutineDescriptor.name.identifier,
|
||||||
Type.getMethodDescriptor(
|
Type.getMethodDescriptor(
|
||||||
languageVersionSettings.continuationAsmType(),
|
languageVersionSettings.continuationAsmType(),
|
||||||
*parameterTypes.toTypedArray()
|
*parameterTypes.toTypedArray()
|
||||||
),
|
),
|
||||||
false
|
false
|
||||||
)
|
)
|
||||||
checkcast(Type.getObjectType(v.thisName))
|
checkcast(Type.getObjectType(v.thisName))
|
||||||
|
|
||||||
@@ -276,9 +279,9 @@ class CoroutineCodegenForLambda private constructor(
|
|||||||
private fun ExpressionCodegen.initializeCoroutineParameters() {
|
private fun ExpressionCodegen.initializeCoroutineParameters() {
|
||||||
for (parameter in allFunctionParameters()) {
|
for (parameter in allFunctionParameters()) {
|
||||||
val fieldStackValue =
|
val fieldStackValue =
|
||||||
StackValue.field(
|
StackValue.field(
|
||||||
parameter.getFieldInfoForCoroutineLambdaParameter(), generateThisOrOuter(context.thisDescriptor, false)
|
parameter.getFieldInfoForCoroutineLambdaParameter(), generateThisOrOuter(context.thisDescriptor, false)
|
||||||
)
|
)
|
||||||
|
|
||||||
val mappedType = typeMapper.mapType(parameter.type)
|
val mappedType = typeMapper.mapType(parameter.type)
|
||||||
fieldStackValue.put(mappedType, v)
|
fieldStackValue.put(mappedType, v)
|
||||||
@@ -291,78 +294,81 @@ class CoroutineCodegenForLambda private constructor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun allFunctionParameters() =
|
private fun allFunctionParameters() =
|
||||||
originalSuspendFunctionDescriptor.extensionReceiverParameter.let(::listOfNotNull) +
|
originalSuspendFunctionDescriptor.extensionReceiverParameter.let(::listOfNotNull) +
|
||||||
originalSuspendFunctionDescriptor.valueParameters
|
originalSuspendFunctionDescriptor.valueParameters
|
||||||
|
|
||||||
private fun ParameterDescriptor.getFieldInfoForCoroutineLambdaParameter() =
|
private fun ParameterDescriptor.getFieldInfoForCoroutineLambdaParameter() =
|
||||||
createHiddenFieldInfo(type, COROUTINE_LAMBDA_PARAMETER_PREFIX + (this.safeAs<ValueParameterDescriptor>()?.index ?: ""))
|
createHiddenFieldInfo(type, COROUTINE_LAMBDA_PARAMETER_PREFIX + (this.safeAs<ValueParameterDescriptor>()?.index ?: ""))
|
||||||
|
|
||||||
private fun createHiddenFieldInfo(type: KotlinType, name: String) =
|
private fun createHiddenFieldInfo(type: KotlinType, name: String) =
|
||||||
FieldInfo.createForHiddenField(
|
FieldInfo.createForHiddenField(
|
||||||
typeMapper.mapClass(closureContext.thisDescriptor),
|
typeMapper.mapClass(closureContext.thisDescriptor),
|
||||||
typeMapper.mapType(type),
|
typeMapper.mapType(type),
|
||||||
name
|
name
|
||||||
)
|
)
|
||||||
|
|
||||||
private fun generateDoResume() {
|
private fun generateDoResume() {
|
||||||
functionCodegen.generateMethod(
|
functionCodegen.generateMethod(
|
||||||
OtherOrigin(element),
|
OtherOrigin(element),
|
||||||
doResumeDescriptor,
|
doResumeDescriptor,
|
||||||
object : FunctionGenerationStrategy.FunctionDefault(state, element as KtDeclarationWithBody) {
|
object : FunctionGenerationStrategy.FunctionDefault(state, element as KtDeclarationWithBody) {
|
||||||
|
|
||||||
override fun wrapMethodVisitor(mv: MethodVisitor, access: Int, name: String, desc: String): MethodVisitor {
|
override fun wrapMethodVisitor(mv: MethodVisitor, access: Int, name: String, desc: String): MethodVisitor {
|
||||||
if (forInline) return super.wrapMethodVisitor(mv, access, name, desc)
|
if (forInline) return super.wrapMethodVisitor(mv, access, name, desc)
|
||||||
return CoroutineTransformerMethodVisitor(
|
return CoroutineTransformerMethodVisitor(
|
||||||
mv, access, name, desc, null, null,
|
mv, access, name, desc, null, null,
|
||||||
obtainClassBuilderForCoroutineState = { v },
|
obtainClassBuilderForCoroutineState = { v },
|
||||||
lineNumber = CodegenUtil.getLineNumberForElement(element, false) ?: 0,
|
lineNumber = CodegenUtil.getLineNumberForElement(element, false) ?: 0,
|
||||||
shouldPreserveClassInitialization = constructorCallNormalizationMode.shouldPreserveClassInitialization,
|
shouldPreserveClassInitialization = constructorCallNormalizationMode.shouldPreserveClassInitialization,
|
||||||
containingClassInternalName = v.thisName,
|
containingClassInternalName = v.thisName,
|
||||||
isForNamedFunction = false,
|
isForNamedFunction = false,
|
||||||
languageVersionSettings = languageVersionSettings
|
languageVersionSettings = languageVersionSettings
|
||||||
)
|
)
|
||||||
}
|
|
||||||
|
|
||||||
override fun doGenerateBody(codegen: ExpressionCodegen, signature: JvmMethodSignature) {
|
|
||||||
codegen.initializeCoroutineParameters()
|
|
||||||
super.doGenerateBody(codegen, signature)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun doGenerateBody(codegen: ExpressionCodegen, signature: JvmMethodSignature) {
|
||||||
|
codegen.initializeCoroutineParameters()
|
||||||
|
super.doGenerateBody(codegen, signature)
|
||||||
|
}
|
||||||
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
fun create(
|
fun create(
|
||||||
expressionCodegen: ExpressionCodegen,
|
expressionCodegen: ExpressionCodegen,
|
||||||
originalSuspendLambdaDescriptor: FunctionDescriptor,
|
originalSuspendLambdaDescriptor: FunctionDescriptor,
|
||||||
declaration: KtElement,
|
declaration: KtElement,
|
||||||
classBuilder: ClassBuilder
|
classBuilder: ClassBuilder
|
||||||
): ClosureCodegen? {
|
): ClosureCodegen? {
|
||||||
if (!originalSuspendLambdaDescriptor.isSuspendLambdaOrLocalFunction() || declaration is KtCallableReferenceExpression) return null
|
if (!originalSuspendLambdaDescriptor.isSuspendLambdaOrLocalFunction() || declaration is KtCallableReferenceExpression) return null
|
||||||
|
|
||||||
return CoroutineCodegenForLambda(
|
return CoroutineCodegenForLambda(
|
||||||
expressionCodegen,
|
expressionCodegen,
|
||||||
declaration,
|
declaration,
|
||||||
expressionCodegen.context.intoCoroutineClosure(
|
expressionCodegen.context.intoCoroutineClosure(
|
||||||
getOrCreateJvmSuspendFunctionView(originalSuspendLambdaDescriptor, expressionCodegen.state),
|
getOrCreateJvmSuspendFunctionView(
|
||||||
originalSuspendLambdaDescriptor, expressionCodegen, expressionCodegen.state.typeMapper
|
originalSuspendLambdaDescriptor,
|
||||||
|
expressionCodegen.state
|
||||||
),
|
),
|
||||||
classBuilder,
|
originalSuspendLambdaDescriptor, expressionCodegen, expressionCodegen.state.typeMapper
|
||||||
originalSuspendLambdaDescriptor,
|
),
|
||||||
// Local suspend lambdas, which call crossinline suspend parameters of containing functions must be generated after inlining
|
classBuilder,
|
||||||
expressionCodegen.bindingContext[CAPTURES_CROSSINLINE_SUSPEND_LAMBDA, originalSuspendLambdaDescriptor] == true
|
originalSuspendLambdaDescriptor,
|
||||||
|
// Local suspend lambdas, which call crossinline suspend parameters of containing functions must be generated after inlining
|
||||||
|
expressionCodegen.bindingContext[CAPTURES_CROSSINLINE_SUSPEND_LAMBDA, originalSuspendLambdaDescriptor] == true
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class CoroutineCodegenForNamedFunction private constructor(
|
class CoroutineCodegenForNamedFunction private constructor(
|
||||||
outerExpressionCodegen: ExpressionCodegen,
|
outerExpressionCodegen: ExpressionCodegen,
|
||||||
element: KtElement,
|
element: KtElement,
|
||||||
closureContext: ClosureContext,
|
closureContext: ClosureContext,
|
||||||
classBuilder: ClassBuilder,
|
classBuilder: ClassBuilder,
|
||||||
originalSuspendFunctionDescriptor: FunctionDescriptor
|
originalSuspendFunctionDescriptor: FunctionDescriptor
|
||||||
) : AbstractCoroutineCodegen(outerExpressionCodegen, element, closureContext, classBuilder) {
|
) : AbstractCoroutineCodegen(outerExpressionCodegen, element, closureContext, classBuilder) {
|
||||||
private val labelFieldStackValue = StackValue.field(
|
private val labelFieldStackValue = StackValue.field(
|
||||||
FieldInfo.createForHiddenField(
|
FieldInfo.createForHiddenField(
|
||||||
@@ -373,7 +379,7 @@ class CoroutineCodegenForNamedFunction private constructor(
|
|||||||
StackValue.LOCAL_0
|
StackValue.LOCAL_0
|
||||||
)
|
)
|
||||||
private val suspendFunctionJvmView =
|
private val suspendFunctionJvmView =
|
||||||
bindingContext[CodegenBinding.SUSPEND_FUNCTION_TO_JVM_VIEW, originalSuspendFunctionDescriptor]!!
|
bindingContext[CodegenBinding.SUSPEND_FUNCTION_TO_JVM_VIEW, originalSuspendFunctionDescriptor]!!
|
||||||
|
|
||||||
override val passArityToSuperClass get() = false
|
override val passArityToSuperClass get() = false
|
||||||
|
|
||||||
@@ -388,85 +394,84 @@ class CoroutineCodegenForNamedFunction private constructor(
|
|||||||
generateSetLabelMethod()
|
generateSetLabelMethod()
|
||||||
|
|
||||||
v.newField(
|
v.newField(
|
||||||
JvmDeclarationOrigin.NO_ORIGIN, Opcodes.ACC_SYNTHETIC or AsmUtil.NO_FLAG_PACKAGE_PRIVATE,
|
JvmDeclarationOrigin.NO_ORIGIN, Opcodes.ACC_SYNTHETIC or AsmUtil.NO_FLAG_PACKAGE_PRIVATE,
|
||||||
DATA_FIELD_NAME, AsmTypes.OBJECT_TYPE.descriptor, null, null
|
DATA_FIELD_NAME, AsmTypes.OBJECT_TYPE.descriptor, null, null
|
||||||
)
|
)
|
||||||
v.newField(
|
v.newField(
|
||||||
JvmDeclarationOrigin.NO_ORIGIN, Opcodes.ACC_SYNTHETIC or AsmUtil.NO_FLAG_PACKAGE_PRIVATE,
|
JvmDeclarationOrigin.NO_ORIGIN, Opcodes.ACC_SYNTHETIC or AsmUtil.NO_FLAG_PACKAGE_PRIVATE,
|
||||||
EXCEPTION_FIELD_NAME, AsmTypes.JAVA_THROWABLE_TYPE.descriptor, null, null
|
EXCEPTION_FIELD_NAME, AsmTypes.JAVA_THROWABLE_TYPE.descriptor, null, null
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun generateDoResume() {
|
private fun generateDoResume() {
|
||||||
functionCodegen.generateMethod(
|
functionCodegen.generateMethod(
|
||||||
OtherOrigin(element),
|
OtherOrigin(element),
|
||||||
doResumeDescriptor,
|
doResumeDescriptor,
|
||||||
object : FunctionGenerationStrategy.CodegenBased(state) {
|
object : FunctionGenerationStrategy.CodegenBased(state) {
|
||||||
override fun doGenerateBody(codegen: ExpressionCodegen, signature: JvmMethodSignature) {
|
override fun doGenerateBody(codegen: ExpressionCodegen, signature: JvmMethodSignature) {
|
||||||
StackValue.field(
|
StackValue.field(
|
||||||
AsmTypes.OBJECT_TYPE, Type.getObjectType(v.thisName), DATA_FIELD_NAME, false,
|
AsmTypes.OBJECT_TYPE, Type.getObjectType(v.thisName), DATA_FIELD_NAME, false,
|
||||||
StackValue.LOCAL_0
|
StackValue.LOCAL_0
|
||||||
).store(StackValue.local(1, AsmTypes.OBJECT_TYPE), codegen.v)
|
).store(StackValue.local(1, AsmTypes.OBJECT_TYPE), codegen.v)
|
||||||
|
|
||||||
StackValue.field(
|
StackValue.field(
|
||||||
AsmTypes.JAVA_THROWABLE_TYPE, Type.getObjectType(v.thisName), EXCEPTION_FIELD_NAME, false,
|
AsmTypes.JAVA_THROWABLE_TYPE, Type.getObjectType(v.thisName), EXCEPTION_FIELD_NAME, false,
|
||||||
StackValue.LOCAL_0
|
StackValue.LOCAL_0
|
||||||
).store(StackValue.local(2, AsmTypes.JAVA_THROWABLE_TYPE), codegen.v)
|
).store(StackValue.local(2, AsmTypes.JAVA_THROWABLE_TYPE), codegen.v)
|
||||||
|
|
||||||
labelFieldStackValue.store(
|
labelFieldStackValue.store(
|
||||||
StackValue.operation(Type.INT_TYPE) {
|
StackValue.operation(Type.INT_TYPE) {
|
||||||
labelFieldStackValue.put(Type.INT_TYPE, it)
|
labelFieldStackValue.put(Type.INT_TYPE, it)
|
||||||
it.iconst(1 shl 31)
|
it.iconst(1 shl 31)
|
||||||
it.or(Type.INT_TYPE)
|
it.or(Type.INT_TYPE)
|
||||||
},
|
},
|
||||||
codegen.v
|
codegen.v
|
||||||
|
)
|
||||||
|
|
||||||
|
val captureThisType = closure.captureThis?.let(typeMapper::mapType)
|
||||||
|
if (captureThisType != null) {
|
||||||
|
StackValue.field(
|
||||||
|
captureThisType, Type.getObjectType(v.thisName), AsmUtil.CAPTURED_THIS_FIELD,
|
||||||
|
false, StackValue.LOCAL_0
|
||||||
|
).put(captureThisType, codegen.v)
|
||||||
|
}
|
||||||
|
|
||||||
|
val isInterfaceMethod = DescriptorUtils.isInterface(suspendFunctionJvmView.containingDeclaration)
|
||||||
|
val callableMethod =
|
||||||
|
typeMapper.mapToCallableMethod(
|
||||||
|
suspendFunctionJvmView,
|
||||||
|
// Obtain default impls method for interfaces
|
||||||
|
isInterfaceMethod
|
||||||
)
|
)
|
||||||
|
|
||||||
val captureThisType = closure.captureThis?.let(typeMapper::mapType)
|
for (argumentType in callableMethod.getAsmMethod().argumentTypes.dropLast(1)) {
|
||||||
if (captureThisType != null) {
|
AsmUtil.pushDefaultValueOnStack(argumentType, codegen.v)
|
||||||
StackValue.field(
|
|
||||||
captureThisType, Type.getObjectType(v.thisName), AsmUtil.CAPTURED_THIS_FIELD,
|
|
||||||
false, StackValue.LOCAL_0
|
|
||||||
).put(captureThisType, codegen.v)
|
|
||||||
}
|
|
||||||
|
|
||||||
val isInterfaceMethod = DescriptorUtils.isInterface(suspendFunctionJvmView.containingDeclaration)
|
|
||||||
val callableMethod =
|
|
||||||
typeMapper.mapToCallableMethod(
|
|
||||||
suspendFunctionJvmView,
|
|
||||||
// Obtain default impls method for interfaces
|
|
||||||
isInterfaceMethod
|
|
||||||
)
|
|
||||||
|
|
||||||
for (argumentType in callableMethod.getAsmMethod().argumentTypes.dropLast(1)) {
|
|
||||||
AsmUtil.pushDefaultValueOnStack(argumentType, codegen.v)
|
|
||||||
}
|
|
||||||
|
|
||||||
codegen.v.load(0, AsmTypes.OBJECT_TYPE)
|
|
||||||
|
|
||||||
if (suspendFunctionJvmView.isOverridable && !isInterfaceMethod && captureThisType != null) {
|
|
||||||
val owner = captureThisType.internalName
|
|
||||||
val impl = callableMethod.getAsmMethod().getImplForOpenMethod(owner)
|
|
||||||
codegen.v.invokestatic(owner, impl.name, impl.descriptor, false)
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
callableMethod.genInvokeInstruction(codegen.v)
|
|
||||||
}
|
|
||||||
|
|
||||||
codegen.v.visitInsn(Opcodes.ARETURN)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
codegen.v.load(0, AsmTypes.OBJECT_TYPE)
|
||||||
|
|
||||||
|
if (suspendFunctionJvmView.isOverridable && !isInterfaceMethod && captureThisType != null) {
|
||||||
|
val owner = captureThisType.internalName
|
||||||
|
val impl = callableMethod.getAsmMethod().getImplForOpenMethod(owner)
|
||||||
|
codegen.v.invokestatic(owner, impl.name, impl.descriptor, false)
|
||||||
|
} else {
|
||||||
|
callableMethod.genInvokeInstruction(codegen.v)
|
||||||
|
}
|
||||||
|
|
||||||
|
codegen.v.visitInsn(Opcodes.ARETURN)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun generateGetLabelMethod() {
|
private fun generateGetLabelMethod() {
|
||||||
val mv = v.newMethod(
|
val mv = v.newMethod(
|
||||||
JvmDeclarationOrigin.NO_ORIGIN,
|
JvmDeclarationOrigin.NO_ORIGIN,
|
||||||
Opcodes.ACC_SYNTHETIC or Opcodes.ACC_FINAL or AsmUtil.NO_FLAG_PACKAGE_PRIVATE,
|
Opcodes.ACC_SYNTHETIC or Opcodes.ACC_FINAL or AsmUtil.NO_FLAG_PACKAGE_PRIVATE,
|
||||||
"getLabel",
|
"getLabel",
|
||||||
Type.getMethodDescriptor(Type.INT_TYPE),
|
Type.getMethodDescriptor(Type.INT_TYPE),
|
||||||
null,
|
null,
|
||||||
null
|
null
|
||||||
)
|
)
|
||||||
|
|
||||||
mv.visitCode()
|
mv.visitCode()
|
||||||
@@ -477,12 +482,12 @@ class CoroutineCodegenForNamedFunction private constructor(
|
|||||||
|
|
||||||
private fun generateSetLabelMethod() {
|
private fun generateSetLabelMethod() {
|
||||||
val mv = v.newMethod(
|
val mv = v.newMethod(
|
||||||
JvmDeclarationOrigin.NO_ORIGIN,
|
JvmDeclarationOrigin.NO_ORIGIN,
|
||||||
Opcodes.ACC_SYNTHETIC or Opcodes.ACC_FINAL or AsmUtil.NO_FLAG_PACKAGE_PRIVATE,
|
Opcodes.ACC_SYNTHETIC or Opcodes.ACC_FINAL or AsmUtil.NO_FLAG_PACKAGE_PRIVATE,
|
||||||
"setLabel",
|
"setLabel",
|
||||||
Type.getMethodDescriptor(Type.VOID_TYPE, Type.INT_TYPE),
|
Type.getMethodDescriptor(Type.VOID_TYPE, Type.INT_TYPE),
|
||||||
null,
|
null,
|
||||||
null
|
null
|
||||||
)
|
)
|
||||||
|
|
||||||
mv.visitCode()
|
mv.visitCode()
|
||||||
@@ -498,36 +503,37 @@ class CoroutineCodegenForNamedFunction private constructor(
|
|||||||
AsmUtil.writeAnnotationData(av, serializer, functionProto)
|
AsmUtil.writeAnnotationData(av, serializer, functionProto)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
fun create(
|
fun create(
|
||||||
cv: ClassBuilder,
|
cv: ClassBuilder,
|
||||||
expressionCodegen: ExpressionCodegen,
|
expressionCodegen: ExpressionCodegen,
|
||||||
originalSuspendDescriptor: FunctionDescriptor,
|
originalSuspendDescriptor: FunctionDescriptor,
|
||||||
declaration: KtFunction
|
declaration: KtFunction
|
||||||
): CoroutineCodegenForNamedFunction {
|
): CoroutineCodegenForNamedFunction {
|
||||||
val bindingContext = expressionCodegen.state.bindingContext
|
val bindingContext = expressionCodegen.state.bindingContext
|
||||||
val closure =
|
val closure =
|
||||||
bindingContext[
|
bindingContext[
|
||||||
CodegenBinding.CLOSURE,
|
CodegenBinding.CLOSURE,
|
||||||
bindingContext[CodegenBinding.CLASS_FOR_CALLABLE, originalSuspendDescriptor]
|
bindingContext[CodegenBinding.CLASS_FOR_CALLABLE, originalSuspendDescriptor]
|
||||||
].sure { "There must be a closure defined for $originalSuspendDescriptor" }
|
].sure { "There must be a closure defined for $originalSuspendDescriptor" }
|
||||||
|
|
||||||
val suspendFunctionView =
|
val suspendFunctionView =
|
||||||
bindingContext[
|
bindingContext[
|
||||||
CodegenBinding.SUSPEND_FUNCTION_TO_JVM_VIEW, originalSuspendDescriptor
|
CodegenBinding.SUSPEND_FUNCTION_TO_JVM_VIEW, originalSuspendDescriptor
|
||||||
].sure { "There must be a jvm view defined for $originalSuspendDescriptor" }
|
].sure { "There must be a jvm view defined for $originalSuspendDescriptor" }
|
||||||
|
|
||||||
if (suspendFunctionView.dispatchReceiverParameter != null) {
|
if (suspendFunctionView.dispatchReceiverParameter != null) {
|
||||||
closure.setCaptureThis()
|
closure.setCaptureThis()
|
||||||
}
|
}
|
||||||
|
|
||||||
return CoroutineCodegenForNamedFunction(
|
return CoroutineCodegenForNamedFunction(
|
||||||
expressionCodegen, declaration,
|
expressionCodegen, declaration,
|
||||||
expressionCodegen.context.intoClosure(
|
expressionCodegen.context.intoClosure(
|
||||||
originalSuspendDescriptor, expressionCodegen, expressionCodegen.state.typeMapper
|
originalSuspendDescriptor, expressionCodegen, expressionCodegen.state.typeMapper
|
||||||
),
|
),
|
||||||
cv,
|
cv,
|
||||||
originalSuspendDescriptor
|
originalSuspendDescriptor
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -541,11 +547,11 @@ private object FailingFunctionGenerationStrategy : FunctionGenerationStrategy()
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun generateBody(
|
override fun generateBody(
|
||||||
mv: MethodVisitor,
|
mv: MethodVisitor,
|
||||||
frameMap: FrameMap,
|
frameMap: FrameMap,
|
||||||
signature: JvmMethodSignature,
|
signature: JvmMethodSignature,
|
||||||
context: MethodContext,
|
context: MethodContext,
|
||||||
parentCodegen: MemberCodegen<*>
|
parentCodegen: MemberCodegen<*>
|
||||||
) {
|
) {
|
||||||
error("This functions must not be called")
|
error("This functions must not be called")
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user