Do not generate suspension points for crossinline lambdas

This commit is contained in:
Ilmir Usmanov
2018-01-26 22:22:33 +03:00
parent e6a353e590
commit 042ca55be7
2 changed files with 12 additions and 7 deletions
@@ -2343,10 +2343,10 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
@NotNull CallGenerator callGenerator,
@NotNull ArgumentGenerator argumentGenerator
) {
boolean isSuspendCall = CoroutineCodegenUtilKt.isSuspendNoInlineCall(resolvedCall);
boolean isSuspendNoInlineCall = CoroutineCodegenUtilKt.isSuspendNoInlineCall(resolvedCall);
boolean isConstructor = resolvedCall.getResultingDescriptor() instanceof ConstructorDescriptor;
if (!(callableMethod instanceof IntrinsicWithSpecialReceiver)) {
putReceiverAndInlineMarkerIfNeeded(callableMethod, resolvedCall, receiver, isSuspendCall, isConstructor);
putReceiverAndInlineMarkerIfNeeded(callableMethod, resolvedCall, receiver, isSuspendNoInlineCall, isConstructor);
}
callGenerator.processAndPutHiddenParameters(false);
@@ -2380,13 +2380,13 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
}
}
if (isSuspendCall) {
if (isSuspendNoInlineCall) {
addSuspendMarker(v, true);
}
callGenerator.genCall(callableMethod, resolvedCall, defaultMaskWasGenerated, this);
if (isSuspendCall) {
if (isSuspendNoInlineCall) {
addReturnsUnitMarkerIfNecessary(v, resolvedCall);
addSuspendMarker(v, false);
@@ -175,11 +175,16 @@ private fun NewResolvedCallImpl<VariableDescriptor>.asDummyOldResolvedCall(bindi
)
}
fun ResolvedCall<*>.isSuspendNoInlineCall() =
resultingDescriptor.safeAs<FunctionDescriptor>()
fun ResolvedCall<*>.isSuspendNoInlineCall(): Boolean {
val isCrossinline =
safeAs<VariableAsFunctionResolvedCall>()?.variableCall?.resultingDescriptor?.safeAs<ValueParameterDescriptor>()?.isCrossinline
?: false
return resultingDescriptor.safeAs<FunctionDescriptor>()
?.let {
it.isSuspend && (!it.isInline || it.isBuiltInSuspendCoroutineOrReturnInJvm() || it.isBuiltInSuspendCoroutineUninterceptedOrReturnInJvm())
val inline = it.isInline || isCrossinline
it.isSuspend && (!inline || it.isBuiltInSuspendCoroutineOrReturnInJvm() || it.isBuiltInSuspendCoroutineUninterceptedOrReturnInJvm())
} == true
}
fun CallableDescriptor.isSuspendFunctionNotSuspensionView(): Boolean {
if (this !is FunctionDescriptor) return false