[KLIB] Introduce compatible mode for klibs.
Based on library ABI version linker could decide which signature mode to be used to guarantee backward compatibility.
This commit is contained in:
committed by
TeamCityServer
parent
3e99951a66
commit
b5c28c1912
+2
-1
@@ -5,6 +5,7 @@ import org.jetbrains.kotlin.backend.common.IrValidator
|
||||
import org.jetbrains.kotlin.backend.common.IrValidatorConfig
|
||||
import org.jetbrains.kotlin.backend.common.lower.createIrBuilder
|
||||
import org.jetbrains.kotlin.backend.common.phaser.*
|
||||
import org.jetbrains.kotlin.backend.common.serialization.CompatibilityMode
|
||||
import org.jetbrains.kotlin.backend.common.serialization.metadata.KlibMetadataMonolithicSerializer
|
||||
import org.jetbrains.kotlin.backend.konan.MemoryModel
|
||||
import org.jetbrains.kotlin.backend.konan.llvm.*
|
||||
@@ -155,7 +156,7 @@ internal val serializerPhase = konanUnitPhase(
|
||||
|
||||
serializedIr = irModule?.let { ir ->
|
||||
KonanIrModuleSerializer(
|
||||
messageLogger, ir.irBuiltins, expectDescriptorToSymbol, skipExpects = !expectActualLinker
|
||||
messageLogger, ir.irBuiltins, expectDescriptorToSymbol, skipExpects = !expectActualLinker, compatibilityMode = CompatibilityMode.CURRENT
|
||||
).serializedIrModule(ir)
|
||||
}
|
||||
|
||||
|
||||
+3
-3
@@ -34,9 +34,9 @@ import org.jetbrains.kotlin.name.Name
|
||||
object KonanBinaryInterface {
|
||||
private val mangler = object : AbstractKonanIrMangler(true) {}
|
||||
|
||||
private val exportChecker = mangler.getExportChecker()
|
||||
private val exportChecker = mangler.getExportChecker(compatibleMode = true)
|
||||
|
||||
val IrFunction.functionName: String get() = mangler.run { signatureString }
|
||||
val IrFunction.functionName: String get() = mangler.run { signatureString() }
|
||||
|
||||
val IrFunction.symbolName: String get() = funSymbolNameImpl()
|
||||
val IrField.symbolName: String get() =
|
||||
@@ -65,7 +65,7 @@ object KonanBinaryInterface {
|
||||
return name // no wrapping currently required
|
||||
}
|
||||
|
||||
return withPrefix(MangleConstant.FUN_PREFIX, mangler.run { mangleString })
|
||||
return withPrefix(MangleConstant.FUN_PREFIX, mangler.run { mangleString() })
|
||||
}
|
||||
|
||||
private fun IrField.fieldSymbolNameImpl(): String {
|
||||
|
||||
+4
-2
@@ -1,5 +1,6 @@
|
||||
package org.jetbrains.kotlin.backend.konan.serialization
|
||||
|
||||
import org.jetbrains.kotlin.backend.common.serialization.CompatibilityMode
|
||||
import org.jetbrains.kotlin.backend.common.serialization.DeclarationTable
|
||||
import org.jetbrains.kotlin.backend.common.serialization.IrFileSerializer
|
||||
import org.jetbrains.kotlin.backend.konan.RuntimeNames
|
||||
@@ -16,8 +17,9 @@ class KonanIrFileSerializer(
|
||||
declarationTable: DeclarationTable,
|
||||
expectDescriptorToSymbol: MutableMap<DeclarationDescriptor, IrSymbol>,
|
||||
skipExpects: Boolean,
|
||||
bodiesOnlyForInlines: Boolean = false
|
||||
): IrFileSerializer(messageLogger, declarationTable, expectDescriptorToSymbol, skipExpects = skipExpects, bodiesOnlyForInlines = bodiesOnlyForInlines) {
|
||||
bodiesOnlyForInlines: Boolean = false,
|
||||
compatibilityMode: CompatibilityMode
|
||||
): IrFileSerializer(messageLogger, declarationTable, expectDescriptorToSymbol, compatibilityMode, bodiesOnlyForInlines, skipExpects) {
|
||||
|
||||
override fun backendSpecificExplicitRoot(node: IrAnnotationContainer): Boolean {
|
||||
val fqn = when (node) {
|
||||
|
||||
+6
-4
@@ -1,6 +1,7 @@
|
||||
package org.jetbrains.kotlin.backend.konan.serialization
|
||||
|
||||
import org.jetbrains.kotlin.backend.common.serialization.*
|
||||
import org.jetbrains.kotlin.backend.common.serialization.CompatibilityMode
|
||||
import org.jetbrains.kotlin.backend.common.serialization.IrModuleSerializer
|
||||
import org.jetbrains.kotlin.backend.common.serialization.signature.IdSignatureSerializer
|
||||
import org.jetbrains.kotlin.backend.konan.ir.interop.IrProviderForCEnumAndCStructStubs
|
||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||
@@ -13,8 +14,9 @@ class KonanIrModuleSerializer(
|
||||
messageLogger: IrMessageLogger,
|
||||
irBuiltIns: IrBuiltIns,
|
||||
private val expectDescriptorToSymbol: MutableMap<DeclarationDescriptor, IrSymbol>,
|
||||
val skipExpects: Boolean
|
||||
) : IrModuleSerializer<KonanIrFileSerializer>(messageLogger) {
|
||||
val skipExpects: Boolean,
|
||||
compatibilityMode: CompatibilityMode
|
||||
) : IrModuleSerializer<KonanIrFileSerializer>(messageLogger, compatibilityMode) {
|
||||
|
||||
private val globalDeclarationTable = KonanGlobalDeclarationTable(irBuiltIns)
|
||||
|
||||
@@ -28,5 +30,5 @@ class KonanIrModuleSerializer(
|
||||
file.fileEntry.name != IrProviderForCEnumAndCStructStubs.cTypeDefinitionsFileName
|
||||
|
||||
override fun createSerializerForFile(file: IrFile): KonanIrFileSerializer =
|
||||
KonanIrFileSerializer(messageLogger, KonanDeclarationTable(globalDeclarationTable), expectDescriptorToSymbol, skipExpects = skipExpects)
|
||||
KonanIrFileSerializer(messageLogger, KonanDeclarationTable(globalDeclarationTable), expectDescriptorToSymbol, skipExpects = skipExpects, compatibilityMode = compatibilityMode)
|
||||
}
|
||||
|
||||
+9
-8
@@ -41,7 +41,7 @@ import org.jetbrains.kotlin.ir.types.classOrNull
|
||||
import org.jetbrains.kotlin.ir.util.*
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementTransformer
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
|
||||
import org.jetbrains.kotlin.library.IrLibrary
|
||||
import org.jetbrains.kotlin.library.KotlinAbiVersion
|
||||
import org.jetbrains.kotlin.library.KotlinLibrary
|
||||
import org.jetbrains.kotlin.name.ClassId
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
@@ -93,16 +93,16 @@ internal class KonanIrLinker(
|
||||
private val forwardDeclarationDeserializer = forwardModuleDescriptor?.let { KonanForwardDeclarationModuleDeserializer(it) }
|
||||
override val fakeOverrideBuilder = FakeOverrideBuilder(this, symbolTable, KonanManglerIr, builtIns, KonanFakeOverrideClassFilter)
|
||||
|
||||
override fun createModuleDeserializer(moduleDescriptor: ModuleDescriptor, klib: IrLibrary?, strategy: DeserializationStrategy): IrModuleDeserializer {
|
||||
override fun createModuleDeserializer(moduleDescriptor: ModuleDescriptor, klib: KotlinLibrary?, strategy: DeserializationStrategy): IrModuleDeserializer {
|
||||
if (moduleDescriptor === forwardModuleDescriptor) {
|
||||
return forwardDeclarationDeserializer ?: error("forward declaration deserializer expected")
|
||||
}
|
||||
|
||||
if (klib is KotlinLibrary && klib.isInteropLibrary()) {
|
||||
if (klib != null && klib.isInteropLibrary()) {
|
||||
// See https://youtrack.jetbrains.com/issue/KT-43517.
|
||||
// Disabling this flag forces linker to generate IR.
|
||||
val isCached = false //cachedLibraries.isLibraryCached(klib)
|
||||
return KonanInteropModuleDeserializer(moduleDescriptor, isCached)
|
||||
return KonanInteropModuleDeserializer(moduleDescriptor, klib, isCached)
|
||||
}
|
||||
|
||||
return KonanModuleDeserializer(moduleDescriptor, klib ?: error("Expecting kotlin library"), strategy)
|
||||
@@ -110,16 +110,17 @@ internal class KonanIrLinker(
|
||||
|
||||
private inner class KonanModuleDeserializer(
|
||||
moduleDescriptor: ModuleDescriptor,
|
||||
klib: IrLibrary,
|
||||
klib: KotlinLibrary,
|
||||
strategy: DeserializationStrategy
|
||||
): BasicIrModuleDeserializer(this@KonanIrLinker, moduleDescriptor, klib, strategy){
|
||||
): BasicIrModuleDeserializer(this@KonanIrLinker, moduleDescriptor, klib, strategy, klib.versions.abiVersion ?: KotlinAbiVersion.CURRENT) {
|
||||
override val moduleFragment: IrModuleFragment = KonanIrModuleFragmentImpl(moduleDescriptor, builtIns, emptyList())
|
||||
}
|
||||
|
||||
private inner class KonanInteropModuleDeserializer(
|
||||
moduleDescriptor: ModuleDescriptor,
|
||||
klib: KotlinLibrary,
|
||||
private val isLibraryCached: Boolean
|
||||
) : IrModuleDeserializer(moduleDescriptor) {
|
||||
) : IrModuleDeserializer(moduleDescriptor, klib.versions.abiVersion ?: KotlinAbiVersion.CURRENT) {
|
||||
init {
|
||||
assert(moduleDescriptor.kotlinLibrary.isInteropLibrary())
|
||||
}
|
||||
@@ -170,7 +171,7 @@ internal class KonanIrLinker(
|
||||
override val moduleDependencies: Collection<IrModuleDeserializer> = listOfNotNull(forwardDeclarationDeserializer)
|
||||
}
|
||||
|
||||
private inner class KonanForwardDeclarationModuleDeserializer(moduleDescriptor: ModuleDescriptor) : IrModuleDeserializer(moduleDescriptor) {
|
||||
private inner class KonanForwardDeclarationModuleDeserializer(moduleDescriptor: ModuleDescriptor) : IrModuleDeserializer(moduleDescriptor, KotlinAbiVersion.CURRENT) {
|
||||
init {
|
||||
assert(moduleDescriptor.isForwardDeclarationModule)
|
||||
}
|
||||
|
||||
+57
-53
@@ -1,5 +1,6 @@
|
||||
package org.jetbrains.kotlin.backend.konan.serialization
|
||||
|
||||
import org.jetbrains.kotlin.backend.common.serialization.mangle.KotlinExportChecker
|
||||
import org.jetbrains.kotlin.backend.common.serialization.mangle.MangleMode
|
||||
import org.jetbrains.kotlin.backend.common.serialization.mangle.descriptor.DescriptorBasedKotlinManglerImpl
|
||||
import org.jetbrains.kotlin.backend.common.serialization.mangle.descriptor.DescriptorExportCheckerVisitor
|
||||
@@ -12,40 +13,42 @@ import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.ir.declarations.*
|
||||
import org.jetbrains.kotlin.ir.types.getClass
|
||||
import org.jetbrains.kotlin.ir.util.hasAnnotation
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
|
||||
abstract class AbstractKonanIrMangler(private val withReturnType: Boolean) : IrBasedKotlinManglerImpl() {
|
||||
override fun getExportChecker(): IrExportCheckerVisitor = KonanIrExportChecker()
|
||||
override fun getExportChecker(compatibleMode: Boolean): IrExportCheckerVisitor = KonanIrExportChecker(compatibleMode)
|
||||
|
||||
override fun getMangleComputer(mode: MangleMode): IrMangleComputer =
|
||||
KonanIrManglerComputer(StringBuilder(256), mode, withReturnType)
|
||||
override fun getMangleComputer(mode: MangleMode): IrMangleComputer = KonanIrManglerComputer(StringBuilder(256), mode, withReturnType)
|
||||
|
||||
private class KonanIrExportChecker : IrExportCheckerVisitor() {
|
||||
override fun IrDeclaration.isPlatformSpecificExported(): Boolean {
|
||||
if (this is IrSimpleFunction) if (isFakeOverride) return false
|
||||
override fun IrDeclaration.isPlatformSpecificExport(): Boolean {
|
||||
if (this is IrSimpleFunction) if (isFakeOverride) return false
|
||||
|
||||
// TODO: revise
|
||||
if (annotations.hasAnnotation(RuntimeNames.symbolNameAnnotation)) {
|
||||
// Treat any `@SymbolName` declaration as exported.
|
||||
return true
|
||||
}
|
||||
if (annotations.hasAnnotation(KonanFqNames.gcUnsafeCall)) {
|
||||
// TODO: revise
|
||||
if (annotations.hasAnnotation(RuntimeNames.symbolNameAnnotation)) {
|
||||
// Treat any `@SymbolName` declaration as exported.
|
||||
return true
|
||||
}
|
||||
if (annotations.hasAnnotation(KonanFqNames.gcUnsafeCall)) {
|
||||
// Treat any `@GCUnsafeCall` declaration as exported.
|
||||
return true
|
||||
}
|
||||
if (annotations.hasAnnotation(RuntimeNames.exportForCppRuntime)) {
|
||||
// Treat any `@ExportForCppRuntime` declaration as exported.
|
||||
return true
|
||||
}
|
||||
if (annotations.hasAnnotation(RuntimeNames.cnameAnnotation)) {
|
||||
// Treat `@CName` declaration as exported.
|
||||
return true
|
||||
}
|
||||
if (annotations.hasAnnotation(RuntimeNames.exportForCompilerAnnotation)) {
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
// Treat any `@ExportForCppRuntime` declaration as exported.
|
||||
return true
|
||||
}
|
||||
if (annotations.hasAnnotation(RuntimeNames.cnameAnnotation)) {
|
||||
// Treat `@CName` declaration as exported.
|
||||
return true
|
||||
}
|
||||
if (annotations.hasAnnotation(RuntimeNames.exportForCompilerAnnotation)) {
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
private inner class KonanIrExportChecker(compatibleMode: Boolean) : IrExportCheckerVisitor(compatibleMode) {
|
||||
override fun IrDeclaration.isPlatformSpecificExported(): Boolean = isPlatformSpecificExport()
|
||||
}
|
||||
|
||||
private class KonanIrManglerComputer(builder: StringBuilder, mode: MangleMode, private val withReturnType: Boolean) : IrMangleComputer(builder, mode) {
|
||||
@@ -88,39 +91,40 @@ abstract class AbstractKonanIrMangler(private val withReturnType: Boolean) : IrB
|
||||
object KonanManglerIr : AbstractKonanIrMangler(false)
|
||||
|
||||
abstract class AbstractKonanDescriptorMangler : DescriptorBasedKotlinManglerImpl() {
|
||||
override fun getExportChecker(): DescriptorExportCheckerVisitor = KonanDescriptorExportChecker()
|
||||
override fun getExportChecker(compatibleMode: Boolean): KotlinExportChecker<DeclarationDescriptor> = KonanDescriptorExportChecker()
|
||||
|
||||
override fun getMangleComputer(mode: MangleMode): DescriptorMangleComputer =
|
||||
KonanDescriptorMangleComputer(StringBuilder(256), mode)
|
||||
override fun getMangleComputer(mode: MangleMode): DescriptorMangleComputer = KonanDescriptorMangleComputer(StringBuilder(256), mode)
|
||||
|
||||
private class KonanDescriptorExportChecker : DescriptorExportCheckerVisitor() {
|
||||
override fun DeclarationDescriptor.isPlatformSpecificExported(): Boolean {
|
||||
if (this is SimpleFunctionDescriptor) {
|
||||
if (kind == CallableMemberDescriptor.Kind.FAKE_OVERRIDE) return false
|
||||
}
|
||||
// TODO: revise
|
||||
if (annotations.hasAnnotation(RuntimeNames.symbolNameAnnotation)) {
|
||||
// Treat any `@SymbolName` declaration as exported.
|
||||
return true
|
||||
}
|
||||
if (annotations.hasAnnotation(KonanFqNames.gcUnsafeCall)) {
|
||||
// Treat any `@GCUnsafeCall` declaration as exported.
|
||||
return true
|
||||
}
|
||||
if (annotations.hasAnnotation(RuntimeNames.exportForCppRuntime)) {
|
||||
// Treat any `@ExportForCppRuntime` declaration as exported.
|
||||
return true
|
||||
}
|
||||
if (annotations.hasAnnotation(RuntimeNames.cnameAnnotation)) {
|
||||
// Treat `@CName` declaration as exported.
|
||||
return true
|
||||
}
|
||||
if (annotations.hasAnnotation(RuntimeNames.exportForCompilerAnnotation)) {
|
||||
return true
|
||||
}
|
||||
private inner class KonanDescriptorExportChecker : DescriptorExportCheckerVisitor() {
|
||||
override fun DeclarationDescriptor.isPlatformSpecificExported(): Boolean = isPlatformSpecificExport()
|
||||
}
|
||||
|
||||
return false
|
||||
override fun DeclarationDescriptor.isPlatformSpecificExport(): Boolean {
|
||||
if (this is SimpleFunctionDescriptor) {
|
||||
if (kind == CallableMemberDescriptor.Kind.FAKE_OVERRIDE) return false
|
||||
}
|
||||
// TODO: revise
|
||||
if (annotations.hasAnnotation(RuntimeNames.symbolNameAnnotation)) {
|
||||
// Treat any `@SymbolName` declaration as exported.
|
||||
return true
|
||||
}
|
||||
if (annotations.hasAnnotation(KonanFqNames.gcUnsafeCall)) {
|
||||
// Treat any `@GCUnsafeCall` declaration as exported.
|
||||
return true
|
||||
}
|
||||
if (annotations.hasAnnotation(RuntimeNames.exportForCppRuntime)) {
|
||||
// Treat any `@ExportForCppRuntime` declaration as exported.
|
||||
return true
|
||||
}
|
||||
if (annotations.hasAnnotation(RuntimeNames.cnameAnnotation)) {
|
||||
// Treat `@CName` declaration as exported.
|
||||
return true
|
||||
}
|
||||
if (annotations.hasAnnotation(RuntimeNames.exportForCompilerAnnotation)) {
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
private class KonanDescriptorMangleComputer(builder: StringBuilder, mode: MangleMode) : DescriptorMangleComputer(builder, mode) {
|
||||
|
||||
Reference in New Issue
Block a user