Merge pull request #4496 from JetBrains/small_backend_optimizations

Small backend optimizations
This commit is contained in:
Igor Chevdar
2020-11-10 10:59:24 +03:00
committed by Stanislav Erokhin
parent 2c898fe72c
commit f8b4db21aa
16 changed files with 234 additions and 82 deletions
@@ -390,11 +390,29 @@ private class CString(val bytes: ByteArray): CValues<ByteVar>() {
} }
} }
private object EmptyCString: CValues<ByteVar>() {
override val size get() = 1
override val align get() = 1
private val placement =
interpretCPointer<ByteVar>(nativeMemUtils.alloc(1, 1).rawPtr)!!.also {
it[0] = 0.toByte()
}
override fun getPointer(scope: AutofreeScope): CPointer<ByteVar> {
return placement
}
override fun place(placement: CPointer<ByteVar>): CPointer<ByteVar> {
placement[0] = 0.toByte()
return placement
}
}
/** /**
* @return the value of zero-terminated UTF-8-encoded C string constructed from given [kotlin.String]. * @return the value of zero-terminated UTF-8-encoded C string constructed from given [kotlin.String].
*/ */
public val String.cstr: CValues<ByteVar> public val String.cstr: CValues<ByteVar>
get() = CString(encodeToUtf8(this)) get() = if (isEmpty()) EmptyCString else CString(encodeToUtf8(this))
/** /**
* @return the value of zero-terminated UTF-8-encoded C string constructed from given [kotlin.String]. * @return the value of zero-terminated UTF-8-encoded C string constructed from given [kotlin.String].
@@ -40,6 +40,7 @@ import org.jetbrains.kotlin.backend.common.ir.copyTo
import org.jetbrains.kotlin.backend.common.ir.copyToWithoutSuperTypes import org.jetbrains.kotlin.backend.common.ir.copyToWithoutSuperTypes
import org.jetbrains.kotlin.backend.konan.objcexport.ObjCExport import org.jetbrains.kotlin.backend.konan.objcexport.ObjCExport
import org.jetbrains.kotlin.backend.konan.llvm.coverage.CoverageManager import org.jetbrains.kotlin.backend.konan.llvm.coverage.CoverageManager
import org.jetbrains.kotlin.ir.declarations.lazy.IrLazyClass
import org.jetbrains.kotlin.ir.descriptors.WrappedSimpleFunctionDescriptor import org.jetbrains.kotlin.ir.descriptors.WrappedSimpleFunctionDescriptor
import org.jetbrains.kotlin.ir.symbols.IrSymbol import org.jetbrains.kotlin.ir.symbols.IrSymbol
import org.jetbrains.kotlin.ir.symbols.impl.IrFieldSymbolImpl import org.jetbrains.kotlin.ir.symbols.impl.IrFieldSymbolImpl
@@ -47,6 +48,7 @@ import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.konan.library.KonanLibraryLayout import org.jetbrains.kotlin.konan.library.KonanLibraryLayout
import org.jetbrains.kotlin.library.SerializedIrModule import org.jetbrains.kotlin.library.SerializedIrModule
import org.jetbrains.kotlin.resolve.descriptorUtil.isEffectivelyExternal import org.jetbrains.kotlin.resolve.descriptorUtil.isEffectivelyExternal
import org.jetbrains.kotlin.utils.addToStdlib.getOrPut
/** /**
* Offset for synthetic elements created by lowerings and not attributable to other places in the source code. * Offset for synthetic elements created by lowerings and not attributable to other places in the source code.
@@ -254,10 +256,20 @@ internal class Context(config: KonanConfig) : KonanBackendContext(config) {
KonanReflectionTypes(moduleDescriptor, KonanFqNames.internalPackageName) KonanReflectionTypes(moduleDescriptor, KonanFqNames.internalPackageName)
} }
val layoutBuilders = mutableMapOf<IrClass, ClassLayoutBuilder>() // TODO: Remove after adding special <userData> property to IrDeclaration.
private val layoutBuilders = mutableMapOf<IrClass, ClassLayoutBuilder>()
fun getLayoutBuilder(irClass: IrClass) = layoutBuilders.getOrPut(irClass) { fun getLayoutBuilder(irClass: IrClass): ClassLayoutBuilder {
ClassLayoutBuilder(irClass, this, isLowered = shouldLower(this, irClass)) if (irClass is IrLazyClass)
return layoutBuilders.getOrPut(irClass) {
ClassLayoutBuilder(irClass, this, isLowered = shouldLower(this, irClass))
}
val metadata = irClass.metadata as? CodegenClassMetadata
?: CodegenClassMetadata(irClass).also { irClass.metadata = it }
metadata.layoutBuilder?.let { return it }
val layoutBuilder = ClassLayoutBuilder(irClass, this, isLowered = shouldLower(this, irClass))
metadata.layoutBuilder = layoutBuilder
return layoutBuilder
} }
lateinit var globalHierarchyAnalysisResult: GlobalHierarchyAnalysisResult lateinit var globalHierarchyAnalysisResult: GlobalHierarchyAnalysisResult
@@ -5,11 +5,10 @@
package org.jetbrains.kotlin.backend.konan package org.jetbrains.kotlin.backend.konan
import org.jetbrains.kotlin.backend.konan.descriptors.konanLibrary import org.jetbrains.kotlin.backend.konan.ir.konanLibrary
import org.jetbrains.kotlin.descriptors.ModuleDescriptor import org.jetbrains.kotlin.descriptors.ModuleDescriptor
import org.jetbrains.kotlin.ir.declarations.IrDeclaration import org.jetbrains.kotlin.ir.declarations.IrDeclaration
import org.jetbrains.kotlin.ir.declarations.IrModuleFragment import org.jetbrains.kotlin.ir.declarations.IrModuleFragment
import org.jetbrains.kotlin.ir.util.module
import org.jetbrains.kotlin.library.KotlinLibrary import org.jetbrains.kotlin.library.KotlinLibrary
internal abstract class LlvmModuleSpecificationBase(protected val cachedLibraries: CachedLibraries) : LlvmModuleSpecification { internal abstract class LlvmModuleSpecificationBase(protected val cachedLibraries: CachedLibraries) : LlvmModuleSpecification {
@@ -26,7 +25,7 @@ internal abstract class LlvmModuleSpecificationBase(protected val cachedLibrarie
module.konanLibrary.let { it == null || containsLibrary(it) } module.konanLibrary.let { it == null || containsLibrary(it) }
override fun containsDeclaration(declaration: IrDeclaration): Boolean = override fun containsDeclaration(declaration: IrDeclaration): Boolean =
declaration.module.konanLibrary.let { it == null || containsLibrary(it) } declaration.konanLibrary.let { it == null || containsLibrary(it) }
} }
internal class DefaultLlvmModuleSpecification(cachedLibraries: CachedLibraries) internal class DefaultLlvmModuleSpecification(cachedLibraries: CachedLibraries)
@@ -8,12 +8,11 @@ import org.jetbrains.kotlin.backend.common.serialization.mangle.ManglerChecker
import org.jetbrains.kotlin.backend.common.serialization.mangle.descriptor.Ir2DescriptorManglerAdapter import org.jetbrains.kotlin.backend.common.serialization.mangle.descriptor.Ir2DescriptorManglerAdapter
import org.jetbrains.kotlin.backend.konan.descriptors.isForwardDeclarationModule import org.jetbrains.kotlin.backend.konan.descriptors.isForwardDeclarationModule
import org.jetbrains.kotlin.backend.konan.descriptors.isFromInteropLibrary import org.jetbrains.kotlin.backend.konan.descriptors.isFromInteropLibrary
import org.jetbrains.kotlin.backend.konan.descriptors.konanLibrary import org.jetbrains.kotlin.backend.konan.ir.konanLibrary
import org.jetbrains.kotlin.backend.konan.ir.KonanSymbols import org.jetbrains.kotlin.backend.konan.ir.KonanSymbols
import org.jetbrains.kotlin.backend.konan.ir.interop.IrProviderForCEnumAndCStructStubs import org.jetbrains.kotlin.backend.konan.ir.interop.IrProviderForCEnumAndCStructStubs
import org.jetbrains.kotlin.backend.konan.serialization.*
import org.jetbrains.kotlin.backend.konan.serialization.KonanIrLinker import org.jetbrains.kotlin.backend.konan.serialization.KonanIrLinker
import org.jetbrains.kotlin.backend.konan.serialization.KonanManglerDesc
import org.jetbrains.kotlin.backend.konan.serialization.KonanManglerIr
import org.jetbrains.kotlin.config.CommonConfigurationKeys import org.jetbrains.kotlin.config.CommonConfigurationKeys
import org.jetbrains.kotlin.config.languageVersionSettings import org.jetbrains.kotlin.config.languageVersionSettings
import org.jetbrains.kotlin.descriptors.ModuleDescriptor import org.jetbrains.kotlin.descriptors.ModuleDescriptor
@@ -154,7 +153,7 @@ internal fun Context.psiToIr(
} }
expectDescriptorToSymbol = mutableMapOf() expectDescriptorToSymbol = mutableMapOf()
val module = translator.generateModuleFragment( val mainModule = translator.generateModuleFragment(
generatorContext, generatorContext,
environment.getSourceFiles(), environment.getSourceFiles(),
irProviders = listOf(irDeserializer), irProviders = listOf(irDeserializer),
@@ -164,7 +163,7 @@ internal fun Context.psiToIr(
// how ExpectedActualResolver is implemented. // how ExpectedActualResolver is implemented.
// Need to fix ExpectActualResolver to either cache expects or somehow reduce the member scope searches. // Need to fix ExpectActualResolver to either cache expects or somehow reduce the member scope searches.
expectDescriptorToSymbol = if (expectActualLinker) expectDescriptorToSymbol else null expectDescriptorToSymbol = if (expectActualLinker) expectDescriptorToSymbol else null
) ).toKonanModule()
irDeserializer.postProcess() irDeserializer.postProcess()
@@ -173,7 +172,7 @@ internal fun Context.psiToIr(
symbolTable.noUnboundLeft("Unbound symbols left after linker") symbolTable.noUnboundLeft("Unbound symbols left after linker")
module.acceptVoid(ManglerChecker(KonanManglerIr, Ir2DescriptorManglerAdapter(KonanManglerDesc))) mainModule.acceptVoid(ManglerChecker(KonanManglerIr, Ir2DescriptorManglerAdapter(KonanManglerDesc)))
val modules = if (isProducingLibrary) emptyMap() else (irDeserializer as KonanIrLinker).modules val modules = if (isProducingLibrary) emptyMap() else (irDeserializer as KonanIrLinker).modules
@@ -182,7 +181,7 @@ internal fun Context.psiToIr(
modules.values.forEach { fakeOverrideChecker.check(it) } modules.values.forEach { fakeOverrideChecker.check(it) }
} }
irModule = module irModule = mainModule
// Note: coupled with [shouldLower] below. // Note: coupled with [shouldLower] below.
irModules = modules.filterValues { llvmModuleSpecification.containsModule(it) } irModules = modules.filterValues { llvmModuleSpecification.containsModule(it) }
@@ -196,6 +195,11 @@ internal fun Context.psiToIr(
functionIrClassFactory.module = (modules.values + irModule!!).single { it.descriptor.isNativeStdlib() } functionIrClassFactory.module = (modules.values + irModule!!).single { it.descriptor.isNativeStdlib() }
} }
mainModule.files.forEach { it.metadata = KonanFileMetadataSource(mainModule) }
modules.values.forEach { module ->
module.files.forEach { it.metadata = KonanFileMetadataSource(module as KonanIrModuleFragmentImpl) }
}
val originalBindingContext = bindingContext as? CleanableBindingContext val originalBindingContext = bindingContext as? CleanableBindingContext
?: error("BindingContext should be cleanable in K/N IR to avoid leaking memory: $bindingContext") ?: error("BindingContext should be cleanable in K/N IR to avoid leaking memory: $bindingContext")
originalBindingContext.clear() originalBindingContext.clear()
@@ -8,7 +8,7 @@ import org.jetbrains.kotlin.backend.common.lower.at
import org.jetbrains.kotlin.backend.common.lower.irNot import org.jetbrains.kotlin.backend.common.lower.irNot
import org.jetbrains.kotlin.backend.konan.PrimitiveBinaryType import org.jetbrains.kotlin.backend.konan.PrimitiveBinaryType
import org.jetbrains.kotlin.backend.konan.RuntimeNames import org.jetbrains.kotlin.backend.konan.RuntimeNames
import org.jetbrains.kotlin.backend.konan.descriptors.konanLibrary import org.jetbrains.kotlin.backend.konan.ir.konanLibrary
import org.jetbrains.kotlin.backend.konan.getObjCMethodInfo import org.jetbrains.kotlin.backend.konan.getObjCMethodInfo
import org.jetbrains.kotlin.backend.konan.ir.KonanSymbols import org.jetbrains.kotlin.backend.konan.ir.KonanSymbols
import org.jetbrains.kotlin.backend.konan.ir.buildSimpleAnnotation import org.jetbrains.kotlin.backend.konan.ir.buildSimpleAnnotation
@@ -303,7 +303,7 @@ internal fun KotlinStubs.generateObjCCall(
) = builder.irBlock { ) = builder.irBlock {
val resolved = method.resolveFakeOverride(allowAbstract = true)?: method val resolved = method.resolveFakeOverride(allowAbstract = true)?: method
val exceptionMode = ForeignExceptionMode.byValue( val exceptionMode = ForeignExceptionMode.byValue(
resolved.module.konanLibrary?.manifestProperties resolved.konanLibrary?.manifestProperties
?.getProperty(ForeignExceptionMode.manifestKey) ?.getProperty(ForeignExceptionMode.manifestKey)
) )
@@ -10,8 +10,6 @@ import org.jetbrains.kotlin.backend.konan.RuntimeNames
import org.jetbrains.kotlin.builtins.konan.KonanBuiltIns import org.jetbrains.kotlin.builtins.konan.KonanBuiltIns
import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor
import org.jetbrains.kotlin.descriptors.konan.DeserializedKlibModuleOrigin
import org.jetbrains.kotlin.descriptors.konan.klibModuleOrigin
import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.resolve.OverridingUtil import org.jetbrains.kotlin.resolve.OverridingUtil
import org.jetbrains.kotlin.resolve.checkers.ExpectedActualDeclarationChecker import org.jetbrains.kotlin.resolve.checkers.ExpectedActualDeclarationChecker
@@ -156,5 +154,3 @@ internal val DeclarationDescriptor.isExpectMember: Boolean
internal val DeclarationDescriptor.isSerializableExpectClass: Boolean internal val DeclarationDescriptor.isSerializableExpectClass: Boolean
get() = this is ClassDescriptor && ExpectedActualDeclarationChecker.shouldGenerateExpectClass(this) get() = this is ClassDescriptor && ExpectedActualDeclarationChecker.shouldGenerateExpectClass(this)
val ModuleDescriptor.konanLibrary get() = (this.klibModuleOrigin as? DeserializedKlibModuleOrigin)?.library
@@ -7,9 +7,17 @@ package org.jetbrains.kotlin.backend.konan.ir
import org.jetbrains.kotlin.backend.common.atMostOne import org.jetbrains.kotlin.backend.common.atMostOne
import org.jetbrains.kotlin.backend.konan.DECLARATION_ORIGIN_INLINE_CLASS_SPECIAL_FUNCTION import org.jetbrains.kotlin.backend.konan.DECLARATION_ORIGIN_INLINE_CLASS_SPECIAL_FUNCTION
import org.jetbrains.kotlin.backend.konan.descriptors.isInteropLibrary
import org.jetbrains.kotlin.backend.konan.llvm.KonanMetadata
import org.jetbrains.kotlin.backend.konan.serialization.KonanFileMetadataSource
import org.jetbrains.kotlin.backend.konan.serialization.KonanIrModuleFragmentImpl
import org.jetbrains.kotlin.descriptors.Modality import org.jetbrains.kotlin.descriptors.Modality
import org.jetbrains.kotlin.descriptors.DescriptorVisibilities import org.jetbrains.kotlin.descriptors.DescriptorVisibilities
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
import org.jetbrains.kotlin.descriptors.konan.DeserializedKlibModuleOrigin
import org.jetbrains.kotlin.descriptors.konan.klibModuleOrigin
import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.declarations.lazy.IrLazyDeclarationBase
import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns
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
@@ -23,6 +31,7 @@ import org.jetbrains.kotlin.ir.types.IdSignatureValues
import org.jetbrains.kotlin.ir.types.classifierOrFail import org.jetbrains.kotlin.ir.types.classifierOrFail
import org.jetbrains.kotlin.ir.types.isMarkedNullable import org.jetbrains.kotlin.ir.types.isMarkedNullable
import org.jetbrains.kotlin.ir.util.* import org.jetbrains.kotlin.ir.util.*
import org.jetbrains.kotlin.library.KotlinLibrary
import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.utils.addToStdlib.safeAs import org.jetbrains.kotlin.utils.addToStdlib.safeAs
@@ -101,3 +110,23 @@ fun buildSimpleAnnotation(irBuiltIns: IrBuiltIns, startOffset: Int, endOffset: I
internal fun IrExpression.isBoxOrUnboxCall() = internal fun IrExpression.isBoxOrUnboxCall() =
(this is IrCall && symbol.owner.origin == DECLARATION_ORIGIN_INLINE_CLASS_SPECIAL_FUNCTION) (this is IrCall && symbol.owner.origin == DECLARATION_ORIGIN_INLINE_CLASS_SPECIAL_FUNCTION)
val ModuleDescriptor.konanLibrary get() = (this.klibModuleOrigin as? DeserializedKlibModuleOrigin)?.library
val IrModuleFragment.konanLibrary get() =
(this as? KonanIrModuleFragmentImpl)?.konanLibrary ?: descriptor.konanLibrary
val IrFile.konanLibrary get() =
(metadata as? KonanFileMetadataSource)?.module?.konanLibrary ?: packageFragmentDescriptor.containingDeclaration.konanLibrary
val IrDeclaration.konanLibrary: KotlinLibrary? get() {
((this as? IrMetadataSourceOwner)?.metadata as? KonanMetadata)?.let { return it.konanLibrary }
val result = when (val parent = parent) {
is IrFile -> parent.konanLibrary
is IrPackageFragment -> parent.packageFragmentDescriptor.containingDeclaration.konanLibrary
is IrDeclaration -> parent.konanLibrary
else -> TODO("Unexpected declaration parent: $parent")
}
if (this is IrMetadataSourceOwner && this !is IrLazyDeclarationBase)
metadata = KonanMetadata(metadata?.name, result)
return result
}
fun IrDeclaration.isFromInteropLibrary() = konanLibrary?.isInteropLibrary() == true
@@ -636,4 +636,4 @@ internal class Llvm(val context: Context, val llvmModule: LLVMModuleRef) {
val llvmVector128 = vector128Type val llvmVector128 = vector128Type
} }
class IrStaticInitializer(val module: ModuleDescriptor, val initializer: LLVMValueRef) class IrStaticInitializer(val konanLibrary: KotlinLibrary?, val initializer: LLVMValueRef)
@@ -15,6 +15,7 @@ import org.jetbrains.kotlin.backend.konan.*
import org.jetbrains.kotlin.backend.konan.descriptors.* import org.jetbrains.kotlin.backend.konan.descriptors.*
import org.jetbrains.kotlin.backend.konan.ir.* import org.jetbrains.kotlin.backend.konan.ir.*
import org.jetbrains.kotlin.backend.konan.llvm.coverage.LLVMCoverageInstrumentation import org.jetbrains.kotlin.backend.konan.llvm.coverage.LLVMCoverageInstrumentation
import org.jetbrains.kotlin.backend.konan.serialization.KonanIrModuleFragmentImpl
import org.jetbrains.kotlin.builtins.UnsignedType import org.jetbrains.kotlin.builtins.UnsignedType
import org.jetbrains.kotlin.descriptors.Modality import org.jetbrains.kotlin.descriptors.Modality
import org.jetbrains.kotlin.descriptors.ModuleDescriptor import org.jetbrains.kotlin.descriptors.ModuleDescriptor
@@ -32,6 +33,7 @@ import org.jetbrains.kotlin.ir.visitors.acceptVoid
import org.jetbrains.kotlin.konan.ForeignExceptionMode import org.jetbrains.kotlin.konan.ForeignExceptionMode
import org.jetbrains.kotlin.konan.target.CompilerOutputKind import org.jetbrains.kotlin.konan.target.CompilerOutputKind
import org.jetbrains.kotlin.konan.target.Family import org.jetbrains.kotlin.konan.target.Family
import org.jetbrains.kotlin.library.KotlinLibrary
import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.resolve.descriptorUtil.classId import org.jetbrains.kotlin.resolve.descriptorUtil.classId
@@ -323,7 +325,7 @@ internal class CodeGeneratorVisitor(val context: Context, val lifetimes: Map<IrE
context.cAdapterGenerator.generateBindings(codegen) context.cAdapterGenerator.generateBindings(codegen)
} }
private fun runAndProcessInitializers(module: ModuleDescriptor, f: () -> Unit) { private fun runAndProcessInitializers(konanLibrary: KotlinLibrary?, f: () -> Unit) {
// TODO: collect those two in one place. // TODO: collect those two in one place.
context.llvm.fileInitializers.clear() context.llvm.fileInitializers.clear()
context.llvm.fileUsesThreadLocalObjects = false context.llvm.fileUsesThreadLocalObjects = false
@@ -337,7 +339,7 @@ internal class CodeGeneratorVisitor(val context: Context, val lifetimes: Map<IrE
// Create global initialization records. // Create global initialization records.
val initNode = createInitNode(createInitBody()) val initNode = createInitNode(createInitBody())
context.llvm.irStaticInitializers.add(IrStaticInitializer(module, createInitCtor(initNode))) context.llvm.irStaticInitializers.add(IrStaticInitializer(konanLibrary, createInitCtor(initNode)))
} }
//-------------------------------------------------------------------------// //-------------------------------------------------------------------------//
@@ -355,7 +357,7 @@ internal class CodeGeneratorVisitor(val context: Context, val lifetimes: Map<IrE
initializeCachedBoxes(context) initializeCachedBoxes(context)
declaration.acceptChildrenVoid(this) declaration.acceptChildrenVoid(this)
runAndProcessInitializers(declaration.descriptor) { runAndProcessInitializers(null) {
// Note: it is here because it also generates some bitcode. // Note: it is here because it also generates some bitcode.
context.objCExport.generate(codegen) context.objCExport.generate(codegen)
@@ -510,7 +512,7 @@ internal class CodeGeneratorVisitor(val context: Context, val lifetimes: Map<IrE
override fun visitFile(declaration: IrFile) { override fun visitFile(declaration: IrFile) {
@Suppress("UNCHECKED_CAST") @Suppress("UNCHECKED_CAST")
using(FileScope(declaration)) { using(FileScope(declaration)) {
runAndProcessInitializers(declaration.packageFragmentDescriptor.module) { runAndProcessInitializers(declaration.konanLibrary) {
declaration.acceptChildrenVoid(this) declaration.acceptChildrenVoid(this)
} }
} }
@@ -2424,7 +2426,7 @@ internal class CodeGeneratorVisitor(val context: Context, val lifetimes: Map<IrE
} }
context.llvm.irStaticInitializers.forEach { context.llvm.irStaticInitializers.forEach {
val library = it.module.konanLibrary val library = it.konanLibrary
val initializers = libraryToInitializers[library] val initializers = libraryToInitializers[library]
?: error("initializer for not included library ${library?.libraryFile}") ?: error("initializer for not included library ${library?.libraryFile}")
@@ -15,17 +15,14 @@ import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.util.* import org.jetbrains.kotlin.ir.util.*
import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid
import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid
import org.jetbrains.kotlin.library.KotlinLibrary
import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.Name
internal fun createLlvmDeclarations(context: Context): LlvmDeclarations { internal fun createLlvmDeclarations(context: Context): LlvmDeclarations {
val generator = DeclarationsGeneratorVisitor(context) val generator = DeclarationsGeneratorVisitor(context)
context.ir.irModule.acceptChildrenVoid(generator) context.ir.irModule.acceptChildrenVoid(generator)
return with(generator) { return LlvmDeclarations(generator.uniques)
LlvmDeclarations(
functions, classes, fields, staticFields, uniques
)
}
} }
// Please note, that llvmName is part of the ABI, and cannot be liberally changed. // Please note, that llvmName is part of the ABI, and cannot be liberally changed.
@@ -34,22 +31,17 @@ enum class UniqueKind(val llvmName: String) {
EMPTY_ARRAY("theEmptyArray") EMPTY_ARRAY("theEmptyArray")
} }
internal class LlvmDeclarations( internal class LlvmDeclarations(private val unique: Map<UniqueKind, UniqueLlvmDeclarations>) {
private val functions: Map<IrFunction, FunctionLlvmDeclarations>,
private val classes: Map<IrClass, ClassLlvmDeclarations>,
private val fields: Map<IrField, FieldLlvmDeclarations>,
private val staticFields: Map<IrField, StaticFieldLlvmDeclarations>,
private val unique: Map<UniqueKind, UniqueLlvmDeclarations>) {
fun forFunction(function: IrFunction) = forFunctionOrNull(function) ?: with(function){error("$name in $file/${parent.fqNameForIrSerialization}")} fun forFunction(function: IrFunction) = forFunctionOrNull(function) ?: with(function){error("$name in $file/${parent.fqNameForIrSerialization}")}
fun forFunctionOrNull(function: IrFunction) = functions[function] fun forFunctionOrNull(function: IrFunction) = (function.metadata as? CodegenFunctionMetadata)?.llvm
fun forClass(irClass: IrClass) = classes[irClass] ?: fun forClass(irClass: IrClass) = (irClass.metadata as? CodegenClassMetadata)?.llvm ?:
error(irClass.descriptor.toString()) error(irClass.descriptor.toString())
fun forField(field: IrField) = fields[field] ?: fun forField(field: IrField) = (field.metadata as? CodegenInstanceFieldMetadata)?.llvm ?:
error(field.descriptor.toString()) error(field.descriptor.toString())
fun forStaticField(field: IrField) = staticFields[field] ?: fun forStaticField(field: IrField) = (field.metadata as? CodegenStaticFieldMetadata)?.llvm ?:
error(field.descriptor.toString()) error(field.descriptor.toString())
fun forSingleton(irClass: IrClass) = forClass(irClass).singletonDeclarations ?: fun forSingleton(irClass: IrClass) = forClass(irClass).singletonDeclarations ?:
@@ -100,10 +92,6 @@ private fun ContextUtils.createClassBodyType(name: String, fields: List<IrField>
private class DeclarationsGeneratorVisitor(override val context: Context) : private class DeclarationsGeneratorVisitor(override val context: Context) :
IrElementVisitorVoid, ContextUtils { IrElementVisitorVoid, ContextUtils {
val functions = mutableMapOf<IrFunction, FunctionLlvmDeclarations>()
val classes = mutableMapOf<IrClass, ClassLlvmDeclarations>()
val fields = mutableMapOf<IrField, FieldLlvmDeclarations>()
val staticFields = mutableMapOf<IrField, StaticFieldLlvmDeclarations>()
val uniques = mutableMapOf<UniqueKind, UniqueLlvmDeclarations>() val uniques = mutableMapOf<UniqueKind, UniqueLlvmDeclarations>()
private class Namer(val prefix: String) { private class Namer(val prefix: String) {
@@ -157,7 +145,10 @@ private class DeclarationsGeneratorVisitor(override val context: Context) :
override fun visitClass(declaration: IrClass) { override fun visitClass(declaration: IrClass) {
if (declaration.requiresRtti()) { if (declaration.requiresRtti()) {
this.classes[declaration] = createClassDeclarations(declaration) val classLlvmDeclarations = createClassDeclarations(declaration)
val metadata = declaration.metadata as? CodegenClassMetadata
?: CodegenClassMetadata(declaration).also { declaration.metadata = it }
metadata.llvm = classLlvmDeclarations
} }
super.visitClass(declaration) super.visitClass(declaration)
} }
@@ -311,12 +302,16 @@ private class DeclarationsGeneratorVisitor(override val context: Context) :
val containingClass = declaration.parent as? IrClass val containingClass = declaration.parent as? IrClass
if (containingClass != null) { if (containingClass != null) {
if (!containingClass.requiresRtti()) return if (!containingClass.requiresRtti()) return
val classDeclarations = this.classes[containingClass] ?: val classDeclarations = (containingClass.metadata as? CodegenClassMetadata)?.llvm
error(containingClass.descriptor.toString()) ?: error(containingClass.descriptor.toString())
val allFields = context.getLayoutBuilder(containingClass).fields val allFields = context.getLayoutBuilder(containingClass).fields
this.fields[declaration] = FieldLlvmDeclarations( declaration.metadata = CodegenInstanceFieldMetadata(
allFields.indexOf(declaration) + 1, // First field is ObjHeader. declaration.metadata?.name,
classDeclarations.bodyType containingClass.konanLibrary,
FieldLlvmDeclarations(
allFields.indexOf(declaration) + 1, // First field is ObjHeader.
classDeclarations.bodyType
)
) )
} else { } else {
// Fields are module-private, so we use internal name: // Fields are module-private, so we use internal name:
@@ -327,7 +322,11 @@ private class DeclarationsGeneratorVisitor(override val context: Context) :
addKotlinGlobal(name, getLLVMType(declaration.type), isExported = false) addKotlinGlobal(name, getLLVMType(declaration.type), isExported = false)
} }
this.staticFields[declaration] = StaticFieldLlvmDeclarations(storage) declaration.metadata = CodegenStaticFieldMetadata(
declaration.metadata?.name,
declaration.konanLibrary,
StaticFieldLlvmDeclarations(storage)
)
} }
} }
@@ -346,7 +345,7 @@ private class DeclarationsGeneratorVisitor(override val context: Context) :
if (declaration.isTypedIntrinsic || declaration.isObjCBridgeBased() if (declaration.isTypedIntrinsic || declaration.isObjCBridgeBased()
// All call-sites to external accessors to interop properties // All call-sites to external accessors to interop properties
// are lowered by InteropLowering. // are lowered by InteropLowering.
|| (declaration.isAccessor && declaration.isFromMetadataInteropLibrary()) || (declaration.isAccessor && declaration.isFromInteropLibrary())
|| declaration.annotations.hasAnnotation(RuntimeNames.cCall)) return || declaration.annotations.hasAnnotation(RuntimeNames.cCall)) return
context.llvm.externalFunction(declaration.symbolName, llvmFunctionType, context.llvm.externalFunction(declaration.symbolName, llvmFunctionType,
@@ -374,6 +373,36 @@ private class DeclarationsGeneratorVisitor(override val context: Context) :
function function
} }
this.functions[declaration] = FunctionLlvmDeclarations(llvmFunction) declaration.metadata = CodegenFunctionMetadata(
declaration.metadata?.name,
declaration.konanLibrary,
FunctionLlvmDeclarations(llvmFunction)
)
} }
} }
internal open class KonanMetadata(override val name: Name?, val konanLibrary: KotlinLibrary?) : MetadataSource
internal class CodegenClassMetadata(irClass: IrClass)
: KonanMetadata(irClass.metadata?.name, irClass.konanLibrary), MetadataSource.Class {
var layoutBuilder: ClassLayoutBuilder? = null
var llvm: ClassLlvmDeclarations? = null
}
private class CodegenFunctionMetadata(
name: Name?,
konanLibrary: KotlinLibrary?,
val llvm: FunctionLlvmDeclarations
) : KonanMetadata(name, konanLibrary), MetadataSource.Function
private class CodegenInstanceFieldMetadata(
name: Name?,
konanLibrary: KotlinLibrary?,
val llvm: FieldLlvmDeclarations
) : KonanMetadata(name, konanLibrary), MetadataSource.Property
private class CodegenStaticFieldMetadata(
name: Name?,
konanLibrary: KotlinLibrary?,
val llvm: StaticFieldLlvmDeclarations
) : KonanMetadata(name, konanLibrary), MetadataSource.Property
@@ -53,6 +53,10 @@ internal class WorkersBridgesBuilding(val context: Context) : DeclarationContain
private fun buildWorkerBridges(declaration: IrDeclaration): List<IrFunction> { private fun buildWorkerBridges(declaration: IrDeclaration): List<IrFunction> {
val bridges = mutableListOf<IrFunction>() val bridges = mutableListOf<IrFunction>()
declaration.transformChildrenVoid(object: IrElementTransformerVoid() { declaration.transformChildrenVoid(object: IrElementTransformerVoid() {
override fun visitClass(declaration: IrClass): IrStatement {
// Skip nested.
return declaration
}
override fun visitCall(expression: IrCall): IrExpression { override fun visitCall(expression: IrCall): IrExpression {
expression.transformChildrenVoid(this) expression.transformChildrenVoid(this)
@@ -133,20 +137,24 @@ internal class BridgesBuilding(val context: Context) : ClassLoweringPass {
override fun lower(irClass: IrClass) { override fun lower(irClass: IrClass) {
val builtBridges = mutableSetOf<IrSimpleFunction>() val builtBridges = mutableSetOf<IrSimpleFunction>()
irClass.simpleFunctions() for (function in irClass.simpleFunctions()) {
.forEach { function -> val set = mutableSetOf<BridgeDirections>()
function.allOverriddenFunctions for (overriddenFunction in function.allOverriddenFunctions) {
.map { OverriddenFunctionInfo(function, it) } val overriddenFunctionInfo = OverriddenFunctionInfo(function, overriddenFunction)
.filter { !it.bridgeDirections.allNotNeeded() } val bridgeDirections = overriddenFunctionInfo.bridgeDirections
.filter { it.canBeCalledVirtually } if (!bridgeDirections.allNotNeeded() && overriddenFunctionInfo.canBeCalledVirtually
.filter { !it.inheritsBridge } && !overriddenFunctionInfo.inheritsBridge && set.add(bridgeDirections)) {
.distinctBy { it.bridgeDirections } buildBridge(overriddenFunctionInfo, irClass)
.forEach { builtBridges += function
buildBridge(it, irClass)
builtBridges += it.function
}
} }
}
}
irClass.transformChildrenVoid(object: IrElementTransformerVoid() { irClass.transformChildrenVoid(object: IrElementTransformerVoid() {
override fun visitClass(declaration: IrClass): IrStatement {
// Skip nested.
return declaration
}
override fun visitFunction(declaration: IrFunction): IrStatement { override fun visitFunction(declaration: IrFunction): IrStatement {
declaration.transformChildrenVoid(this) declaration.transformChildrenVoid(this)
@@ -16,6 +16,7 @@ import org.jetbrains.kotlin.backend.konan.DECLARATION_ORIGIN_ENUM
import org.jetbrains.kotlin.backend.konan.llvm.IntrinsicType import org.jetbrains.kotlin.backend.konan.llvm.IntrinsicType
import org.jetbrains.kotlin.backend.konan.llvm.tryGetIntrinsicType import org.jetbrains.kotlin.backend.konan.llvm.tryGetIntrinsicType
import org.jetbrains.kotlin.descriptors.ClassKind import org.jetbrains.kotlin.descriptors.ClassKind
import org.jetbrains.kotlin.ir.IrStatement
import org.jetbrains.kotlin.ir.builders.* import org.jetbrains.kotlin.ir.builders.*
import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.declarations.impl.IrPropertyImpl import org.jetbrains.kotlin.ir.declarations.impl.IrPropertyImpl
@@ -124,19 +125,25 @@ internal class EnumUsageLowering(val context: Context)
} }
} }
internal class EnumClassLowering(val context: Context) : ClassLoweringPass { internal class EnumClassLowering(val context: Context) : FileLoweringPass {
fun run(irFile: IrFile) { fun run(irFile: IrFile) {
// EnumWhenLowering should be performed before EnumUsageLowering because // EnumWhenLowering should be performed before EnumUsageLowering because
// the latter performs lowering of IrGetEnumValue // the latter performs lowering of IrGetEnumValue
EnumWhenLowering(context).lower(irFile) EnumWhenLowering(context).lower(irFile)
runOnFilePostfix(irFile) lower(irFile)
EnumUsageLowering(context).lower(irFile) EnumUsageLowering(context).lower(irFile)
} }
override fun lower(irClass: IrClass) { override fun lower(irFile: IrFile) {
if (irClass.kind != ClassKind.ENUM_CLASS) return irFile.transformChildrenVoid(object : IrElementTransformerVoid() {
EnumClassTransformer(irClass).run() override fun visitClass(declaration: IrClass): IrStatement {
declaration.transformChildrenVoid()
if (declaration.kind == ClassKind.ENUM_CLASS)
EnumClassTransformer(declaration).run()
return declaration
}
})
} }
private inner class EnumClassTransformer(val irClass: IrClass) { private inner class EnumClassTransformer(val irClass: IrClass) {
@@ -9,6 +9,7 @@ import org.jetbrains.kotlin.backend.common.ClassLoweringPass
import org.jetbrains.kotlin.backend.common.IrElementTransformerVoidWithContext import org.jetbrains.kotlin.backend.common.IrElementTransformerVoidWithContext
import org.jetbrains.kotlin.backend.common.lower.callsSuper import org.jetbrains.kotlin.backend.common.lower.callsSuper
import org.jetbrains.kotlin.backend.konan.Context import org.jetbrains.kotlin.backend.konan.Context
import org.jetbrains.kotlin.ir.IrStatement
import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.expressions.IrBlockBody import org.jetbrains.kotlin.ir.expressions.IrBlockBody
import org.jetbrains.kotlin.ir.expressions.IrExpression import org.jetbrains.kotlin.ir.expressions.IrExpression
@@ -87,6 +88,11 @@ internal class InnerClassLowering(val context: Context) : ClassLoweringPass {
private fun lowerOuterThisReferences() { private fun lowerOuterThisReferences() {
irClass.transformChildrenVoid(object : IrElementTransformerVoidWithContext() { irClass.transformChildrenVoid(object : IrElementTransformerVoidWithContext() {
override fun visitClassNew(declaration: IrClass): IrStatement {
// Skip nested.
return declaration
}
override fun visitGetValue(expression: IrGetValue): IrExpression { override fun visitGetValue(expression: IrGetValue): IrExpression {
expression.transformChildrenVoid(this) expression.transformChildrenVoid(this)
@@ -14,8 +14,6 @@ import org.jetbrains.kotlin.backend.common.lower.*
import org.jetbrains.kotlin.backend.konan.* import org.jetbrains.kotlin.backend.konan.*
import org.jetbrains.kotlin.backend.konan.cgen.* import org.jetbrains.kotlin.backend.konan.cgen.*
import org.jetbrains.kotlin.backend.konan.descriptors.allOverriddenFunctions import org.jetbrains.kotlin.backend.konan.descriptors.allOverriddenFunctions
import org.jetbrains.kotlin.backend.konan.descriptors.isFromInteropLibrary
import org.jetbrains.kotlin.backend.konan.descriptors.konanLibrary
import org.jetbrains.kotlin.backend.konan.descriptors.synthesizedName import org.jetbrains.kotlin.backend.konan.descriptors.synthesizedName
import org.jetbrains.kotlin.backend.konan.ir.* import org.jetbrains.kotlin.backend.konan.ir.*
import org.jetbrains.kotlin.backend.konan.ir.companionObject import org.jetbrains.kotlin.backend.konan.ir.companionObject
@@ -811,7 +809,7 @@ private class InteropTransformer(val context: Context, override val irFile: IrFi
private fun tryGenerateInteropConstantRead(expression: IrCall): IrExpression? { private fun tryGenerateInteropConstantRead(expression: IrCall): IrExpression? {
val function = expression.symbol.owner val function = expression.symbol.owner
if (!function.descriptor.module.isFromInteropLibrary()) return null if (!function.isFromInteropLibrary()) return null
if (!function.isGetter) return null if (!function.isGetter) return null
val constantProperty = (function as? IrSimpleFunction) val constantProperty = (function as? IrSimpleFunction)
@@ -870,7 +868,7 @@ private class InteropTransformer(val context: Context, override val irFile: IrFi
if (function.annotations.hasAnnotation(RuntimeNames.cCall)) { if (function.annotations.hasAnnotation(RuntimeNames.cCall)) {
context.llvmImports.add(function.llvmSymbolOrigin) context.llvmImports.add(function.llvmSymbolOrigin)
val exceptionMode = ForeignExceptionMode.byValue( val exceptionMode = ForeignExceptionMode.byValue(
function.module.konanLibrary?.manifestProperties?.getProperty(ForeignExceptionMode.manifestKey) function.konanLibrary?.manifestProperties?.getProperty(ForeignExceptionMode.manifestKey)
) )
return generateWithStubs { generateCCall(expression, builder, isInvoke = false, exceptionMode) } return generateWithStubs { generateCCall(expression, builder, isInvoke = false, exceptionMode) }
} }
@@ -25,6 +25,7 @@ import org.jetbrains.kotlin.backend.konan.KonanBackendContext
import org.jetbrains.kotlin.builtins.PrimitiveType import org.jetbrains.kotlin.builtins.PrimitiveType
import org.jetbrains.kotlin.builtins.UnsignedType import org.jetbrains.kotlin.builtins.UnsignedType
import org.jetbrains.kotlin.ir.IrElement import org.jetbrains.kotlin.ir.IrElement
import org.jetbrains.kotlin.ir.IrStatement
import org.jetbrains.kotlin.ir.builders.* import org.jetbrains.kotlin.ir.builders.*
import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.expressions.* import org.jetbrains.kotlin.ir.expressions.*
@@ -61,6 +62,11 @@ internal class VarargInjectionLowering constructor(val context: KonanBackendCont
private fun lower(owner: IrSymbol, element: IrElement?) { private fun lower(owner: IrSymbol, element: IrElement?) {
element?.transformChildrenVoid(object: IrElementTransformerVoid() { element?.transformChildrenVoid(object: IrElementTransformerVoid() {
override fun visitClass(declaration: IrClass): IrStatement {
// Skip nested.
return declaration
}
val transformer = this val transformer = this
private fun replaceEmptyParameterWithEmptyArray(expression: IrFunctionAccessExpression) { private fun replaceEmptyParameterWithEmptyArray(expression: IrFunctionAccessExpression) {
@@ -24,22 +24,24 @@ import org.jetbrains.kotlin.backend.common.serialization.encodings.BinarySymbolD
import org.jetbrains.kotlin.backend.common.serialization.signature.IdSignatureSerializer import org.jetbrains.kotlin.backend.common.serialization.signature.IdSignatureSerializer
import org.jetbrains.kotlin.backend.konan.CachedLibraries import org.jetbrains.kotlin.backend.konan.CachedLibraries
import org.jetbrains.kotlin.backend.konan.descriptors.isInteropLibrary import org.jetbrains.kotlin.backend.konan.descriptors.isInteropLibrary
import org.jetbrains.kotlin.backend.konan.descriptors.konanLibrary
import org.jetbrains.kotlin.backend.konan.ir.interop.IrProviderForCEnumAndCStructStubs import org.jetbrains.kotlin.backend.konan.ir.interop.IrProviderForCEnumAndCStructStubs
import org.jetbrains.kotlin.backend.konan.ir.konanLibrary
import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.konan.DeserializedKlibModuleOrigin
import org.jetbrains.kotlin.descriptors.konan.isNativeStdlib import org.jetbrains.kotlin.descriptors.konan.isNativeStdlib
import org.jetbrains.kotlin.descriptors.konan.klibModuleOrigin
import org.jetbrains.kotlin.descriptors.konan.kotlinLibrary import org.jetbrains.kotlin.descriptors.konan.kotlinLibrary
import org.jetbrains.kotlin.ir.builders.TranslationPluginContext import org.jetbrains.kotlin.ir.builders.TranslationPluginContext
import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.declarations.impl.IrFileImpl import org.jetbrains.kotlin.ir.declarations.impl.IrFileImpl
import org.jetbrains.kotlin.ir.declarations.impl.IrModuleFragmentImpl
import org.jetbrains.kotlin.ir.descriptors.IrAbstractFunctionFactory import org.jetbrains.kotlin.ir.descriptors.IrAbstractFunctionFactory
import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns
import org.jetbrains.kotlin.ir.symbols.IrSymbol import org.jetbrains.kotlin.ir.symbols.IrSymbol
import org.jetbrains.kotlin.ir.symbols.impl.IrFileSymbolImpl
import org.jetbrains.kotlin.ir.symbols.impl.IrPublicSymbolBase import org.jetbrains.kotlin.ir.symbols.impl.IrPublicSymbolBase
import org.jetbrains.kotlin.ir.types.classOrNull import org.jetbrains.kotlin.ir.types.classOrNull
import org.jetbrains.kotlin.ir.util.* 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.IrLibrary
import org.jetbrains.kotlin.library.KotlinLibrary import org.jetbrains.kotlin.library.KotlinLibrary
import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.ClassId
@@ -107,8 +109,13 @@ internal class KonanIrLinker(
return KonanModuleDeserializer(moduleDescriptor, klib ?: error("Expecting kotlin library"), strategy) return KonanModuleDeserializer(moduleDescriptor, klib ?: error("Expecting kotlin library"), strategy)
} }
private inner class KonanModuleDeserializer(moduleDescriptor: ModuleDescriptor, klib: IrLibrary, strategy: DeserializationStrategy): private inner class KonanModuleDeserializer(
KotlinIrLinker.BasicIrModuleDeserializer(moduleDescriptor, klib, strategy) moduleDescriptor: ModuleDescriptor,
klib: IrLibrary,
strategy: DeserializationStrategy
): KotlinIrLinker.BasicIrModuleDeserializer(moduleDescriptor, klib, strategy) {
override val moduleFragment: IrModuleFragment = KonanIrModuleFragmentImpl(moduleDescriptor, builtIns, emptyList())
}
private inner class KonanInteropModuleDeserializer( private inner class KonanInteropModuleDeserializer(
moduleDescriptor: ModuleDescriptor, moduleDescriptor: ModuleDescriptor,
@@ -160,7 +167,7 @@ internal class KonanIrLinker(
return symbolOwner.symbol return symbolOwner.symbol
} }
override val moduleFragment: IrModuleFragment = IrModuleFragmentImpl(moduleDescriptor, builtIns) override val moduleFragment: IrModuleFragment = KonanIrModuleFragmentImpl(moduleDescriptor, builtIns)
override val moduleDependencies: Collection<IrModuleDeserializer> = listOfNotNull(forwardDeclarationDeserializer) override val moduleDependencies: Collection<IrModuleDeserializer> = listOfNotNull(forwardDeclarationDeserializer)
} }
@@ -208,7 +215,7 @@ internal class KonanIrLinker(
return declaredDeclaration.getOrPut(idSig) { buildForwardDeclarationStub(descriptor) }.symbol return declaredDeclaration.getOrPut(idSig) { buildForwardDeclarationStub(descriptor) }.symbol
} }
override val moduleFragment: IrModuleFragment = IrModuleFragmentImpl(moduleDescriptor, builtIns) override val moduleFragment: IrModuleFragment = KonanIrModuleFragmentImpl(moduleDescriptor, builtIns)
override val moduleDependencies: Collection<IrModuleDeserializer> = emptyList() override val moduleDependencies: Collection<IrModuleDeserializer> = emptyList()
} }
@@ -226,3 +233,34 @@ internal class KonanIrLinker(
override val irBuiltIns: IrBuiltIns override val irBuiltIns: IrBuiltIns
):TranslationPluginContext ):TranslationPluginContext
} }
class KonanIrModuleFragmentImpl(
override val descriptor: ModuleDescriptor,
override val irBuiltins: IrBuiltIns,
files: List<IrFile> = emptyList(),
) : IrModuleFragment() {
override val name: Name get() = descriptor.name // TODO
override val files: MutableList<IrFile> = files.toMutableList()
val konanLibrary = (descriptor.klibModuleOrigin as? DeserializedKlibModuleOrigin)?.library
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R =
visitor.visitModuleFragment(this, data)
override fun <D> acceptChildren(visitor: IrElementVisitor<Unit, D>, data: D) {
files.forEach { it.accept(visitor, data) }
}
override fun <D> transformChildren(transformer: IrElementTransformer<D>, data: D) {
files.forEachIndexed { i, irFile ->
files[i] = irFile.transform(transformer, data)
}
}
}
fun IrModuleFragment.toKonanModule() = KonanIrModuleFragmentImpl(descriptor, irBuiltins, files)
class KonanFileMetadataSource(val module: KonanIrModuleFragmentImpl) : MetadataSource.File {
override val name: Name? = null
}