JVM: introduce JvmBackendConfig

Move language version settings, compiler configuration and different
flags there, and use this config everywhere in both backends instead of
GenerationState.

This will hopefully make GenerationState less of a "god object" and
remove the need to have it available everywhere, in particular in JVM IR
lowerings code, in the future.

Also, future refactorings will make it easier to inject backend-specific
behavior into common code, so that we would not need to handle support
of new features in the old backend.
This commit is contained in:
Alexander Udalov
2023-07-21 18:18:42 +02:00
committed by Space Team
parent b6f8991072
commit 72d048bd62
70 changed files with 265 additions and 237 deletions
@@ -86,7 +86,7 @@ class ClassCodegen private constructor(
private val innerClasses = mutableSetOf<IrClass>()
val typeMapper =
if (context.state.oldInnerClassesLogic)
if (context.config.oldInnerClassesLogic)
context.defaultTypeMapper
else object : IrTypeMapper(context) {
override fun mapType(type: IrType, mode: TypeMappingMode, sw: JvmSignatureWriter?, materialized: Boolean): Type {
@@ -118,7 +118,7 @@ class ClassCodegen private constructor(
}
defineClass(
irClass.psiElement,
state.classFileVersion,
state.config.classFileVersion,
irClass.getFlags(context.state.languageVersionSettings),
signature.name,
signature.javaGenericSignature,
@@ -151,7 +151,7 @@ class ClassCodegen private constructor(
// Generate PermittedSubclasses attribute for sealed class.
if (state.languageVersionSettings.supportsFeature(LanguageFeature.JvmPermittedSubclassesAttributeForSealed) &&
irClass.modality == Modality.SEALED &&
state.target >= JvmTarget.JVM_17
state.config.target >= JvmTarget.JVM_17
) {
generatePermittedSubclasses()
}
@@ -213,7 +213,7 @@ class ClassCodegen private constructor(
generateInnerAndOuterClasses()
visitor.done(state.generateSmapCopyToAnnotation)
visitor.done(state.config.generateSmapCopyToAnnotation)
jvmSignatureClashDetector.reportErrors()
}
@@ -281,7 +281,7 @@ class ClassCodegen private constructor(
val isMultifileClassOrPart = kind == KotlinClassHeader.Kind.MULTIFILE_CLASS || kind == KotlinClassHeader.Kind.MULTIFILE_CLASS_PART
var extraFlags = context.backendExtension.generateMetadataExtraFlags(state.abiStability)
var extraFlags = context.backendExtension.generateMetadataExtraFlags(state.config.abiStability)
if (isMultifileClassOrPart && state.languageVersionSettings.getFlag(JvmAnalysisFlags.inheritMultifileParts)) {
extraFlags = extraFlags or JvmAnnotationNames.METADATA_MULTIFILE_PARTS_INHERIT_FLAG
}
@@ -279,7 +279,7 @@ class ExpressionCodegen(
}
private fun generateNonNullAssertions() {
if (state.isParamAssertionsDisabled)
if (state.config.isParamAssertionsDisabled)
return
if ((DescriptorVisibilities.isPrivate(irFunction.visibility) && !shouldGenerateNonNullAssertionsForPrivateFun(irFunction)) ||
@@ -339,7 +339,7 @@ class ExpressionCodegen(
if (!expandedType.isNullable() && !isPrimitive(asmType)) {
mv.load(findLocalIndex(param.symbol), asmType)
mv.aconst(param.name.asString())
val methodName = if (state.unifiedNullChecks) "checkNotNullParameter" else "checkParameterIsNotNull"
val methodName = if (state.config.unifiedNullChecks) "checkNotNullParameter" else "checkParameterIsNotNull"
mv.invokestatic(JvmSymbols.INTRINSICS_CLASS_NAME, methodName, "(Ljava/lang/Object;Ljava/lang/String;)V", false)
}
}
@@ -823,7 +823,7 @@ class ExpressionCodegen(
override fun visitFieldAccess(expression: IrFieldAccessExpression, data: BlockInfo): PromisedValue {
val callee = expression.symbol.owner
if (context.state.shouldInlineConstVals) {
if (context.config.shouldInlineConstVals) {
// Const fields should only have reads, and those should have been transformed by ConstLowering.
assert(callee.constantValue() == null) { "access of const val: ${expression.dump()}" }
}
@@ -983,7 +983,7 @@ class ExpressionCodegen(
}
private fun generateGlobalReturnFlagIfPossible(expression: IrExpression, label: String) {
if (state.isInlineDisabled) {
if (state.config.isInlineDisabled) {
context.ktDiagnosticReporter.at(expression, irFunction).report(BackendErrors.NON_LOCAL_RETURN_IN_DISABLED_INLINE)
genThrow(mv, "java/lang/UnsupportedOperationException", "Non-local returns are not allowed with inlining disabled")
} else {
@@ -1476,10 +1476,10 @@ class ExpressionCodegen(
}
override fun visitStringConcatenation(expression: IrStringConcatenation, data: BlockInfo): PromisedValue {
assert(context.state.runtimeStringConcat.isDynamic) {
assert(context.config.runtimeStringConcat.isDynamic) {
"IrStringConcatenation expression should be presented only with dynamic concatenation: ${expression.dump()}"
}
val generator = StringConcatGenerator(context.state.runtimeStringConcat, mv)
val generator = StringConcatGenerator(context.config.runtimeStringConcat, mv)
expression.arguments.forEach { arg ->
if (arg is IrConst<*>) {
val type = when (arg.kind) {
@@ -1580,7 +1580,7 @@ class ExpressionCodegen(
IrInlineIntrinsicsSupport(classCodegen, element, irFunction.fileParent),
context.typeSystem,
state.languageVersionSettings,
state.unifiedNullChecks,
state.config.unifiedNullChecks,
)
return IrInlineCodegen(this, state, callee, signature, mappings, sourceCompiler, reifiedTypeInliner)
@@ -70,7 +70,7 @@ class FunctionCodegen(private val irFunction: IrFunction, private val classCodeg
)
val methodVisitor: MethodVisitor = wrapWithMaxLocalCalc(methodNode)
if (context.state.generateParametersMetadata && !isSynthetic) {
if (context.config.generateParametersMetadata && !isSynthetic) {
generateParameterNames(irFunction, methodVisitor, context.state)
}
@@ -58,7 +58,7 @@ class IrInlineIntrinsicsSupport(
when (val parent = typeParameter.owner.parent) {
is IrClass -> putClassInstance(v, parent.defaultType).also { AsmUtil.wrapJavaClassIntoKClass(v) }
is IrSimpleFunction -> {
check(classCodegen.context.state.generateOptimizedCallableReferenceSuperClasses) {
check(classCodegen.context.config.generateOptimizedCallableReferenceSuperClasses) {
"typeOf() of a non-reified type parameter is only allowed if optimized callable references are enabled.\n" +
"Please make sure API version is set to 1.4, and -Xno-optimized-callable-references is NOT used.\n" +
"Container: $parent"
@@ -33,7 +33,7 @@ object HashCode : IntrinsicMethod() {
val receiverJvmType = typeMapper.mapType(receiverIrType)
val receiverValue = receiver.accept(this, data).materialized()
val receiverType = receiverValue.type
val target = context.state.target
val target = context.config.target
when {
irFunction.origin == JvmLoweredDeclarationOrigin.INLINE_CLASS_GENERATED_IMPL_METHOD ||
irFunction.origin == JvmLoweredDeclarationOrigin.MULTI_FIELD_VALUE_CLASS_GENERATED_IMPL_METHOD ||
@@ -31,7 +31,7 @@ object IrCheckNotNull : IntrinsicMethod() {
private fun ExpressionCodegen.checkTopValueForNull() {
mv.dup()
if (state.unifiedNullChecks) {
if (state.config.unifiedNullChecks) {
mv.invokestatic(IntrinsicMethods.INTRINSICS_CLASS_NAME, "checkNotNull", "(Ljava/lang/Object;)V", false)
} else {
val ifNonNullLabel = Label()
@@ -17,7 +17,7 @@ object ThrowKotlinNothingValueException : IntrinsicMethod() {
classCodegen: ClassCodegen
): IntrinsicFunction =
IntrinsicFunction.create(expression, signature, classCodegen) { mv ->
if (classCodegen.context.state.useKotlinNothingValueException) {
if (classCodegen.context.config.useKotlinNothingValueException) {
mv.anew(Type.getObjectType("kotlin/KotlinNothingValueException"))
mv.dup()
mv.invokespecial("kotlin/KotlinNothingValueException", "<init>", "()V", false)
@@ -26,4 +26,4 @@ object ThrowKotlinNothingValueException : IntrinsicMethod() {
}
mv.athrow()
}
}
}