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 CallGenerator callGenerator,
@NotNull ArgumentGenerator argumentGenerator @NotNull ArgumentGenerator argumentGenerator
) { ) {
boolean isSuspendCall = CoroutineCodegenUtilKt.isSuspendNoInlineCall(resolvedCall); boolean isSuspendNoInlineCall = CoroutineCodegenUtilKt.isSuspendNoInlineCall(resolvedCall);
boolean isConstructor = resolvedCall.getResultingDescriptor() instanceof ConstructorDescriptor; boolean isConstructor = resolvedCall.getResultingDescriptor() instanceof ConstructorDescriptor;
if (!(callableMethod instanceof IntrinsicWithSpecialReceiver)) { if (!(callableMethod instanceof IntrinsicWithSpecialReceiver)) {
putReceiverAndInlineMarkerIfNeeded(callableMethod, resolvedCall, receiver, isSuspendCall, isConstructor); putReceiverAndInlineMarkerIfNeeded(callableMethod, resolvedCall, receiver, isSuspendNoInlineCall, isConstructor);
} }
callGenerator.processAndPutHiddenParameters(false); callGenerator.processAndPutHiddenParameters(false);
@@ -2380,13 +2380,13 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
} }
} }
if (isSuspendCall) { if (isSuspendNoInlineCall) {
addSuspendMarker(v, true); addSuspendMarker(v, true);
} }
callGenerator.genCall(callableMethod, resolvedCall, defaultMaskWasGenerated, this); callGenerator.genCall(callableMethod, resolvedCall, defaultMaskWasGenerated, this);
if (isSuspendCall) { if (isSuspendNoInlineCall) {
addReturnsUnitMarkerIfNecessary(v, resolvedCall); addReturnsUnitMarkerIfNecessary(v, resolvedCall);
addSuspendMarker(v, false); addSuspendMarker(v, false);
@@ -175,11 +175,16 @@ private fun NewResolvedCallImpl<VariableDescriptor>.asDummyOldResolvedCall(bindi
) )
} }
fun ResolvedCall<*>.isSuspendNoInlineCall() = fun ResolvedCall<*>.isSuspendNoInlineCall(): Boolean {
resultingDescriptor.safeAs<FunctionDescriptor>() val isCrossinline =
safeAs<VariableAsFunctionResolvedCall>()?.variableCall?.resultingDescriptor?.safeAs<ValueParameterDescriptor>()?.isCrossinline
?: false
return resultingDescriptor.safeAs<FunctionDescriptor>()
?.let { ?.let {
it.isSuspend && (!it.isInline || it.isBuiltInSuspendCoroutineOrReturnInJvm() || it.isBuiltInSuspendCoroutineUninterceptedOrReturnInJvm()) val inline = it.isInline || isCrossinline
it.isSuspend && (!inline || it.isBuiltInSuspendCoroutineOrReturnInJvm() || it.isBuiltInSuspendCoroutineUninterceptedOrReturnInJvm())
} == true } == true
}
fun CallableDescriptor.isSuspendFunctionNotSuspensionView(): Boolean { fun CallableDescriptor.isSuspendFunctionNotSuspensionView(): Boolean {
if (this !is FunctionDescriptor) return false if (this !is FunctionDescriptor) return false