Collected pieces of library management in KonanLibrary interface.
In anticipation of klib implementation.
This commit is contained in:
committed by
alexander-gorshenev
parent
f56e68e255
commit
28c03a36cc
+14
-14
@@ -17,7 +17,6 @@
|
||||
package org.jetbrains.kotlin.backend.konan
|
||||
|
||||
import com.intellij.openapi.project.Project
|
||||
import org.jetbrains.kotlin.backend.konan.llvm.loadMetadata
|
||||
import org.jetbrains.kotlin.backend.konan.util.profile
|
||||
import org.jetbrains.kotlin.config.CommonConfigurationKeys
|
||||
import org.jetbrains.kotlin.config.CompilerConfiguration
|
||||
@@ -26,9 +25,12 @@ import java.io.File
|
||||
|
||||
class KonanConfig(val project: Project, val configuration: CompilerConfiguration) {
|
||||
|
||||
val moduleId: String
|
||||
get() = configuration.getNotNull(CommonConfigurationKeys.MODULE_NAME)
|
||||
|
||||
internal val distribution = Distribution(configuration)
|
||||
|
||||
internal val libraries: List<String>
|
||||
private val libraryNames: List<String>
|
||||
get() {
|
||||
val fromCommandLine = configuration.getList(KonanConfigKeys.LIBRARY_FILES)
|
||||
if (configuration.get(KonanConfigKeys.NOSTDLIB) ?: false) {
|
||||
@@ -37,25 +39,23 @@ class KonanConfig(val project: Project, val configuration: CompilerConfiguration
|
||||
return fromCommandLine + distribution.stdlib
|
||||
}
|
||||
|
||||
private val loadedDescriptors = loadLibMetadata(libraries)
|
||||
internal val libraries: List<KonanLibrary> by lazy {
|
||||
// Here we have chosen a particular .kt.bc KonanLibrary implementation
|
||||
libraryNames.map{it -> KtBcLibrary(it, configuration)}
|
||||
}
|
||||
|
||||
private val loadedDescriptors = loadLibMetadata()
|
||||
|
||||
internal val nativeLibraries: List<String> = configuration.getList(KonanConfigKeys.NATIVE_LIBRARY_FILES)
|
||||
|
||||
val moduleId: String
|
||||
get() = configuration.getNotNull(CommonConfigurationKeys.MODULE_NAME)
|
||||
|
||||
fun loadLibMetadata(libraries: List<String>): List<ModuleDescriptorImpl> {
|
||||
fun loadLibMetadata(): List<ModuleDescriptorImpl> {
|
||||
|
||||
val allMetadata = mutableListOf<ModuleDescriptorImpl>()
|
||||
|
||||
for (path in libraries) {
|
||||
val filePath = File(path)
|
||||
if (!filePath.exists()) {
|
||||
error("Path '" + path + "' does not exist")
|
||||
}
|
||||
|
||||
profile("Loading ${filePath}") {
|
||||
val moduleDescriptor = loadMetadata(configuration, filePath)
|
||||
for (klib in libraries) {
|
||||
profile("Loading ${klib.libraryName}") {
|
||||
val moduleDescriptor = klib.moduleDescriptor
|
||||
allMetadata.add(moduleDescriptor)
|
||||
}
|
||||
}
|
||||
|
||||
+69
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
* Copyright 2010-2017 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.backend.konan
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl
|
||||
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
||||
import org.jetbrains.kotlin.backend.konan.llvm.MetadataReader
|
||||
import org.jetbrains.kotlin.backend.konan.llvm.loadSerializedModule
|
||||
import org.jetbrains.kotlin.backend.konan.llvm.loadSerializedPackageFragment
|
||||
import org.jetbrains.kotlin.config.CompilerConfiguration
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.backend.konan.serialization.Base64
|
||||
import org.jetbrains.kotlin.backend.konan.serialization.deserializeModule
|
||||
import java.io.File
|
||||
|
||||
interface KonanLibrary {
|
||||
val libraryName: String
|
||||
val moduleName: String
|
||||
val moduleDescriptor: ModuleDescriptorImpl
|
||||
val bitcodePaths: List<String>
|
||||
}
|
||||
|
||||
class KtBcLibrary(val file: File, val configuration: CompilerConfiguration): KonanLibrary {
|
||||
constructor(path: String, configuration: CompilerConfiguration) : this(File(path), configuration)
|
||||
init {
|
||||
if (!file.exists())
|
||||
error("Path '" + file.path + "' does not exist")
|
||||
}
|
||||
|
||||
override val libraryName: String
|
||||
get() = file.path
|
||||
|
||||
override val bitcodePaths: List<String>
|
||||
get() = listOf(libraryName)
|
||||
|
||||
private val reader = MetadataReader(file)
|
||||
|
||||
private val namedModuleData by lazy {
|
||||
val currentAbiVersion = configuration.get(KonanConfigKeys.ABI_VERSION)!!
|
||||
reader.loadSerializedModule(currentAbiVersion)
|
||||
}
|
||||
override val moduleName = namedModuleData.name
|
||||
|
||||
private val tableOfContentsAsString = namedModuleData.base64
|
||||
|
||||
private fun packageMetadata(fqName: String): Base64 =
|
||||
reader.loadSerializedPackageFragment(fqName)
|
||||
|
||||
override val moduleDescriptor: ModuleDescriptorImpl by lazy {
|
||||
deserializeModule(configuration,
|
||||
{it -> packageMetadata(it)},
|
||||
tableOfContentsAsString, moduleName)
|
||||
}
|
||||
}
|
||||
|
||||
+2
-1
@@ -266,7 +266,8 @@ internal class LinkStage(val context: Context) {
|
||||
context.log{"# Compiler root: ${distribution.konanHome}"}
|
||||
|
||||
val bitcodeFiles = listOf<BitcodeFile>(emitted, distribution.start,
|
||||
distribution.runtime, distribution.launcher) + libraries
|
||||
distribution.runtime, distribution.launcher) +
|
||||
libraries.map{it -> it.bitcodePaths}.flatten()
|
||||
|
||||
var objectFiles: List<String> = listOf()
|
||||
|
||||
|
||||
+12
-25
@@ -20,57 +20,44 @@ import kotlinx.cinterop.*
|
||||
import llvm.*
|
||||
import org.jetbrains.kotlin.backend.konan.Context
|
||||
import org.jetbrains.kotlin.backend.konan.KonanConfigKeys
|
||||
import org.jetbrains.kotlin.backend.konan.serialization.deserializeModule
|
||||
import org.jetbrains.kotlin.config.CompilerConfiguration
|
||||
import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl
|
||||
import org.jetbrains.kotlin.ir.declarations.IrModuleFragment
|
||||
import java.io.Closeable
|
||||
import java.io.File
|
||||
|
||||
fun loadMetadata(configuration: CompilerConfiguration, file: File): ModuleDescriptorImpl {
|
||||
class NamedModuleData(val name:String, val base64: String)
|
||||
|
||||
val reader = MetadataReader(file)
|
||||
|
||||
var moduleName: String? = null
|
||||
val currentAbiVersion = configuration.get(KonanConfigKeys.ABI_VERSION)
|
||||
|
||||
val (nodeCount, kmetadataNodeArg) = reader.namedMetadataNode("kmetadata")
|
||||
fun MetadataReader.loadSerializedModule(currentAbiVersion: Int): NamedModuleData {
|
||||
val (nodeCount, kmetadataNodeArg) = namedMetadataNode("kmetadata")
|
||||
|
||||
if (nodeCount != 1) {
|
||||
throw Error("Unknown metadata format. The 'kmetadata' node has ${nodeCount} arguments. Don't know what to do.")
|
||||
}
|
||||
|
||||
val operands = reader.metadataNodeOperands(kmetadataNodeArg)
|
||||
val operands = metadataNodeOperands(kmetadataNodeArg)
|
||||
|
||||
val abiNode = operands[0]
|
||||
val nameNode = operands[1]
|
||||
val dataNode = operands[2]
|
||||
|
||||
val abiVersion = reader.string(abiNode).toInt()
|
||||
|
||||
val abiVersion = string(abiNode).toInt()
|
||||
if (abiVersion != currentAbiVersion) {
|
||||
throw Error("Expected ABI version ${currentAbiVersion}, but the binary is ${abiVersion}")
|
||||
}
|
||||
moduleName = reader.string(nameNode)
|
||||
|
||||
val tableOfContentsAsString = reader.string(dataNode)
|
||||
|
||||
val moduleDescriptor =
|
||||
deserializeModule(configuration, {it->loadPackageFragment(reader, it)}, tableOfContentsAsString, moduleName)
|
||||
|
||||
return moduleDescriptor
|
||||
val moduleName = string(nameNode)
|
||||
val tableOfContentsAsString = string(dataNode)
|
||||
return NamedModuleData(moduleName, tableOfContentsAsString)
|
||||
}
|
||||
|
||||
fun loadPackageFragment(reader: MetadataReader, fqName: String): String {
|
||||
val (nodeCount, kpackageNodeArg) = reader.namedMetadataNode("kpackage:$fqName")
|
||||
fun MetadataReader.loadSerializedPackageFragment(fqName: String): String {
|
||||
val (nodeCount, kpackageNodeArg) = namedMetadataNode("kpackage:$fqName")
|
||||
|
||||
if (nodeCount != 1) {
|
||||
throw Error("The 'kpackage:$fqName' node has ${nodeCount} arguments.")
|
||||
}
|
||||
|
||||
val operands = reader.metadataNodeOperands(kpackageNodeArg)
|
||||
val operands = metadataNodeOperands(kpackageNodeArg)
|
||||
val dataNode = operands[0]
|
||||
val base64 = reader.string(dataNode)
|
||||
val base64 = string(dataNode)
|
||||
return base64
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user