Search in sources :

Example 1 with CalculatedClosure

use of org.jetbrains.kotlin.codegen.binding.CalculatedClosure in project kotlin by JetBrains.

the class ExpressionCodegen method pushClosureOnStack.

public void pushClosureOnStack(@NotNull ClassDescriptor classDescriptor, boolean putThis, @NotNull CallGenerator callGenerator, @Nullable StackValue functionReferenceReceiver) {
    CalculatedClosure closure = bindingContext.get(CLOSURE, classDescriptor);
    if (closure == null)
        return;
    int paramIndex = 0;
    if (putThis) {
        ClassDescriptor captureThis = closure.getCaptureThis();
        if (captureThis != null) {
            StackValue thisOrOuter = generateThisOrOuter(captureThis, false);
            assert !isPrimitive(thisOrOuter.type) : "This or outer should be non primitive: " + thisOrOuter.type;
            callGenerator.putCapturedValueOnStack(thisOrOuter, thisOrOuter.type, paramIndex++);
        }
    }
    KotlinType captureReceiver = closure.getCaptureReceiverType();
    if (captureReceiver != null) {
        StackValue capturedReceiver = functionReferenceReceiver != null ? functionReferenceReceiver : generateExtensionReceiver(unwrapOriginalReceiverOwnerForSuspendFunction(context));
        callGenerator.putCapturedValueOnStack(capturedReceiver, capturedReceiver.type, paramIndex++);
    }
    for (Map.Entry<DeclarationDescriptor, EnclosedValueDescriptor> entry : closure.getCaptureVariables().entrySet()) {
        Type sharedVarType = typeMapper.getSharedVarType(entry.getKey());
        if (sharedVarType == null) {
            sharedVarType = typeMapper.mapType((VariableDescriptor) entry.getKey());
        }
        StackValue capturedVar = lookupOuterValue(entry.getValue());
        callGenerator.putCapturedValueOnStack(capturedVar, sharedVarType, paramIndex++);
    }
    ClassDescriptor superClass = DescriptorUtilsKt.getSuperClassNotAny(classDescriptor);
    if (superClass != null) {
        pushClosureOnStack(superClass, putThis && closure.getCaptureThis() == null, callGenerator, /* functionReferenceReceiver = */
        null);
    }
    if (closure.isSuspend()) {
        // resultContinuation
        if (closure.isSuspendLambda()) {
            v.aconst(null);
        } else {
            assert context.getFunctionDescriptor().isSuspend() : "Coroutines closure must be created only inside suspend functions";
            ValueParameterDescriptor continuationParameter = CollectionsKt.last(context.getFunctionDescriptor().getValueParameters());
            StackValue continuationValue = findLocalOrCapturedValue(continuationParameter);
            assert continuationValue != null : "Couldn't find a value for continuation parameter of " + context.getFunctionDescriptor();
            callGenerator.putCapturedValueOnStack(continuationValue, continuationValue.type, paramIndex++);
        }
    }
}
Also used : IElementType(com.intellij.psi.tree.IElementType) Type(org.jetbrains.org.objectweb.asm.Type) KotlinType(org.jetbrains.kotlin.types.KotlinType) KotlinType(org.jetbrains.kotlin.types.KotlinType) CalculatedClosure(org.jetbrains.kotlin.codegen.binding.CalculatedClosure) LocalVariableDescriptor(org.jetbrains.kotlin.descriptors.impl.LocalVariableDescriptor)

Aggregations

IElementType (com.intellij.psi.tree.IElementType)1 CalculatedClosure (org.jetbrains.kotlin.codegen.binding.CalculatedClosure)1 LocalVariableDescriptor (org.jetbrains.kotlin.descriptors.impl.LocalVariableDescriptor)1 KotlinType (org.jetbrains.kotlin.types.KotlinType)1 Type (org.jetbrains.org.objectweb.asm.Type)1