JVM_IR: use IrBasedDescriptors across codegen

This commit is contained in:
Georgy Bronnikov
2020-08-09 16:29:12 +03:00
parent 0b4c43083d
commit 85ba170217
6 changed files with 45 additions and 31 deletions
@@ -17,7 +17,7 @@ import org.jetbrains.kotlin.descriptors.Modality
import org.jetbrains.kotlin.descriptors.Visibility
import org.jetbrains.kotlin.ir.builders.declarations.buildFun
import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.descriptors.WrappedClassDescriptor
import org.jetbrains.kotlin.ir.descriptors.toIrBasedDescriptor
import org.jetbrains.kotlin.ir.expressions.IrBlockBody
import org.jetbrains.kotlin.ir.expressions.IrConst
import org.jetbrains.kotlin.ir.expressions.IrExpression
@@ -65,13 +65,16 @@ abstract class ClassCodegen protected constructor(
// pass in a wrapped descriptor instead, except for lambdas where we use the descriptor
// of the original function.
// TODO: Migrate class builders away from descriptors
val descriptor = WrappedClassDescriptor().apply { bind(irClass) }
val descriptor = irClass.toIrBasedDescriptor()
val psiElement = context.psiSourceManager.findPsiElement(irClass)
when (irClass.origin) {
IrDeclarationOrigin.FILE_CLASS ->
JvmDeclarationOrigin(JvmDeclarationOriginKind.PACKAGE_PART, psiElement, descriptor)
JvmLoweredDeclarationOrigin.LAMBDA_IMPL, JvmLoweredDeclarationOrigin.FUNCTION_REFERENCE_IMPL ->
OtherOrigin(psiElement, irClass.attributeOwnerId.safeAs<IrFunctionReference>()?.symbol?.descriptor ?: descriptor)
OtherOrigin(
psiElement,
irClass.attributeOwnerId.safeAs<IrFunctionReference>()?.symbol?.owner?.toIrBasedDescriptor() ?: descriptor
)
else ->
OtherOrigin(psiElement, descriptor)
}
@@ -425,9 +428,9 @@ internal val IrDeclaration.OtherOrigin: JvmDeclarationOrigin
// This is needed for plugins which check for lambdas inside of inline functions using the descriptor
// contained in JvmDeclarationOrigin. This matches the behavior of the JVM backend.
if (klass.origin == JvmLoweredDeclarationOrigin.LAMBDA_IMPL || klass.origin == JvmLoweredDeclarationOrigin.SUSPEND_LAMBDA) {
klass.attributeOwnerId.safeAs<IrFunctionReference>()?.symbol?.descriptor ?: descriptor
klass.attributeOwnerId.safeAs<IrFunctionReference>()?.symbol?.owner?.toIrBasedDescriptor() ?: toIrBasedDescriptor()
} else {
descriptor
toIrBasedDescriptor()
}
)
}
@@ -28,11 +28,12 @@ import org.jetbrains.kotlin.config.LanguageFeature
import org.jetbrains.kotlin.config.isReleaseCoroutines
import org.jetbrains.kotlin.config.languageVersionSettings
import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.ConstructorDescriptor
import org.jetbrains.kotlin.descriptors.Visibilities
import org.jetbrains.kotlin.diagnostics.Errors
import org.jetbrains.kotlin.ir.IrElement
import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.descriptors.toIrBasedDescriptor
import org.jetbrains.kotlin.ir.descriptors.toIrBasedKotlinType
import org.jetbrains.kotlin.ir.expressions.*
import org.jetbrains.kotlin.ir.symbols.IrSymbol
import org.jetbrains.kotlin.ir.symbols.IrTypeParameterSymbol
@@ -183,7 +184,7 @@ class ExpressionCodegen(
} else {
expression.accept(this, data).materializeAt(type, irType)
}
return StackValue.onStack(type, irType.toKotlinType())
return StackValue.onStack(type, irType.toIrBasedKotlinType())
}
internal fun genOrGetLocal(expression: IrExpression, data: BlockInfo): StackValue {
@@ -198,7 +199,7 @@ class ExpressionCodegen(
}
return if (expression is IrGetValue)
StackValue.local(findLocalIndex(expression.symbol), frameMap.typeOf(expression.symbol), expression.type.toKotlinType())
StackValue.local(findLocalIndex(expression.symbol), frameMap.typeOf(expression.symbol), expression.type.toIrBasedKotlinType())
else
gen(expression, typeMapper.mapType(expression.type), expression.type, data)
}
@@ -317,7 +318,7 @@ class ExpressionCodegen(
// then generate name accordingly.
val name = if (param.origin == BOUND_RECEIVER_PARAMETER || isReceiver) {
getNameForReceiverParameter(
irFunction.descriptor,
irFunction.toIrBasedDescriptor(),
state.bindingContext,
context.configuration.languageVersionSettings
)
@@ -428,8 +429,8 @@ class ExpressionCodegen(
}
}
}
expression.symbol.descriptor is ConstructorDescriptor ->
throw AssertionError("IrCall with ConstructorDescriptor: ${expression.javaClass.simpleName}")
expression.symbol.owner is IrConstructor ->
throw AssertionError("IrCall to IrConstructor: ${expression.javaClass.simpleName}")
}
expression.dispatchReceiver?.let { receiver ->
@@ -831,7 +832,7 @@ class ExpressionCodegen(
override fun visitTypeOperator(expression: IrTypeOperatorCall, data: BlockInfo): PromisedValue {
val typeOperand = expression.typeOperand
val kotlinType = typeOperand.toKotlinType()
val kotlinType = typeOperand.toIrBasedKotlinType()
return when (expression.operator) {
IrTypeOperator.IMPLICIT_CAST ->
expression.argument.accept(this, data)
@@ -23,6 +23,7 @@ import org.jetbrains.kotlin.config.LanguageFeature
import org.jetbrains.kotlin.descriptors.Modality
import org.jetbrains.kotlin.descriptors.Visibilities
import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.descriptors.toIrBasedDescriptor
import org.jetbrains.kotlin.ir.expressions.*
import org.jetbrains.kotlin.ir.util.*
import org.jetbrains.kotlin.load.java.JavaVisibilities
@@ -109,7 +110,7 @@ class FunctionCodegen(
} else {
val sourceMapper = context.getSourceMapper(classCodegen.irClass)
val frameMap = irFunction.createFrameMapWithReceivers()
context.state.globalInlineContext.enterDeclaration(irFunction.suspendFunctionOriginal().descriptor)
context.state.globalInlineContext.enterDeclaration(irFunction.suspendFunctionOriginal().toIrBasedDescriptor())
try {
val adapter = InstructionAdapter(methodVisitor)
ExpressionCodegen(
@@ -15,7 +15,8 @@ import org.jetbrains.kotlin.codegen.state.GenerationState
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor
import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.descriptors.WrappedSimpleFunctionDescriptor
import org.jetbrains.kotlin.ir.descriptors.toIrBasedDescriptor
import org.jetbrains.kotlin.ir.descriptors.toIrBasedKotlinType
import org.jetbrains.kotlin.ir.expressions.*
import org.jetbrains.kotlin.ir.types.*
import org.jetbrains.kotlin.ir.util.*
@@ -37,7 +38,7 @@ class IrInlineCodegen(
reifiedTypeInliner: ReifiedTypeInliner<IrType>
) :
InlineCodegen<ExpressionCodegen>(
codegen, state, function.descriptor, methodOwner, signature, typeParameterMappings, sourceCompiler, reifiedTypeInliner
codegen, state, function.toIrBasedDescriptor(), methodOwner, signature, typeParameterMappings, sourceCompiler, reifiedTypeInliner
),
IrCallGenerator {
@@ -124,7 +125,7 @@ class IrInlineCodegen(
//TODO support default argument erasure
if (!processDefaultMaskOrMethodHandler(onStack, kind)) {
val expectedType = JvmKotlinType(parameterType, irValueParameter.type.toKotlinType())
val expectedType = JvmKotlinType(parameterType, irValueParameter.type.toIrBasedKotlinType())
putArgumentOrCapturedToLocalVal(expectedType, onStack, -1, irValueParameter.index, kind)
}
}
@@ -132,7 +133,7 @@ class IrInlineCodegen(
private fun putCapturedValueOnStack(argumentExpression: IrExpression, valueType: Type, capturedParamIndex: Int) {
val onStack = codegen.genOrGetLocal(argumentExpression, BlockInfo())
val expectedType = JvmKotlinType(valueType, argumentExpression.type.toKotlinType())
val expectedType = JvmKotlinType(valueType, argumentExpression.type.toIrBasedKotlinType())
putArgumentOrCapturedToLocalVal(expectedType, onStack, capturedParamIndex, capturedParamIndex, ValueKind.CAPTURED)
}
@@ -147,7 +148,9 @@ class IrInlineCodegen(
) {
val element = codegen.context.psiSourceManager.findPsiElement(expression, codegen.irFunction)
?: codegen.context.psiSourceManager.findPsiElement(codegen.irFunction)
if (!state.globalInlineContext.enterIntoInlining(expression.symbol.owner.suspendFunctionOriginal().descriptor, element)) {
if (!state.globalInlineContext.enterIntoInlining(
expression.symbol.owner.suspendFunctionOriginal().toIrBasedDescriptor(), element)
) {
val message = "Call is a part of inline call cycle: ${expression.render()}"
AsmUtil.genThrow(codegen.v, "java/lang/UnsupportedOperationException", message)
return
@@ -239,13 +242,12 @@ class IrExpressionLambdaImpl(
)
}
override val invokeMethodDescriptor: FunctionDescriptor =
// Need the descriptor without captured parameters here.
function.originalFunction.descriptor
// Need the descriptor without captured parameters here.
override val invokeMethodDescriptor: FunctionDescriptor = function.originalFunction.toIrBasedDescriptor()
override val hasDispatchReceiver: Boolean = false
override fun getInlineSuspendLambdaViewDescriptor(): FunctionDescriptor = function.descriptor
override fun getInlineSuspendLambdaViewDescriptor(): FunctionDescriptor = function.toIrBasedDescriptor()
override fun isCapturedSuspend(desc: CapturedParamDesc): Boolean =
capturedParameters[desc]?.let { it.isInlineParameter() && it.type.isSuspendFunctionTypeOrSubtype() } == true
@@ -257,7 +259,9 @@ class IrDefaultLambda(
private val irValueParameter: IrValueParameter,
offset: Int,
needReification: Boolean
) : DefaultLambda(lambdaClassType, capturedArgs, irValueParameter.descriptor as ValueParameterDescriptor, offset, needReification) {
) : DefaultLambda(
lambdaClassType, capturedArgs, irValueParameter.toIrBasedDescriptor() as ValueParameterDescriptor, offset, needReification
) {
override fun mapAsmSignature(sourceCompiler: SourceCompilerForInline): Method {
val invoke =
@@ -268,7 +272,7 @@ class IrDefaultLambda(
override fun findInvokeMethodDescriptor(): FunctionDescriptor =
(irValueParameter.type.classifierOrFail.owner as IrClass).functions.single {
it.name == OperatorNameConventions.INVOKE
}.descriptor
}.toIrBasedDescriptor()
}
fun isInlineIrExpression(argumentExpression: IrExpression) =
@@ -7,7 +7,6 @@ package org.jetbrains.kotlin.backend.jvm.codegen
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
import org.jetbrains.kotlin.backend.jvm.JvmLoweredDeclarationOrigin
import org.jetbrains.kotlin.builtins.functions.FunctionClassDescriptor
import org.jetbrains.kotlin.builtins.functions.FunctionInvokeDescriptor
import org.jetbrains.kotlin.codegen.AsmUtil
import org.jetbrains.kotlin.codegen.JvmCodegenUtil
@@ -30,6 +30,9 @@ import org.jetbrains.kotlin.descriptors.Visibilities
import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.declarations.lazy.IrLazyClass
import org.jetbrains.kotlin.ir.declarations.lazy.IrLazyFunctionBase
import org.jetbrains.kotlin.ir.descriptors.IrBasedSimpleFunctionDescriptor
import org.jetbrains.kotlin.ir.descriptors.toIrBasedDescriptor
import org.jetbrains.kotlin.ir.descriptors.toIrBasedKotlinType
import org.jetbrains.kotlin.ir.expressions.IrCall
import org.jetbrains.kotlin.ir.expressions.IrConst
import org.jetbrains.kotlin.ir.expressions.IrFunctionAccessExpression
@@ -163,7 +166,7 @@ class MethodSignatureMapper(private val context: JvmBackendContext) {
return typeMapper.mapType(returnType, typeMappingModeFromAnnotation, sw)
}
val mappingMode = TypeMappingMode.getOptimalModeForReturnType(returnType.toKotlinType(), isAnnotationMethod)
val mappingMode = TypeMappingMode.getOptimalModeForReturnType(returnType.toIrBasedKotlinType(), isAnnotationMethod)
return typeMapper.mapType(returnType, mappingMode, sw)
}
@@ -224,7 +227,8 @@ class MethodSignatureMapper(private val context: JvmBackendContext) {
JvmLoweredDeclarationOrigin.ENUM_CONSTRUCTOR_SYNTHETIC_PARAMETER -> JvmMethodParameterKind.ENUM_NAME_OR_ORDINAL
else -> JvmMethodParameterKind.VALUE
}
val type = if (forceSingleValueParameterBoxing(function.descriptor)) parameter.type.makeNullable() else parameter.type
val type =
if (forceSingleValueParameterBoxing(function.toIrBasedDescriptor())) parameter.type.makeNullable() else parameter.type
writeParameter(sw, kind, type, function)
}
@@ -234,7 +238,8 @@ class MethodSignatureMapper(private val context: JvmBackendContext) {
val signature = sw.makeJvmMethodSignature(mapFunctionName(function, skipSpecial))
val specialSignatureInfo = with(BuiltinMethodsWithSpecialGenericSignature) { function.descriptor.getSpecialSignatureInfo() }
val specialSignatureInfo =
with(BuiltinMethodsWithSpecialGenericSignature) { function.toIrBasedDescriptor().getSpecialSignatureInfo() }
if (specialSignatureInfo != null) {
val newGenericSignature = specialSignatureInfo.replaceValueParametersIn(signature.genericsSignature)
@@ -263,7 +268,7 @@ class MethodSignatureMapper(private val context: JvmBackendContext) {
?: if (declaration.isMethodWithDeclarationSiteWildcards && type.argumentsCount() != 0) {
TypeMappingMode.GENERIC_ARGUMENT // Render all wildcards
} else {
TypeMappingMode.getOptimalModeForValueParameter(type.toKotlinType())
TypeMappingMode.getOptimalModeForValueParameter(type.toIrBasedKotlinType())
}
}
@@ -336,9 +341,10 @@ class MethodSignatureMapper(private val context: JvmBackendContext) {
if (caller.origin == IrDeclarationOrigin.BRIDGE || caller.origin == IrDeclarationOrigin.BRIDGE_SPECIAL) return null
// Do not remap calls to static replacements of inline class methods, since they have completely different signatures.
if (callee.isStaticInlineClassReplacement) return null
val overriddenSpecialBuiltinFunction = callee.descriptor.original.getOverriddenBuiltinReflectingJvmDescriptor()
val overriddenSpecialBuiltinFunction =
(callee.toIrBasedDescriptor().getOverriddenBuiltinReflectingJvmDescriptor() as IrBasedSimpleFunctionDescriptor?)?.owner
if (overriddenSpecialBuiltinFunction != null && !superCall) {
return mapSignatureSkipGeneric(context.referenceFunction(overriddenSpecialBuiltinFunction.original).owner)
return mapSignatureSkipGeneric(overriddenSpecialBuiltinFunction)
}
return null