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