[K/N] Reduce usages of NativeGenerationState.context

Now that NativeGenerationState is a PhaseContext we don't need to
access `context` property that frequently.
This commit is contained in:
Sergey Bogolepov
2022-12-01 13:32:59 +02:00
committed by Space Team
parent b8f9b07a5a
commit dca14d4285
20 changed files with 132 additions and 107 deletions
@@ -14,13 +14,13 @@ typealias ExecutableFile = String
internal class BitcodeCompiler(val generationState: NativeGenerationState) {
private val context = generationState.context
private val platform = context.config.platform
private val optimize = context.shouldOptimize()
private val debug = context.config.debug
private val config = generationState.config
private val platform = config.platform
private val optimize = generationState.shouldOptimize()
private val debug = config.debug
private val overrideClangOptions =
context.configuration.getList(KonanConfigKeys.OVERRIDE_CLANG_OPTIONS)
config.configuration.getList(KonanConfigKeys.OVERRIDE_CLANG_OPTIONS)
private fun MutableList<String>.addNonEmpty(elements: List<String>) {
addAll(elements.filter { it.isNotEmpty() })
@@ -28,7 +28,7 @@ internal class BitcodeCompiler(val generationState: NativeGenerationState) {
private fun runTool(vararg command: String) =
Command(*command)
.logWith(context::log)
.logWith(generationState::log)
.execute()
private fun temporary(name: String, suffix: String): String =
@@ -68,8 +68,8 @@ internal class BitcodeCompiler(val generationState: NativeGenerationState) {
debug -> configurables.clangDebugFlags
else -> configurables.clangNooptFlags
})
addNonEmpty(BitcodeEmbedding.getClangOptions(context.config))
addNonEmpty(configurables.currentRelocationMode(context).translateToClangCc1Flag())
addNonEmpty(BitcodeEmbedding.getClangOptions(config))
addNonEmpty(configurables.currentRelocationMode(generationState).translateToClangCc1Flag())
}
if (configurables is AppleConfigurables) {
targetTool("clang++", *flags.toTypedArray(), file, "-o", objectFile)
@@ -178,7 +178,7 @@ internal fun IrConstantPrimitive.toBoxCacheValue(generationState: NativeGenerati
IrConstKind.Long -> value.value as Long
else -> throw IllegalArgumentException("IrConst of kind ${value.kind} can't be converted to box cache")
}
val (start, end) = generationState.context.config.target.getBoxCacheRange(cacheType)
val (start, end) = generationState.config.target.getBoxCacheRange(cacheType)
return if (value in start..end) {
generationState.llvm.let { llvm ->
llvm.boxCacheGlobals[cacheType]?.pointer?.getElementPtr(llvm, value.toInt() - start)?.getElementPtr(llvm, 0)
@@ -91,11 +91,10 @@ internal fun llvmIrDumpCallback(state: ActionState, module: IrModuleFragment, co
}
internal fun produceCStubs(generationState: NativeGenerationState) {
val context = generationState.context
generationState.cStubsManager.compile(
context.config.clang,
context.messageCollector,
context.inVerbosePhase
generationState.config.clang,
generationState.messageCollector,
generationState.inVerbosePhase
).forEach {
parseAndLinkBitcodeFile(generationState, generationState.llvm.module, it.absolutePath)
}
@@ -116,7 +115,7 @@ private data class LlvmModules(
* - Everything else.
*/
private fun collectLlvmModules(generationState: NativeGenerationState, generatedBitcodeFiles: List<String>): LlvmModules {
val config = generationState.context.config
val config = generationState.config
val (bitcodePartOfStdlib, bitcodeLibraries) = generationState.llvm.bitcodeToLink
.partition { it.isStdlib && generationState.producedLlvmModuleContainsStdlib }
@@ -141,7 +140,7 @@ private fun collectLlvmModules(generationState: NativeGenerationState, generated
fun parseBitcodeFiles(files: List<String>): List<LLVMModuleRef> = files.map { bitcodeFile ->
val parsedModule = parseBitcodeFile(generationState.llvmContext, bitcodeFile)
if (!generationState.context.shouldUseDebugInfoFromNativeLibs()) {
if (!generationState.shouldUseDebugInfoFromNativeLibs()) {
LLVMStripModuleDebugInfo(parsedModule)
}
parsedModule
@@ -172,7 +171,7 @@ private fun linkAllDependencies(generationState: NativeGenerationState, generate
}
private fun insertAliasToEntryPoint(generationState: NativeGenerationState) {
val config = generationState.context.config
val config = generationState.config
val nomain = config.configuration.get(KonanConfigKeys.NOMAIN) ?: false
if (config.produce != CompilerOutputKind.PROGRAM || nomain)
return
@@ -184,7 +183,7 @@ private fun insertAliasToEntryPoint(generationState: NativeGenerationState) {
}
internal fun linkBitcodeDependencies(generationState: NativeGenerationState) {
val config = generationState.context.config
val config = generationState.config
val tempFiles = generationState.tempFiles
val produce = config.produce
@@ -285,7 +284,7 @@ internal fun produceOutput(generationState: NativeGenerationState) {
private fun parseAndLinkBitcodeFile(generationState: NativeGenerationState, llvmModule: LLVMModuleRef, path: String) {
val parsedModule = parseBitcodeFile(generationState.llvmContext, path)
if (!generationState.context.shouldUseDebugInfoFromNativeLibs()) {
if (!generationState.shouldUseDebugInfoFromNativeLibs()) {
LLVMStripModuleDebugInfo(parsedModule)
}
val failed = llvmLinkModules2(generationState, llvmModule, parsedModule)
@@ -103,6 +103,8 @@ internal class Context(
override val optimizeLoopsOverUnsignedArrays = true
// TODO: Drop it to reduce code coupling and make it possible to have multiple
// generationStates at the same time.
lateinit var generationState: NativeGenerationState
fun disposeGenerationState() {
@@ -1,5 +1,6 @@
package org.jetbrains.kotlin.backend.konan
import org.jetbrains.kotlin.backend.konan.driver.PhaseContext
import org.jetbrains.kotlin.backend.konan.serialization.ClassFieldsSerializer
import org.jetbrains.kotlin.backend.konan.serialization.InlineFunctionBodyReferenceSerializer
import org.jetbrains.kotlin.konan.KonanExternalToolFailure
@@ -13,7 +14,7 @@ import org.jetbrains.kotlin.konan.target.presetName
import org.jetbrains.kotlin.library.metadata.resolver.TopologicalLibraryOrder
import org.jetbrains.kotlin.library.uniqueName
internal fun determineLinkerOutput(context: Context): LinkerOutputKind =
internal fun determineLinkerOutput(context: PhaseContext): LinkerOutputKind =
when (context.config.produce) {
CompilerOutputKind.FRAMEWORK -> {
val staticFramework = context.config.produceStaticFramework
@@ -37,7 +38,7 @@ internal fun determineLinkerOutput(context: Context): LinkerOutputKind =
}
internal class CacheStorage(val generationState: NativeGenerationState) {
private val config = generationState.context.config
private val config = generationState.config
private val outputFiles = generationState.outputFiles
fun renameOutput() {
@@ -80,20 +81,19 @@ internal class CacheStorage(val generationState: NativeGenerationState) {
// TODO: We have a Linker.kt file in the shared module.
internal class Linker(val generationState: NativeGenerationState) {
private val context = generationState.context
private val platform = context.config.platform
private val config = context.config.configuration
private val linkerOutput = determineLinkerOutput(context)
private val config = generationState.config
private val platform = config.platform
private val linkerOutput = determineLinkerOutput(generationState)
private val linker = platform.linker
private val target = context.config.target
private val optimize = context.shouldOptimize()
private val debug = context.config.debug || context.config.lightDebug
private val target = config.target
private val optimize = generationState.shouldOptimize()
private val debug = config.debug || config.lightDebug
fun link(objectFiles: List<ObjectFile>) {
val nativeDependencies = generationState.llvm.nativeDependenciesToLink
val includedBinariesLibraries = context.config.libraryToCache?.let { listOf(it.klib) }
?: nativeDependencies.filterNot { context.config.cachedLibraries.isLibraryCached(it) }
val includedBinariesLibraries = config.libraryToCache?.let { listOf(it.klib) }
?: nativeDependencies.filterNot { config.cachedLibraries.isLibraryCached(it) }
val includedBinaries = includedBinariesLibraries.map { (it as? KonanLibrary)?.includedPaths.orEmpty() }.flatten()
val libraryProvidedLinkerFlags = generationState.llvm.allNativeDependencies.map { it.linkerOpts }.flatten()
@@ -126,9 +126,9 @@ internal class Linker(val generationState: NativeGenerationState) {
val additionalLinkerArgs: List<String>
val executable: String
if (context.config.produce != CompilerOutputKind.FRAMEWORK) {
if (config.produce != CompilerOutputKind.FRAMEWORK) {
additionalLinkerArgs = if (target.family.isAppleFamily) {
when (context.config.produce) {
when (config.produce) {
CompilerOutputKind.DYNAMIC_CACHE ->
listOf("-install_name", outputFiles.dynamicCacheInstallName)
else -> listOf("-dead_strip")
@@ -154,13 +154,13 @@ internal class Linker(val generationState: NativeGenerationState) {
}
val needsProfileLibrary = generationState.coverage.enabled
val mimallocEnabled = context.config.allocationMode == AllocationMode.MIMALLOC
val mimallocEnabled = config.allocationMode == AllocationMode.MIMALLOC
val linkerInput = determineLinkerInput(objectFiles, linkerOutput)
try {
File(executable).delete()
val linkerArgs = asLinkerArgs(config.getNotNull(KonanConfigKeys.LINKER_ARGS)) +
BitcodeEmbedding.getLinkerOptions(context.config) +
val linkerArgs = asLinkerArgs(config.configuration.getNotNull(KonanConfigKeys.LINKER_ARGS)) +
BitcodeEmbedding.getLinkerOptions(config) +
linkerInput.caches.dynamic +
libraryProvidedLinkerFlags + additionalLinkerArgs
@@ -175,10 +175,10 @@ internal class Linker(val generationState: NativeGenerationState) {
outputDsymBundle = outputFiles.symbolicInfoFile,
needsProfileLibrary = needsProfileLibrary,
mimallocEnabled = mimallocEnabled,
sanitizer = context.config.sanitizer
sanitizer = config.sanitizer
)
(linkerInput.preLinkCommands + finalOutputCommands).forEach {
it.logWith(context::log)
it.logWith(generationState::log)
it.execute()
}
} catch (e: KonanExternalToolFailure) {
@@ -192,7 +192,7 @@ internal class Linker(val generationState: NativeGenerationState) {
Also, consider filing an issue with full Gradle log here: https://kotl.in/issue
""".trimIndent()
else ""
context.reportCompilationError("${e.toolName} invocation reported errors\n$extraUserInfo\n${e.message}")
generationState.reportCompilationError("${e.toolName} invocation reported errors\n$extraUserInfo\n${e.message}")
}
return executable
}
@@ -200,8 +200,8 @@ internal class Linker(val generationState: NativeGenerationState) {
private fun shouldPerformPreLink(caches: CachesToLink, linkerOutputKind: LinkerOutputKind): Boolean {
// Pre-link is only useful when producing static library. Otherwise its just a waste of time.
val isStaticLibrary = linkerOutputKind == LinkerOutputKind.STATIC_LIBRARY &&
context.config.isFinalBinary
val enabled = context.config.cacheSupport.preLinkCaches
config.isFinalBinary
val enabled = config.cacheSupport.preLinkCaches
val nonEmptyCaches = caches.static.isNotEmpty()
return isStaticLibrary && enabled && nonEmptyCaches
}
@@ -212,7 +212,7 @@ internal class Linker(val generationState: NativeGenerationState) {
// we should detect cache usage early to report errors correctly.
val cachingInvolved = caches.static.isNotEmpty() || caches.dynamic.isNotEmpty()
return when {
context.config.produce == CompilerOutputKind.STATIC_CACHE -> {
config.produce == CompilerOutputKind.STATIC_CACHE -> {
// Do not link static cache dependencies.
LinkerInput(objectFiles, CachesToLink(emptyList(), caches.dynamic), emptyList(), cachingInvolved)
}
@@ -241,7 +241,7 @@ private fun determineCachesToLink(generationState: NativeGenerationState): Cache
generationState.llvm.allCachedBitcodeDependencies.forEach { library ->
val currentBinaryContainsLibrary = generationState.llvmModuleSpecification.containsLibrary(library)
val cache = generationState.context.config.cachedLibraries.getLibraryCache(library)
val cache = generationState.config.cachedLibraries.getLibraryCache(library)
?: error("Library $library is expected to be cached")
// Consistency check. Generally guaranteed by implementation.
@@ -45,6 +45,8 @@ internal class FileLowerState {
internal class NativeGenerationState(
config: KonanConfig,
// TODO: Get rid of this property completely once transition to the dynamic driver is complete.
// It will reduce code coupling and make it easier to create NativeGenerationState instances.
val context: Context,
val cacheDeserializationStrategy: CacheDeserializationStrategy?
) : BasicPhaseContext(config) {
@@ -114,12 +116,17 @@ internal class NativeGenerationState(
verifyModule(llvm.module)
}
// TODO: Do we need this function?
fun printBitCode() {
if (!llvmDelegate.isInitialized()) return
context.separator("BitCode:")
separator("BitCode:")
LLVMDumpModule(llvm.module)
}
private fun separator(title: String) {
println("\n\n--- ${title} ----------------------\n")
}
private var isDisposed = false
override fun dispose() {
if (isDisposed) return
@@ -3,6 +3,7 @@ package org.jetbrains.kotlin.backend.konan
import kotlinx.cinterop.*
import llvm.*
import org.jetbrains.kotlin.backend.common.LoggingContext
import org.jetbrains.kotlin.backend.konan.driver.PhaseContext
import org.jetbrains.kotlin.backend.konan.llvm.*
import org.jetbrains.kotlin.konan.target.*
import java.io.Closeable
@@ -56,7 +57,7 @@ data class LlvmPipelineConfig(
val sanitizer: SanitizerKind?,
)
private fun getCpuModel(context: Context): String {
private fun getCpuModel(context: PhaseContext): String {
val target = context.config.target
val configurables: Configurables = context.config.platform.configurables
return configurables.targetCpu ?: run {
@@ -65,10 +66,10 @@ private fun getCpuModel(context: Context): String {
}
}
private fun getCpuFeatures(context: Context): String =
private fun getCpuFeatures(context: PhaseContext): String =
context.config.platform.configurables.targetCpuFeatures ?: ""
private fun tryGetInlineThreshold(context: Context): Int? {
private fun tryGetInlineThreshold(context: PhaseContext): Int? {
val configurables: Configurables = context.config.platform.configurables
return configurables.llvmInlineThreshold?.let {
it.toIntOrNull() ?: run {
@@ -87,22 +88,22 @@ private fun tryGetInlineThreshold(context: Context): Int? {
* even in debug compilation.
*/
internal fun createLTOPipelineConfigForRuntime(generationState: NativeGenerationState): LlvmPipelineConfig {
val context = generationState.context
val configurables: Configurables = context.config.platform.configurables
val config = generationState.config
val configurables: Configurables = config.platform.configurables
return LlvmPipelineConfig(
generationState.llvm.targetTriple,
getCpuModel(context),
getCpuFeatures(context),
getCpuModel(generationState),
getCpuFeatures(generationState),
LlvmOptimizationLevel.AGGRESSIVE,
LlvmSizeLevel.NONE,
LLVMCodeGenOptLevel.LLVMCodeGenLevelAggressive,
configurables.currentRelocationMode(context).translateToLlvmRelocMode(),
configurables.currentRelocationMode(generationState).translateToLlvmRelocMode(),
LLVMCodeModel.LLVMCodeModelDefault,
globalDce = false,
internalize = false,
objCPasses = configurables is AppleConfigurables,
makeDeclarationsHidden = false,
inlineThreshold = tryGetInlineThreshold(context),
inlineThreshold = tryGetInlineThreshold(generationState),
sanitizer = null
)
}
@@ -116,30 +117,30 @@ internal fun createLTOPipelineConfigForRuntime(generationState: NativeGeneration
* but for release binaries we rely on "closed" world and enable a lot of optimizations.
*/
internal fun createLTOFinalPipelineConfig(generationState: NativeGenerationState): LlvmPipelineConfig {
val context = generationState.context
val target = context.config.target
val configurables: Configurables = context.config.platform.configurables
val cpuModel = getCpuModel(context)
val cpuFeatures = getCpuFeatures(context)
val config = generationState.config
val target = config.target
val configurables: Configurables = config.platform.configurables
val cpuModel = getCpuModel(generationState)
val cpuFeatures = getCpuFeatures(generationState)
val optimizationLevel: LlvmOptimizationLevel = when {
context.shouldOptimize() -> LlvmOptimizationLevel.AGGRESSIVE
context.shouldContainDebugInfo() -> LlvmOptimizationLevel.NONE
generationState.shouldOptimize() -> LlvmOptimizationLevel.AGGRESSIVE
generationState.shouldContainDebugInfo() -> LlvmOptimizationLevel.NONE
else -> LlvmOptimizationLevel.DEFAULT
}
val sizeLevel: LlvmSizeLevel = when {
// We try to optimize code as much as possible on embedded targets.
target is KonanTarget.ZEPHYR ||
target == KonanTarget.WASM32 -> LlvmSizeLevel.AGGRESSIVE
context.shouldOptimize() -> LlvmSizeLevel.NONE
context.shouldContainDebugInfo() -> LlvmSizeLevel.NONE
generationState.shouldOptimize() -> LlvmSizeLevel.NONE
generationState.shouldContainDebugInfo() -> LlvmSizeLevel.NONE
else -> LlvmSizeLevel.NONE
}
val codegenOptimizationLevel: LLVMCodeGenOptLevel = when {
context.shouldOptimize() -> LLVMCodeGenOptLevel.LLVMCodeGenLevelAggressive
context.shouldContainDebugInfo() -> LLVMCodeGenOptLevel.LLVMCodeGenLevelNone
generationState.shouldOptimize() -> LLVMCodeGenOptLevel.LLVMCodeGenLevelAggressive
generationState.shouldContainDebugInfo() -> LLVMCodeGenOptLevel.LLVMCodeGenLevelNone
else -> LLVMCodeGenOptLevel.LLVMCodeGenLevelDefault
}
val relocMode: LLVMRelocMode = configurables.currentRelocationMode(context).translateToLlvmRelocMode()
val relocMode: LLVMRelocMode = configurables.currentRelocationMode(generationState).translateToLlvmRelocMode()
val codeModel: LLVMCodeModel = LLVMCodeModel.LLVMCodeModelDefault
val globalDce = true
// Since we are in a "closed world" internalization can be safely used
@@ -150,14 +151,14 @@ internal fun createLTOFinalPipelineConfig(generationState: NativeGenerationState
// similar to DCE enabled by internalize but later:
//
// Important for binary size, workarounds references to undefined symbols from interop libraries.
val makeDeclarationsHidden = context.config.produce == CompilerOutputKind.STATIC_CACHE
val makeDeclarationsHidden = config.produce == CompilerOutputKind.STATIC_CACHE
val objcPasses = configurables is AppleConfigurables
// Null value means that LLVM should use default inliner params
// for the provided optimization and size level.
val inlineThreshold: Int? = when {
context.shouldOptimize() -> tryGetInlineThreshold(context)
context.shouldContainDebugInfo() -> null
generationState.shouldOptimize() -> tryGetInlineThreshold(generationState)
generationState.shouldContainDebugInfo() -> null
else -> null
}
@@ -175,7 +176,7 @@ internal fun createLTOFinalPipelineConfig(generationState: NativeGenerationState
makeDeclarationsHidden,
objcPasses,
inlineThreshold,
context.config.sanitizer
config.sanitizer
)
}
@@ -298,7 +299,7 @@ class LlvmOptimizationPipeline(
}
}
internal fun RelocationModeFlags.currentRelocationMode(context: Context): RelocationModeFlags.Mode =
internal fun RelocationModeFlags.currentRelocationMode(context: PhaseContext): RelocationModeFlags.Mode =
when (determineLinkerOutput(context)) {
LinkerOutputKind.DYNAMIC_LIBRARY -> dynamicLibraryRelocationMode
LinkerOutputKind.STATIC_LIBRARY -> staticLibraryRelocationMode
@@ -52,7 +52,7 @@ internal sealed class RuntimeLinkageStrategy {
}
}
val config = createLTOPipelineConfigForRuntime(generationState)
LlvmOptimizationPipeline(config, runtimeModule, generationState.context).use {
LlvmOptimizationPipeline(config, runtimeModule, generationState).use {
it.run()
}
return listOf(runtimeModule)
@@ -64,7 +64,7 @@ internal sealed class RuntimeLinkageStrategy {
* Choose runtime linkage strategy based on current compiler configuration and [BinaryOptions.linkRuntime].
*/
internal fun pick(generationState: NativeGenerationState, runtimeLlvmModules: List<LLVMModuleRef>): RuntimeLinkageStrategy {
val config = generationState.context.config
val config = generationState.config
val binaryOption = config.configuration.get(BinaryOptions.linkRuntime)
return when {
binaryOption == RuntimeLinkageStrategyBinaryOption.Raw -> Raw(runtimeLlvmModules)
@@ -92,7 +92,7 @@ internal val objCExportPhase = konanUnitPhase(
objCExportedInterface = when {
!config.target.family.isAppleFamily -> null
config.produce != CompilerOutputKind.FRAMEWORK -> null
else -> produceObjCExportInterface(this)
else -> produceObjCExportInterface(this, this.moduleDescriptor, this.frontendServices)
}
objCExportCodeSpec = objCExportedInterface?.createCodeSpec(symbolTable!!)
},
@@ -246,7 +246,12 @@ internal val codegenPhase = makeKonanModuleOpPhase(
name = "Codegen",
description = "Code generation",
op = { context, irModule ->
context.generationState.objCExport = ObjCExport(context.generationState, context.objCExportedInterface, context.objCExportCodeSpec)
context.generationState.objCExport = ObjCExport(
context.generationState,
context.moduleDescriptor,
context.objCExportedInterface,
context.objCExportCodeSpec
)
irModule.acceptVoid(CodeGeneratorVisitor(context.generationState, context.lifetimes))
@@ -285,8 +290,9 @@ internal val bitcodeOptimizationPhase = makeKonanModuleOpPhase(
name = "BitcodeOptimization",
description = "Optimize bitcode",
op = { context, _ ->
val generationState = context.generationState
val config = createLTOFinalPipelineConfig(context.generationState)
LlvmOptimizationPipeline(config, context.generationState.llvm.module, context).use {
LlvmOptimizationPipeline(config, context.generationState.llvm.module, generationState).use {
it.run()
}
}
@@ -267,7 +267,7 @@ internal fun String?.toFileAndFolder(config: KonanConfig): FileAndFolder {
internal fun alignTo(value: Long, align: Long): Long = (value + align - 1) / align * align
internal fun setupBridgeDebugInfo(generationState: NativeGenerationState, function: LLVMValueRef): LocationInfo? {
if (!generationState.context.shouldContainLocationDebugInfo()) {
if (!generationState.shouldContainLocationDebugInfo()) {
return null
}
@@ -2918,8 +2918,7 @@ internal fun NativeGenerationState.generateRuntimeConstantsModule() : LLVMModule
global.setLinkage(LLVMLinkage.LLVMExternalLinkage)
}
val config = context.config
setRuntimeConstGlobal("Kotlin_needDebugInfo", llvm.constInt32(if (context.shouldContainDebugInfo()) 1 else 0))
setRuntimeConstGlobal("Kotlin_needDebugInfo", llvm.constInt32(if (shouldContainDebugInfo()) 1 else 0))
setRuntimeConstGlobal("Kotlin_runtimeAssertsMode", llvm.constInt32(config.runtimeAssertsMode.value))
val runtimeLogs = config.runtimeLogs?.let {
static.cStringLiteral(it)
@@ -21,7 +21,7 @@ import org.jetbrains.kotlin.resolve.descriptorUtil.module
*/
internal class CoverageManager(val generationState: NativeGenerationState) {
private val context = generationState.context
private val config = context.config
private val config = generationState.config
private val shouldCoverSources: Boolean =
config.shouldCoverSources
@@ -45,7 +45,7 @@ internal class CoverageManager(val generationState: NativeGenerationState) {
init {
if (enabled && !checkRestrictions()) {
context.reportCompilationError("Coverage is not supported for ${config.target}.")
generationState.reportCompilationError("Coverage is not supported for ${config.target}.")
}
}
@@ -6,10 +6,11 @@
package org.jetbrains.kotlin.backend.konan.llvm
import org.jetbrains.kotlin.backend.konan.Context
import org.jetbrains.kotlin.backend.konan.driver.PhaseContext
import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity
internal open class DefaultLlvmDiagnosticHandler(
private val context: Context,
private val context: PhaseContext,
private val policy: Policy = Policy.Default
) : LlvmDiagnosticHandler {
interface Policy {
@@ -10,7 +10,7 @@ import org.jetbrains.kotlin.backend.konan.Context
import org.jetbrains.kotlin.backend.konan.NativeGenerationState
internal fun llvmLinkModules2(generationState: NativeGenerationState, dest: LLVMModuleRef, src: LLVMModuleRef): LLVMBool {
val diagnosticHandler = DefaultLlvmDiagnosticHandler(generationState.context, object : DefaultLlvmDiagnosticHandler.Policy {
val diagnosticHandler = DefaultLlvmDiagnosticHandler(generationState, object : DefaultLlvmDiagnosticHandler.Policy {
override fun suppressWarning(diagnostic: LlvmDiagnostic): Boolean {
if (super.suppressWarning(diagnostic)) return true
@@ -15,7 +15,7 @@ import org.jetbrains.kotlin.backend.konan.objcexport.NSNumberKind
import org.jetbrains.kotlin.backend.konan.objcexport.ObjCExportNamer
internal fun patchObjCRuntimeModule(generationState: NativeGenerationState): LLVMModuleRef? {
val config = generationState.context.config
val config = generationState.config
if (!(config.isFinalBinary && config.target.family.isAppleFamily)) return null
val patchBuilder = PatchBuilder(generationState.objCExport.namer)
@@ -2078,7 +2078,7 @@ private val TypeBridge.objCEncoding: String get() = when (this) {
}
private fun NativeGenerationState.is64BitNSInteger(): Boolean {
val configurables = context.config.platform.configurables
val configurables = config.platform.configurables
require(configurables is AppleConfigurables) {
"Target ${configurables.target} has no support for NSInteger type."
}
@@ -7,11 +7,13 @@ package org.jetbrains.kotlin.backend.konan.objcexport
import org.jetbrains.kotlin.backend.konan.*
import org.jetbrains.kotlin.backend.konan.descriptors.isInterface
import org.jetbrains.kotlin.backend.konan.driver.PhaseContext
import org.jetbrains.kotlin.backend.konan.llvm.CodeGenerator
import org.jetbrains.kotlin.backend.konan.llvm.objcexport.ObjCExportBlockCodeGenerator
import org.jetbrains.kotlin.backend.konan.llvm.objcexport.ObjCExportCodeGenerator
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor
import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
import org.jetbrains.kotlin.descriptors.SourceFile
import org.jetbrains.kotlin.konan.exec.Command
import org.jetbrains.kotlin.konan.file.File
@@ -27,10 +29,14 @@ internal class ObjCExportedInterface(
val mapper: ObjCExportMapper
)
// TODO: Replace Context with a more lightweight class.
internal fun produceObjCExportInterface(context: Context): ObjCExportedInterface {
require(context.config.target.family.isAppleFamily)
require(context.config.produce == CompilerOutputKind.FRAMEWORK)
internal fun produceObjCExportInterface(
context: PhaseContext,
moduleDescriptor: ModuleDescriptor,
frontendServices: FrontendServices,
): ObjCExportedInterface {
val config = context.config
require(config.target.family.isAppleFamily)
require(config.produce == CompilerOutputKind.FRAMEWORK)
val topLevelNamePrefix = context.objCExportTopLevelNamePrefix
@@ -38,13 +44,13 @@ internal fun produceObjCExportInterface(context: Context): ObjCExportedInterface
// Not possible yet, since ObjCExport translates the entire "world" API at once
// and can't do this per-module, e.g. due to global name conflict resolution.
val unitSuspendFunctionExport = context.config.unitSuspendFunctionObjCExport
val mapper = ObjCExportMapper(context.frontendServices.deprecationResolver, unitSuspendFunctionExport = unitSuspendFunctionExport)
val moduleDescriptors = listOf(context.moduleDescriptor) + context.getExportedDependencies()
val objcGenerics = context.configuration.getBoolean(KonanConfigKeys.OBJC_GENERICS)
val unitSuspendFunctionExport = config.unitSuspendFunctionObjCExport
val mapper = ObjCExportMapper(frontendServices.deprecationResolver, unitSuspendFunctionExport = unitSuspendFunctionExport)
val moduleDescriptors = listOf(moduleDescriptor) + moduleDescriptor.getExportedDependencies(config)
val objcGenerics = config.configuration.getBoolean(KonanConfigKeys.OBJC_GENERICS)
val namer = ObjCExportNamerImpl(
moduleDescriptors.toSet(),
context.moduleDescriptor.builtIns,
moduleDescriptor.builtIns,
mapper,
topLevelNamePrefix,
local = false,
@@ -56,13 +62,14 @@ internal fun produceObjCExportInterface(context: Context): ObjCExportedInterface
}
internal class ObjCExport(
val generationState: NativeGenerationState,
private val generationState: NativeGenerationState,
private val moduleDescriptor: ModuleDescriptor,
private val exportedInterface: ObjCExportedInterface?,
private val codeSpec: ObjCExportCodeSpec?
) {
private val context = generationState.context
private val target get() = context.config.target
private val topLevelNamePrefix get() = context.objCExportTopLevelNamePrefix
private val config = generationState.config
private val target get() = config.target
private val topLevelNamePrefix get() = generationState.objCExportTopLevelNamePrefix
lateinit var namer: ObjCExportNamer
@@ -73,12 +80,12 @@ internal class ObjCExport(
ObjCExportBlockCodeGenerator(codegen).generate()
}
if (!context.config.isFinalBinary) return // TODO: emit RTTI to the same modules as classes belong to.
if (!config.isFinalBinary) return // TODO: emit RTTI to the same modules as classes belong to.
val mapper = exportedInterface?.mapper ?: ObjCExportMapper(unitSuspendFunctionExport = context.config.unitSuspendFunctionObjCExport)
val mapper = exportedInterface?.mapper ?: ObjCExportMapper(unitSuspendFunctionExport = config.unitSuspendFunctionObjCExport)
namer = exportedInterface?.namer ?: ObjCExportNamerImpl(
setOf(codegen.context.moduleDescriptor),
context.moduleDescriptor.builtIns,
setOf(moduleDescriptor),
moduleDescriptor.builtIns,
mapper,
topLevelNamePrefix,
local = false
@@ -105,14 +112,14 @@ internal class ObjCExport(
val frameworkDirectory = File(generationState.outputFile)
val frameworkName = frameworkDirectory.name.removeSuffix(".framework")
val frameworkBuilder = FrameworkBuilder(
context.config,
infoPListBuilder = InfoPListBuilder(context.config),
config,
infoPListBuilder = InfoPListBuilder(config),
moduleMapBuilder = ModuleMapBuilder(),
objCHeaderWriter = ObjCHeaderWriter(),
mainPackageGuesser = MainPackageGuesser(),
)
frameworkBuilder.build(
context.moduleDescriptor,
moduleDescriptor,
frameworkDirectory,
frameworkName,
headerLines,
@@ -145,7 +152,7 @@ internal class ObjCExport(
val bitcode = createTempFile("protocols", ".bc").deleteOnExit()
val clangCommand = context.config.clang.clangC(
val clangCommand = config.clang.clangC(
source.absolutePath,
"-O2",
"-emit-llvm",
@@ -5,8 +5,8 @@
package org.jetbrains.kotlin.backend.konan.objcexport
import org.jetbrains.kotlin.backend.konan.Context
import org.jetbrains.kotlin.backend.konan.KonanConfigKeys
import org.jetbrains.kotlin.backend.konan.driver.PhaseContext
import org.jetbrains.kotlin.backend.konan.reportCompilationWarning
import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity
import org.jetbrains.kotlin.cli.common.messages.MessageUtil
@@ -17,7 +17,7 @@ import org.jetbrains.kotlin.renderer.DescriptorRenderer
import org.jetbrains.kotlin.resolve.source.getPsi
internal class ObjCExportHeaderGeneratorImpl(
val context: Context,
val context: PhaseContext,
moduleDescriptors: List<ModuleDescriptor>,
mapper: ObjCExportMapper,
namer: ObjCExportNamer,
@@ -26,7 +26,7 @@ internal class ObjCExportHeaderGeneratorImpl(
override val shouldExportKDoc = context.shouldExportKDoc()
private class ProblemCollector(val context: Context) : ObjCExportProblemCollector {
private class ProblemCollector(val context: PhaseContext) : ObjCExportProblemCollector {
override fun reportWarning(text: String) {
context.reportCompilationWarning(text)
}
@@ -7,8 +7,11 @@ package org.jetbrains.kotlin.backend.konan.objcexport
import org.jetbrains.kotlin.backend.common.serialization.findSourceFile
import org.jetbrains.kotlin.backend.konan.*
import org.jetbrains.kotlin.backend.konan.cKeywords
import org.jetbrains.kotlin.backend.konan.descriptors.isArray
import org.jetbrains.kotlin.backend.konan.descriptors.isInterface
import org.jetbrains.kotlin.backend.konan.driver.PhaseContext
import org.jetbrains.kotlin.descriptors.konan.isNativeStdlib
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.builtins.StandardNames
import org.jetbrains.kotlin.descriptors.*
@@ -1040,7 +1043,7 @@ internal val ModuleDescriptor.objCExportAdditionalNamePrefix: String get() {
return abbreviate(fullPrefix)
}
internal val Context.objCExportTopLevelNamePrefix: String
internal val PhaseContext.objCExportTopLevelNamePrefix: String
get() = abbreviate(config.fullExportedNamePrefix)
fun abbreviate(name: String): String {