diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/Context.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/Context.kt index 40324439529..288dba71a35 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/Context.kt +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/Context.kt @@ -156,10 +156,14 @@ internal class SpecialDeclarationsFactory(val context: Context) { internal class Context(config: KonanConfig) : KonanBackendContext(config) { lateinit var moduleDescriptor: ModuleDescriptor - override val builtIns: KonanBuiltIns by lazy(PUBLICATION) { moduleDescriptor.builtIns as KonanBuiltIns } + override val builtIns: KonanBuiltIns by lazy(PUBLICATION) { + moduleDescriptor.builtIns as KonanBuiltIns + } val specialDeclarationsFactory = SpecialDeclarationsFactory(this) - override val reflectionTypes: ReflectionTypes by lazy(PUBLICATION) { ReflectionTypes(moduleDescriptor, FqName("konan.internal")) } + override val reflectionTypes: ReflectionTypes by lazy(PUBLICATION) { + ReflectionTypes(moduleDescriptor, FqName("konan.internal")) + } private val vtableBuilders = mutableMapOf() fun getVtableBuilder(classDescriptor: ClassDescriptor) = vtableBuilders.getOrPut(classDescriptor) { @@ -182,9 +186,16 @@ internal class Context(config: KonanConfig) : KonanBackendContext(config) { config.librariesWithDependencies(moduleDescriptor) } + fun needGlobalInit(field: IrField): Boolean { + if (field.descriptor.containingDeclaration !is PackageFragmentDescriptor) return false + // TODO: add some smartness here. Maybe if package of the field is in never accessed + // assume its global init can be actually omitted. + return true + } + // TODO: make lateinit? var irModule: IrModuleFragment? = null - set(module: IrModuleFragment?) { + set(module) { if (field != null) { throw Error("Another IrModule in the context.") } @@ -203,7 +214,7 @@ internal class Context(config: KonanConfig) : KonanBackendContext(config) { } var llvmModule: LLVMModuleRef? = null - set(module: LLVMModuleRef?) { + set(module) { if (field != null) { throw Error("Another LLVMModule in the context.") } diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/CodeGenerator.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/CodeGenerator.kt index 8541cf9d12d..d14092333e4 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/CodeGenerator.kt +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/CodeGenerator.kt @@ -195,7 +195,7 @@ internal class FunctionGenerationContext(val function: LLVMValueRef, val value = LLVMBuildLoad(builder, address, name)!! if (isObjectRef(value) && isVar) { val slot = alloca(LLVMTypeOf(value), variableLocation = null) - storeAnyLocal(value, slot) + storeAny(value, slot) } return value } @@ -206,15 +206,7 @@ internal class FunctionGenerationContext(val function: LLVMValueRef, LLVMBuildStore(builder, value, ptr) } - fun storeAnyLocal(value: LLVMValueRef, ptr: LLVMValueRef) { - if (isObjectRef(value)) { - updateRef(value, ptr) - } else { - LLVMBuildStore(builder, value, ptr) - } - } - - fun storeAnyGlobal(value: LLVMValueRef, ptr: LLVMValueRef) { + fun storeAny(value: LLVMValueRef, ptr: LLVMValueRef) { if (isObjectRef(value)) { updateRef(value, ptr) } else { diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/ContextUtils.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/ContextUtils.kt index a3158c5acbc..b7d68f74a2c 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/ContextUtils.kt +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/ContextUtils.kt @@ -25,7 +25,7 @@ import org.jetbrains.kotlin.descriptors.ClassDescriptor import org.jetbrains.kotlin.descriptors.DeclarationDescriptor import org.jetbrains.kotlin.descriptors.FunctionDescriptor import org.jetbrains.kotlin.descriptors.impl.TypeAliasConstructorDescriptor -import org.jetbrains.kotlin.ir.IrElement +import org.jetbrains.kotlin.ir.declarations.IrField import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.resolve.descriptorUtil.module @@ -343,5 +343,5 @@ internal class Llvm(val context: Context, val llvmModule: LLVMModuleRef) { val usedFunctions = mutableListOf() val staticInitializers = mutableListOf() - val fileInitializers = mutableListOf() + val fileInitializers = mutableListOf() } diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/IrToBitcode.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/IrToBitcode.kt index 50a78d5a4ff..1a2d9856a35 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/IrToBitcode.kt +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/IrToBitcode.kt @@ -34,7 +34,6 @@ import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.declarations.impl.IrValueParameterImpl import org.jetbrains.kotlin.ir.descriptors.IrBuiltinOperatorDescriptorBase import org.jetbrains.kotlin.ir.expressions.* -import org.jetbrains.kotlin.ir.expressions.impl.IrGetValueImpl import org.jetbrains.kotlin.ir.expressions.impl.IrReturnableBlockImpl import org.jetbrains.kotlin.ir.util.getArguments import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid @@ -286,7 +285,7 @@ internal class CodeGeneratorVisitor(val context: Context, val lifetimes: Map } .forEach { - val descriptor = it.descriptor - val initialization = evaluateExpression(it.initializer!!.expression) - val globalPtr = context.llvmDeclarations.forStaticField(descriptor).storage - storeAnyGlobal(initialization, globalPtr) + if (it.initializer?.expression !is IrConst<*>?) { + val initialization = evaluateExpression(it.initializer!!.expression) + val address = context.llvmDeclarations.forStaticField(it.descriptor).storage + storeAny(initialization, address) + } } ret(null) } @@ -327,7 +324,7 @@ internal class CodeGeneratorVisitor(val context: Context, val lifetimes: Map) { @@ -640,10 +638,8 @@ internal class CodeGeneratorVisitor(val context: Context, val lifetimes: Map): LLVMValueRef { + private fun delegatingConstructorCall( + descriptor: ClassConstructorDescriptor, args: List): LLVMValueRef { val constructedClass = functionGenerationContext.constructedClass!! val thisPtr = currentCodeContext.genGetValue(constructedClass.thisAsReceiverParameter) @@ -2359,7 +2355,7 @@ internal class CodeGeneratorVisitor(val context: Context, val lifetimes: Map) { + private fun appendLlvmUsed(args: List) { if (args.isEmpty()) return memScoped { @@ -2374,7 +2370,7 @@ internal class CodeGeneratorVisitor(val context: Context, val lifetimes: Map, CharSequence { } // TODO: in big Kotlin this operations are in kotlin.kotlin_builtins. -private val kNullString = "null" +private fun nullString() = "null" public operator fun kotlin.String?.plus(other: kotlin.Any?): kotlin.String = - (this?.toString() ?: kNullString).plus(other?.toString() ?: kNullString) + (this?.toString() ?: nullString()).plus(other?.toString() ?: nullString()) -public fun Any?.toString() = this?.toString() ?: kNullString \ No newline at end of file +public fun Any?.toString() = this?.toString() ?: nullString() \ No newline at end of file