JVM_IR: Do not generate null checks for suspend function views.
The arguments are null whenever the suspend function is resumed and takes its state from the continuation parameter.
This commit is contained in:
@@ -44,5 +44,6 @@ interface JvmLoweredDeclarationOrigin : IrDeclarationOrigin {
|
||||
object INLINE_CLASS_GENERATED_IMPL_METHOD : IrDeclarationOriginImpl("INLINE_CLASS_GENERATED_IMPL_METHOD")
|
||||
object GENERATED_ASSERTION_ENABLED_FIELD : IrDeclarationOriginImpl("GENERATED_ASSERTION_ENABLED_FIELD", isSynthetic = true)
|
||||
object GENERATED_MAIN_FOR_PARAMETERLESS_MAIN_METHOD : IrDeclarationOriginImpl("GENERATED_MAIN_FOR_PARAMETERLESS_MAIN_METHOD", isSynthetic = true)
|
||||
object SUSPEND_FUNCTION_VIEW : IrDeclarationOriginImpl("SUSPEND_FUNCTION_VIEW")
|
||||
object SUSPEND_IMPL_STATIC_FUNCTION : IrDeclarationOriginImpl("SUSPEND_IMPL_STATIC_FUNCTION", isSynthetic = true)
|
||||
}
|
||||
|
||||
+2
-4
@@ -125,12 +125,10 @@ internal fun IrFunction.shouldNotContainSuspendMarkers(context: JvmBackendContex
|
||||
// Transform `suspend fun foo(params): RetType` into `fun foo(params, $completion: Continuation<RetType>): Any?`
|
||||
// the result is called 'view', just to be consistent with old backend.
|
||||
internal fun IrFunction.getOrCreateSuspendFunctionViewIfNeeded(context: JvmBackendContext): IrFunction {
|
||||
if (!isSuspend || origin == SUSPEND_FUNCTION_VIEW) return this
|
||||
if (!isSuspend || origin == JvmLoweredDeclarationOrigin.SUSPEND_FUNCTION_VIEW) return this
|
||||
return if (isSuspend) context.suspendFunctionViews.getOrElse(this) { suspendFunctionView(context) } else this
|
||||
}
|
||||
|
||||
private object SUSPEND_FUNCTION_VIEW : IrDeclarationOriginImpl("SUSPEND_FUNCTION_VIEW")
|
||||
|
||||
private fun IrFunction.suspendFunctionView(context: JvmBackendContext): IrFunction {
|
||||
require(this.isSuspend && this is IrSimpleFunction)
|
||||
val originalDescriptor = this.descriptor
|
||||
@@ -146,7 +144,7 @@ private fun IrFunction.suspendFunctionView(context: JvmBackendContext): IrFuncti
|
||||
else
|
||||
WrappedSimpleFunctionDescriptor(sourceElement = originalDescriptor.source)
|
||||
return IrFunctionImpl(
|
||||
startOffset, endOffset, SUSPEND_FUNCTION_VIEW, IrSimpleFunctionSymbolImpl(descriptor),
|
||||
startOffset, endOffset, JvmLoweredDeclarationOrigin.SUSPEND_FUNCTION_VIEW, IrSimpleFunctionSymbolImpl(descriptor),
|
||||
name, visibility, modality, context.irBuiltIns.anyNType,
|
||||
isInline = isInline, isExternal = isExternal, isTailrec = isTailrec, isSuspend = isSuspend, isExpect = isExpect
|
||||
).also {
|
||||
|
||||
+13
-4
@@ -220,10 +220,19 @@ class ExpressionCodegen(
|
||||
irFunction.origin == JvmLoweredDeclarationOrigin.DEFAULT_IMPLS_BRIDGE ||
|
||||
irFunction.origin == JvmLoweredDeclarationOrigin.JVM_STATIC_WRAPPER ||
|
||||
irFunction.origin == JvmLoweredDeclarationOrigin.MULTIFILE_BRIDGE
|
||||
if (!notCallableFromJava) {
|
||||
irFunction.extensionReceiverParameter?.let { generateNonNullAssertion(it) }
|
||||
irFunction.valueParameters.forEach(::generateNonNullAssertion)
|
||||
}
|
||||
|
||||
if (notCallableFromJava)
|
||||
return
|
||||
|
||||
// Do not generate non-null checks for suspend function views. When resumed the arguments
|
||||
// will be null and the actual values are taken from the continuation.
|
||||
val isSuspendFunctionView = irFunction.origin == JvmLoweredDeclarationOrigin.SUSPEND_FUNCTION_VIEW
|
||||
|
||||
if (isSuspendFunctionView)
|
||||
return
|
||||
|
||||
irFunction.extensionReceiverParameter?.let { generateNonNullAssertion(it) }
|
||||
irFunction.valueParameters.forEach(::generateNonNullAssertion)
|
||||
}
|
||||
|
||||
private fun generateNonNullAssertion(param: IrValueParameter) {
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
// WITH_RUNTIME
|
||||
// WITH_COROUTINES
|
||||
// TARGET_BACKEND: JVM
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
|
||||
import helpers.*
|
||||
import kotlin.coroutines.*
|
||||
|
||||
Reference in New Issue
Block a user