Working program output
diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/CompilerOutput.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/CompilerOutput.kt
index c4f9189..3efffad 100644
--- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/CompilerOutput.kt
+++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/CompilerOutput.kt
@@ -170,11 +170,10 @@
}
}
-internal fun insertAliasToEntryPoint(context: Context) {
+internal fun insertAliasToEntryPoint(context: PhaseContext, module: LLVMModuleRef) {
val nomain = context.config.configuration.get(KonanConfigKeys.NOMAIN) ?: false
if (context.config.produce != CompilerOutputKind.PROGRAM || nomain)
return
- val module = context.generationState.llvm.module
val entryPointName = context.config.entryPointName
val entryPoint = LLVMGetNamedFunction(module, entryPointName)
?: error("Module doesn't contain `$entryPointName`")
@@ -224,7 +223,7 @@
context.bitcodeFileName = output
// Insert `_main` after pipeline so we won't worry about optimizations
// corrupting entry point.
- insertAliasToEntryPoint(context)
+ insertAliasToEntryPoint(context, context.generationState.llvm.module)
LLVMWriteBitcodeToFile(context.generationState.llvm.module, output)
}
CompilerOutputKind.LIBRARY -> {
diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/driver/DynamicCompilerDriver.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/driver/DynamicCompilerDriver.kt
index e057dc4..d989c24 100644
--- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/driver/DynamicCompilerDriver.kt
+++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/driver/DynamicCompilerDriver.kt
@@ -35,7 +35,7 @@
usingNativeMemoryAllocator {
usingJvmCInteropCallbacks {
when (config.produce) {
- CompilerOutputKind.PROGRAM -> TODO()
+ CompilerOutputKind.PROGRAM -> produceProgram(engine, config, environment)
CompilerOutputKind.DYNAMIC -> TODO()
CompilerOutputKind.STATIC -> TODO()
CompilerOutputKind.FRAMEWORK -> produceFramework(engine, config, environment)
@@ -120,4 +120,43 @@
}
}
}
+
+ private fun produceProgram(engine: PhaseEngine<PhaseContext>, config: KonanConfig, environment: KotlinCoreEnvironment) {
+ val frontendResult = engine.useContext(FrontendContextImpl(config)) { frontendEngine ->
+ frontendEngine.runFrontend(environment)
+ }
+ if (frontendResult is FrontendPhaseResult.ShouldNotGenerateCode) {
+ return
+ }
+ require(frontendResult is FrontendPhaseResult.Full)
+ val psiToIrResult = run {
+ val symbolTable = SymbolTable(KonanIdSignaturer(KonanManglerDesc), IrFactoryImpl)
+ val psiToIrContext = PsiToContextImpl(config, frontendResult.moduleDescriptor, symbolTable)
+ engine.useContext(psiToIrContext) { psiToIrEngine ->
+ psiToIrEngine.runPsiToIr(frontendResult, isProducingLibrary = false)
+ }
+ }
+ // Let's "eat" Context step-by-step. We don't use it for frontend and psi2ir,
+ // but use it for lowerings and bitcode generation for now.
+ val context = Context(config).also {
+ it.populateAfterFrontend(frontendResult)
+ it.populateAfterPsiToIr(psiToIrResult)
+ it.objCExport = ObjCExport(it, null, null)
+ }
+ engine.useContext(context) { middleEndEngine ->
+ middleEndEngine.runPhase(context, functionsWithoutBoundCheck, Unit)
+ middleEndEngine.useContext(NativeGenerationState(context)) { nativeGenerationEngine ->
+ // TODO: Drop this property, use generation state separately.
+ context.generationState = nativeGenerationEngine.context
+ middleEndEngine.runBackendCodegen(context.irModule!!)
+ val module = context.generationState.llvm.module
+ insertAliasToEntryPoint(context, module)
+ val bitcodeFile = nativeGenerationEngine.writeBitcodeFile(module)
+ // TODO: These two phases should not use NativeGenerationEngine. Instead, they should use their own.
+ // Probably separate, because in the future we want linker to accumulate results.
+ val objectFiles = nativeGenerationEngine.produceObjectFiles(bitcodeFile)
+ nativeGenerationEngine.linkObjectFiles(objectFiles, context.llvmModuleSpecification, context.coverage.enabled)
+ }
+ }
+ }
}
\ No newline at end of file