Implemented code generation of combined IR of all libraries
This commit is contained in:
@@ -153,7 +153,6 @@ classes.dependsOn 'compilerClasses', 'cli_bcClasses', 'bc_frontendClasses'
|
|||||||
|
|
||||||
// These are just a couple of aliases
|
// These are just a couple of aliases
|
||||||
task stdlib(dependsOn: "${hostName}Stdlib")
|
task stdlib(dependsOn: "${hostName}Stdlib")
|
||||||
task start(dependsOn: "${hostName}Start")
|
|
||||||
|
|
||||||
def commonSrc = file('build/stdlib')
|
def commonSrc = file('build/stdlib')
|
||||||
|
|
||||||
@@ -180,7 +179,8 @@ final List<File> stdLibSrc = [
|
|||||||
project(':Interop:Runtime').file('src/main/kotlin'),
|
project(':Interop:Runtime').file('src/main/kotlin'),
|
||||||
project(':Interop:Runtime').file('src/native/kotlin'),
|
project(':Interop:Runtime').file('src/native/kotlin'),
|
||||||
project(':Interop:JsRuntime').file('src/main/kotlin'),
|
project(':Interop:JsRuntime').file('src/main/kotlin'),
|
||||||
project(':runtime').file('src/main/kotlin')
|
project(':runtime').file('src/main/kotlin'),
|
||||||
|
project(':runtime').file('src/launcher/kotlin')
|
||||||
]
|
]
|
||||||
|
|
||||||
task zipStdLibSources(type: Zip, dependsOn: unzipStdlibSources) {
|
task zipStdLibSources(type: Zip, dependsOn: unzipStdlibSources) {
|
||||||
@@ -244,21 +244,6 @@ targetList.each { target ->
|
|||||||
dependsOn ":runtime:${target}Runtime"
|
dependsOn ":runtime:${target}Runtime"
|
||||||
dependsOn ":distCompiler"
|
dependsOn ":distCompiler"
|
||||||
}
|
}
|
||||||
|
|
||||||
task("${target}Start", type: JavaExec) {
|
|
||||||
main = 'org.jetbrains.kotlin.cli.bc.K2NativeKt'
|
|
||||||
classpath = project.configurations.cli_bc
|
|
||||||
jvmArgs = konanJvmArgs
|
|
||||||
args = [*konanArgs, '-produce', 'bitcode',
|
|
||||||
'-output', project(':runtime').file("build/${target}Start"),
|
|
||||||
'-library', project(':runtime').file("build/${target}Stdlib"),
|
|
||||||
project(':runtime').file('src/launcher/kotlin')]
|
|
||||||
|
|
||||||
inputs.dir(project(':runtime').file('src/launcher/kotlin'))
|
|
||||||
outputs.file(project(':runtime').file("build/${target}Start.bc"))
|
|
||||||
|
|
||||||
dependsOn ":runtime:${target}Runtime", "${target}Stdlib"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
task run {
|
task run {
|
||||||
|
|||||||
+6
-8
@@ -29,7 +29,6 @@ internal fun produceCStubs(context: Context) {
|
|||||||
|
|
||||||
internal fun produceOutput(context: Context) {
|
internal fun produceOutput(context: Context) {
|
||||||
|
|
||||||
val llvmModule = context.llvmModule!!
|
|
||||||
val config = context.config.configuration
|
val config = context.config.configuration
|
||||||
val tempFiles = context.config.tempFiles
|
val tempFiles = context.config.tempFiles
|
||||||
val produce = config.get(KonanConfigKeys.PRODUCE)
|
val produce = config.get(KonanConfigKeys.PRODUCE)
|
||||||
@@ -42,7 +41,7 @@ internal fun produceOutput(context: Context) {
|
|||||||
val output = tempFiles.nativeBinaryFileName
|
val output = tempFiles.nativeBinaryFileName
|
||||||
context.bitcodeFileName = output
|
context.bitcodeFileName = output
|
||||||
|
|
||||||
val generatedBitcodeFiles =
|
val generatedBitcodeFiles =
|
||||||
if (produce == CompilerOutputKind.DYNAMIC || produce == CompilerOutputKind.STATIC) {
|
if (produce == CompilerOutputKind.DYNAMIC || produce == CompilerOutputKind.STATIC) {
|
||||||
produceCAdapterBitcode(
|
produceCAdapterBitcode(
|
||||||
context.config.clang,
|
context.config.clang,
|
||||||
@@ -57,16 +56,15 @@ internal fun produceOutput(context: Context) {
|
|||||||
generatedBitcodeFiles
|
generatedBitcodeFiles
|
||||||
|
|
||||||
for (library in nativeLibraries) {
|
for (library in nativeLibraries) {
|
||||||
parseAndLinkBitcodeFile(llvmModule, library)
|
parseAndLinkBitcodeFile(context.llvmModule!!, library)
|
||||||
}
|
}
|
||||||
|
|
||||||
LLVMWriteBitcodeToFile(llvmModule, output)
|
LLVMWriteBitcodeToFile(context.llvmModule!!, output)
|
||||||
}
|
}
|
||||||
CompilerOutputKind.LIBRARY -> {
|
CompilerOutputKind.LIBRARY -> {
|
||||||
val output = context.config.outputFiles.outputName
|
val output = context.config.outputFiles.outputName
|
||||||
val libraryName = context.config.moduleId
|
val libraryName = context.config.moduleId
|
||||||
val neededLibraries
|
val neededLibraries = context.librariesWithDependencies
|
||||||
= context.llvm.librariesForLibraryManifest
|
|
||||||
val abiVersion = KonanAbiVersion.CURRENT
|
val abiVersion = KonanAbiVersion.CURRENT
|
||||||
val compilerVersion = KonanVersion.CURRENT
|
val compilerVersion = KonanVersion.CURRENT
|
||||||
val libraryVersion = config.get(KonanConfigKeys.LIBRARY_VERSION)
|
val libraryVersion = config.get(KonanConfigKeys.LIBRARY_VERSION)
|
||||||
@@ -85,7 +83,7 @@ internal fun produceOutput(context: Context) {
|
|||||||
target,
|
target,
|
||||||
output,
|
output,
|
||||||
libraryName,
|
libraryName,
|
||||||
llvmModule,
|
null,
|
||||||
nopack,
|
nopack,
|
||||||
manifestProperties,
|
manifestProperties,
|
||||||
context.dataFlowGraph)
|
context.dataFlowGraph)
|
||||||
@@ -96,7 +94,7 @@ internal fun produceOutput(context: Context) {
|
|||||||
CompilerOutputKind.BITCODE -> {
|
CompilerOutputKind.BITCODE -> {
|
||||||
val output = context.config.outputFile
|
val output = context.config.outputFile
|
||||||
context.bitcodeFileName = output
|
context.bitcodeFileName = output
|
||||||
LLVMWriteBitcodeToFile(llvmModule, output)
|
LLVMWriteBitcodeToFile(context.llvmModule!!, output)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+7
-20
@@ -99,7 +99,9 @@ internal class SpecialDeclarationsFactory(val context: Context) {
|
|||||||
DECLARATION_ORIGIN_FIELD_FOR_OUTER_THIS,
|
DECLARATION_ORIGIN_FIELD_FOR_OUTER_THIS,
|
||||||
descriptor,
|
descriptor,
|
||||||
outerClass.defaultType
|
outerClass.defaultType
|
||||||
)
|
).apply {
|
||||||
|
parent = innerClass
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getLoweredEnum(enumClass: IrClass): LoweredEnum {
|
fun getLoweredEnum(enumClass: IrClass): LoweredEnum {
|
||||||
@@ -109,25 +111,8 @@ internal class SpecialDeclarationsFactory(val context: Context) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun assignOrdinalsToEnumEntries(classDescriptor: ClassDescriptor): Map<ClassDescriptor, Int> {
|
fun getEnumEntryOrdinal(enumEntry: IrEnumEntry) =
|
||||||
val enumEntryOrdinals = mutableMapOf<ClassDescriptor, Int>()
|
enumEntry.parentAsClass.declarations.filterIsInstance<IrEnumEntry>().indexOf(enumEntry)
|
||||||
classDescriptor.enumEntries.forEachIndexed { index, entry ->
|
|
||||||
enumEntryOrdinals[entry] = index
|
|
||||||
}
|
|
||||||
return enumEntryOrdinals
|
|
||||||
}
|
|
||||||
|
|
||||||
fun getEnumEntryOrdinal(entryDescriptor: ClassDescriptor): Int {
|
|
||||||
val enumClassDescriptor = entryDescriptor.containingDeclaration as ClassDescriptor
|
|
||||||
// If enum came from another module then we need to get serialized ordinal number.
|
|
||||||
// We serialize ordinal because current serialization cannot preserve enum entry order.
|
|
||||||
if (enumClassDescriptor is DeserializedClassDescriptor) {
|
|
||||||
return enumClassDescriptor.classProto.enumEntryList
|
|
||||||
.first { entryDescriptor.name == enumClassDescriptor.c.nameResolver.getName(it.name) }
|
|
||||||
.getExtension(KonanProtoBuf.enumEntryOrdinal)
|
|
||||||
}
|
|
||||||
return ordinals.getOrPut(enumClassDescriptor) { assignOrdinalsToEnumEntries(enumClassDescriptor) }[entryDescriptor]!!
|
|
||||||
}
|
|
||||||
|
|
||||||
fun getBridge(overriddenFunction: OverriddenFunctionInfo): IrSimpleFunction {
|
fun getBridge(overriddenFunction: OverriddenFunctionInfo): IrSimpleFunction {
|
||||||
val irFunction = overriddenFunction.function
|
val irFunction = overriddenFunction.function
|
||||||
@@ -295,6 +280,8 @@ internal class Context(config: KonanConfig) : KonanBackendContext(config) {
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
lateinit var irModules: Map<String, IrModuleFragment>
|
||||||
|
|
||||||
// TODO: make lateinit?
|
// TODO: make lateinit?
|
||||||
var irModule: IrModuleFragment? = null
|
var irModule: IrModuleFragment? = null
|
||||||
set(module) {
|
set(module) {
|
||||||
|
|||||||
+2
-1
@@ -22,6 +22,7 @@ import org.jetbrains.kotlin.konan.properties.loadProperties
|
|||||||
import org.jetbrains.kotlin.konan.target.*
|
import org.jetbrains.kotlin.konan.target.*
|
||||||
import org.jetbrains.kotlin.konan.KonanAbiVersion
|
import org.jetbrains.kotlin.konan.KonanAbiVersion
|
||||||
import org.jetbrains.kotlin.konan.KonanVersion
|
import org.jetbrains.kotlin.konan.KonanVersion
|
||||||
|
import org.jetbrains.kotlin.konan.library.resolver.TopologicalLibraryOrder
|
||||||
import org.jetbrains.kotlin.konan.library.toUnresolvedLibraries
|
import org.jetbrains.kotlin.konan.library.toUnresolvedLibraries
|
||||||
import org.jetbrains.kotlin.konan.parseKonanVersion
|
import org.jetbrains.kotlin.konan.parseKonanVersion
|
||||||
|
|
||||||
@@ -105,7 +106,7 @@ class KonanConfig(val project: Project, val configuration: CompilerConfiguration
|
|||||||
fun librariesWithDependencies(moduleDescriptor: ModuleDescriptor?): List<KonanLibrary> {
|
fun librariesWithDependencies(moduleDescriptor: ModuleDescriptor?): List<KonanLibrary> {
|
||||||
if (moduleDescriptor == null) error("purgeUnneeded() only works correctly after resolve is over, and we have successfully marked package files as needed or not needed.")
|
if (moduleDescriptor == null) error("purgeUnneeded() only works correctly after resolve is over, and we have successfully marked package files as needed or not needed.")
|
||||||
|
|
||||||
return resolvedLibraries.filterRoots { (!it.isDefault && !this.purgeUserLibs) || it.isNeededForLink }.getFullList()
|
return resolvedLibraries.filterRoots { (!it.isDefault && !this.purgeUserLibs) || it.isNeededForLink }.getFullList(TopologicalLibraryOrder)
|
||||||
}
|
}
|
||||||
|
|
||||||
internal val defaultNativeLibraries: List<String> = mutableListOf<String>().apply {
|
internal val defaultNativeLibraries: List<String> = mutableListOf<String>().apply {
|
||||||
|
|||||||
+1
-1
@@ -190,7 +190,7 @@ internal val innerClassPhase = makeKonanFileLoweringPhase(
|
|||||||
::InnerClassLowering,
|
::InnerClassLowering,
|
||||||
name = "InnerClasses",
|
name = "InnerClasses",
|
||||||
description = "Inner classes lowering",
|
description = "Inner classes lowering",
|
||||||
prerequisite = setOf(defaultParameterExtentPhase, genSyntheticFieldsPhase )
|
prerequisite = setOf(defaultParameterExtentPhase)
|
||||||
)
|
)
|
||||||
|
|
||||||
internal val forLoopsPhase = makeKonanFileLoweringPhase(
|
internal val forLoopsPhase = makeKonanFileLoweringPhase(
|
||||||
|
|||||||
+2
@@ -5,5 +5,7 @@ import org.jetbrains.kotlin.name.FqName
|
|||||||
object RuntimeNames {
|
object RuntimeNames {
|
||||||
val symbolName = FqName("kotlin.native.SymbolName")
|
val symbolName = FqName("kotlin.native.SymbolName")
|
||||||
val exportForCppRuntime = FqName("kotlin.native.internal.ExportForCppRuntime")
|
val exportForCppRuntime = FqName("kotlin.native.internal.ExportForCppRuntime")
|
||||||
|
val exportForCompilerAnnotation = FqName("kotlin.native.internal.ExportForCompiler")
|
||||||
|
val exportTypeInfoAnnotation = FqName("kotlin.native.internal.ExportTypeInfo")
|
||||||
val cCall = FqName("kotlinx.cinterop.internal.CCall")
|
val cCall = FqName("kotlinx.cinterop.internal.CCall")
|
||||||
}
|
}
|
||||||
|
|||||||
+134
-78
@@ -12,6 +12,7 @@ import org.jetbrains.kotlin.backend.konan.serialization.*
|
|||||||
import org.jetbrains.kotlin.cli.common.messages.AnalyzerWithCompilerReport
|
import org.jetbrains.kotlin.cli.common.messages.AnalyzerWithCompilerReport
|
||||||
import org.jetbrains.kotlin.config.CommonConfigurationKeys
|
import org.jetbrains.kotlin.config.CommonConfigurationKeys
|
||||||
import org.jetbrains.kotlin.config.languageVersionSettings
|
import org.jetbrains.kotlin.config.languageVersionSettings
|
||||||
|
import org.jetbrains.kotlin.ir.declarations.IrFile
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrModuleFragment
|
import org.jetbrains.kotlin.ir.declarations.IrModuleFragment
|
||||||
import org.jetbrains.kotlin.ir.util.patchDeclarationParents
|
import org.jetbrains.kotlin.ir.util.patchDeclarationParents
|
||||||
import org.jetbrains.kotlin.konan.target.CompilerOutputKind
|
import org.jetbrains.kotlin.konan.target.CompilerOutputKind
|
||||||
@@ -65,22 +66,39 @@ internal val psiToIrPhase = konanUnitPhase(
|
|||||||
forwardDeclarationsModuleDescriptor
|
forwardDeclarationsModuleDescriptor
|
||||||
)
|
)
|
||||||
|
|
||||||
val irModules = moduleDescriptor.allDependencyModules.map {
|
val modules = mutableMapOf<String, IrModuleFragment>()
|
||||||
val library = it.konanLibrary
|
|
||||||
if (library == null) {
|
var dependenciesCount = 0
|
||||||
return@map null
|
while (true) {
|
||||||
|
// context.config.librariesWithDependencies could change at each iteration.
|
||||||
|
val dependencies = moduleDescriptor.allDependencyModules.filter {
|
||||||
|
config.librariesWithDependencies(moduleDescriptor).contains(it.konanLibrary)
|
||||||
}
|
}
|
||||||
library.irHeader?.let { header -> deserializer.deserializeIrModule(it, header) }
|
for (dependency in dependencies) {
|
||||||
}.filterNotNull()
|
val konanLibrary = dependency.konanLibrary!!
|
||||||
|
if (modules.containsKey(konanLibrary.libraryName)) continue
|
||||||
|
konanLibrary.irHeader?.let { header ->
|
||||||
|
val deserializationStrategy = when {
|
||||||
|
config.produce.isNativeBinary -> DeserializationStrategy.EXPLICITLY_EXPORTED
|
||||||
|
else -> DeserializationStrategy.ONLY_REFERENCED
|
||||||
|
}
|
||||||
|
modules[konanLibrary.libraryName] = deserializer.deserializeIrModuleHeader(dependency, header, deserializationStrategy)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (dependencies.size == dependenciesCount) break
|
||||||
|
dependenciesCount = dependencies.size
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
val symbols = KonanSymbols(this, generatorContext.symbolTable, generatorContext.symbolTable.lazyWrapper)
|
val symbols = KonanSymbols(this, generatorContext.symbolTable, generatorContext.symbolTable.lazyWrapper)
|
||||||
val module = translator.generateModuleFragment(generatorContext, environment.getSourceFiles(), deserializer)
|
val module = translator.generateModuleFragment(generatorContext, environment.getSourceFiles(), deserializer)
|
||||||
|
|
||||||
irModules.forEach {
|
modules.values.forEach {
|
||||||
it.patchDeclarationParents()
|
it.patchDeclarationParents()
|
||||||
}
|
}
|
||||||
|
|
||||||
irModule = module
|
irModule = module
|
||||||
|
irModules = modules
|
||||||
ir.symbols = symbols
|
ir.symbols = symbols
|
||||||
|
|
||||||
// validateIrModule(this, module)
|
// validateIrModule(this, module)
|
||||||
@@ -102,12 +120,6 @@ internal val irGeneratorPluginsPhase = konanUnitPhase(
|
|||||||
description = "Plugged-in ir generators"
|
description = "Plugged-in ir generators"
|
||||||
)
|
)
|
||||||
|
|
||||||
internal val genSyntheticFieldsPhase = konanUnitPhase(
|
|
||||||
op = { markBackingFields(this) },
|
|
||||||
name = "GenSyntheticFields",
|
|
||||||
description = "Generate synthetic fields"
|
|
||||||
)
|
|
||||||
|
|
||||||
// TODO: We copy default value expressions from expects to actuals before IR serialization,
|
// TODO: We copy default value expressions from expects to actuals before IR serialization,
|
||||||
// because the current infrastructure doesn't allow us to get them at deserialization stage.
|
// because the current infrastructure doesn't allow us to get them at deserialization stage.
|
||||||
// That requires some design and implementation work.
|
// That requires some design and implementation work.
|
||||||
@@ -128,15 +140,13 @@ internal val patchDeclarationParents0Phase = konanUnitPhase(
|
|||||||
internal val serializerPhase = konanUnitPhase(
|
internal val serializerPhase = konanUnitPhase(
|
||||||
op = {
|
op = {
|
||||||
val declarationTable = DeclarationTable(irModule!!.irBuiltins, DescriptorTable())
|
val declarationTable = DeclarationTable(irModule!!.irBuiltins, DescriptorTable())
|
||||||
val serializedIr = IrModuleSerializer(
|
val serializedIr = IrModuleSerializer(this, declarationTable).serializedIrModule(irModule!!)
|
||||||
this, declarationTable, bodiesOnlyForInlines = config.isInteropStubs).serializedIrModule(irModule!!)
|
|
||||||
val serializer = KonanSerializationUtil(this, config.configuration.get(CommonConfigurationKeys.METADATA_VERSION)!!, declarationTable)
|
val serializer = KonanSerializationUtil(this, config.configuration.get(CommonConfigurationKeys.METADATA_VERSION)!!, declarationTable)
|
||||||
serializedLinkData =
|
serializedLinkData =
|
||||||
serializer.serializeModule(moduleDescriptor, /*if (!config.isInteropStubs) serializedIr else null*/ serializedIr)
|
serializer.serializeModule(moduleDescriptor, /*if (!config.isInteropStubs) serializedIr else null*/ serializedIr)
|
||||||
},
|
},
|
||||||
name = "Serializer",
|
name = "Serializer",
|
||||||
description = "Serialize descriptor tree and inline IR bodies",
|
description = "Serialize descriptor tree and inline IR bodies"
|
||||||
prerequisite = setOf(genSyntheticFieldsPhase)
|
|
||||||
)
|
)
|
||||||
|
|
||||||
internal val setUpLinkStagePhase = konanUnitPhase(
|
internal val setUpLinkStagePhase = konanUnitPhase(
|
||||||
@@ -165,13 +175,108 @@ internal val linkPhase = namedUnitPhase(
|
|||||||
linkerPhase
|
linkerPhase
|
||||||
)
|
)
|
||||||
|
|
||||||
|
internal val allLoweringsPhase = namedIrModulePhase(
|
||||||
|
name = "IrLowering",
|
||||||
|
description = "IR Lowering",
|
||||||
|
lower = removeExpectDeclarationsPhase then
|
||||||
|
lowerBeforeInlinePhase then
|
||||||
|
inlinePhase then
|
||||||
|
lowerAfterInlinePhase then
|
||||||
|
interopPart1Phase then
|
||||||
|
patchDeclarationParents1Phase then
|
||||||
|
performByIrFile(
|
||||||
|
name = "IrLowerByFile",
|
||||||
|
description = "IR Lowering by file",
|
||||||
|
lower = lateinitPhase then
|
||||||
|
stringConcatenationPhase then
|
||||||
|
enumConstructorsPhase then
|
||||||
|
initializersPhase then
|
||||||
|
sharedVariablesPhase then
|
||||||
|
localFunctionsPhase then
|
||||||
|
tailrecPhase then
|
||||||
|
defaultParameterExtentPhase then
|
||||||
|
innerClassPhase then
|
||||||
|
forLoopsPhase then
|
||||||
|
dataClassesPhase then
|
||||||
|
builtinOperatorPhase then
|
||||||
|
finallyBlocksPhase then
|
||||||
|
testProcessorPhase then
|
||||||
|
enumClassPhase then
|
||||||
|
delegationPhase then
|
||||||
|
callableReferencePhase then
|
||||||
|
interopPart2Phase then
|
||||||
|
varargPhase then
|
||||||
|
compileTimeEvaluatePhase then
|
||||||
|
coroutinesPhase then
|
||||||
|
typeOperatorPhase then
|
||||||
|
bridgesPhase then
|
||||||
|
autoboxPhase then
|
||||||
|
returnsInsertionPhase
|
||||||
|
) then
|
||||||
|
checkDeclarationParentsPhase
|
||||||
|
// validateIrModulePhase // Temporarily disabled until moving to new IR finished.
|
||||||
|
)
|
||||||
|
|
||||||
|
internal val dependenciesLowerPhase = SameTypeNamedPhaseWrapper(
|
||||||
|
name = "LowerLibIR",
|
||||||
|
description = "Lower library's IR",
|
||||||
|
prerequisite = emptySet(),
|
||||||
|
dumperVerifier = EmptyDumperVerifier(),
|
||||||
|
lower = object : CompilerPhase<Context, IrModuleFragment, IrModuleFragment> {
|
||||||
|
override fun invoke(phaseConfig: PhaseConfig, phaserState: PhaserState, context: Context, irModule: IrModuleFragment): IrModuleFragment {
|
||||||
|
|
||||||
|
val files = mutableListOf<IrFile>()
|
||||||
|
files += irModule.files
|
||||||
|
irModule.files.clear()
|
||||||
|
|
||||||
|
// TODO: KonanLibraryResolver.TopologicalLibraryOrder actually returns libraries in the reverse topological order.
|
||||||
|
context.librariesWithDependencies
|
||||||
|
.reversed()
|
||||||
|
.forEach {
|
||||||
|
val libModule = context.irModules[it.libraryName]
|
||||||
|
?: return@forEach
|
||||||
|
|
||||||
|
irModule.files += libModule.files
|
||||||
|
allLoweringsPhase.invoke(phaseConfig, phaserState, context, irModule)
|
||||||
|
|
||||||
|
irModule.files.clear()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Save all files for codegen in reverse topological order.
|
||||||
|
// This guarantees that libraries initializers are emitted in correct order.
|
||||||
|
context.librariesWithDependencies
|
||||||
|
.forEach {
|
||||||
|
val libModule = context.irModules[it.libraryName]
|
||||||
|
?: return@forEach
|
||||||
|
irModule.files += libModule.files
|
||||||
|
}
|
||||||
|
irModule.files += files
|
||||||
|
|
||||||
|
return irModule
|
||||||
|
}
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
|
internal val bitcodePhase = namedIrModulePhase(
|
||||||
|
name = "Bitcode",
|
||||||
|
description = "LLVM Bitcode generation",
|
||||||
|
lower = contextLLVMSetupPhase then
|
||||||
|
RTTIPhase then
|
||||||
|
generateDebugInfoHeaderPhase then
|
||||||
|
deserializeDFGPhase then
|
||||||
|
devirtualizationPhase then
|
||||||
|
escapeAnalysisPhase then
|
||||||
|
codegenPhase then
|
||||||
|
finalizeDebugInfoPhase then
|
||||||
|
cStubsPhase
|
||||||
|
)
|
||||||
|
|
||||||
internal val toplevelPhase = namedUnitPhase(
|
internal val toplevelPhase = namedUnitPhase(
|
||||||
name = "Compiler",
|
name = "Compiler",
|
||||||
description = "The whole compilation process",
|
description = "The whole compilation process",
|
||||||
lower = frontendPhase then
|
lower = frontendPhase then
|
||||||
psiToIrPhase then
|
psiToIrPhase then
|
||||||
irGeneratorPluginsPhase then
|
irGeneratorPluginsPhase then
|
||||||
genSyntheticFieldsPhase then
|
|
||||||
copyDefaultValuesToActualPhase then
|
copyDefaultValuesToActualPhase then
|
||||||
patchDeclarationParents0Phase then
|
patchDeclarationParents0Phase then
|
||||||
serializerPhase then
|
serializerPhase then
|
||||||
@@ -179,67 +284,16 @@ internal val toplevelPhase = namedUnitPhase(
|
|||||||
name = "Backend",
|
name = "Backend",
|
||||||
description = "All backend",
|
description = "All backend",
|
||||||
lower = takeFromContext<Context, Unit, IrModuleFragment> { it.irModule!! } then
|
lower = takeFromContext<Context, Unit, IrModuleFragment> { it.irModule!! } then
|
||||||
namedIrModulePhase(
|
allLoweringsPhase then // Lower current module first.
|
||||||
name = "IrLowering",
|
dependenciesLowerPhase then // Then lower all libraries in topological order.
|
||||||
description = "IR Lowering",
|
// With that we guarantee that inline functions are unlowered while being inlined.
|
||||||
lower = removeExpectDeclarationsPhase then
|
moduleIndexForCodegenPhase then
|
||||||
lowerBeforeInlinePhase then
|
buildDFGPhase then
|
||||||
inlinePhase then
|
serializeDFGPhase then
|
||||||
lowerAfterInlinePhase then
|
bitcodePhase then
|
||||||
interopPart1Phase then
|
produceOutputPhase then
|
||||||
patchDeclarationParents1Phase then
|
|
||||||
performByIrFile(
|
|
||||||
name = "IrLowerByFile",
|
|
||||||
description = "IR Lowering by file",
|
|
||||||
lower = lateinitPhase then
|
|
||||||
stringConcatenationPhase then
|
|
||||||
enumConstructorsPhase then
|
|
||||||
initializersPhase then
|
|
||||||
sharedVariablesPhase then
|
|
||||||
localFunctionsPhase then
|
|
||||||
tailrecPhase then
|
|
||||||
defaultParameterExtentPhase then
|
|
||||||
innerClassPhase then
|
|
||||||
forLoopsPhase then
|
|
||||||
dataClassesPhase then
|
|
||||||
builtinOperatorPhase then
|
|
||||||
finallyBlocksPhase then
|
|
||||||
testProcessorPhase then
|
|
||||||
enumClassPhase then
|
|
||||||
delegationPhase then
|
|
||||||
callableReferencePhase then
|
|
||||||
interopPart2Phase then
|
|
||||||
varargPhase then
|
|
||||||
compileTimeEvaluatePhase then
|
|
||||||
coroutinesPhase then
|
|
||||||
typeOperatorPhase then
|
|
||||||
bridgesPhase then
|
|
||||||
autoboxPhase then
|
|
||||||
returnsInsertionPhase
|
|
||||||
) then
|
|
||||||
checkDeclarationParentsPhase then
|
|
||||||
// validateIrModulePhase then // Temporarily disabled until moving to new IR finished.
|
|
||||||
moduleIndexForCodegenPhase
|
|
||||||
) then
|
|
||||||
namedIrModulePhase(
|
|
||||||
name = "Bitcode",
|
|
||||||
description = "LLVM Bitcode generation",
|
|
||||||
lower = contextLLVMSetupPhase then
|
|
||||||
RTTIPhase then
|
|
||||||
generateDebugInfoHeaderPhase then
|
|
||||||
buildDFGPhase then
|
|
||||||
deserializeDFGPhase then
|
|
||||||
devirtualizationPhase then
|
|
||||||
escapeAnalysisPhase then
|
|
||||||
serializeDFGPhase then
|
|
||||||
codegenPhase then
|
|
||||||
finalizeDebugInfoPhase then
|
|
||||||
cStubsPhase then
|
|
||||||
bitcodeLinkerPhase
|
|
||||||
) then
|
|
||||||
verifyBitcodePhase then
|
verifyBitcodePhase then
|
||||||
printBitcodePhase
|
printBitcodePhase then
|
||||||
then
|
|
||||||
unitSink()
|
unitSink()
|
||||||
) then
|
) then
|
||||||
linkPhase
|
linkPhase
|
||||||
@@ -256,6 +310,8 @@ internal fun PhaseConfig.konanPhasesConfig(config: KonanConfig) {
|
|||||||
|
|
||||||
// Don't serialize anything to a final executable.
|
// Don't serialize anything to a final executable.
|
||||||
switch(serializerPhase, config.produce == CompilerOutputKind.LIBRARY)
|
switch(serializerPhase, config.produce == CompilerOutputKind.LIBRARY)
|
||||||
|
switch(dependenciesLowerPhase, config.produce != CompilerOutputKind.LIBRARY)
|
||||||
|
switch(bitcodePhase, config.produce != CompilerOutputKind.LIBRARY)
|
||||||
switch(linkPhase, config.produce.isNativeBinary)
|
switch(linkPhase, config.produce.isNativeBinary)
|
||||||
switch(testProcessorPhase, getNotNull(KonanConfigKeys.GENERATE_TEST_RUNNER) != TestRunnerKind.NONE)
|
switch(testProcessorPhase, getNotNull(KonanConfigKeys.GENERATE_TEST_RUNNER) != TestRunnerKind.NONE)
|
||||||
}
|
}
|
||||||
|
|||||||
-1
@@ -25,7 +25,6 @@ import org.jetbrains.kotlin.ir.IrElement
|
|||||||
import org.jetbrains.kotlin.ir.declarations.*
|
import org.jetbrains.kotlin.ir.declarations.*
|
||||||
import org.jetbrains.kotlin.ir.expressions.*
|
import org.jetbrains.kotlin.ir.expressions.*
|
||||||
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
|
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
|
||||||
import org.jetbrains.kotlin.ir.symbols.IrEnumEntrySymbol
|
|
||||||
import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
|
import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
|
||||||
import org.jetbrains.kotlin.ir.symbols.IrSymbol
|
import org.jetbrains.kotlin.ir.symbols.IrSymbol
|
||||||
import org.jetbrains.kotlin.ir.symbols.impl.IrClassSymbolImpl
|
import org.jetbrains.kotlin.ir.symbols.impl.IrClassSymbolImpl
|
||||||
|
|||||||
+6
-25
@@ -7,25 +7,22 @@ package org.jetbrains.kotlin.backend.konan.irasdescriptors
|
|||||||
|
|
||||||
import org.jetbrains.kotlin.backend.common.atMostOne
|
import org.jetbrains.kotlin.backend.common.atMostOne
|
||||||
import org.jetbrains.kotlin.backend.konan.descriptors.getArgumentValueOrNull
|
import org.jetbrains.kotlin.backend.konan.descriptors.getArgumentValueOrNull
|
||||||
import org.jetbrains.kotlin.backend.konan.descriptors.konanBackingField
|
|
||||||
import org.jetbrains.kotlin.backend.konan.descriptors.isInterface
|
import org.jetbrains.kotlin.backend.konan.descriptors.isInterface
|
||||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||||
import org.jetbrains.kotlin.descriptors.ClassKind
|
|
||||||
import org.jetbrains.kotlin.descriptors.Modality
|
import org.jetbrains.kotlin.descriptors.Modality
|
||||||
import org.jetbrains.kotlin.descriptors.Visibilities
|
import org.jetbrains.kotlin.descriptors.Visibilities
|
||||||
import org.jetbrains.kotlin.ir.SourceManager
|
|
||||||
import org.jetbrains.kotlin.ir.declarations.*
|
import org.jetbrains.kotlin.ir.declarations.*
|
||||||
import org.jetbrains.kotlin.ir.declarations.impl.IrFieldImpl
|
import org.jetbrains.kotlin.ir.expressions.IrCall
|
||||||
import org.jetbrains.kotlin.ir.expressions.*
|
import org.jetbrains.kotlin.ir.expressions.IrConst
|
||||||
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
|
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
|
||||||
import org.jetbrains.kotlin.ir.types.*
|
import org.jetbrains.kotlin.ir.types.classifierOrFail
|
||||||
|
import org.jetbrains.kotlin.ir.types.isMarkedNullable
|
||||||
import org.jetbrains.kotlin.ir.util.explicitParameters
|
import org.jetbrains.kotlin.ir.util.explicitParameters
|
||||||
import org.jetbrains.kotlin.name.ClassId
|
|
||||||
import org.jetbrains.kotlin.ir.util.isFunction
|
import org.jetbrains.kotlin.ir.util.isFunction
|
||||||
import org.jetbrains.kotlin.ir.util.isSuspendFunction
|
import org.jetbrains.kotlin.ir.util.isSuspendFunction
|
||||||
|
import org.jetbrains.kotlin.name.ClassId
|
||||||
import org.jetbrains.kotlin.name.FqName
|
import org.jetbrains.kotlin.name.FqName
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedPropertyDescriptor
|
|
||||||
|
|
||||||
val IrConstructor.constructedClass get() = this.parent as IrClass
|
val IrConstructor.constructedClass get() = this.parent as IrClass
|
||||||
|
|
||||||
@@ -95,23 +92,7 @@ fun IrClass.getSuperInterfaces() = this.superClasses.map { it.owner }.filter { i
|
|||||||
val IrProperty.konanBackingField: IrField?
|
val IrProperty.konanBackingField: IrField?
|
||||||
get() {
|
get() {
|
||||||
assert(this.isReal)
|
assert(this.isReal)
|
||||||
this.backingField?.let { return it }
|
return this.backingField
|
||||||
|
|
||||||
(this.descriptor as? DeserializedPropertyDescriptor)?.konanBackingField?.let { backingFieldDescriptor ->
|
|
||||||
val result = IrFieldImpl(
|
|
||||||
this.startOffset,
|
|
||||||
this.endOffset,
|
|
||||||
IrDeclarationOrigin.PROPERTY_BACKING_FIELD,
|
|
||||||
backingFieldDescriptor,
|
|
||||||
this.getter!!.returnType
|
|
||||||
).also {
|
|
||||||
it.parent = this.parent
|
|
||||||
}
|
|
||||||
this.backingField = result
|
|
||||||
return result
|
|
||||||
}
|
|
||||||
|
|
||||||
return null
|
|
||||||
}
|
}
|
||||||
|
|
||||||
val IrFunction.isReal get() = this.origin != IrDeclarationOrigin.FAKE_OVERRIDE
|
val IrFunction.isReal get() = this.origin != IrDeclarationOrigin.FAKE_OVERRIDE
|
||||||
|
|||||||
+2
-2
@@ -121,14 +121,14 @@ internal fun buildLibrary(
|
|||||||
target: KonanTarget,
|
target: KonanTarget,
|
||||||
output: String,
|
output: String,
|
||||||
moduleName: String,
|
moduleName: String,
|
||||||
llvmModule: LLVMModuleRef,
|
llvmModule: LLVMModuleRef?,
|
||||||
nopack: Boolean,
|
nopack: Boolean,
|
||||||
manifestProperties: Properties?,
|
manifestProperties: Properties?,
|
||||||
dataFlowGraph: ByteArray?): KonanLibraryWriter {
|
dataFlowGraph: ByteArray?): KonanLibraryWriter {
|
||||||
|
|
||||||
val library = LibraryWriterImpl(File(output), moduleName, versions, target, nopack)
|
val library = LibraryWriterImpl(File(output), moduleName, versions, target, nopack)
|
||||||
|
|
||||||
library.addKotlinBitcode(llvmModule)
|
llvmModule?.let { library.addKotlinBitcode(it) }
|
||||||
library.addLinkData(linkData)
|
library.addLinkData(linkData)
|
||||||
natives.forEach {
|
natives.forEach {
|
||||||
library.addNativeBitcode(it)
|
library.addNativeBitcode(it)
|
||||||
|
|||||||
+1
-1
@@ -107,7 +107,7 @@ private val cnameAnnotation = FqName("kotlin.native.CName")
|
|||||||
|
|
||||||
private val exportForCppRuntimeAnnotation = RuntimeNames.exportForCppRuntime
|
private val exportForCppRuntimeAnnotation = RuntimeNames.exportForCppRuntime
|
||||||
|
|
||||||
private val exportForCompilerAnnotation = FqName("kotlin.native.internal.ExportForCompiler")
|
private val exportForCompilerAnnotation = RuntimeNames.exportForCompilerAnnotation
|
||||||
|
|
||||||
private val publishedApiAnnotation = FqName("kotlin.PublishedApi")
|
private val publishedApiAnnotation = FqName("kotlin.PublishedApi")
|
||||||
|
|
||||||
|
|||||||
+3
-3
@@ -151,9 +151,9 @@ internal val cStubsPhase = makeKonanModuleOpPhase(
|
|||||||
op = { context, _ -> produceCStubs(context) }
|
op = { context, _ -> produceCStubs(context) }
|
||||||
)
|
)
|
||||||
|
|
||||||
internal val bitcodeLinkerPhase = makeKonanModuleOpPhase(
|
internal val produceOutputPhase = makeKonanModuleOpPhase(
|
||||||
name = "BitcodeLinker",
|
name = "ProduceOutput",
|
||||||
description = "Bitcode linking",
|
description = "Produce output",
|
||||||
op = { context, _ -> produceOutput(context) }
|
op = { context, _ -> produceOutput(context) }
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
+1
-19
@@ -142,12 +142,7 @@ internal interface ContextUtils : RuntimeAware {
|
|||||||
get() = context.llvm.staticData
|
get() = context.llvm.staticData
|
||||||
|
|
||||||
fun isExternal(declaration: IrDeclaration): Boolean {
|
fun isExternal(declaration: IrDeclaration): Boolean {
|
||||||
val pkg = declaration.findPackage()
|
return false
|
||||||
return when (pkg) {
|
|
||||||
is IrFile -> pkg.packageFragmentDescriptor.containingDeclaration != context.moduleDescriptor
|
|
||||||
is IrExternalPackageFragment -> true
|
|
||||||
else -> error(pkg)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -367,19 +362,6 @@ internal class Llvm(val context: Context, val llvmModule: LLVMModuleRef) {
|
|||||||
.getFullList(TopologicalLibraryOrder)
|
.getFullList(TopologicalLibraryOrder)
|
||||||
}
|
}
|
||||||
|
|
||||||
val librariesForLibraryManifest: List<KonanLibrary>
|
|
||||||
get() {
|
|
||||||
// Note: library manifest should contain the list of all user libraries and frontend-used default libraries.
|
|
||||||
// However this would result into linking too many default libraries into the application which uses current
|
|
||||||
// library. This problem should probably be fixed by adding different kind of dependencies to library
|
|
||||||
// manifest.
|
|
||||||
// Currently the problem is workarounded like this:
|
|
||||||
return this.librariesToLink
|
|
||||||
// This list contains all user libraries and the default libraries required for link (not frontend).
|
|
||||||
// That's why the workaround doesn't work only in very special cases, e.g. when `-nodefaultlibs` is enabled
|
|
||||||
// when compiling the application, while the library API uses types from default libs.
|
|
||||||
}
|
|
||||||
|
|
||||||
val staticData = StaticData(context)
|
val staticData = StaticData(context)
|
||||||
|
|
||||||
private val target = context.config.target
|
private val target = context.config.target
|
||||||
|
|||||||
+2
-3
@@ -40,10 +40,9 @@ internal fun findMainEntryPoint(context: Context): FunctionDescriptor? {
|
|||||||
candidates.singleOrNull { it.hasSingleArrayOfStringParameter } ?:
|
candidates.singleOrNull { it.hasSingleArrayOfStringParameter } ?:
|
||||||
candidates.singleOrNull { it.hasNoParameters } ?:
|
candidates.singleOrNull { it.hasNoParameters } ?:
|
||||||
context.reportCompilationError("Could not find '$entryName' in '$packageName' package.")
|
context.reportCompilationError("Could not find '$entryName' in '$packageName' package.")
|
||||||
|
|
||||||
if (main.isSuspend) {
|
if (main.isSuspend)
|
||||||
context.reportCompilationError("Entry point can not be a suspend function.")
|
context.reportCompilationError("Entry point can not be a suspend function.")
|
||||||
}
|
|
||||||
|
|
||||||
return main
|
return main
|
||||||
}
|
}
|
||||||
|
|||||||
+8
@@ -58,6 +58,7 @@ internal enum class IntrinsicType {
|
|||||||
IDENTITY,
|
IDENTITY,
|
||||||
IMMUTABLE_BLOB,
|
IMMUTABLE_BLOB,
|
||||||
INIT_INSTANCE,
|
INIT_INSTANCE,
|
||||||
|
SELECT_ENTRY_POINT,
|
||||||
// Coroutines
|
// Coroutines
|
||||||
GET_CONTINUATION,
|
GET_CONTINUATION,
|
||||||
RETURN_IF_SUSPEND,
|
RETURN_IF_SUSPEND,
|
||||||
@@ -218,6 +219,7 @@ internal class IntrinsicGenerator(private val environment: IntrinsicGeneratorEnv
|
|||||||
IntrinsicType.IDENTITY -> emitIdentity(args)
|
IntrinsicType.IDENTITY -> emitIdentity(args)
|
||||||
IntrinsicType.GET_CONTINUATION -> emitGetContinuation()
|
IntrinsicType.GET_CONTINUATION -> emitGetContinuation()
|
||||||
IntrinsicType.INTEROP_MEMORY_COPY -> emitMemoryCopy(callSite, args)
|
IntrinsicType.INTEROP_MEMORY_COPY -> emitMemoryCopy(callSite, args)
|
||||||
|
IntrinsicType.SELECT_ENTRY_POINT -> emitEntryPointSelection(args)
|
||||||
IntrinsicType.RETURN_IF_SUSPEND,
|
IntrinsicType.RETURN_IF_SUSPEND,
|
||||||
IntrinsicType.INTEROP_BITS_TO_FLOAT,
|
IntrinsicType.INTEROP_BITS_TO_FLOAT,
|
||||||
IntrinsicType.INTEROP_BITS_TO_DOUBLE,
|
IntrinsicType.INTEROP_BITS_TO_DOUBLE,
|
||||||
@@ -246,6 +248,12 @@ internal class IntrinsicGenerator(private val environment: IntrinsicGeneratorEnv
|
|||||||
private fun FunctionGenerationContext.emitIdentity(args: List<LLVMValueRef>): LLVMValueRef =
|
private fun FunctionGenerationContext.emitIdentity(args: List<LLVMValueRef>): LLVMValueRef =
|
||||||
args.single()
|
args.single()
|
||||||
|
|
||||||
|
private fun FunctionGenerationContext.emitEntryPointSelection(args: List<LLVMValueRef>): LLVMValueRef {
|
||||||
|
val entryPoint = context.ir.symbols.entryPoint?.owner ?: return unreachable()!! // TODO: Don't put start.kt in source set unless produce=PROGRAM.
|
||||||
|
return call(codegen.llvmFunction(entryPoint), args.take(entryPoint.valueParameters.size),
|
||||||
|
Lifetime.IRRELEVANT, environment.exceptionHandler)
|
||||||
|
}
|
||||||
|
|
||||||
private fun FunctionGenerationContext.emitListOfInternal(callSite: IrCall, args: List<LLVMValueRef>): LLVMValueRef {
|
private fun FunctionGenerationContext.emitListOfInternal(callSite: IrCall, args: List<LLVMValueRef>): LLVMValueRef {
|
||||||
val varargExpression = callSite.getValueArgument(0) as IrVararg
|
val varargExpression = callSite.getValueArgument(0) as IrVararg
|
||||||
val vararg = args.single()
|
val vararg = args.single()
|
||||||
|
|||||||
-9
@@ -324,7 +324,6 @@ internal class CodeGeneratorVisitor(val context: Context, val lifetimes: Map<IrE
|
|||||||
appendLlvmUsed("llvm.used", context.llvm.usedFunctions + context.llvm.usedGlobals)
|
appendLlvmUsed("llvm.used", context.llvm.usedFunctions + context.llvm.usedGlobals)
|
||||||
appendLlvmUsed("llvm.compiler.used", context.llvm.compilerUsedGlobals)
|
appendLlvmUsed("llvm.compiler.used", context.llvm.compilerUsedGlobals)
|
||||||
appendStaticInitializers()
|
appendStaticInitializers()
|
||||||
appendEntryPointSelector(context.ir.symbols.entryPoint?.owner)
|
|
||||||
if (context.isNativeLibrary) {
|
if (context.isNativeLibrary) {
|
||||||
appendCAdapters()
|
appendCAdapters()
|
||||||
}
|
}
|
||||||
@@ -2336,14 +2335,6 @@ internal class CodeGeneratorVisitor(val context: Context, val lifetimes: Map<IrE
|
|||||||
appendingTo(bbNeedInit) {
|
appendingTo(bbNeedInit) {
|
||||||
LLVMBuildStore(builder, kImmOne, initGuard)
|
LLVMBuildStore(builder, kImmOne, initGuard)
|
||||||
|
|
||||||
if (context.config.produce.isNativeBinary) {
|
|
||||||
context.llvm.librariesToLink.forEach {
|
|
||||||
val dependencyCtorFunction = context.llvm.externalFunction(
|
|
||||||
it.moduleConstructorName, kVoidFuncType, CurrentKonanModuleOrigin)
|
|
||||||
call(dependencyCtorFunction, emptyList(), Lifetime.IRRELEVANT,
|
|
||||||
exceptionHandler = ExceptionHandler.Caller, verbatim = true)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// TODO: shall we put that into the try block?
|
// TODO: shall we put that into the try block?
|
||||||
context.llvm.staticInitializers.forEach {
|
context.llvm.staticInitializers.forEach {
|
||||||
call(it, emptyList(), Lifetime.IRRELEVANT,
|
call(it, emptyList(), Lifetime.IRRELEVANT,
|
||||||
|
|||||||
+1
-1
@@ -212,7 +212,7 @@ internal fun ContextUtils.importGlobal(name: String, type: LLVMTypeRef, origin:
|
|||||||
val found = LLVMGetNamedGlobal(context.llvmModule, name)
|
val found = LLVMGetNamedGlobal(context.llvmModule, name)
|
||||||
if (found != null) {
|
if (found != null) {
|
||||||
assert (getGlobalType(found) == type)
|
assert (getGlobalType(found) == type)
|
||||||
assert (LLVMGetInitializer(found) == null)
|
assert (LLVMGetInitializer(found) == null) { "$name is already declared in the current module" }
|
||||||
if (threadLocal)
|
if (threadLocal)
|
||||||
assert(LLVMGetThreadLocalMode(found) == context.llvm.tlsMode)
|
assert(LLVMGetThreadLocalMode(found) == context.llvm.tlsMode)
|
||||||
return found
|
return found
|
||||||
|
|||||||
-9
@@ -86,15 +86,6 @@ internal fun StaticData.createConstKotlinObject(type: IrClass, vararg fields: Co
|
|||||||
internal fun StaticData.createInitializer(type: IrClass, vararg fields: ConstValue): ConstValue =
|
internal fun StaticData.createInitializer(type: IrClass, vararg fields: ConstValue): ConstValue =
|
||||||
Struct(objHeader(type.typeInfoPtr), *fields)
|
Struct(objHeader(type.typeInfoPtr), *fields)
|
||||||
|
|
||||||
private fun StaticData.getArrayListClass(): ClassDescriptor {
|
|
||||||
val module = context.irModule!!.descriptor
|
|
||||||
val pkg = module.getPackage(FqName.fromSegments(listOf("kotlin", "collections")))
|
|
||||||
val classifier = pkg.memberScope.getContributedClassifier(Name.identifier("ArrayList"),
|
|
||||||
NoLookupLocation.FROM_BACKEND)
|
|
||||||
|
|
||||||
return classifier as ClassDescriptor
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates static instance of `kotlin.collections.ArrayList<elementType>` with given values of fields.
|
* Creates static instance of `kotlin.collections.ArrayList<elementType>` with given values of fields.
|
||||||
*
|
*
|
||||||
|
|||||||
+1
-1
@@ -59,7 +59,7 @@ internal class DeepCopyIrTreeWithSymbolsForInliner(val context: Context,
|
|||||||
|
|
||||||
override fun visitField(declaration: IrField) {
|
override fun visitField(declaration: IrField) {
|
||||||
// TODO: inlining a function returning an object
|
// TODO: inlining a function returning an object
|
||||||
// we get PropertyDescriptors from whithin that object here.
|
// we get PropertyDescriptors from within that object here.
|
||||||
// That is a bug, most probably.
|
// That is a bug, most probably.
|
||||||
// We workaround the issue with question marks here.
|
// We workaround the issue with question marks here.
|
||||||
(declaration.descriptor as? WrappedFieldDescriptor)?.bind(declaration)
|
(declaration.descriptor as? WrappedFieldDescriptor)?.bind(declaration)
|
||||||
|
|||||||
+1
-1
@@ -136,10 +136,10 @@ internal class EnumUsageLowering(val context: Context)
|
|||||||
internal class EnumClassLowering(val context: Context) : ClassLoweringPass {
|
internal class EnumClassLowering(val context: Context) : ClassLoweringPass {
|
||||||
|
|
||||||
fun run(irFile: IrFile) {
|
fun run(irFile: IrFile) {
|
||||||
runOnFilePostfix(irFile)
|
|
||||||
// EnumWhenLowering should be performed before EnumUsageLowering because
|
// EnumWhenLowering should be performed before EnumUsageLowering because
|
||||||
// the latter performs lowering of IrGetEnumValue
|
// the latter performs lowering of IrGetEnumValue
|
||||||
EnumWhenLowering(context).lower(irFile)
|
EnumWhenLowering(context).lower(irFile)
|
||||||
|
runOnFilePostfix(irFile)
|
||||||
EnumUsageLowering(context).lower(irFile)
|
EnumUsageLowering(context).lower(irFile)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -238,7 +238,7 @@ internal class EnumConstructorsLowering(val context: Context) : ClassLoweringPas
|
|||||||
|
|
||||||
override fun transform(enumConstructorCall: IrEnumConstructorCall): IrExpression {
|
override fun transform(enumConstructorCall: IrEnumConstructorCall): IrExpression {
|
||||||
val name = enumEntry.name.asString()
|
val name = enumEntry.name.asString()
|
||||||
val ordinal = context.specialDeclarationsFactory.getEnumEntryOrdinal(enumEntry.descriptor)
|
val ordinal = context.specialDeclarationsFactory.getEnumEntryOrdinal(enumEntry)
|
||||||
|
|
||||||
val startOffset = enumConstructorCall.startOffset
|
val startOffset = enumConstructorCall.startOffset
|
||||||
val endOffset = enumConstructorCall.endOffset
|
val endOffset = enumConstructorCall.endOffset
|
||||||
|
|||||||
+1
-1
@@ -143,7 +143,7 @@ internal class EnumWhenLowering(private val context: Context) : IrElementTransfo
|
|||||||
if (lhs is IrValueAccessExpression && lhs.symbol.owner == topmostSubject && rhs is IrGetEnumValue &&
|
if (lhs is IrValueAccessExpression && lhs.symbol.owner == topmostSubject && rhs is IrGetEnumValue &&
|
||||||
// Both entries should belong to the same class:
|
// Both entries should belong to the same class:
|
||||||
topmostSubject.type.classifierOrNull?.owner == rhs.symbol.owner.parent) {
|
topmostSubject.type.classifierOrNull?.owner == rhs.symbol.owner.parent) {
|
||||||
val entryOrdinal = context.specialDeclarationsFactory.getEnumEntryOrdinal(rhs.descriptor)
|
val entryOrdinal = context.specialDeclarationsFactory.getEnumEntryOrdinal(rhs.symbol.owner)
|
||||||
val subjectOrdinal = topmostOrdinalProvider.value
|
val subjectOrdinal = topmostOrdinalProvider.value
|
||||||
return IrCallImpl(call.startOffset, call.endOffset, areEqualByValue.owner.returnType, areEqualByValue).apply {
|
return IrCallImpl(call.startOffset, call.endOffset, areEqualByValue.owner.returnType, areEqualByValue).apply {
|
||||||
putValueArgument(0,
|
putValueArgument(0,
|
||||||
|
|||||||
+26
-2
@@ -12,6 +12,10 @@ import org.jetbrains.kotlin.backend.common.descriptors.WrappedVariableDescriptor
|
|||||||
import org.jetbrains.kotlin.backend.konan.Context
|
import org.jetbrains.kotlin.backend.konan.Context
|
||||||
import org.jetbrains.kotlin.backend.konan.ir.KonanIrReturnableBlockImpl
|
import org.jetbrains.kotlin.backend.konan.ir.KonanIrReturnableBlockImpl
|
||||||
import org.jetbrains.kotlin.backend.konan.irasdescriptors.file
|
import org.jetbrains.kotlin.backend.konan.irasdescriptors.file
|
||||||
|
import org.jetbrains.kotlin.backend.konan.SYNTHETIC_OFFSET
|
||||||
|
import org.jetbrains.kotlin.descriptors.Modality
|
||||||
|
import org.jetbrains.kotlin.descriptors.SimpleFunctionDescriptor
|
||||||
|
import org.jetbrains.kotlin.descriptors.Visibilities
|
||||||
import org.jetbrains.kotlin.ir.IrElement
|
import org.jetbrains.kotlin.ir.IrElement
|
||||||
import org.jetbrains.kotlin.ir.IrStatement
|
import org.jetbrains.kotlin.ir.IrStatement
|
||||||
import org.jetbrains.kotlin.ir.builders.*
|
import org.jetbrains.kotlin.ir.builders.*
|
||||||
@@ -24,6 +28,8 @@ import org.jetbrains.kotlin.ir.symbols.impl.IrReturnableBlockSymbolImpl
|
|||||||
import org.jetbrains.kotlin.ir.types.IrType
|
import org.jetbrains.kotlin.ir.types.IrType
|
||||||
import org.jetbrains.kotlin.ir.builders.irGet
|
import org.jetbrains.kotlin.ir.builders.irGet
|
||||||
import org.jetbrains.kotlin.ir.declarations.*
|
import org.jetbrains.kotlin.ir.declarations.*
|
||||||
|
import org.jetbrains.kotlin.ir.declarations.impl.IrFunctionImpl
|
||||||
|
import org.jetbrains.kotlin.ir.symbols.impl.IrSimpleFunctionSymbolImpl
|
||||||
import org.jetbrains.kotlin.ir.symbols.impl.IrVariableSymbolImpl
|
import org.jetbrains.kotlin.ir.symbols.impl.IrVariableSymbolImpl
|
||||||
import org.jetbrains.kotlin.ir.types.IrSimpleType
|
import org.jetbrains.kotlin.ir.types.IrSimpleType
|
||||||
import org.jetbrains.kotlin.ir.util.defaultType
|
import org.jetbrains.kotlin.ir.util.defaultType
|
||||||
@@ -169,6 +175,24 @@ internal class FinallyBlocksLowering(val context: Context): FileLoweringPass, Ir
|
|||||||
else -> error("Unknown ReturnTarget: $this")
|
else -> error("Unknown ReturnTarget: $this")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun createSyntheticFunctionDescriptor(name: String): SimpleFunctionDescriptor {
|
||||||
|
val descriptor = WrappedSimpleFunctionDescriptor()
|
||||||
|
descriptor.bind(IrFunctionImpl(
|
||||||
|
SYNTHETIC_OFFSET, SYNTHETIC_OFFSET,
|
||||||
|
IrDeclarationOrigin.DEFINED,
|
||||||
|
IrSimpleFunctionSymbolImpl(descriptor),
|
||||||
|
Name.identifier(name),
|
||||||
|
Visibilities.PUBLIC,
|
||||||
|
Modality.FINAL,
|
||||||
|
context.irBuiltIns.unitType,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
false)
|
||||||
|
)
|
||||||
|
return descriptor
|
||||||
|
}
|
||||||
|
|
||||||
private fun performHighLevelJump(tryScopes: List<TryScope>,
|
private fun performHighLevelJump(tryScopes: List<TryScope>,
|
||||||
index: Int,
|
index: Int,
|
||||||
jump: HighLevelJump,
|
jump: HighLevelJump,
|
||||||
@@ -181,7 +205,7 @@ internal class FinallyBlocksLowering(val context: Context): FileLoweringPass, Ir
|
|||||||
val currentTryScope = tryScopes[index]
|
val currentTryScope = tryScopes[index]
|
||||||
currentTryScope.jumps.getOrPut(jump) {
|
currentTryScope.jumps.getOrPut(jump) {
|
||||||
val type = (jump as? Return)?.target?.owner?.returnType ?: value.type
|
val type = (jump as? Return)?.target?.owner?.returnType ?: value.type
|
||||||
val symbol = IrReturnableBlockSymbolImpl(WrappedSimpleFunctionDescriptor())
|
val symbol = IrReturnableBlockSymbolImpl(createSyntheticFunctionDescriptor("\$Finally$index"))
|
||||||
with(currentTryScope) {
|
with(currentTryScope) {
|
||||||
irBuilder.run {
|
irBuilder.run {
|
||||||
val inlinedFinally = irInlineFinally(symbol, type, expression, finallyExpression)
|
val inlinedFinally = irInlineFinally(symbol, type, expression, finallyExpression)
|
||||||
@@ -252,7 +276,7 @@ internal class FinallyBlocksLowering(val context: Context): FileLoweringPass, Ir
|
|||||||
)
|
)
|
||||||
using(TryScope(syntheticTry, transformedFinallyExpression, this)) {
|
using(TryScope(syntheticTry, transformedFinallyExpression, this)) {
|
||||||
val fallThroughType = aTry.type
|
val fallThroughType = aTry.type
|
||||||
val fallThroughSymbol = IrReturnableBlockSymbolImpl(WrappedSimpleFunctionDescriptor())
|
val fallThroughSymbol = IrReturnableBlockSymbolImpl(createSyntheticFunctionDescriptor("\$Fallthrough"))
|
||||||
val transformedResult = aTry.tryResult.transform(transformer, null)
|
val transformedResult = aTry.tryResult.transform(transformer, null)
|
||||||
transformedTry.tryResult = irReturn(fallThroughSymbol, transformedResult)
|
transformedTry.tryResult = irReturn(fallThroughSymbol, transformedResult)
|
||||||
for (aCatch in aTry.catches) {
|
for (aCatch in aTry.catches) {
|
||||||
|
|||||||
+3
@@ -131,6 +131,9 @@ internal class FunctionInlining(val context: Context) : IrElementTransformerVoid
|
|||||||
val irBuilder = context.createIrBuilder(irReturnableBlockSymbol, startOffset, endOffset)
|
val irBuilder = context.createIrBuilder(irReturnableBlockSymbol, startOffset, endOffset)
|
||||||
|
|
||||||
if (descriptor.isInlineConstructor) {
|
if (descriptor.isInlineConstructor) {
|
||||||
|
// Copier sets parent to be the current function but
|
||||||
|
// constructor's parent cannot be a function.
|
||||||
|
copiedCallee.parent = callee.parent
|
||||||
val delegatingConstructorCall = statements[0] as IrDelegatingConstructorCall
|
val delegatingConstructorCall = statements[0] as IrDelegatingConstructorCall
|
||||||
irBuilder.run {
|
irBuilder.run {
|
||||||
val constructorDescriptor = delegatingConstructorCall.descriptor.original
|
val constructorDescriptor = delegatingConstructorCall.descriptor.original
|
||||||
|
|||||||
+1
@@ -44,6 +44,7 @@ internal class InnerClassLowering(val context: Context) : ClassLoweringPass {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun createOuterThisField() {
|
private fun createOuterThisField() {
|
||||||
|
irClass.declarations += context.specialDeclarationsFactory.getOuterThisField(irClass)
|
||||||
outerThisFieldSymbol = context.specialDeclarationsFactory.getOuterThisField(irClass).symbol
|
outerThisFieldSymbol = context.specialDeclarationsFactory.getOuterThisField(irClass).symbol
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -628,7 +628,7 @@ internal class InteropLoweringPart1(val context: Context) : IrBuildingTransforme
|
|||||||
|
|
||||||
descriptor.getExternalObjCMethodInfo()?.let { methodInfo ->
|
descriptor.getExternalObjCMethodInfo()?.let { methodInfo ->
|
||||||
val isInteropStubsFile =
|
val isInteropStubsFile =
|
||||||
currentFile.fileAnnotations.any { it.fqName == FqName("kotlinx.cinterop.InteropStubs") }
|
currentFile.annotations.hasAnnotation(FqName("kotlinx.cinterop.InteropStubs"))
|
||||||
|
|
||||||
// Special case: bridge from Objective-C method implementation template to Kotlin method;
|
// Special case: bridge from Objective-C method implementation template to Kotlin method;
|
||||||
// handled in CodeGeneratorVisitor.callVirtual.
|
// handled in CodeGeneratorVisitor.callVirtual.
|
||||||
|
|||||||
-54
@@ -1,54 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
|
||||||
* that can be found in the LICENSE file.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.jetbrains.kotlin.backend.konan.serialization
|
|
||||||
|
|
||||||
import org.jetbrains.kotlin.backend.konan.Context
|
|
||||||
import org.jetbrains.kotlin.ir.IrElement
|
|
||||||
import org.jetbrains.kotlin.ir.declarations.*
|
|
||||||
import org.jetbrains.kotlin.ir.util.addChild
|
|
||||||
import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid
|
|
||||||
import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid
|
|
||||||
|
|
||||||
internal class BackingFieldVisitor(val context: Context) : IrElementVisitorVoid {
|
|
||||||
|
|
||||||
override fun visitElement(element: IrElement) {
|
|
||||||
element.acceptChildrenVoid(this)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun visitProperty(declaration: IrProperty) {
|
|
||||||
super.visitProperty(declaration)
|
|
||||||
|
|
||||||
if (declaration.isDelegated) {
|
|
||||||
val irClass = declaration.parent as? IrClass
|
|
||||||
val list = irClass?.let { context.ir.classesDelegatedBackingFields.getOrPut(irClass.descriptor) { mutableListOf() } }
|
|
||||||
list?.add(declaration.backingField!!.descriptor)
|
|
||||||
}
|
|
||||||
if (declaration.backingField == null || declaration.isDelegated) return
|
|
||||||
assert(declaration.backingField!!.descriptor == declaration.descriptor) {
|
|
||||||
"backing field descriptor mismatch: ${declaration.backingField!!.descriptor} != ${declaration.descriptor}"
|
|
||||||
}
|
|
||||||
|
|
||||||
context.ir.propertiesWithBackingFields.add(declaration.descriptor)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun visitClass(declaration: IrClass) {
|
|
||||||
if (declaration.isInner)
|
|
||||||
declaration.declarations += context.specialDeclarationsFactory.getOuterThisField(declaration)
|
|
||||||
|
|
||||||
// Mark all dangling fields (they are created when class is inherited via delegation).
|
|
||||||
declaration.declarations.filterIsInstance<IrField>().forEach {
|
|
||||||
val list = context.ir.classesDelegatedBackingFields.getOrPut(declaration.descriptor) { mutableListOf() }
|
|
||||||
list.add(it.descriptor)
|
|
||||||
}
|
|
||||||
|
|
||||||
super.visitClass(declaration)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
internal fun markBackingFields(context: Context) {
|
|
||||||
context.irModule!!.accept(BackingFieldVisitor(context), null)
|
|
||||||
}
|
|
||||||
|
|
||||||
+26
@@ -18,6 +18,7 @@ package org.jetbrains.kotlin.backend.konan.serialization
|
|||||||
|
|
||||||
import org.jetbrains.kotlin.backend.common.LoggingContext
|
import org.jetbrains.kotlin.backend.common.LoggingContext
|
||||||
import org.jetbrains.kotlin.backend.common.ir.ir2string
|
import org.jetbrains.kotlin.backend.common.ir.ir2string
|
||||||
|
import org.jetbrains.kotlin.backend.konan.RuntimeNames
|
||||||
import org.jetbrains.kotlin.backend.konan.descriptors.findTopLevelDeclaration
|
import org.jetbrains.kotlin.backend.konan.descriptors.findTopLevelDeclaration
|
||||||
import org.jetbrains.kotlin.backend.konan.descriptors.isExpectMember
|
import org.jetbrains.kotlin.backend.konan.descriptors.isExpectMember
|
||||||
import org.jetbrains.kotlin.backend.konan.descriptors.isSerializableExpectClass
|
import org.jetbrains.kotlin.backend.konan.descriptors.isSerializableExpectClass
|
||||||
@@ -39,6 +40,10 @@ import org.jetbrains.kotlin.ir.expressions.impl.IrUnaryPrimitiveImpl
|
|||||||
import org.jetbrains.kotlin.ir.symbols.*
|
import org.jetbrains.kotlin.ir.symbols.*
|
||||||
import org.jetbrains.kotlin.ir.types.*
|
import org.jetbrains.kotlin.ir.types.*
|
||||||
import org.jetbrains.kotlin.ir.types.impl.IrStarProjectionImpl
|
import org.jetbrains.kotlin.ir.types.impl.IrStarProjectionImpl
|
||||||
|
import org.jetbrains.kotlin.ir.util.dump
|
||||||
|
import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid
|
||||||
|
import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid
|
||||||
|
import org.jetbrains.kotlin.ir.visitors.acceptVoid
|
||||||
import org.jetbrains.kotlin.konan.library.impl.CombinedIrFileWriter
|
import org.jetbrains.kotlin.konan.library.impl.CombinedIrFileWriter
|
||||||
import org.jetbrains.kotlin.konan.library.impl.DeclarationId
|
import org.jetbrains.kotlin.konan.library.impl.DeclarationId
|
||||||
import org.jetbrains.kotlin.metadata.KonanIr
|
import org.jetbrains.kotlin.metadata.KonanIr
|
||||||
@@ -1058,6 +1063,7 @@ internal class IrModuleSerializer(
|
|||||||
val proto = KonanIr.IrFile.newBuilder()
|
val proto = KonanIr.IrFile.newBuilder()
|
||||||
.setFileEntry(serializeFileEntry(file.fileEntry))
|
.setFileEntry(serializeFileEntry(file.fileEntry))
|
||||||
.setFqName(serializeString(file.fqName.toString()))
|
.setFqName(serializeString(file.fqName.toString()))
|
||||||
|
.setAnnotations(serializeAnnotations(file.annotations))
|
||||||
|
|
||||||
file.declarations.forEach {
|
file.declarations.forEach {
|
||||||
if (it is IrTypeAlias || (it.descriptor.isExpectMember && !it.descriptor.isSerializableExpectClass)) {
|
if (it is IrTypeAlias || (it.descriptor.isExpectMember && !it.descriptor.isSerializableExpectClass)) {
|
||||||
@@ -1070,6 +1076,26 @@ internal class IrModuleSerializer(
|
|||||||
writer.addDeclaration(DeclarationId(uniqId.index, uniqId.isLocal), byteArray)
|
writer.addDeclaration(DeclarationId(uniqId.index, uniqId.isLocal), byteArray)
|
||||||
proto.addDeclarationId(protoUniqId(uniqId))
|
proto.addDeclarationId(protoUniqId(uniqId))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
file.acceptVoid(object: IrElementVisitorVoid {
|
||||||
|
override fun visitElement(element: IrElement) {
|
||||||
|
element.acceptChildrenVoid(this)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun visitFunction(declaration: IrFunction) {
|
||||||
|
if (declaration.descriptor.annotations.hasAnnotation(RuntimeNames.exportForCppRuntime)
|
||||||
|
|| declaration.descriptor.annotations.hasAnnotation(RuntimeNames.exportForCompilerAnnotation))
|
||||||
|
proto.addExplicitlyExportedToCompiler(serializeIrSymbol(declaration.symbol))
|
||||||
|
super.visitDeclaration(declaration)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun visitClass(declaration: IrClass) {
|
||||||
|
if (declaration.descriptor.annotations.hasAnnotation(RuntimeNames.exportTypeInfoAnnotation))
|
||||||
|
proto.addExplicitlyExportedToCompiler(serializeIrSymbol(declaration.symbol))
|
||||||
|
super.visitDeclaration(declaration)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
return proto.build()
|
return proto.build()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+2
@@ -89,6 +89,8 @@ message IrFile {
|
|||||||
repeated UniqId declaration_id = 1;
|
repeated UniqId declaration_id = 1;
|
||||||
required FileEntry file_entry = 2;
|
required FileEntry file_entry = 2;
|
||||||
required String fq_name = 3;
|
required String fq_name = 3;
|
||||||
|
required Annotations annotations = 4;
|
||||||
|
repeated IrSymbol explicitly_exported_to_compiler = 5; // Symbols referenced by C runtime. TODO: Make an extension?
|
||||||
}
|
}
|
||||||
|
|
||||||
message IrModule {
|
message IrModule {
|
||||||
|
|||||||
+19
-6
@@ -309,7 +309,7 @@ class KonanIrModuleDeserializer(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun deserializeIrFile(fileProto: KonanIr.IrFile, moduleDescriptor: ModuleDescriptor, deserializeAllDeclarations: Boolean): IrFile {
|
fun deserializeIrFile(fileProto: KonanIr.IrFile, moduleDescriptor: ModuleDescriptor, deseralizationStrategy: DeserializationStrategy): IrFile {
|
||||||
val fileEntry = NaiveSourceBasedFileEntryImpl(
|
val fileEntry = NaiveSourceBasedFileEntryImpl(
|
||||||
deserializeString(fileProto.fileEntry.name),
|
deserializeString(fileProto.fileEntry.name),
|
||||||
fileProto.fileEntry.lineStartOffsetsList.toIntArray()
|
fileProto.fileEntry.lineStartOffsetsList.toIntArray()
|
||||||
@@ -327,15 +327,22 @@ class KonanIrModuleDeserializer(
|
|||||||
val uniqIdKey = it.uniqIdKey(moduleDescriptor)
|
val uniqIdKey = it.uniqIdKey(moduleDescriptor)
|
||||||
reversedFileIndex.put(uniqIdKey, file)
|
reversedFileIndex.put(uniqIdKey, file)
|
||||||
|
|
||||||
if (deserializeAllDeclarations) {
|
if (deseralizationStrategy == DeserializationStrategy.ALL) {
|
||||||
file.declarations.add(deserializeTopLevelDeclaration(uniqIdKey))
|
file.declarations.add(deserializeTopLevelDeclaration(uniqIdKey))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val annotations = deserializeAnnotations(fileProto.annotations)
|
||||||
|
file.annotations.addAll(annotations)
|
||||||
|
|
||||||
|
|
||||||
|
if (deseralizationStrategy == DeserializationStrategy.EXPLICITLY_EXPORTED)
|
||||||
|
fileProto.explicitlyExportedToCompilerList.forEach { deserializeIrSymbol(it) }
|
||||||
|
|
||||||
return file
|
return file
|
||||||
}
|
}
|
||||||
|
|
||||||
fun deserializeIrModule(proto: KonanIr.IrModule, moduleDescriptor: ModuleDescriptor, deserializeAllDeclarations: Boolean): IrModuleFragment {
|
fun deserializeIrModuleHeader(proto: KonanIr.IrModule, moduleDescriptor: ModuleDescriptor, deserializationStrategy: DeserializationStrategy): IrModuleFragment {
|
||||||
|
|
||||||
deserializedModuleDescriptor = moduleDescriptor
|
deserializedModuleDescriptor = moduleDescriptor
|
||||||
deserializedModuleProtoSymbolTables.put(moduleDescriptor, proto.symbolTable)
|
deserializedModuleProtoSymbolTables.put(moduleDescriptor, proto.symbolTable)
|
||||||
@@ -343,7 +350,7 @@ class KonanIrModuleDeserializer(
|
|||||||
deserializedModuleProtoTypeTables.put(moduleDescriptor, proto.typeTable)
|
deserializedModuleProtoTypeTables.put(moduleDescriptor, proto.typeTable)
|
||||||
|
|
||||||
val files = proto.fileList.map {
|
val files = proto.fileList.map {
|
||||||
deserializeIrFile(it, moduleDescriptor, deserializeAllDeclarations)
|
deserializeIrFile(it, moduleDescriptor, deserializationStrategy)
|
||||||
|
|
||||||
}
|
}
|
||||||
val module = IrModuleFragmentImpl(moduleDescriptor, builtIns, files)
|
val module = IrModuleFragmentImpl(moduleDescriptor, builtIns, files)
|
||||||
@@ -351,8 +358,14 @@ class KonanIrModuleDeserializer(
|
|||||||
return module
|
return module
|
||||||
}
|
}
|
||||||
|
|
||||||
fun deserializeIrModule(moduleDescriptor: ModuleDescriptor, byteArray: ByteArray, deserializeAllDeclarations: Boolean = false): IrModuleFragment {
|
fun deserializeIrModuleHeader(moduleDescriptor: ModuleDescriptor, byteArray: ByteArray, deserializationStrategy: DeserializationStrategy = DeserializationStrategy.ONLY_REFERENCED): IrModuleFragment {
|
||||||
val proto = KonanIr.IrModule.parseFrom(byteArray.codedInputStream, KonanSerializerProtocol.extensionRegistry)
|
val proto = KonanIr.IrModule.parseFrom(byteArray.codedInputStream, KonanSerializerProtocol.extensionRegistry)
|
||||||
return deserializeIrModule(proto, moduleDescriptor, deserializeAllDeclarations)
|
return deserializeIrModuleHeader(proto, moduleDescriptor, deserializationStrategy)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum class DeserializationStrategy {
|
||||||
|
ONLY_REFERENCED,
|
||||||
|
ALL,
|
||||||
|
EXPLICITLY_EXPORTED
|
||||||
|
}
|
||||||
-2
@@ -53,8 +53,6 @@ internal class KonanSerializerExtension(val context: Context, override val metad
|
|||||||
override fun serializeEnumEntry(descriptor: ClassDescriptor, proto: ProtoBuf.EnumEntry.Builder) {
|
override fun serializeEnumEntry(descriptor: ClassDescriptor, proto: ProtoBuf.EnumEntry.Builder) {
|
||||||
uniqId(descriptor) ?.let { proto.setExtension(KonanProtoBuf.enumEntryUniqId, it) }
|
uniqId(descriptor) ?.let { proto.setExtension(KonanProtoBuf.enumEntryUniqId, it) }
|
||||||
// Serialization doesn't preserve enum entry order, so we need to serialize ordinal.
|
// Serialization doesn't preserve enum entry order, so we need to serialize ordinal.
|
||||||
val ordinal = context.specialDeclarationsFactory.getEnumEntryOrdinal(descriptor)
|
|
||||||
proto.setExtension(KonanProtoBuf.enumEntryOrdinal, ordinal)
|
|
||||||
super.serializeEnumEntry(descriptor, proto)
|
super.serializeEnumEntry(descriptor, proto)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -340,7 +340,6 @@ targetList.each { target ->
|
|||||||
task("${target}CrossDistRuntime", type: Copy) {
|
task("${target}CrossDistRuntime", type: Copy) {
|
||||||
dependsOn ":runtime:${target}Runtime"
|
dependsOn ":runtime:${target}Runtime"
|
||||||
dependsOn ":backend.native:${target}Stdlib"
|
dependsOn ":backend.native:${target}Stdlib"
|
||||||
dependsOn ":backend.native:${target}Start"
|
|
||||||
|
|
||||||
destinationDir distDir
|
destinationDir distDir
|
||||||
|
|
||||||
@@ -357,10 +356,6 @@ targetList.each { target ->
|
|||||||
include('**')
|
include('**')
|
||||||
into(stdlib)
|
into(stdlib)
|
||||||
}
|
}
|
||||||
from(project(':runtime').file("build/${target}Start.bc")) {
|
|
||||||
rename("${target}Start.bc", 'start.bc')
|
|
||||||
into("konan/targets/$target/native")
|
|
||||||
}
|
|
||||||
if (target == 'wasm32') {
|
if (target == 'wasm32') {
|
||||||
into("$stdlib/targets/wasm32/included") {
|
into("$stdlib/targets/wasm32/included") {
|
||||||
from(project(':runtime').file('src/main/js'))
|
from(project(':runtime').file('src/main/js'))
|
||||||
|
|||||||
@@ -4,16 +4,18 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import kotlin.native.internal.ExportForCppRuntime
|
import kotlin.native.internal.ExportForCppRuntime
|
||||||
|
import kotlin.native.internal.TypedIntrinsic
|
||||||
|
import kotlin.native.internal.IntrinsicType
|
||||||
|
|
||||||
// This function is produced by the code generator given
|
// This function is produced by the code generator given
|
||||||
// the '-entry foo.bar.main' flag.
|
// the '-entry foo.bar.main' flag.
|
||||||
// It calls the requested entry point.
|
// It calls the requested entry point.
|
||||||
// The default is main(Array<String>):Unit in the root package.
|
// The default is main(Array<String>):Unit in the root package.
|
||||||
@SymbolName("EntryPointSelector")
|
@TypedIntrinsic(IntrinsicType.SELECT_ENTRY_POINT)
|
||||||
external fun EntryPointSelector(args: Array<String>)
|
private external fun EntryPointSelector(args: Array<String>)
|
||||||
|
|
||||||
@SymbolName("OnUnhandledException")
|
@SymbolName("OnUnhandledException")
|
||||||
external private fun OnUnhandledException(throwable: Throwable)
|
private external fun OnUnhandledException(throwable: Throwable)
|
||||||
|
|
||||||
@ExportForCppRuntime
|
@ExportForCppRuntime
|
||||||
private fun Konan_start(args: Array<String>): Int {
|
private fun Konan_start(args: Array<String>): Int {
|
||||||
|
|||||||
@@ -59,7 +59,7 @@ class AutoFree {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// RuntimeUtiks.kt
|
// RuntimeUtils.kt
|
||||||
extern "C" void ReportUnhandledException(KRef throwable);
|
extern "C" void ReportUnhandledException(KRef throwable);
|
||||||
extern "C" void ExceptionReporterLaunchpad(KRef reporter, KRef throwable);
|
extern "C" void ExceptionReporterLaunchpad(KRef reporter, KRef throwable);
|
||||||
|
|
||||||
|
|||||||
@@ -52,6 +52,7 @@ class IntrinsicType {
|
|||||||
const val IDENTITY = "IDENTITY"
|
const val IDENTITY = "IDENTITY"
|
||||||
const val IMMUTABLE_BLOB = "IMMUTABLE_BLOB"
|
const val IMMUTABLE_BLOB = "IMMUTABLE_BLOB"
|
||||||
const val INIT_INSTANCE = "INIT_INSTANCE"
|
const val INIT_INSTANCE = "INIT_INSTANCE"
|
||||||
|
const val SELECT_ENTRY_POINT = "SELECT_ENTRY_POINT"
|
||||||
|
|
||||||
const val GET_CONTINUATION = "GET_CONTINUATION"
|
const val GET_CONTINUATION = "GET_CONTINUATION"
|
||||||
const val RETURN_IF_SUSPEND = "RETURN_IF_SUSPEND"
|
const val RETURN_IF_SUSPEND = "RETURN_IF_SUSPEND"
|
||||||
|
|||||||
@@ -81,7 +81,7 @@ class Distribution(
|
|||||||
|
|
||||||
fun runtime(target: KonanTarget) = runtimeFileOverride ?: "$stdlib/targets/${target.visibleName}/native/runtime.bc"
|
fun runtime(target: KonanTarget) = runtimeFileOverride ?: "$stdlib/targets/${target.visibleName}/native/runtime.bc"
|
||||||
|
|
||||||
val launcherFiles = listOf("start.bc", "launcher.bc")
|
val launcherFiles = listOf("launcher.bc")
|
||||||
|
|
||||||
val dependenciesDir = DependencyProcessor.defaultDependenciesRoot.absolutePath
|
val dependenciesDir = DependencyProcessor.defaultDependenciesRoot.absolutePath
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user