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
|
package org.jetbrains.kotlin.backend.konan
|
||||||
|
|
||||||
import com.intellij.openapi.project.Project
|
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.backend.konan.util.profile
|
||||||
import org.jetbrains.kotlin.config.CommonConfigurationKeys
|
import org.jetbrains.kotlin.config.CommonConfigurationKeys
|
||||||
import org.jetbrains.kotlin.config.CompilerConfiguration
|
import org.jetbrains.kotlin.config.CompilerConfiguration
|
||||||
@@ -26,9 +25,12 @@ import java.io.File
|
|||||||
|
|
||||||
class KonanConfig(val project: Project, val configuration: CompilerConfiguration) {
|
class KonanConfig(val project: Project, val configuration: CompilerConfiguration) {
|
||||||
|
|
||||||
|
val moduleId: String
|
||||||
|
get() = configuration.getNotNull(CommonConfigurationKeys.MODULE_NAME)
|
||||||
|
|
||||||
internal val distribution = Distribution(configuration)
|
internal val distribution = Distribution(configuration)
|
||||||
|
|
||||||
internal val libraries: List<String>
|
private val libraryNames: List<String>
|
||||||
get() {
|
get() {
|
||||||
val fromCommandLine = configuration.getList(KonanConfigKeys.LIBRARY_FILES)
|
val fromCommandLine = configuration.getList(KonanConfigKeys.LIBRARY_FILES)
|
||||||
if (configuration.get(KonanConfigKeys.NOSTDLIB) ?: false) {
|
if (configuration.get(KonanConfigKeys.NOSTDLIB) ?: false) {
|
||||||
@@ -37,25 +39,23 @@ class KonanConfig(val project: Project, val configuration: CompilerConfiguration
|
|||||||
return fromCommandLine + distribution.stdlib
|
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)
|
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>()
|
val allMetadata = mutableListOf<ModuleDescriptorImpl>()
|
||||||
|
|
||||||
for (path in libraries) {
|
for (klib in libraries) {
|
||||||
val filePath = File(path)
|
profile("Loading ${klib.libraryName}") {
|
||||||
if (!filePath.exists()) {
|
val moduleDescriptor = klib.moduleDescriptor
|
||||||
error("Path '" + path + "' does not exist")
|
|
||||||
}
|
|
||||||
|
|
||||||
profile("Loading ${filePath}") {
|
|
||||||
val moduleDescriptor = loadMetadata(configuration, filePath)
|
|
||||||
allMetadata.add(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}"}
|
context.log{"# Compiler root: ${distribution.konanHome}"}
|
||||||
|
|
||||||
val bitcodeFiles = listOf<BitcodeFile>(emitted, distribution.start,
|
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()
|
var objectFiles: List<String> = listOf()
|
||||||
|
|
||||||
|
|||||||
+12
-25
@@ -20,57 +20,44 @@ import kotlinx.cinterop.*
|
|||||||
import llvm.*
|
import llvm.*
|
||||||
import org.jetbrains.kotlin.backend.konan.Context
|
import org.jetbrains.kotlin.backend.konan.Context
|
||||||
import org.jetbrains.kotlin.backend.konan.KonanConfigKeys
|
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 org.jetbrains.kotlin.ir.declarations.IrModuleFragment
|
||||||
import java.io.Closeable
|
import java.io.Closeable
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
|
||||||
fun loadMetadata(configuration: CompilerConfiguration, file: File): ModuleDescriptorImpl {
|
class NamedModuleData(val name:String, val base64: String)
|
||||||
|
|
||||||
val reader = MetadataReader(file)
|
fun MetadataReader.loadSerializedModule(currentAbiVersion: Int): NamedModuleData {
|
||||||
|
val (nodeCount, kmetadataNodeArg) = namedMetadataNode("kmetadata")
|
||||||
var moduleName: String? = null
|
|
||||||
val currentAbiVersion = configuration.get(KonanConfigKeys.ABI_VERSION)
|
|
||||||
|
|
||||||
val (nodeCount, kmetadataNodeArg) = reader.namedMetadataNode("kmetadata")
|
|
||||||
|
|
||||||
if (nodeCount != 1) {
|
if (nodeCount != 1) {
|
||||||
throw Error("Unknown metadata format. The 'kmetadata' node has ${nodeCount} arguments. Don't know what to do.")
|
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 abiNode = operands[0]
|
||||||
val nameNode = operands[1]
|
val nameNode = operands[1]
|
||||||
val dataNode = operands[2]
|
val dataNode = operands[2]
|
||||||
|
|
||||||
val abiVersion = reader.string(abiNode).toInt()
|
val abiVersion = string(abiNode).toInt()
|
||||||
|
|
||||||
if (abiVersion != currentAbiVersion) {
|
if (abiVersion != currentAbiVersion) {
|
||||||
throw Error("Expected ABI version ${currentAbiVersion}, but the binary is ${abiVersion}")
|
throw Error("Expected ABI version ${currentAbiVersion}, but the binary is ${abiVersion}")
|
||||||
}
|
}
|
||||||
moduleName = reader.string(nameNode)
|
val moduleName = string(nameNode)
|
||||||
|
val tableOfContentsAsString = string(dataNode)
|
||||||
val tableOfContentsAsString = reader.string(dataNode)
|
return NamedModuleData(moduleName, tableOfContentsAsString)
|
||||||
|
|
||||||
val moduleDescriptor =
|
|
||||||
deserializeModule(configuration, {it->loadPackageFragment(reader, it)}, tableOfContentsAsString, moduleName)
|
|
||||||
|
|
||||||
return moduleDescriptor
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun loadPackageFragment(reader: MetadataReader, fqName: String): String {
|
fun MetadataReader.loadSerializedPackageFragment(fqName: String): String {
|
||||||
val (nodeCount, kpackageNodeArg) = reader.namedMetadataNode("kpackage:$fqName")
|
val (nodeCount, kpackageNodeArg) = namedMetadataNode("kpackage:$fqName")
|
||||||
|
|
||||||
if (nodeCount != 1) {
|
if (nodeCount != 1) {
|
||||||
throw Error("The 'kpackage:$fqName' node has ${nodeCount} arguments.")
|
throw Error("The 'kpackage:$fqName' node has ${nodeCount} arguments.")
|
||||||
}
|
}
|
||||||
|
|
||||||
val operands = reader.metadataNodeOperands(kpackageNodeArg)
|
val operands = metadataNodeOperands(kpackageNodeArg)
|
||||||
val dataNode = operands[0]
|
val dataNode = operands[0]
|
||||||
val base64 = reader.string(dataNode)
|
val base64 = string(dataNode)
|
||||||
return base64
|
return base64
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user