JVM_IR: do not box inline classes in suspend synthetic accessors
This commit is contained in:
+6
@@ -10643,6 +10643,12 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
|
||||
public void testReturnResult() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/coroutines/inlineClasses/resume/returnResult.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("syntheticAccessor.kt")
|
||||
public void testSyntheticAccessor() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/coroutines/inlineClasses/resume/syntheticAccessor.kt");
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
|
||||
+12
-10
@@ -20,7 +20,6 @@ import org.jetbrains.kotlin.codegen.coroutines.CoroutineTransformerMethodVisitor
|
||||
import org.jetbrains.kotlin.codegen.coroutines.INVOKE_SUSPEND_METHOD_NAME
|
||||
import org.jetbrains.kotlin.codegen.coroutines.SUSPEND_IMPL_NAME_SUFFIX
|
||||
import org.jetbrains.kotlin.codegen.coroutines.reportSuspensionPointInsideMonitor
|
||||
import org.jetbrains.kotlin.codegen.inline.coroutines.FOR_INLINE_SUFFIX
|
||||
import org.jetbrains.kotlin.config.JVMConfigurationKeys
|
||||
import org.jetbrains.kotlin.config.isReleaseCoroutines
|
||||
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
|
||||
@@ -142,16 +141,19 @@ private fun IrFunction.isStaticInlineClassReplacementDelegatingCall(): Boolean =
|
||||
parentAsClass.declarations.find { it is IrAttributeContainer && it.attributeOwnerId == attributeOwnerId && it !== this }
|
||||
?.isStaticInlineClassReplacement == true
|
||||
|
||||
internal fun IrFunction.shouldContainSuspendMarkers(): Boolean = !isInvokeSuspendOfContinuation() &&
|
||||
// These are tail-call bridges and do not require any bytecode modifications.
|
||||
origin != IrDeclarationOrigin.FUNCTION_FOR_DEFAULT_PARAMETER &&
|
||||
origin != JvmLoweredDeclarationOrigin.JVM_OVERLOADS_WRAPPER &&
|
||||
origin != JvmLoweredDeclarationOrigin.SYNTHETIC_ACCESSOR &&
|
||||
origin != JvmLoweredDeclarationOrigin.SYNTHETIC_ACCESSOR_FOR_HIDDEN_CONSTRUCTOR &&
|
||||
origin != JvmLoweredDeclarationOrigin.SUPER_INTERFACE_METHOD_BRIDGE &&
|
||||
origin != IrDeclarationOrigin.BRIDGE &&
|
||||
origin != IrDeclarationOrigin.BRIDGE_SPECIAL &&
|
||||
internal val BRIDGE_ORIGINS = setOf(
|
||||
IrDeclarationOrigin.FUNCTION_FOR_DEFAULT_PARAMETER,
|
||||
JvmLoweredDeclarationOrigin.JVM_OVERLOADS_WRAPPER,
|
||||
JvmLoweredDeclarationOrigin.SYNTHETIC_ACCESSOR,
|
||||
JvmLoweredDeclarationOrigin.SYNTHETIC_ACCESSOR_FOR_HIDDEN_CONSTRUCTOR,
|
||||
JvmLoweredDeclarationOrigin.SUPER_INTERFACE_METHOD_BRIDGE,
|
||||
IrDeclarationOrigin.BRIDGE,
|
||||
IrDeclarationOrigin.BRIDGE_SPECIAL,
|
||||
)
|
||||
|
||||
internal fun IrFunction.shouldContainSuspendMarkers(): Boolean = origin !in BRIDGE_ORIGINS &&
|
||||
origin != IrDeclarationOrigin.DELEGATED_MEMBER &&
|
||||
!isInvokeSuspendOfContinuation() &&
|
||||
!isMultifileBridge() &&
|
||||
!isInvokeOfSuspendCallableReference() &&
|
||||
!isBridgeToSuspendImplMethod() &&
|
||||
|
||||
+10
-13
@@ -229,20 +229,17 @@ class ExpressionCodegen(
|
||||
if (irFunction.origin != JvmLoweredDeclarationOrigin.CLASS_STATIC_INITIALIZER) {
|
||||
irFunction.markLineNumber(startOffset = irFunction is IrConstructor && irFunction.isPrimary)
|
||||
}
|
||||
if (irFunction.isSuspend && irFunction.origin == IrDeclarationOrigin.BRIDGE) {
|
||||
mv.areturn(OBJECT_TYPE)
|
||||
val unboxedInlineClass =
|
||||
irFunction.suspendFunctionOriginal().originalReturnTypeOfSuspendFunctionReturningUnboxedInlineClass()
|
||||
if (unboxedInlineClass != null && irFunction.origin !in BRIDGE_ORIGINS) {
|
||||
result.materializeAt(unboxedInlineClass.asmType, unboxedInlineClass)
|
||||
} else {
|
||||
var returnType = signature.returnType
|
||||
var returnIrType = if (irFunction !is IrConstructor) irFunction.returnType else context.irBuiltIns.unitType
|
||||
val unboxedInlineClass =
|
||||
irFunction.suspendFunctionOriginal().originalReturnTypeOfSuspendFunctionReturningUnboxedInlineClass()
|
||||
if (unboxedInlineClass != null) {
|
||||
returnIrType = unboxedInlineClass
|
||||
returnType = unboxedInlineClass.asmType
|
||||
}
|
||||
result.materializeAt(returnType, returnIrType)
|
||||
mv.areturn(returnType)
|
||||
val returnIrType = if (irFunction !is IrConstructor) irFunction.returnType else context.irBuiltIns.unitType
|
||||
result.materializeAt(signature.returnType, returnIrType)
|
||||
}
|
||||
// `signature.returnType` is valid here even if the return value of a suspend function was unboxed,
|
||||
// as it's still a reference type.
|
||||
mv.areturn(signature.returnType)
|
||||
}
|
||||
val endLabel = markNewLabel()
|
||||
writeLocalVariablesInTable(info, endLabel)
|
||||
@@ -508,7 +505,7 @@ class ExpressionCodegen(
|
||||
wrapJavaClassesIntoKClasses(mv)
|
||||
MaterialValue(this, AsmTypes.K_CLASS_ARRAY_TYPE, expression.type)
|
||||
}
|
||||
unboxedInlineClassIrType != null && !irFunction.isInvokeSuspendOfContinuation() ->
|
||||
unboxedInlineClassIrType != null && !irFunction.isInvokeSuspendOfContinuation() && irFunction.origin !in BRIDGE_ORIGINS ->
|
||||
object : PromisedValue(this, unboxedInlineClassIrType.asmType, unboxedInlineClassIrType) {
|
||||
override fun materializeAt(target: Type, irTarget: IrType, castForReified: Boolean) {
|
||||
mv.checkcast(unboxedInlineClassIrType.asmType)
|
||||
|
||||
+1
-1
@@ -416,7 +416,7 @@ internal class SyntheticAccessorLowering(val context: JvmBackendContext) : IrEle
|
||||
isSuspend = source.isSuspend // synthetic accessors of suspend functions are handled in codegen
|
||||
}.also { accessor ->
|
||||
accessor.parent = parent
|
||||
|
||||
accessor.copyAttributes(source)
|
||||
accessor.copyTypeParametersFrom(source, JvmLoweredDeclarationOrigin.SYNTHETIC_ACCESSOR)
|
||||
accessor.copyValueParametersToStatic(source, JvmLoweredDeclarationOrigin.SYNTHETIC_ACCESSOR, dispatchReceiverType)
|
||||
accessor.returnType = source.returnType.remapTypeParameters(source, accessor)
|
||||
|
||||
+29
@@ -0,0 +1,29 @@
|
||||
// WITH_RUNTIME
|
||||
// WITH_COROUTINES
|
||||
|
||||
import helpers.*
|
||||
import kotlin.coroutines.*
|
||||
import kotlin.coroutines.intrinsics.*
|
||||
|
||||
@Suppress("UNSUPPORTED_FEATURE")
|
||||
inline class I(val x: Any?)
|
||||
|
||||
suspend fun suspendHere(): Unit = suspendCoroutineUninterceptedOrReturn { c ->
|
||||
c.resume(Unit)
|
||||
COROUTINE_SUSPENDED
|
||||
}
|
||||
|
||||
class C {
|
||||
private suspend fun f(): I {
|
||||
suspendHere()
|
||||
return I("OK")
|
||||
}
|
||||
|
||||
fun g() = suspend { f() }
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
var result = "fail"
|
||||
suspend { result = C().g()().x as String }.startCoroutine(EmptyContinuation)
|
||||
return result
|
||||
}
|
||||
+6
@@ -10643,6 +10643,12 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
|
||||
public void testReturnResult() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/coroutines/inlineClasses/resume/returnResult.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("syntheticAccessor.kt")
|
||||
public void testSyntheticAccessor() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/coroutines/inlineClasses/resume/syntheticAccessor.kt");
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
|
||||
+6
@@ -10643,6 +10643,12 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
|
||||
public void testReturnResult() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/coroutines/inlineClasses/resume/returnResult.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("syntheticAccessor.kt")
|
||||
public void testSyntheticAccessor() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/coroutines/inlineClasses/resume/syntheticAccessor.kt");
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
|
||||
+5
@@ -8448,6 +8448,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
|
||||
public void testReturnResult() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/coroutines/inlineClasses/resume/returnResult.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("syntheticAccessor.kt")
|
||||
public void testSyntheticAccessor() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/coroutines/inlineClasses/resume/syntheticAccessor.kt");
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/codegen/box/coroutines/inlineClasses/resumeWithException")
|
||||
|
||||
js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/es6/semantics/IrJsCodegenBoxES6TestGenerated.java
Generated
+5
@@ -7592,6 +7592,11 @@ public class IrJsCodegenBoxES6TestGenerated extends AbstractIrJsCodegenBoxES6Tes
|
||||
public void testReturnResult() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/coroutines/inlineClasses/resume/returnResult.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("syntheticAccessor.kt")
|
||||
public void testSyntheticAccessor() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/coroutines/inlineClasses/resume/syntheticAccessor.kt");
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/codegen/box/coroutines/inlineClasses/resumeWithException")
|
||||
|
||||
Generated
+5
@@ -7003,6 +7003,11 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest {
|
||||
public void testReturnResult() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/coroutines/inlineClasses/resume/returnResult.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("syntheticAccessor.kt")
|
||||
public void testSyntheticAccessor() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/coroutines/inlineClasses/resume/syntheticAccessor.kt");
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/codegen/box/coroutines/inlineClasses/resumeWithException")
|
||||
|
||||
Generated
+5
@@ -7003,6 +7003,11 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest {
|
||||
public void testReturnResult() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/coroutines/inlineClasses/resume/returnResult.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("syntheticAccessor.kt")
|
||||
public void testSyntheticAccessor() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/coroutines/inlineClasses/resume/syntheticAccessor.kt");
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/codegen/box/coroutines/inlineClasses/resumeWithException")
|
||||
|
||||
Reference in New Issue
Block a user