JVM_IR: deal with inline class default values in AddContinuationLowering.
Whenever we want the default 0/null value for a type we need to check if it is a non-nullable inline class type and produce the right value for the underlying type.
This commit is contained in:
@@ -12,6 +12,7 @@ import org.jetbrains.kotlin.backend.jvm.codegen.isInlineOnly
|
|||||||
import org.jetbrains.kotlin.backend.jvm.codegen.isJvmInterface
|
import org.jetbrains.kotlin.backend.jvm.codegen.isJvmInterface
|
||||||
import org.jetbrains.kotlin.backend.jvm.descriptors.JvmDeclarationFactory
|
import org.jetbrains.kotlin.backend.jvm.descriptors.JvmDeclarationFactory
|
||||||
import org.jetbrains.kotlin.backend.jvm.lower.inlineclasses.hasMangledParameters
|
import org.jetbrains.kotlin.backend.jvm.lower.inlineclasses.hasMangledParameters
|
||||||
|
import org.jetbrains.kotlin.backend.jvm.lower.inlineclasses.unboxInlineClass
|
||||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||||
import org.jetbrains.kotlin.descriptors.Visibilities
|
import org.jetbrains.kotlin.descriptors.Visibilities
|
||||||
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
|
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
|
||||||
@@ -20,6 +21,8 @@ import org.jetbrains.kotlin.ir.builders.Scope
|
|||||||
import org.jetbrains.kotlin.ir.declarations.*
|
import org.jetbrains.kotlin.ir.declarations.*
|
||||||
import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns
|
import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns
|
||||||
import org.jetbrains.kotlin.ir.expressions.*
|
import org.jetbrains.kotlin.ir.expressions.*
|
||||||
|
import org.jetbrains.kotlin.ir.expressions.impl.IrCallImpl
|
||||||
|
import org.jetbrains.kotlin.ir.expressions.impl.IrConstImpl
|
||||||
import org.jetbrains.kotlin.ir.expressions.impl.IrGetFieldImpl
|
import org.jetbrains.kotlin.ir.expressions.impl.IrGetFieldImpl
|
||||||
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
|
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
|
||||||
import org.jetbrains.kotlin.ir.symbols.IrSymbol
|
import org.jetbrains.kotlin.ir.symbols.IrSymbol
|
||||||
@@ -88,6 +91,25 @@ val IrType.erasedUpperBound: IrClass
|
|||||||
else -> throw IllegalStateException()
|
else -> throw IllegalStateException()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the default null/0 value for the type.
|
||||||
|
*
|
||||||
|
* This handles unboxing of non-nullable inline class types to their underlying types and produces
|
||||||
|
* a null/0 default value for the resulting type. When such unboxing takes place it ensures that
|
||||||
|
* the value is not reboxed and reunboxed by the codegen by using the unsafeCoerceIntrinsic.
|
||||||
|
*/
|
||||||
|
fun IrType.defaultValue(startOffset: Int, endOffset: Int, context: JvmBackendContext): IrExpression {
|
||||||
|
if (this !is IrSimpleType || hasQuestionMark || classOrNull?.owner?.isInline != true)
|
||||||
|
return IrConstImpl.defaultValueForType(startOffset, endOffset, this)
|
||||||
|
|
||||||
|
val underlyingType = unboxInlineClass()
|
||||||
|
val defaultValueForUnderlyingType = IrConstImpl.defaultValueForType(startOffset, endOffset, underlyingType)
|
||||||
|
return IrCallImpl(startOffset, endOffset, this, context.ir.symbols.unsafeCoerceIntrinsic).also {
|
||||||
|
it.putTypeArgument(0, underlyingType) // from
|
||||||
|
it.putTypeArgument(1, this) // to
|
||||||
|
it.putValueArgument(0, defaultValueForUnderlyingType)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fun IrDeclaration.getJvmNameFromAnnotation(): String? {
|
fun IrDeclaration.getJvmNameFromAnnotation(): String? {
|
||||||
// TODO lower @JvmName?
|
// TODO lower @JvmName?
|
||||||
|
|||||||
+12
-11
@@ -13,6 +13,7 @@ import org.jetbrains.kotlin.backend.common.phaser.makeIrFilePhase
|
|||||||
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
|
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
|
||||||
import org.jetbrains.kotlin.backend.jvm.JvmLoweredDeclarationOrigin
|
import org.jetbrains.kotlin.backend.jvm.JvmLoweredDeclarationOrigin
|
||||||
import org.jetbrains.kotlin.backend.jvm.ir.IrInlineReferenceLocator
|
import org.jetbrains.kotlin.backend.jvm.ir.IrInlineReferenceLocator
|
||||||
|
import org.jetbrains.kotlin.backend.jvm.ir.defaultValue
|
||||||
import org.jetbrains.kotlin.codegen.coroutines.*
|
import org.jetbrains.kotlin.codegen.coroutines.*
|
||||||
import org.jetbrains.kotlin.codegen.inline.coroutines.FOR_INLINE_SUFFIX
|
import org.jetbrains.kotlin.codegen.inline.coroutines.FOR_INLINE_SUFFIX
|
||||||
import org.jetbrains.kotlin.descriptors.Modality
|
import org.jetbrains.kotlin.descriptors.Modality
|
||||||
@@ -23,7 +24,6 @@ import org.jetbrains.kotlin.ir.builders.*
|
|||||||
import org.jetbrains.kotlin.ir.builders.declarations.*
|
import org.jetbrains.kotlin.ir.builders.declarations.*
|
||||||
import org.jetbrains.kotlin.ir.declarations.*
|
import org.jetbrains.kotlin.ir.declarations.*
|
||||||
import org.jetbrains.kotlin.ir.expressions.*
|
import org.jetbrains.kotlin.ir.expressions.*
|
||||||
import org.jetbrains.kotlin.ir.expressions.impl.IrConstImpl
|
|
||||||
import org.jetbrains.kotlin.ir.expressions.impl.IrGetFieldImpl
|
import org.jetbrains.kotlin.ir.expressions.impl.IrGetFieldImpl
|
||||||
import org.jetbrains.kotlin.ir.expressions.impl.IrGetValueImpl
|
import org.jetbrains.kotlin.ir.expressions.impl.IrGetValueImpl
|
||||||
import org.jetbrains.kotlin.ir.expressions.impl.IrReturnImpl
|
import org.jetbrains.kotlin.ir.expressions.impl.IrReturnImpl
|
||||||
@@ -446,6 +446,7 @@ private class AddContinuationLowering(private val context: JvmBackendContext) :
|
|||||||
capturedThisField: IrField?,
|
capturedThisField: IrField?,
|
||||||
isStaticSuspendImpl: Boolean
|
isStaticSuspendImpl: Boolean
|
||||||
) {
|
) {
|
||||||
|
val backendContext = context
|
||||||
val invokeSuspend = context.ir.symbols.continuationImplClass.owner.functions
|
val invokeSuspend = context.ir.symbols.continuationImplClass.owner.functions
|
||||||
.single { it.name == Name.identifier(INVOKE_SUSPEND_METHOD_NAME) }
|
.single { it.name == Name.identifier(INVOKE_SUSPEND_METHOD_NAME) }
|
||||||
addFunctionOverride(invokeSuspend).also { function ->
|
addFunctionOverride(invokeSuspend).also { function ->
|
||||||
@@ -481,15 +482,12 @@ private class AddContinuationLowering(private val context: JvmBackendContext) :
|
|||||||
it.dispatchReceiver = capturedThisValue
|
it.dispatchReceiver = capturedThisValue
|
||||||
}
|
}
|
||||||
irFunction.extensionReceiverParameter?.let { extensionReceiverParameter ->
|
irFunction.extensionReceiverParameter?.let { extensionReceiverParameter ->
|
||||||
it.extensionReceiver = IrConstImpl.defaultValueForType(
|
it.extensionReceiver = extensionReceiverParameter.type.defaultValue(
|
||||||
UNDEFINED_OFFSET, UNDEFINED_OFFSET, extensionReceiverParameter.type
|
UNDEFINED_OFFSET, UNDEFINED_OFFSET, backendContext
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
for ((i, parameter) in irFunction.valueParameters.withIndex()) {
|
for ((i, parameter) in irFunction.valueParameters.withIndex()) {
|
||||||
val defaultValueForParameter = IrConstImpl.defaultValueForType(
|
it.putValueArgument(i, parameter.type.defaultValue(UNDEFINED_OFFSET, UNDEFINED_OFFSET, backendContext))
|
||||||
UNDEFINED_OFFSET, UNDEFINED_OFFSET, parameter.type
|
|
||||||
)
|
|
||||||
it.putValueArgument(i, defaultValueForParameter)
|
|
||||||
}
|
}
|
||||||
if (isStaticSuspendImpl) {
|
if (isStaticSuspendImpl) {
|
||||||
it.putValueArgument(0, capturedThisValue)
|
it.putValueArgument(0, capturedThisValue)
|
||||||
@@ -501,6 +499,7 @@ private class AddContinuationLowering(private val context: JvmBackendContext) :
|
|||||||
|
|
||||||
private fun createStaticSuspendImpl(irFunction: IrSimpleFunction): IrSimpleFunction {
|
private fun createStaticSuspendImpl(irFunction: IrSimpleFunction): IrSimpleFunction {
|
||||||
// Create static suspend impl method.
|
// Create static suspend impl method.
|
||||||
|
val backendContext = context
|
||||||
val static = createStaticFunctionWithReceivers(
|
val static = createStaticFunctionWithReceivers(
|
||||||
irFunction.parent,
|
irFunction.parent,
|
||||||
irFunction.name.toSuspendImplementationName(),
|
irFunction.name.toSuspendImplementationName(),
|
||||||
@@ -520,12 +519,14 @@ private class AddContinuationLowering(private val context: JvmBackendContext) :
|
|||||||
it.putValueArgument(i++, irGet(irFunction.dispatchReceiverParameter!!))
|
it.putValueArgument(i++, irGet(irFunction.dispatchReceiverParameter!!))
|
||||||
}
|
}
|
||||||
if (irFunction.extensionReceiverParameter != null) {
|
if (irFunction.extensionReceiverParameter != null) {
|
||||||
it.putValueArgument(i++, irNull())
|
val defaultValueForParameter = irFunction.extensionReceiverParameter!!.type.defaultValue(
|
||||||
|
UNDEFINED_OFFSET, UNDEFINED_OFFSET, backendContext
|
||||||
|
)
|
||||||
|
it.putValueArgument(i++, defaultValueForParameter)
|
||||||
|
|
||||||
}
|
}
|
||||||
for (parameter in irFunction.valueParameters) {
|
for (parameter in irFunction.valueParameters) {
|
||||||
val defaultValueForParameter = IrConstImpl.defaultValueForType(
|
val defaultValueForParameter = parameter.type.defaultValue(UNDEFINED_OFFSET, UNDEFINED_OFFSET, backendContext)
|
||||||
UNDEFINED_OFFSET, UNDEFINED_OFFSET, parameter.type
|
|
||||||
)
|
|
||||||
it.putValueArgument(i++, defaultValueForParameter)
|
it.putValueArgument(i++, defaultValueForParameter)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|||||||
+2
-13
@@ -7,15 +7,12 @@ package org.jetbrains.kotlin.backend.jvm.lower
|
|||||||
|
|
||||||
import org.jetbrains.kotlin.backend.common.lower.DefaultParameterInjector
|
import org.jetbrains.kotlin.backend.common.lower.DefaultParameterInjector
|
||||||
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
|
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
|
||||||
|
import org.jetbrains.kotlin.backend.jvm.ir.defaultValue
|
||||||
import org.jetbrains.kotlin.backend.jvm.ir.getJvmVisibilityOfDefaultArgumentStub
|
import org.jetbrains.kotlin.backend.jvm.ir.getJvmVisibilityOfDefaultArgumentStub
|
||||||
import org.jetbrains.kotlin.backend.jvm.lower.inlineclasses.unboxInlineClass
|
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrFunction
|
import org.jetbrains.kotlin.ir.declarations.IrFunction
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrValueParameter
|
import org.jetbrains.kotlin.ir.declarations.IrValueParameter
|
||||||
import org.jetbrains.kotlin.ir.expressions.IrExpression
|
import org.jetbrains.kotlin.ir.expressions.IrExpression
|
||||||
import org.jetbrains.kotlin.ir.expressions.impl.IrCallImpl
|
|
||||||
import org.jetbrains.kotlin.ir.types.IrSimpleType
|
|
||||||
import org.jetbrains.kotlin.ir.types.IrType
|
import org.jetbrains.kotlin.ir.types.IrType
|
||||||
import org.jetbrains.kotlin.ir.types.classOrNull
|
|
||||||
|
|
||||||
class JvmDefaultParameterInjector(context: JvmBackendContext) :
|
class JvmDefaultParameterInjector(context: JvmBackendContext) :
|
||||||
DefaultParameterInjector(context, skipInline = false, skipExternalMethods = false) {
|
DefaultParameterInjector(context, skipInline = false, skipExternalMethods = false) {
|
||||||
@@ -26,15 +23,7 @@ class JvmDefaultParameterInjector(context: JvmBackendContext) :
|
|||||||
nullConst(startOffset, endOffset, irParameter.type)
|
nullConst(startOffset, endOffset, irParameter.type)
|
||||||
|
|
||||||
override fun nullConst(startOffset: Int, endOffset: Int, type: IrType): IrExpression {
|
override fun nullConst(startOffset: Int, endOffset: Int, type: IrType): IrExpression {
|
||||||
if (type !is IrSimpleType || type.hasQuestionMark || type.classOrNull?.owner?.isInline != true)
|
return type.defaultValue(startOffset, endOffset, context)
|
||||||
return super.nullConst(startOffset, endOffset, type)
|
|
||||||
|
|
||||||
val underlyingType = type.unboxInlineClass()
|
|
||||||
return IrCallImpl(startOffset, endOffset, type, context.ir.symbols.unsafeCoerceIntrinsic).apply {
|
|
||||||
putTypeArgument(0, underlyingType) // from
|
|
||||||
putTypeArgument(1, type) // to
|
|
||||||
putValueArgument(0, super.nullConst(startOffset, endOffset, underlyingType))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun defaultArgumentStubVisibility(function: IrFunction) = function.getJvmVisibilityOfDefaultArgumentStub()
|
override fun defaultArgumentStubVisibility(function: IrFunction) = function.getJvmVisibilityOfDefaultArgumentStub()
|
||||||
|
|||||||
+1
-1
@@ -1,7 +1,7 @@
|
|||||||
// IGNORE_BACKEND_FIR: JVM_IR
|
// IGNORE_BACKEND_FIR: JVM_IR
|
||||||
// WITH_COROUTINES
|
// WITH_COROUTINES
|
||||||
// WITH_RUNTIME
|
// WITH_RUNTIME
|
||||||
// IGNORE_BACKEND: JVM_IR, JS_IR
|
// IGNORE_BACKEND: JS_IR
|
||||||
|
|
||||||
import helpers.*
|
import helpers.*
|
||||||
import kotlin.coroutines.*
|
import kotlin.coroutines.*
|
||||||
|
|||||||
Reference in New Issue
Block a user