JVM_IR: Add returns unit marker if suspend call returns unit

This commit is contained in:
Ilmir Usmanov
2019-12-19 19:54:57 +01:00
parent 1911cbb077
commit 4ef2ecf9a9
4 changed files with 18 additions and 7 deletions
@@ -423,7 +423,7 @@ internal fun addReturnsUnitMarkerIfNecessary(v: InstructionAdapter, resolvedCall
} }
} }
private fun addReturnsUnitMarker(v: InstructionAdapter) { fun addReturnsUnitMarker(v: InstructionAdapter) {
v.emitInlineMarker(INLINE_MARKER_RETURNS_UNIT) v.emitInlineMarker(INLINE_MARKER_RETURNS_UNIT)
} }
@@ -42,6 +42,7 @@ import org.jetbrains.kotlin.ir.symbols.IrValueSymbol
import org.jetbrains.kotlin.ir.types.* import org.jetbrains.kotlin.ir.types.*
import org.jetbrains.kotlin.ir.util.* import org.jetbrains.kotlin.ir.util.*
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.resolve.jvm.AsmTypes import org.jetbrains.kotlin.resolve.jvm.AsmTypes
import org.jetbrains.kotlin.resolve.jvm.AsmTypes.OBJECT_TYPE import org.jetbrains.kotlin.resolve.jvm.AsmTypes.OBJECT_TYPE
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodParameterKind import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodParameterKind
@@ -400,7 +401,7 @@ class ExpressionCodegen(
} }
expression.symbol.descriptor is ConstructorDescriptor -> expression.symbol.descriptor is ConstructorDescriptor ->
throw AssertionError("IrCall with ConstructorDescriptor: ${expression.javaClass.simpleName}") throw AssertionError("IrCall with ConstructorDescriptor: ${expression.javaClass.simpleName}")
callee.isSuspend && !irFunction.shouldNotContainSuspendMarkers() -> callee.shouldGenerateSuspendMarkers() ->
addInlineMarker(mv, isStartNotEnd = true) addInlineMarker(mv, isStartNotEnd = true)
} }
@@ -426,13 +427,20 @@ class ExpressionCodegen(
expression.markLineNumber(true) expression.markLineNumber(true)
// Do not generate redundant markers in continuation class. // Do not generate redundant markers in continuation class.
if (callee.isSuspend && !irFunction.shouldNotContainSuspendMarkers()) { if (callee.shouldGenerateSuspendMarkers()) {
addSuspendMarker(mv, isStartNotEnd = true) addSuspendMarker(mv, isStartNotEnd = true)
} }
callGenerator.genCall(callable, this, expression) callGenerator.genCall(callable, this, expression)
if (callee.isSuspend && !irFunction.shouldNotContainSuspendMarkers()) { if (callee.shouldGenerateSuspendMarkers()) {
// Check return type of non-lowered suspend call, in order to replace the result of the call with Unit,
// otherwise, it would seem like the call returns non-unit upon resume.
// See box/coroutines/tailCallOptimization/unit tests.
if (context.suspendFunctionViewToOriginal[expression.symbol.owner]?.returnType?.isUnit() == true) {
addReturnsUnitMarker(mv)
}
addSuspendMarker(mv, isStartNotEnd = false) addSuspendMarker(mv, isStartNotEnd = false)
addInlineMarker(mv, isStartNotEnd = false) addInlineMarker(mv, isStartNotEnd = false)
} }
@@ -457,6 +465,12 @@ class ExpressionCodegen(
} }
} }
private fun IrFunction.shouldGenerateSuspendMarkers(): Boolean {
if (!isSuspend) return false
if (irFunction.shouldNotContainSuspendMarkers()) return false
return !symbol.owner.isInline || fqNameForIrSerialization == FqName("kotlin.coroutines.intrinsics.IntrinsicsKt.suspendCoroutineUninterceptedOrReturn")
}
override fun visitVariable(declaration: IrVariable, data: BlockInfo): PromisedValue { override fun visitVariable(declaration: IrVariable, data: BlockInfo): PromisedValue {
val varType = typeMapper.mapType(declaration) val varType = typeMapper.mapType(declaration)
val index = frameMap.enter(declaration.symbol, varType) val index = frameMap.enter(declaration.symbol, varType)
@@ -24,9 +24,7 @@ final class InlineWithoutStateMachineKt$complexSuspend$1 {
} }
@kotlin.Metadata @kotlin.Metadata
@kotlin.coroutines.jvm.internal.DebugMetadata
final class InlineWithoutStateMachineKt$suspendHere$1 { final class InlineWithoutStateMachineKt$suspendHere$1 {
field L$0: java.lang.Object
field label: int field label: int
@org.jetbrains.annotations.NotNull field result: java.lang.Object @org.jetbrains.annotations.NotNull field result: java.lang.Object
public method <init>(p0: kotlin.coroutines.Continuation): void public method <init>(p0: kotlin.coroutines.Continuation): void
@@ -1,6 +1,5 @@
// IGNORE_BACKEND_FIR: JVM_IR // IGNORE_BACKEND_FIR: JVM_IR
// TARGET_BACKEND: JVM // TARGET_BACKEND: JVM
// IGNORE_BACKEND: JVM_IR
// FULL_JDK // FULL_JDK
// WITH_RUNTIME // WITH_RUNTIME
// WITH_COROUTINES // WITH_COROUTINES