backend: rework builtIns configuration

* Do not create separate builtIns for analyzer.
* Make builtInsModule synthetic but depending on stdlib.
This commit is contained in:
Svyatoslav Scherbina
2017-02-28 12:25:24 +07:00
committed by SvyatoslavScherbina
parent 5584ef2541
commit 093671f549
7 changed files with 69 additions and 21 deletions
+1 -1
View File
@@ -200,7 +200,7 @@ targetList.each { target ->
"-Dkonan.home=${project.parent.file('dist')}",
"-Djava.library.path=${project.buildDir}/nativelibs"
args('-output', project(':runtime').file("build/${target}/stdlib.kt.bc"),
'-nolink', '-nostdlib',
'-nolink', '-nostdlib', '-compile_as_stdlib',
'-target', target,
'-runtime', project(':runtime').file("build/${target}/runtime.bc"),
'-properties', project(':backend.native').file('konan.properties'),
@@ -55,6 +55,7 @@ class K2Native : CLICompiler<K2NativeCompilerArguments>() {
with (KonanConfigKeys) { with (configuration) {
put(NOSTDLIB, arguments.nostdlib)
put(COMPILE_AS_STDLIB, arguments.compileAsStdlib)
put(NOLINK, arguments.nolink)
put(LIBRARY_FILES,
arguments.libraries.toNonNullList())
@@ -31,6 +31,9 @@ public class K2NativeCompilerArguments extends CommonCompilerArguments {
@Argument(value = "nostdlib", description = "Don't link with stdlib")
public boolean nostdlib;
@Argument(value = "compile_as_stdlib", description = "Compile the module as stdlib")
public boolean compileAsStdlib;
@Argument(value = "opt", description = "Enable optimizations during compilation")
public boolean optimization;
@@ -18,7 +18,9 @@ class KonanConfig(val project: Project, val configuration: CompilerConfiguration
internal val distribution = Distribution(configuration)
internal val libraries: List<String>
internal val compileAsStdlib = configuration.get(KonanConfigKeys.COMPILE_AS_STDLIB) ?: false
internal val libraries: List<String>
get() {
val fromCommandLine = configuration.getList(KonanConfigKeys.LIBRARY_FILES)
if (configuration.get(KonanConfigKeys.NOSTDLIB) ?: false) {
@@ -29,6 +31,13 @@ class KonanConfig(val project: Project, val configuration: CompilerConfiguration
private val loadedDescriptors = loadLibMetadata(libraries)
init {
if (!compileAsStdlib) {
val stdlib = loadedDescriptors.single { it.isStdlib() }
KonanPlatform.builtIns.createBuiltInsModule(stdlib)
}
}
internal val librariesToLink: List<String>
get() = libraries + configuration.getList(KonanConfigKeys.NATIVE_LIBRARY_FILES)
@@ -23,6 +23,8 @@ class KonanConfigKeys {
= CompilerConfigurationKey.create("optimized compilation")
val NOSTDLIB: CompilerConfigurationKey<Boolean>
= CompilerConfigurationKey.create("don't link with stdlib")
val COMPILE_AS_STDLIB: CompilerConfigurationKey<Boolean>
= CompilerConfigurationKey.create("compile the module as stdlib")
val NOLINK: CompilerConfigurationKey<Boolean>
= CompilerConfigurationKey.create("don't link, only produce a bitcode file ")
val TARGET: CompilerConfigurationKey<String?>
@@ -17,21 +17,44 @@
package org.jetbrains.kotlin.backend.konan
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.backend.konan.KonanPlatformConfigurator
import org.jetbrains.kotlin.builtins.PrimitiveType
import org.jetbrains.kotlin.builtins.createBuiltInPackageFragmentProvider
import org.jetbrains.kotlin.config.LanguageVersionSettings
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.resolve.ImportPath
import org.jetbrains.kotlin.resolve.MultiTargetPlatform
import org.jetbrains.kotlin.resolve.PlatformConfigurator
import org.jetbrains.kotlin.resolve.TargetPlatform
import org.jetbrains.kotlin.storage.StorageManager
import org.jetbrains.kotlin.storage.LockBasedStorageManager
import org.jetbrains.kotlin.storage.StorageManager
class KonanBuiltIns: KotlinBuiltIns {
constructor(storageManager: StorageManager) : super(storageManager)
val STDLIB_MODULE_NAME = Name.special("<stdlib>")
constructor(storageManager: StorageManager, withModule: Boolean) : this(storageManager) {
if (withModule) createBuiltInsModule()
fun ModuleDescriptor.isStdlib(): Boolean {
return name == STDLIB_MODULE_NAME
}
class KonanBuiltIns(storageManager: StorageManager) : KotlinBuiltIns(storageManager) {
override fun createBuiltInsModule() = throw Error("should not be called")
fun createBuiltInsModule(stdlib: ModuleDescriptorImpl) {
builtInsModule = ModuleDescriptorImpl(BUILTINS_MODULE_NAME, storageManager, this, null)
val packageFragmentProvider = createBuiltInPackageFragmentProvider(
storageManager, builtInsModule, BUILT_INS_PACKAGE_FQ_NAMES,
classDescriptorFactories,
platformDependentDeclarationFilter,
additionalClassPartsProvider
) { path ->
val classLoader = KotlinBuiltIns::class.java.classLoader
if (classLoader != null) classLoader.getResourceAsStream(path) else ClassLoader.getSystemResourceAsStream(path)
}
builtInsModule.initialize(packageFragmentProvider)
// The code above is copy-pasted from super.createBuiltInsModule(); TODO: refactor.
// stdlib comes first to override declarations from builtIns (even when they are requested from builtIns).
builtInsModule.setDependencies(stdlib, builtInsModule)
}
}
@@ -47,5 +70,5 @@ object KonanPlatform : TargetPlatform("Konan") {
override val platformConfigurator: PlatformConfigurator = KonanPlatformConfigurator
val builtIns: KonanBuiltIns = KonanBuiltIns(LockBasedStorageManager.NO_LOCKS, false)
val builtIns: KonanBuiltIns = KonanBuiltIns(LockBasedStorageManager.NO_LOCKS)
}
@@ -31,19 +31,29 @@ import org.jetbrains.kotlin.resolve.lazy.declarations.FileBasedDeclarationProvid
object TopDownAnalyzerFacadeForKonan {
fun analyzeFiles(files: Collection<KtFile>, config: KonanConfig): AnalysisResult {
val context = ContextForNewModule(ProjectContext(config.project), Name.special("<${config.moduleId}>"),
KonanPlatform.builtIns, null)
val moduleName = if (config.compileAsStdlib) {
STDLIB_MODULE_NAME
} else {
Name.special("<${config.moduleId}>")
}
val builtinsForCompilerModule = KonanBuiltIns(context.storageManager, true)
val compilerBuiltInsModule = builtinsForCompilerModule.builtInsModule
KonanPlatform.builtIns.builtInsModule = context.module
val context = ContextForNewModule(ProjectContext(config.project), moduleName, KonanPlatform.builtIns, null)
val module = context.module
assert (module.isStdlib() == config.compileAsStdlib)
if (!module.isStdlib()) {
context.setDependencies(listOf(module) + config.moduleDescriptors + KonanPlatform.builtIns.builtInsModule)
} else {
KonanPlatform.builtIns.createBuiltInsModule(module)
assert (config.moduleDescriptors.isEmpty())
context.setDependencies(module)
// TODO: stdlib should probably also depend on builtInsModule.
// However this would lead to mutual dependency between stdlib and builtInsModule,
// and the compiler can't handle it.
}
// Make sure the compiler produced BuiltIns module comes in last
context.setDependencies(
listOf(context.module) +
config.moduleDescriptors +
listOf(compilerBuiltInsModule)
)
return analyzeFilesWithGivenTrace(files, BindingTraceContext(), context, config)
}