Inlined ir-as-descriptors typedefs.

This commit is contained in:
Alexander Gorshenev
2019-01-25 21:34:54 +03:00
committed by alexander-gorshenev
parent f54f570fbf
commit 9565420c7a
16 changed files with 166 additions and 200 deletions
@@ -9,10 +9,7 @@ import org.jetbrains.kotlin.backend.konan.ir.KonanSymbols
import org.jetbrains.kotlin.backend.konan.irasdescriptors.* import org.jetbrains.kotlin.backend.konan.irasdescriptors.*
import org.jetbrains.kotlin.builtins.KotlinBuiltIns import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.ir.IrStatement import org.jetbrains.kotlin.ir.IrStatement
import org.jetbrains.kotlin.ir.declarations.IrField import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.declarations.IrFunction
import org.jetbrains.kotlin.ir.declarations.IrValueDeclaration
import org.jetbrains.kotlin.ir.declarations.IrVariable
import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns
import org.jetbrains.kotlin.ir.expressions.* import org.jetbrains.kotlin.ir.expressions.*
import org.jetbrains.kotlin.ir.symbols.* import org.jetbrains.kotlin.ir.symbols.*
@@ -48,7 +45,7 @@ internal abstract class AbstractValueUsageTransformer(
protected open fun IrExpression.useAsValue(value: IrValueDeclaration): IrExpression = this.useAs(value.type) protected open fun IrExpression.useAsValue(value: IrValueDeclaration): IrExpression = this.useAs(value.type)
protected open fun IrExpression.useAsArgument(parameter: ParameterDescriptor): IrExpression = protected open fun IrExpression.useAsArgument(parameter: IrValueParameter): IrExpression =
this.useAsValue(parameter) this.useAsValue(parameter)
protected open fun IrExpression.useAsDispatchReceiver(expression: IrFunctionAccessExpression): IrExpression = protected open fun IrExpression.useAsDispatchReceiver(expression: IrFunctionAccessExpression): IrExpression =
@@ -58,10 +55,11 @@ internal abstract class AbstractValueUsageTransformer(
this.useAsArgument(expression.symbol.owner.extensionReceiverParameter!!) this.useAsArgument(expression.symbol.owner.extensionReceiverParameter!!)
protected open fun IrExpression.useAsValueArgument(expression: IrFunctionAccessExpression, protected open fun IrExpression.useAsValueArgument(expression: IrFunctionAccessExpression,
parameter: ValueParameterDescriptor): IrExpression = parameter: IrValueParameter
): IrExpression =
this.useAsArgument(parameter) this.useAsArgument(parameter)
private fun IrExpression.useForVariable(variable: VariableDescriptor): IrExpression = private fun IrExpression.useForVariable(variable: IrVariable): IrExpression =
this.useAsValue(variable) this.useAsValue(variable)
private fun IrExpression.useForField(field: IrField): IrExpression = private fun IrExpression.useForField(field: IrField): IrExpression =
@@ -12,6 +12,7 @@ import org.jetbrains.kotlin.backend.konan.llvm.localHash
import org.jetbrains.kotlin.backend.konan.lower.bridgeTarget import org.jetbrains.kotlin.backend.konan.lower.bridgeTarget
import org.jetbrains.kotlin.descriptors.Modality import org.jetbrains.kotlin.descriptors.Modality
import org.jetbrains.kotlin.ir.declarations.IrClass import org.jetbrains.kotlin.ir.declarations.IrClass
import org.jetbrains.kotlin.ir.declarations.IrFunction
import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction
import org.jetbrains.kotlin.ir.util.simpleFunctions import org.jetbrains.kotlin.ir.util.simpleFunctions
@@ -77,7 +78,7 @@ internal class OverriddenFunctionDescriptor(
} }
} }
internal class ClassVtablesBuilder(val classDescriptor: ClassDescriptor, val context: Context) { internal class ClassVtablesBuilder(val classDescriptor: IrClass, val context: Context) {
private val DEBUG = 0 private val DEBUG = 0
private inline fun DEBUG_OUTPUT(severity: Int, block: () -> Unit) { private inline fun DEBUG_OUTPUT(severity: Int, block: () -> Unit) {
@@ -178,7 +179,7 @@ internal class ClassVtablesBuilder(val classDescriptor: ClassDescriptor, val con
&& it.bridgeTarget == null } && it.bridgeTarget == null }
.sortedBy { it.uniqueId } .sortedBy { it.uniqueId }
private val functionIds = mutableMapOf<FunctionDescriptor, Long>() private val functionIds = mutableMapOf<IrFunction, Long>()
private val FunctionDescriptor.uniqueId get() = functionIds.getOrPut(this) { functionName.localHash.value } private val IrFunction.uniqueId get() = functionIds.getOrPut(this) { functionName.localHash.value }
} }
@@ -7,24 +7,16 @@ package org.jetbrains.kotlin.backend.konan.descriptors
import org.jetbrains.kotlin.backend.common.ir.ir2stringWhole import org.jetbrains.kotlin.backend.common.ir.ir2stringWhole
import org.jetbrains.kotlin.backend.konan.irasdescriptors.* import org.jetbrains.kotlin.backend.konan.irasdescriptors.*
import org.jetbrains.kotlin.backend.konan.irasdescriptors.ClassDescriptor
import org.jetbrains.kotlin.backend.konan.irasdescriptors.ConstructorDescriptor
import org.jetbrains.kotlin.backend.konan.irasdescriptors.DeclarationDescriptor
import org.jetbrains.kotlin.backend.konan.irasdescriptors.FunctionDescriptor
import org.jetbrains.kotlin.backend.konan.irasdescriptors.PackageFragmentDescriptor
import org.jetbrains.kotlin.backend.konan.isInlined import org.jetbrains.kotlin.backend.konan.isInlined
import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.ir.declarations.IrDeclaration import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.declarations.IrField
import org.jetbrains.kotlin.ir.declarations.IrFile
import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction
import org.jetbrains.kotlin.ir.types.isUnit import org.jetbrains.kotlin.ir.types.isUnit
import org.jetbrains.kotlin.types.SimpleType import org.jetbrains.kotlin.types.SimpleType
/** /**
* List of all implemented interfaces (including those which implemented by a super class) * List of all implemented interfaces (including those which implemented by a super class)
*/ */
internal val ClassDescriptor.implementedInterfaces: List<ClassDescriptor> internal val IrClass.implementedInterfaces: List<IrClass>
get() { get() {
val superClassImplementedInterfaces = this.getSuperClassNotAny()?.implementedInterfaces ?: emptyList() val superClassImplementedInterfaces = this.getSuperClassNotAny()?.implementedInterfaces ?: emptyList()
val superInterfaces = this.getSuperInterfaces() val superInterfaces = this.getSuperInterfaces()
@@ -79,10 +71,10 @@ internal fun IrSimpleFunction.resolveFakeOverride(allowAbstract: Boolean = false
} }
// TODO: don't forget to remove descriptor access here. // TODO: don't forget to remove descriptor access here.
internal val FunctionDescriptor.isTypedIntrinsic: Boolean internal val IrFunction.isTypedIntrinsic: Boolean
get() = this.descriptor.isTypedIntrinsic get() = this.descriptor.isTypedIntrinsic
internal val DeclarationDescriptor.isFrozen: Boolean internal val IrDeclaration.isFrozen: Boolean
get() = this.descriptor.isFrozen get() = this.descriptor.isFrozen
internal val arrayTypes = setOf( internal val arrayTypes = setOf(
@@ -100,17 +92,17 @@ internal val arrayTypes = setOf(
) )
internal val ClassDescriptor.isArray: Boolean internal val IrClass.isArray: Boolean
get() = this.fqNameSafe.asString() in arrayTypes get() = this.fqNameSafe.asString() in arrayTypes
internal val ClassDescriptor.isInterface: Boolean internal val IrClass.isInterface: Boolean
get() = (this.kind == ClassKind.INTERFACE) get() = (this.kind == ClassKind.INTERFACE)
fun ClassDescriptor.isAbstract() = this.modality == Modality.SEALED || this.modality == Modality.ABSTRACT fun IrClass.isAbstract() = this.modality == Modality.SEALED || this.modality == Modality.ABSTRACT
|| this.kind == ClassKind.ENUM_CLASS || this.kind == ClassKind.ENUM_CLASS
internal fun FunctionDescriptor.hasValueTypeAt(index: Int): Boolean { internal fun IrFunction.hasValueTypeAt(index: Int): Boolean {
when (index) { when (index) {
0 -> return !isSuspend && returnType.let { (it.isInlined() || it.isUnit()) } 0 -> return !isSuspend && returnType.let { (it.isInlined() || it.isUnit()) }
1 -> return dispatchReceiverParameter.let { it != null && it.type.isInlined() } 1 -> return dispatchReceiverParameter.let { it != null && it.type.isInlined() }
@@ -119,7 +111,7 @@ internal fun FunctionDescriptor.hasValueTypeAt(index: Int): Boolean {
} }
} }
internal fun FunctionDescriptor.hasReferenceAt(index: Int): Boolean { internal fun IrFunction.hasReferenceAt(index: Int): Boolean {
when (index) { when (index) {
0 -> return isSuspend || returnType.let { !it.isInlined() && !it.isUnit() } 0 -> return isSuspend || returnType.let { !it.isInlined() && !it.isUnit() }
1 -> return dispatchReceiverParameter.let { it != null && !it.type.isInlined() } 1 -> return dispatchReceiverParameter.let { it != null && !it.type.isInlined() }
@@ -128,18 +120,19 @@ internal fun FunctionDescriptor.hasReferenceAt(index: Int): Boolean {
} }
} }
private fun FunctionDescriptor.needBridgeToAt(target: FunctionDescriptor, index: Int) private fun IrFunction.needBridgeToAt(target: IrFunction, index: Int)
= hasValueTypeAt(index) xor target.hasValueTypeAt(index) = hasValueTypeAt(index) xor target.hasValueTypeAt(index)
internal fun FunctionDescriptor.needBridgeTo(target: FunctionDescriptor) internal fun IrFunction.needBridgeTo(target: IrFunction)
= (0..this.valueParameters.size + 2).any { needBridgeToAt(target, it) } = (0..this.valueParameters.size + 2).any { needBridgeToAt(target, it) }
internal val IrSimpleFunction.target: IrSimpleFunction internal val IrSimpleFunction.target: IrSimpleFunction
get() = (if (modality == Modality.ABSTRACT) this else resolveFakeOverride()).original get() = (if (modality == Modality.ABSTRACT) this else resolveFakeOverride()).original
internal val FunctionDescriptor.target: FunctionDescriptor get() = when (this) { internal val IrFunction.target: IrFunction
get() = when (this) {
is IrSimpleFunction -> this.target is IrSimpleFunction -> this.target
is ConstructorDescriptor -> this is IrConstructor -> this
else -> error(this) else -> error(this)
} }
@@ -149,7 +142,7 @@ internal enum class BridgeDirection {
TO_VALUE_TYPE TO_VALUE_TYPE
} }
private fun FunctionDescriptor.bridgeDirectionToAt(target: FunctionDescriptor, index: Int) private fun IrFunction.bridgeDirectionToAt(target: IrFunction, index: Int)
= when { = when {
hasValueTypeAt(index) && target.hasReferenceAt(index) -> BridgeDirection.FROM_VALUE_TYPE hasValueTypeAt(index) && target.hasReferenceAt(index) -> BridgeDirection.FROM_VALUE_TYPE
hasReferenceAt(index) && target.hasValueTypeAt(index) -> BridgeDirection.TO_VALUE_TYPE hasReferenceAt(index) && target.hasValueTypeAt(index) -> BridgeDirection.TO_VALUE_TYPE
@@ -221,13 +214,13 @@ internal fun IrSimpleFunction.bridgeDirectionsTo(
return ourDirections return ourDirections
} }
tailrec internal fun DeclarationDescriptor.findPackage(): PackageFragmentDescriptor { tailrec internal fun IrDeclaration.findPackage(): IrPackageFragment {
val parent = this.parent val parent = this.parent
return parent as? PackageFragmentDescriptor return parent as? IrPackageFragment
?: (parent as DeclarationDescriptor).findPackage() ?: (parent as IrDeclaration).findPackage()
} }
fun FunctionDescriptor.isComparisonDescriptor(map: Map<SimpleType, IrSimpleFunction>): Boolean = fun IrFunction.isComparisonDescriptor(map: Map<SimpleType, IrSimpleFunction>): Boolean =
this in map.values this in map.values
val IrDeclaration.isPropertyAccessor get() = val IrDeclaration.isPropertyAccessor get() =
@@ -9,7 +9,6 @@ import org.jetbrains.kotlin.backend.konan.*
import org.jetbrains.kotlin.backend.konan.llvm.llvmSymbolOrigin import org.jetbrains.kotlin.backend.konan.llvm.llvmSymbolOrigin
import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.types.IrType import org.jetbrains.kotlin.ir.types.IrType
import org.jetbrains.kotlin.ir.types.classifierOrFail
import org.jetbrains.kotlin.ir.types.toKotlinType import org.jetbrains.kotlin.ir.types.toKotlinType
import org.jetbrains.kotlin.resolve.DescriptorUtils import org.jetbrains.kotlin.resolve.DescriptorUtils
import org.jetbrains.kotlin.resolve.descriptorUtil.module import org.jetbrains.kotlin.resolve.descriptorUtil.module
@@ -1,21 +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.irasdescriptors
import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.symbols.IrValueSymbol
internal typealias DeclarationDescriptor = IrDeclaration
internal typealias FunctionDescriptor = IrFunction
internal typealias ClassDescriptor = IrClass
internal typealias ConstructorDescriptor = IrConstructor
internal typealias ClassConstructorDescriptor = IrConstructor
internal typealias PackageFragmentDescriptor = IrPackageFragment
internal typealias VariableDescriptor = IrVariable
internal typealias ValueDescriptor = IrValueDeclaration
internal typealias ParameterDescriptor = IrValueParameter
internal typealias ValueParameterDescriptor = IrValueParameter
internal typealias TypeParameterDescriptor = IrTypeParameter
@@ -7,13 +7,11 @@ 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.getStringValue
import org.jetbrains.kotlin.backend.konan.descriptors.konanBackingField 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.ClassKind
import org.jetbrains.kotlin.descriptors.Modality import org.jetbrains.kotlin.descriptors.Modality
import org.jetbrains.kotlin.descriptors.ParameterDescriptor
import org.jetbrains.kotlin.descriptors.Visibilities import org.jetbrains.kotlin.descriptors.Visibilities
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.declarations.impl.IrFieldImpl
@@ -112,7 +112,7 @@ private val exportForCompilerAnnotation = FqName("kotlin.native.internal.ExportF
private val publishedApiAnnotation = FqName("kotlin.PublishedApi") private val publishedApiAnnotation = FqName("kotlin.PublishedApi")
private fun acyclicTypeMangler(visited: MutableSet<TypeParameterDescriptor>, type: IrType): String { private fun acyclicTypeMangler(visited: MutableSet<IrTypeParameter>, type: IrType): String {
val descriptor = (type.classifierOrNull as? IrTypeParameterSymbol)?.owner val descriptor = (type.classifierOrNull as? IrTypeParameterSymbol)?.owner
if (descriptor != null) { if (descriptor != null) {
val upperBounds = if (visited.contains(descriptor)) "" else { val upperBounds = if (visited.contains(descriptor)) "" else {
@@ -148,7 +148,7 @@ private fun acyclicTypeMangler(visited: MutableSet<TypeParameterDescriptor>, typ
} }
private fun typeToHashString(type: IrType) private fun typeToHashString(type: IrType)
= acyclicTypeMangler(mutableSetOf<TypeParameterDescriptor>(), type) = acyclicTypeMangler(mutableSetOf<IrTypeParameter>(), type)
internal val IrValueParameter.extensionReceiverNamePart: String internal val IrValueParameter.extensionReceiverNamePart: String
get() = "@${typeToHashString(this.type)}." get() = "@${typeToHashString(this.type)}."
@@ -12,9 +12,6 @@ import org.jetbrains.kotlin.backend.common.ir.ir2string
import org.jetbrains.kotlin.backend.konan.* import org.jetbrains.kotlin.backend.konan.*
import org.jetbrains.kotlin.backend.konan.descriptors.isInterface import org.jetbrains.kotlin.backend.konan.descriptors.isInterface
import org.jetbrains.kotlin.backend.konan.irasdescriptors.* import org.jetbrains.kotlin.backend.konan.irasdescriptors.*
import org.jetbrains.kotlin.backend.konan.irasdescriptors.ClassConstructorDescriptor
import org.jetbrains.kotlin.backend.konan.irasdescriptors.ClassDescriptor
import org.jetbrains.kotlin.backend.konan.irasdescriptors.FunctionDescriptor
import org.jetbrains.kotlin.backend.konan.llvm.objc.* import org.jetbrains.kotlin.backend.konan.llvm.objc.*
import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.declarations.*
@@ -24,7 +21,7 @@ import org.jetbrains.kotlin.backend.konan.descriptors.resolveFakeOverride
internal class CodeGenerator(override val context: Context) : ContextUtils { internal class CodeGenerator(override val context: Context) : ContextUtils {
fun llvmFunction(function: FunctionDescriptor): LLVMValueRef = function.llvmFunction fun llvmFunction(function: IrFunction): LLVMValueRef = function.llvmFunction
val intPtrType = LLVMIntPtrType(llvmTargetData)!! val intPtrType = LLVMIntPtrType(llvmTargetData)!!
internal val immOneIntPtrType = LLVMConstInt(intPtrType, 1, 1)!! internal val immOneIntPtrType = LLVMConstInt(intPtrType, 1, 1)!!
// Keep in sync with OBJECT_TAG_MASK in C++. // Keep in sync with OBJECT_TAG_MASK in C++.
@@ -33,19 +30,19 @@ internal class CodeGenerator(override val context: Context) : ContextUtils {
//-------------------------------------------------------------------------// //-------------------------------------------------------------------------//
/* to class descriptor */ /* to class descriptor */
fun typeInfoValue(descriptor: ClassDescriptor): LLVMValueRef = descriptor.llvmTypeInfoPtr fun typeInfoValue(descriptor: IrClass): LLVMValueRef = descriptor.llvmTypeInfoPtr
fun param(fn: FunctionDescriptor, i: Int): LLVMValueRef { fun param(fn: IrFunction, i: Int): LLVMValueRef {
assert(i >= 0 && i < countParams(fn)) assert(i >= 0 && i < countParams(fn))
return LLVMGetParam(fn.llvmFunction, i)!! return LLVMGetParam(fn.llvmFunction, i)!!
} }
private fun countParams(fn: FunctionDescriptor) = LLVMCountParams(fn.llvmFunction) private fun countParams(fn: IrFunction) = LLVMCountParams(fn.llvmFunction)
fun functionEntryPointAddress(descriptor: FunctionDescriptor) = descriptor.entryPointAddress.llvm fun functionEntryPointAddress(descriptor: IrFunction) = descriptor.entryPointAddress.llvm
fun functionHash(descriptor: FunctionDescriptor): LLVMValueRef = descriptor.functionName.localHash.llvm fun functionHash(descriptor: IrFunction): LLVMValueRef = descriptor.functionName.localHash.llvm
fun getObjectInstanceStorage(descriptor: ClassDescriptor, shared: Boolean): LLVMValueRef { fun getObjectInstanceStorage(descriptor: IrClass, shared: Boolean): LLVMValueRef {
assert (!descriptor.isUnit()) assert (!descriptor.isUnit())
val llvmGlobal = if (!isExternal(descriptor)) { val llvmGlobal = if (!isExternal(descriptor)) {
context.llvmDeclarations.forSingleton(descriptor).instanceFieldRef context.llvmDeclarations.forSingleton(descriptor).instanceFieldRef
@@ -65,7 +62,7 @@ internal class CodeGenerator(override val context: Context) : ContextUtils {
return llvmGlobal return llvmGlobal
} }
fun getObjectInstanceShadowStorage(descriptor: ClassDescriptor): LLVMValueRef { fun getObjectInstanceShadowStorage(descriptor: IrClass): LLVMValueRef {
assert (!descriptor.isUnit()) assert (!descriptor.isUnit())
assert (descriptor.objectIsShared) assert (descriptor.objectIsShared)
val llvmGlobal = if (!isExternal(descriptor)) { val llvmGlobal = if (!isExternal(descriptor)) {
@@ -83,7 +80,7 @@ internal class CodeGenerator(override val context: Context) : ContextUtils {
return llvmGlobal return llvmGlobal
} }
fun typeInfoForAllocation(constructedClass: ClassDescriptor): LLVMValueRef { fun typeInfoForAllocation(constructedClass: IrClass): LLVMValueRef {
assert(!constructedClass.isObjCClass()) assert(!constructedClass.isObjCClass())
return typeInfoValue(constructedClass) return typeInfoValue(constructedClass)
} }
@@ -115,7 +112,7 @@ val LLVMValueRef.isConst:Boolean
internal inline fun<R> generateFunction(codegen: CodeGenerator, internal inline fun<R> generateFunction(codegen: CodeGenerator,
descriptor: FunctionDescriptor, descriptor: IrFunction,
startLocation: LocationInfo? = null, startLocation: LocationInfo? = null,
endLocation: LocationInfo? = null, endLocation: LocationInfo? = null,
code:FunctionGenerationContext.(FunctionGenerationContext) -> R) { code:FunctionGenerationContext.(FunctionGenerationContext) -> R) {
@@ -161,7 +158,7 @@ internal class FunctionGenerationContext(val function: LLVMValueRef,
val codegen: CodeGenerator, val codegen: CodeGenerator,
startLocation: LocationInfo?, startLocation: LocationInfo?,
endLocation: LocationInfo?, endLocation: LocationInfo?,
internal val functionDescriptor: FunctionDescriptor? = null): ContextUtils { internal val functionDescriptor: IrFunction? = null): ContextUtils {
override val context = codegen.context override val context = codegen.context
val vars = VariableManager(this) val vars = VariableManager(this)
@@ -175,8 +172,8 @@ internal class FunctionGenerationContext(val function: LLVMValueRef,
var returnType: LLVMTypeRef? = LLVMGetReturnType(getFunctionType(function)) var returnType: LLVMTypeRef? = LLVMGetReturnType(getFunctionType(function))
private val returns: MutableMap<LLVMBasicBlockRef, LLVMValueRef> = mutableMapOf() private val returns: MutableMap<LLVMBasicBlockRef, LLVMValueRef> = mutableMapOf()
// TODO: remove, to make CodeGenerator descriptor-agnostic. // TODO: remove, to make CodeGenerator descriptor-agnostic.
val constructedClass: ClassDescriptor? val constructedClass: IrClass?
get() = (functionDescriptor as? ClassConstructorDescriptor)?.constructedClass get() = (functionDescriptor as? IrConstructor)?.constructedClass
private var returnSlot: LLVMValueRef? = null private var returnSlot: LLVMValueRef? = null
private var slotsPhi: LLVMValueRef? = null private var slotsPhi: LLVMValueRef? = null
private val frameOverlaySlotCount = private val frameOverlaySlotCount =
@@ -412,7 +409,7 @@ internal class FunctionGenerationContext(val function: LLVMValueRef,
return call(context.llvm.allocInstanceFunction, listOf(typeInfo), lifetime) return call(context.llvm.allocInstanceFunction, listOf(typeInfo), lifetime)
} }
fun allocInstance(descriptor: ClassDescriptor, lifetime: Lifetime): LLVMValueRef = fun allocInstance(descriptor: IrClass, lifetime: Lifetime): LLVMValueRef =
allocInstance(codegen.typeInfoForAllocation(descriptor), lifetime) allocInstance(codegen.typeInfoForAllocation(descriptor), lifetime)
fun allocArray( fun allocArray(
@@ -631,7 +628,7 @@ internal class FunctionGenerationContext(val function: LLVMValueRef,
return switch return switch
} }
fun lookupVirtualImpl(receiver: LLVMValueRef, descriptor: FunctionDescriptor): LLVMValueRef { fun lookupVirtualImpl(receiver: LLVMValueRef, descriptor: IrFunction): LLVMValueRef {
assert(LLVMTypeOf(receiver) == codegen.kObjHeaderPtr) assert(LLVMTypeOf(receiver) == codegen.kObjHeaderPtr)
val typeInfoPtr: LLVMValueRef = if (descriptor.getObjCMethodInfo() != null) { val typeInfoPtr: LLVMValueRef = if (descriptor.getObjCMethodInfo() != null) {
@@ -655,7 +652,7 @@ internal class FunctionGenerationContext(val function: LLVMValueRef,
* owner as Any and dispatch it via vtable. * owner as Any and dispatch it via vtable.
*/ */
val anyMethod = (descriptor as IrSimpleFunction).findOverriddenMethodOfAny() val anyMethod = (descriptor as IrSimpleFunction).findOverriddenMethodOfAny()
val owner = (anyMethod ?: descriptor).containingDeclaration as ClassDescriptor val owner = (anyMethod ?: descriptor).containingDeclaration as IrClass
val llvmMethod = if (!owner.isInterface) { val llvmMethod = if (!owner.isInterface) {
// If this is a virtual method of the class - we can call via vtable. // If this is a virtual method of the class - we can call via vtable.
@@ -680,7 +677,7 @@ internal class FunctionGenerationContext(val function: LLVMValueRef,
private fun IrSimpleFunction.findOverriddenMethodOfAny(): IrSimpleFunction? { private fun IrSimpleFunction.findOverriddenMethodOfAny(): IrSimpleFunction? {
if (modality == Modality.ABSTRACT) return null if (modality == Modality.ABSTRACT) return null
val resolved = resolveFakeOverride() val resolved = resolveFakeOverride()
if ((resolved.parent as ClassDescriptor).isAny()) { if ((resolved.parent as IrClass).isAny()) {
return resolved return resolved
} }
@@ -688,9 +685,9 @@ internal class FunctionGenerationContext(val function: LLVMValueRef,
} }
fun getObjectValue( fun getObjectValue(
descriptor: ClassDescriptor, descriptor: IrClass,
exceptionHandler: ExceptionHandler, exceptionHandler: ExceptionHandler,
locationInfo: LocationInfo? locationInfo: LocationInfo?
): LLVMValueRef { ): LLVMValueRef {
if (descriptor.isUnit()) { if (descriptor.isUnit()) {
return codegen.theUnitInstanceRef.llvm return codegen.theUnitInstanceRef.llvm
@@ -745,7 +742,7 @@ internal class FunctionGenerationContext(val function: LLVMValueRef,
* Note: the same code is generated as IR in [org.jetbrains.kotlin.backend.konan.lower.EnumUsageLowering]. * Note: the same code is generated as IR in [org.jetbrains.kotlin.backend.konan.lower.EnumUsageLowering].
*/ */
fun getEnumEntry(descriptor: IrEnumEntry, exceptionHandler: ExceptionHandler): LLVMValueRef { fun getEnumEntry(descriptor: IrEnumEntry, exceptionHandler: ExceptionHandler): LLVMValueRef {
val enumClassDescriptor = descriptor.containingDeclaration as ClassDescriptor val enumClassDescriptor = descriptor.containingDeclaration as IrClass
val loweredEnum = context.specialDeclarationsFactory.getLoweredEnum(enumClassDescriptor) val loweredEnum = context.specialDeclarationsFactory.getLoweredEnum(enumClassDescriptor)
val ordinal = loweredEnum.entriesMap[descriptor.name]!! val ordinal = loweredEnum.entriesMap[descriptor.name]!!
@@ -14,9 +14,7 @@ import org.jetbrains.kotlin.backend.konan.irasdescriptors.*
import org.jetbrains.kotlin.descriptors.konan.CompiledKonanModuleOrigin import org.jetbrains.kotlin.descriptors.konan.CompiledKonanModuleOrigin
import org.jetbrains.kotlin.descriptors.konan.CurrentKonanModuleOrigin import org.jetbrains.kotlin.descriptors.konan.CurrentKonanModuleOrigin
import org.jetbrains.kotlin.descriptors.konan.DeserializedKonanModuleOrigin import org.jetbrains.kotlin.descriptors.konan.DeserializedKonanModuleOrigin
import org.jetbrains.kotlin.ir.declarations.IrExternalPackageFragment import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.declarations.IrField
import org.jetbrains.kotlin.ir.declarations.IrFile
import org.jetbrains.kotlin.konan.library.KonanLibrary import org.jetbrains.kotlin.konan.library.KonanLibrary
import org.jetbrains.kotlin.konan.library.resolver.TopologicalLibraryOrder import org.jetbrains.kotlin.konan.library.resolver.TopologicalLibraryOrder
import org.jetbrains.kotlin.konan.target.KonanTarget import org.jetbrains.kotlin.konan.target.KonanTarget
@@ -143,7 +141,7 @@ internal interface ContextUtils : RuntimeAware {
val staticData: StaticData val staticData: StaticData
get() = context.llvm.staticData get() = context.llvm.staticData
fun isExternal(descriptor: DeclarationDescriptor): Boolean { fun isExternal(descriptor: IrDeclaration): Boolean {
val pkg = descriptor.findPackage() val pkg = descriptor.findPackage()
return when (pkg) { return when (pkg) {
is IrFile -> pkg.packageFragmentDescriptor.containingDeclaration != context.moduleDescriptor is IrFile -> pkg.packageFragmentDescriptor.containingDeclaration != context.moduleDescriptor
@@ -156,7 +154,7 @@ internal interface ContextUtils : RuntimeAware {
* LLVM function generated from the Kotlin function. * LLVM function generated from the Kotlin function.
* It may be declared as external function prototype. * It may be declared as external function prototype.
*/ */
val FunctionDescriptor.llvmFunction: LLVMValueRef val IrFunction.llvmFunction: LLVMValueRef
get() { get() {
assert(this.isReal) assert(this.isReal)
@@ -171,13 +169,13 @@ internal interface ContextUtils : RuntimeAware {
/** /**
* Address of entry point of [llvmFunction]. * Address of entry point of [llvmFunction].
*/ */
val FunctionDescriptor.entryPointAddress: ConstPointer val IrFunction.entryPointAddress: ConstPointer
get() { get() {
val result = LLVMConstBitCast(this.llvmFunction, int8TypePtr)!! val result = LLVMConstBitCast(this.llvmFunction, int8TypePtr)!!
return constPointer(result) return constPointer(result)
} }
val ClassDescriptor.typeInfoPtr: ConstPointer val IrClass.typeInfoPtr: ConstPointer
get() { get() {
return if (isExternal(this)) { return if (isExternal(this)) {
constPointer(importGlobal(this.typeInfoSymbolName, runtime.typeInfoType, constPointer(importGlobal(this.typeInfoSymbolName, runtime.typeInfoType,
@@ -191,7 +189,7 @@ internal interface ContextUtils : RuntimeAware {
* Pointer to type info for given class. * Pointer to type info for given class.
* It may be declared as pointer to external variable. * It may be declared as pointer to external variable.
*/ */
val ClassDescriptor.llvmTypeInfoPtr: LLVMValueRef val IrClass.llvmTypeInfoPtr: LLVMValueRef
get() = typeInfoPtr.llvm get() = typeInfoPtr.llvm
/** /**
@@ -12,10 +12,10 @@ import org.jetbrains.kotlin.backend.konan.SYNTHETIC_OFFSET
import org.jetbrains.kotlin.backend.konan.Context import org.jetbrains.kotlin.backend.konan.Context
import org.jetbrains.kotlin.backend.konan.KonanConfig import org.jetbrains.kotlin.backend.konan.KonanConfig
import org.jetbrains.kotlin.backend.konan.KonanConfigKeys import org.jetbrains.kotlin.backend.konan.KonanConfigKeys
import org.jetbrains.kotlin.backend.konan.irasdescriptors.FunctionDescriptor
import org.jetbrains.kotlin.builtins.KotlinBuiltIns import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.ir.SourceManager.FileEntry import org.jetbrains.kotlin.ir.SourceManager.FileEntry
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
import org.jetbrains.kotlin.ir.declarations.IrFunction
import org.jetbrains.kotlin.js.descriptorUtils.getJetTypeFqName import org.jetbrains.kotlin.js.descriptorUtils.getJetTypeFqName
import org.jetbrains.kotlin.konan.KonanVersion import org.jetbrains.kotlin.konan.KonanVersion
import org.jetbrains.kotlin.konan.file.File import org.jetbrains.kotlin.konan.file.File
@@ -200,7 +200,7 @@ private fun debugInfoBaseType(context:Context, targetData:LLVMTargetDataRef, typ
LLVMSizeOfTypeInBits(targetData, type), LLVMSizeOfTypeInBits(targetData, type),
LLVMPreferredAlignmentOfType(targetData, type).toLong(), encoding) as DITypeOpaqueRef LLVMPreferredAlignmentOfType(targetData, type).toLong(), encoding) as DITypeOpaqueRef
internal val FunctionDescriptor.types:List<KotlinType> internal val IrFunction.types:List<KotlinType>
get() { get() {
val parameters = descriptor.valueParameters.map{it.type} val parameters = descriptor.valueParameters.map{it.type}
return listOf(descriptor.returnType!!, *parameters.toTypedArray()) return listOf(descriptor.returnType!!, *parameters.toTypedArray())
@@ -223,7 +223,7 @@ internal fun KotlinType.encoding(context: Context): DwarfTypeKind = when {
internal fun alignTo(value:Long, align:Long):Long = (value + align - 1) / align * align internal fun alignTo(value:Long, align:Long):Long = (value + align - 1) / align * align
internal fun FunctionDescriptor.subroutineType(context: Context, llvmTargetData: LLVMTargetDataRef): DISubroutineTypeRef { internal fun IrFunction.subroutineType(context: Context, llvmTargetData: LLVMTargetDataRef): DISubroutineTypeRef {
val types = this@subroutineType.types val types = this@subroutineType.types
return subroutineType(context, llvmTargetData, types) return subroutineType(context, llvmTargetData, types)
} }
@@ -232,19 +232,19 @@ internal interface CodeContext {
* Declares the variable. * Declares the variable.
* @return index of declared variable. * @return index of declared variable.
*/ */
fun genDeclareVariable(descriptor: VariableDescriptor, value: LLVMValueRef?, variableLocation: VariableDebugLocation?): Int fun genDeclareVariable(descriptor: IrVariable, value: LLVMValueRef?, variableLocation: VariableDebugLocation?): Int
/** /**
* @return index of variable declared before, or -1 if no such variable has been declared yet. * @return index of variable declared before, or -1 if no such variable has been declared yet.
*/ */
fun getDeclaredVariable(descriptor: VariableDescriptor): Int fun getDeclaredVariable(descriptor: IrVariable): Int
/** /**
* Generates the code to obtain a value available in this context. * Generates the code to obtain a value available in this context.
* *
* @return the requested value * @return the requested value
*/ */
fun genGetValue(descriptor: ValueDescriptor): LLVMValueRef fun genGetValue(descriptor: IrValueDeclaration): LLVMValueRef
/** /**
* Returns owning function scope. * Returns owning function scope.
@@ -342,11 +342,11 @@ internal class CodeGeneratorVisitor(val context: Context, val lifetimes: Map<IrE
override fun genThrow(exception: LLVMValueRef) = unsupported() override fun genThrow(exception: LLVMValueRef) = unsupported()
override fun genDeclareVariable(descriptor: VariableDescriptor, value: LLVMValueRef?, variableLocation: VariableDebugLocation?) = unsupported(descriptor) override fun genDeclareVariable(descriptor: IrVariable, value: LLVMValueRef?, variableLocation: VariableDebugLocation?) = unsupported(descriptor)
override fun getDeclaredVariable(descriptor: VariableDescriptor) = -1 override fun getDeclaredVariable(descriptor: IrVariable) = -1
override fun genGetValue(descriptor: ValueDescriptor) = unsupported(descriptor) override fun genGetValue(descriptor: IrValueDeclaration) = unsupported(descriptor)
override fun functionScope(): CodeContext? = null override fun functionScope(): CodeContext? = null
@@ -622,16 +622,16 @@ internal class CodeGeneratorVisitor(val context: Context, val lifetimes: Map<IrE
*/ */
private inner class VariableScope : InnerScopeImpl() { private inner class VariableScope : InnerScopeImpl() {
override fun genDeclareVariable(descriptor: VariableDescriptor, value: LLVMValueRef?, variableLocation: VariableDebugLocation?): Int { override fun genDeclareVariable(descriptor: IrVariable, value: LLVMValueRef?, variableLocation: VariableDebugLocation?): Int {
return functionGenerationContext.vars.createVariable(descriptor, value, variableLocation) return functionGenerationContext.vars.createVariable(descriptor, value, variableLocation)
} }
override fun getDeclaredVariable(descriptor: VariableDescriptor): Int { override fun getDeclaredVariable(descriptor: IrVariable): Int {
val index = functionGenerationContext.vars.indexOf(descriptor) val index = functionGenerationContext.vars.indexOf(descriptor)
return if (index < 0) super.getDeclaredVariable(descriptor) else return index return if (index < 0) super.getDeclaredVariable(descriptor) else return index
} }
override fun genGetValue(descriptor: ValueDescriptor): LLVMValueRef { override fun genGetValue(descriptor: IrValueDeclaration): LLVMValueRef {
val index = functionGenerationContext.vars.indexOf(descriptor) val index = functionGenerationContext.vars.indexOf(descriptor)
if (index < 0) { if (index < 0) {
return super.genGetValue(descriptor) return super.genGetValue(descriptor)
@@ -664,7 +664,7 @@ internal class CodeGeneratorVisitor(val context: Context, val lifetimes: Map<IrE
} }
} }
override fun genGetValue(descriptor: ValueDescriptor): LLVMValueRef { override fun genGetValue(descriptor: IrValueDeclaration): LLVMValueRef {
val index = functionGenerationContext.vars.indexOf(descriptor) val index = functionGenerationContext.vars.indexOf(descriptor)
if (index < 0) { if (index < 0) {
return super.genGetValue(descriptor) return super.genGetValue(descriptor)
@@ -735,7 +735,7 @@ internal class CodeGeneratorVisitor(val context: Context, val lifetimes: Map<IrE
/** /**
* Binds LLVM function parameters to IR parameter descriptors. * Binds LLVM function parameters to IR parameter descriptors.
*/ */
private fun bindParameters(descriptor: FunctionDescriptor?): Map<ParameterDescriptor, LLVMValueRef> { private fun bindParameters(descriptor: IrFunction?): Map<IrValueParameter, LLVMValueRef> {
if (descriptor == null) return emptyMap() if (descriptor == null) return emptyMap()
val parameterDescriptors = descriptor.allParameters val parameterDescriptors = descriptor.allParameters
return parameterDescriptors.mapIndexed { i, parameterDescriptor -> return parameterDescriptors.mapIndexed { i, parameterDescriptor ->
@@ -1600,7 +1600,7 @@ internal class CodeGeneratorVisitor(val context: Context, val lifetimes: Map<IrE
private fun fieldPtrOfClass(thisPtr: LLVMValueRef, value: IrField): LLVMValueRef { private fun fieldPtrOfClass(thisPtr: LLVMValueRef, value: IrField): LLVMValueRef {
val fieldInfo = context.llvmDeclarations.forField(value) val fieldInfo = context.llvmDeclarations.forField(value)
val classDescriptor = value.containingDeclaration as ClassDescriptor val classDescriptor = value.containingDeclaration as IrClass
val typePtr = pointerType(fieldInfo.classBodyType) val typePtr = pointerType(fieldInfo.classBodyType)
val bodyPtr = getObjectBodyPtr(classDescriptor, thisPtr) val bodyPtr = getObjectBodyPtr(classDescriptor, thisPtr)
@@ -1610,7 +1610,7 @@ internal class CodeGeneratorVisitor(val context: Context, val lifetimes: Map<IrE
return fieldPtr!! return fieldPtr!!
} }
private fun getObjectBodyPtr(classDescriptor: ClassDescriptor, objectPtr: LLVMValueRef): LLVMValueRef { private fun getObjectBodyPtr(classDescriptor: IrClass, objectPtr: LLVMValueRef): LLVMValueRef {
return if (classDescriptor.isObjCClass()) { return if (classDescriptor.isObjCClass()) {
assert(classDescriptor.isKotlinObjCClass()) assert(classDescriptor.isKotlinObjCClass())
@@ -1920,7 +1920,7 @@ internal class CodeGeneratorVisitor(val context: Context, val lifetimes: Map<IrE
this.scope(startLine()) else null this.scope(startLine()) else null
@Suppress("UNCHECKED_CAST") @Suppress("UNCHECKED_CAST")
private fun FunctionDescriptor.scope(startLine:Int): DIScopeOpaqueRef? { private fun IrFunction.scope(startLine:Int): DIScopeOpaqueRef? {
if (codegen.isExternal(this) || !context.shouldContainDebugInfo()) if (codegen.isExternal(this) || !context.shouldContainDebugInfo())
return null return null
return context.debugInfo.subprograms.getOrPut(codegen.llvmFunction(this)) { return context.debugInfo.subprograms.getOrPut(codegen.llvmFunction(this)) {
@@ -1973,7 +1973,7 @@ internal class CodeGeneratorVisitor(val context: Context, val lifetimes: Map<IrE
} }
} }
private fun FunctionDescriptor.returnsUnit() = returnType.isUnit() && !isSuspend private fun IrFunction.returnsUnit() = returnType.isUnit() && !isSuspend
/** /**
* Evaluates all arguments of [expression] that are explicitly represented in the IR. * Evaluates all arguments of [expression] that are explicitly represented in the IR.
@@ -2047,10 +2047,10 @@ internal class CodeGeneratorVisitor(val context: Context, val lifetimes: Map<IrE
} }
} }
private inner class SuspensionPointScope(val suspensionPointId: VariableDescriptor, private inner class SuspensionPointScope(val suspensionPointId: IrVariable,
val bbResume: LLVMBasicBlockRef, val bbResume: LLVMBasicBlockRef,
val bbResumeId: Int): InnerScopeImpl() { val bbResumeId: Int): InnerScopeImpl() {
override fun genGetValue(descriptor: ValueDescriptor): LLVMValueRef { override fun genGetValue(descriptor: IrValueDeclaration): LLVMValueRef {
if (descriptor == suspensionPointId) { if (descriptor == suspensionPointId) {
return if (context.config.indirectBranchesAreAllowed) return if (context.config.indirectBranchesAreAllowed)
functionGenerationContext.blockAddress(bbResume) functionGenerationContext.blockAddress(bbResume)
@@ -2092,7 +2092,7 @@ internal class CodeGeneratorVisitor(val context: Context, val lifetimes: Map<IrE
return when { return when {
function.isTypedIntrinsic -> intrinsicGenerator.evaluateCall(callee, args) function.isTypedIntrinsic -> intrinsicGenerator.evaluateCall(callee, args)
function.origin == IrDeclarationOrigin.IR_BUILTINS_STUB -> evaluateOperatorCall(callee, argsWithContinuationIfNeeded) function.origin == IrDeclarationOrigin.IR_BUILTINS_STUB -> evaluateOperatorCall(callee, argsWithContinuationIfNeeded)
function is ConstructorDescriptor -> evaluateConstructorCall(callee, argsWithContinuationIfNeeded) function is IrConstructor -> evaluateConstructorCall(callee, argsWithContinuationIfNeeded)
else -> evaluateSimpleFunctionCall(function, argsWithContinuationIfNeeded, resultLifetime, callee.superQualifierSymbol?.owner) else -> evaluateSimpleFunctionCall(function, argsWithContinuationIfNeeded, resultLifetime, callee.superQualifierSymbol?.owner)
} }
} }
@@ -2141,8 +2141,8 @@ internal class CodeGeneratorVisitor(val context: Context, val lifetimes: Map<IrE
//-------------------------------------------------------------------------// //-------------------------------------------------------------------------//
private fun evaluateSimpleFunctionCall( private fun evaluateSimpleFunctionCall(
descriptor: FunctionDescriptor, args: List<LLVMValueRef>, descriptor: IrFunction, args: List<LLVMValueRef>,
resultLifetime: Lifetime, superClass: ClassDescriptor? = null): LLVMValueRef { resultLifetime: Lifetime, superClass: IrClass? = null): LLVMValueRef {
//context.log{"evaluateSimpleFunctionCall : $tmpVariableName = ${ir2string(value)}"} //context.log{"evaluateSimpleFunctionCall : $tmpVariableName = ${ir2string(value)}"}
if (superClass == null && descriptor is IrSimpleFunction && descriptor.isOverridable) if (superClass == null && descriptor is IrSimpleFunction && descriptor.isOverridable)
return callVirtual(descriptor, args, resultLifetime) return callVirtual(descriptor, args, resultLifetime)
@@ -2190,7 +2190,7 @@ internal class CodeGeneratorVisitor(val context: Context, val lifetimes: Map<IrE
} }
} }
private fun genGetObjCClass(classDescriptor: ClassDescriptor): LLVMValueRef { private fun genGetObjCClass(classDescriptor: IrClass): LLVMValueRef {
return functionGenerationContext.getObjCClass(classDescriptor, currentCodeContext.exceptionHandler) return functionGenerationContext.getObjCClass(classDescriptor, currentCodeContext.exceptionHandler)
} }
@@ -2251,7 +2251,7 @@ internal class CodeGeneratorVisitor(val context: Context, val lifetimes: Map<IrE
//-------------------------------------------------------------------------// //-------------------------------------------------------------------------//
fun callDirect(descriptor: FunctionDescriptor, args: List<LLVMValueRef>, fun callDirect(descriptor: IrFunction, args: List<LLVMValueRef>,
resultLifetime: Lifetime): LLVMValueRef { resultLifetime: Lifetime): LLVMValueRef {
val realDescriptor = descriptor.target val realDescriptor = descriptor.target
val llvmFunction = codegen.llvmFunction(realDescriptor) val llvmFunction = codegen.llvmFunction(realDescriptor)
@@ -2260,7 +2260,7 @@ internal class CodeGeneratorVisitor(val context: Context, val lifetimes: Map<IrE
//-------------------------------------------------------------------------// //-------------------------------------------------------------------------//
fun callVirtual(descriptor: FunctionDescriptor, args: List<LLVMValueRef>, fun callVirtual(descriptor: IrFunction, args: List<LLVMValueRef>,
resultLifetime: Lifetime): LLVMValueRef { resultLifetime: Lifetime): LLVMValueRef {
val function = functionGenerationContext.lookupVirtualImpl(args.first(), descriptor) val function = functionGenerationContext.lookupVirtualImpl(args.first(), descriptor)
@@ -2274,7 +2274,7 @@ internal class CodeGeneratorVisitor(val context: Context, val lifetimes: Map<IrE
// instead of a plain list. // instead of a plain list.
// In such case it would be possible to check that all args are available and in the correct order. // In such case it would be possible to check that all args are available and in the correct order.
// However, it currently requires some refactoring to be performed. // However, it currently requires some refactoring to be performed.
private fun call(descriptor: FunctionDescriptor, function: LLVMValueRef, args: List<LLVMValueRef>, private fun call(descriptor: IrFunction, function: LLVMValueRef, args: List<LLVMValueRef>,
resultLifetime: Lifetime): LLVMValueRef { resultLifetime: Lifetime): LLVMValueRef {
val result = call(function, args, resultLifetime) val result = call(function, args, resultLifetime)
if (descriptor.returnType.isNothing()) { if (descriptor.returnType.isNothing()) {
@@ -2315,7 +2315,7 @@ internal class CodeGeneratorVisitor(val context: Context, val lifetimes: Map<IrE
//-------------------------------------------------------------------------// //-------------------------------------------------------------------------//
private fun delegatingConstructorCall( private fun delegatingConstructorCall(
descriptor: ClassConstructorDescriptor, args: List<LLVMValueRef>): LLVMValueRef { descriptor: IrConstructor, args: List<LLVMValueRef>): LLVMValueRef {
val constructedClass = functionGenerationContext.constructedClass!! val constructedClass = functionGenerationContext.constructedClass!!
val thisPtr = currentCodeContext.genGetValue(constructedClass.thisReceiver!!) val thisPtr = currentCodeContext.genGetValue(constructedClass.thisReceiver!!)
@@ -2385,7 +2385,7 @@ internal class CodeGeneratorVisitor(val context: Context, val lifetimes: Map<IrE
//-------------------------------------------------------------------------// //-------------------------------------------------------------------------//
private fun appendEntryPointSelector(descriptor: FunctionDescriptor?) { private fun appendEntryPointSelector(descriptor: IrFunction?) {
if (descriptor == null) return if (descriptor == null) return
val entryPoint = codegen.llvmFunction(descriptor) val entryPoint = codegen.llvmFunction(descriptor)
@@ -36,15 +36,15 @@ enum class UniqueKind(val llvmName: String) {
} }
internal class LlvmDeclarations( internal class LlvmDeclarations(
private val functions: Map<FunctionDescriptor, FunctionLlvmDeclarations>, private val functions: Map<IrFunction, FunctionLlvmDeclarations>,
private val classes: Map<ClassDescriptor, ClassLlvmDeclarations>, private val classes: Map<IrClass, ClassLlvmDeclarations>,
private val fields: Map<IrField, FieldLlvmDeclarations>, private val fields: Map<IrField, FieldLlvmDeclarations>,
private val staticFields: Map<IrField, StaticFieldLlvmDeclarations>, private val staticFields: Map<IrField, StaticFieldLlvmDeclarations>,
private val unique: Map<UniqueKind, UniqueLlvmDeclarations>) { private val unique: Map<UniqueKind, UniqueLlvmDeclarations>) {
fun forFunction(descriptor: FunctionDescriptor) = functions[descriptor] ?: fun forFunction(descriptor: IrFunction) = functions[descriptor] ?:
error("${descriptor.toString()} ${descriptor.name} in ${(descriptor.parent as IrDeclaration).name}") error("${descriptor.toString()} ${descriptor.name} in ${(descriptor.parent as IrDeclaration).name}")
fun forClass(descriptor: ClassDescriptor) = classes[descriptor] ?: fun forClass(descriptor: IrClass) = classes[descriptor] ?:
error("$descriptor ${descriptor.name}") error("$descriptor ${descriptor.name}")
fun forField(descriptor: IrField) = fields[descriptor] ?: fun forField(descriptor: IrField) = fields[descriptor] ?:
@@ -53,7 +53,7 @@ internal class LlvmDeclarations(
fun forStaticField(descriptor: IrField) = staticFields[descriptor] ?: fun forStaticField(descriptor: IrField) = staticFields[descriptor] ?:
error(descriptor.toString()) error(descriptor.toString())
fun forSingleton(descriptor: ClassDescriptor) = forClass(descriptor).singletonDeclarations ?: fun forSingleton(descriptor: IrClass) = forClass(descriptor).singletonDeclarations ?:
error(descriptor.toString()) error(descriptor.toString())
fun forUnique(kind: UniqueKind) = unique[kind] ?: error("No unique $kind") fun forUnique(kind: UniqueKind) = unique[kind] ?: error("No unique $kind")
@@ -91,9 +91,9 @@ internal class UniqueLlvmDeclarations(val pointer: ConstPointer)
* All fields of the class instance. * All fields of the class instance.
* The order respects the class hierarchy, i.e. a class [fields] contains superclass [fields] as a prefix. * The order respects the class hierarchy, i.e. a class [fields] contains superclass [fields] as a prefix.
*/ */
internal fun ContextUtils.getFields(classDescriptor: ClassDescriptor) = context.getFields(classDescriptor) internal fun ContextUtils.getFields(classDescriptor: IrClass) = context.getFields(classDescriptor)
internal fun Context.getFields(classDescriptor: ClassDescriptor): List<IrField> { internal fun Context.getFields(classDescriptor: IrClass): List<IrField> {
val superClass = classDescriptor.getSuperClassNotAny() // TODO: what if Any has fields? val superClass = classDescriptor.getSuperClassNotAny() // TODO: what if Any has fields?
val superFields = if (superClass != null) getFields(superClass) else emptyList() val superFields = if (superClass != null) getFields(superClass) else emptyList()
@@ -103,7 +103,7 @@ internal fun Context.getFields(classDescriptor: ClassDescriptor): List<IrField>
/** /**
* Fields declared in the class. * Fields declared in the class.
*/ */
private fun Context.getDeclaredFields(classDescriptor: ClassDescriptor): List<IrField> { private fun Context.getDeclaredFields(classDescriptor: IrClass): List<IrField> {
// TODO: Here's what is going on here: // TODO: Here's what is going on here:
// The existence of a backing field for a property is only described in the IR, // The existence of a backing field for a property is only described in the IR,
// but not in the PropertyDescriptor. // but not in the PropertyDescriptor.
@@ -147,17 +147,17 @@ private fun ContextUtils.createClassBodyType(name: String, fields: List<IrField>
private class DeclarationsGeneratorVisitor(override val context: Context) : private class DeclarationsGeneratorVisitor(override val context: Context) :
IrElementVisitorVoid, ContextUtils { IrElementVisitorVoid, ContextUtils {
val functions = mutableMapOf<FunctionDescriptor, FunctionLlvmDeclarations>() val functions = mutableMapOf<IrFunction, FunctionLlvmDeclarations>()
val classes = mutableMapOf<ClassDescriptor, ClassLlvmDeclarations>() val classes = mutableMapOf<IrClass, ClassLlvmDeclarations>()
val fields = mutableMapOf<IrField, FieldLlvmDeclarations>() val fields = mutableMapOf<IrField, FieldLlvmDeclarations>()
val staticFields = mutableMapOf<IrField, StaticFieldLlvmDeclarations>() val staticFields = mutableMapOf<IrField, StaticFieldLlvmDeclarations>()
val uniques = mutableMapOf<UniqueKind, UniqueLlvmDeclarations>() val uniques = mutableMapOf<UniqueKind, UniqueLlvmDeclarations>()
private class Namer(val prefix: String) { private class Namer(val prefix: String) {
private val names = mutableMapOf<DeclarationDescriptor, Name>() private val names = mutableMapOf<IrDeclaration, Name>()
private val counts = mutableMapOf<FqName, Int>() private val counts = mutableMapOf<FqName, Int>()
fun getName(parent: FqName, descriptor: DeclarationDescriptor): Name { fun getName(parent: FqName, descriptor: IrDeclaration): Name {
return names.getOrPut(descriptor) { return names.getOrPut(descriptor) {
val count = counts.getOrDefault(parent, 0) + 1 val count = counts.getOrDefault(parent, 0) + 1
counts[parent] = count counts[parent] = count
@@ -168,7 +168,7 @@ private class DeclarationsGeneratorVisitor(override val context: Context) :
val objectNamer = Namer("object-") val objectNamer = Namer("object-")
private fun getLocalName(parent: FqName, descriptor: DeclarationDescriptor): Name { private fun getLocalName(parent: FqName, descriptor: IrDeclaration): Name {
if (descriptor.isAnonymousObject) { if (descriptor.isAnonymousObject) {
return objectNamer.getName(parent, descriptor) return objectNamer.getName(parent, descriptor)
} }
@@ -176,7 +176,7 @@ private class DeclarationsGeneratorVisitor(override val context: Context) :
return descriptor.name return descriptor.name
} }
private fun getFqName(descriptor: DeclarationDescriptor): FqName { private fun getFqName(descriptor: IrDeclaration): FqName {
val parent = descriptor.parent val parent = descriptor.parent
val parentFqName = when (parent) { val parentFqName = when (parent) {
is IrPackageFragment -> parent.fqName is IrPackageFragment -> parent.fqName
@@ -194,7 +194,7 @@ private class DeclarationsGeneratorVisitor(override val context: Context) :
* Note: since these declarations are going to be private, the name is only required not to clash with any * Note: since these declarations are going to be private, the name is only required not to clash with any
* exported declarations. * exported declarations.
*/ */
private fun qualifyInternalName(descriptor: DeclarationDescriptor): String { private fun qualifyInternalName(descriptor: IrDeclaration): String {
return getFqName(descriptor).asString() + "#internal" return getFqName(descriptor).asString() + "#internal"
} }
@@ -295,7 +295,7 @@ private class DeclarationsGeneratorVisitor(override val context: Context) :
} }
private fun createUniqueDeclarations( private fun createUniqueDeclarations(
descriptor: ClassDescriptor, typeInfoPtr: ConstPointer, bodyType: LLVMTypeRef) { descriptor: IrClass, typeInfoPtr: ConstPointer, bodyType: LLVMTypeRef) {
when { when {
descriptor.isUnit() -> { descriptor.isUnit() -> {
uniques[UniqueKind.UNIT] = uniques[UniqueKind.UNIT] =
@@ -309,7 +309,7 @@ private class DeclarationsGeneratorVisitor(override val context: Context) :
} }
} }
private fun createSingletonDeclarations(descriptor: ClassDescriptor): SingletonLlvmDeclarations? { private fun createSingletonDeclarations(descriptor: IrClass): SingletonLlvmDeclarations? {
if (descriptor.isUnit()) { if (descriptor.isUnit()) {
return null return null
@@ -343,7 +343,7 @@ private class DeclarationsGeneratorVisitor(override val context: Context) :
return SingletonLlvmDeclarations(instanceFieldRef, instanceShadowFieldRef) return SingletonLlvmDeclarations(instanceFieldRef, instanceShadowFieldRef)
} }
private fun createKotlinObjCClassDeclarations(descriptor: ClassDescriptor): KotlinObjCClassLlvmDeclarations { private fun createKotlinObjCClassDeclarations(descriptor: IrClass): KotlinObjCClassLlvmDeclarations {
val internalName = qualifyInternalName(descriptor) val internalName = qualifyInternalName(descriptor)
val classPointerGlobal = staticData.createGlobal(int8TypePtr, "kobjcclassptr:$internalName") val classPointerGlobal = staticData.createGlobal(int8TypePtr, "kobjcclassptr:$internalName")
@@ -393,7 +393,7 @@ private class DeclarationsGeneratorVisitor(override val context: Context) :
val descriptor = declaration val descriptor = declaration
val llvmFunctionType = getLlvmFunctionType(descriptor) val llvmFunctionType = getLlvmFunctionType(descriptor)
if ((descriptor is ConstructorDescriptor && descriptor.isObjCConstructor)) { if ((descriptor is IrConstructor && descriptor.isObjCConstructor)) {
return return
} }
@@ -12,7 +12,9 @@ import org.jetbrains.kotlin.backend.konan.computePrimitiveBinaryTypeOrNull
import org.jetbrains.kotlin.backend.konan.descriptors.* import org.jetbrains.kotlin.backend.konan.descriptors.*
import org.jetbrains.kotlin.backend.konan.irasdescriptors.* import org.jetbrains.kotlin.backend.konan.irasdescriptors.*
import org.jetbrains.kotlin.backend.konan.isExternalObjCClassMethod import org.jetbrains.kotlin.backend.konan.isExternalObjCClassMethod
import org.jetbrains.kotlin.ir.declarations.IrClass
import org.jetbrains.kotlin.ir.declarations.IrField import org.jetbrains.kotlin.ir.declarations.IrField
import org.jetbrains.kotlin.ir.declarations.IrFunction
import org.jetbrains.kotlin.ir.declarations.IrProperty import org.jetbrains.kotlin.ir.declarations.IrProperty
import org.jetbrains.kotlin.ir.types.* import org.jetbrains.kotlin.ir.types.*
import org.jetbrains.kotlin.ir.util.isAnnotationClass import org.jetbrains.kotlin.ir.util.isAnnotationClass
@@ -44,14 +46,14 @@ internal class RTTIGenerator(override val context: Context) : ContextUtils {
} }
} }
private fun checkAcyclicClass(classDescriptor: ClassDescriptor): Boolean = when { private fun checkAcyclicClass(classDescriptor: IrClass): Boolean = when {
classDescriptor.symbol == context.ir.symbols.array -> false classDescriptor.symbol == context.ir.symbols.array -> false
classDescriptor.isArray -> true classDescriptor.isArray -> true
context.llvmDeclarations.forClass(classDescriptor).fields.all { checkAcyclicFieldType(it.type) } -> true context.llvmDeclarations.forClass(classDescriptor).fields.all { checkAcyclicFieldType(it.type) } -> true
else -> false else -> false
} }
private fun flagsFromClass(classDescriptor: ClassDescriptor): Int { private fun flagsFromClass(classDescriptor: IrClass): Int {
var result = 0 var result = 0
if (classDescriptor.isFrozen) if (classDescriptor.isFrozen)
result = result or TF_IMMUTABLE result = result or TF_IMMUTABLE
@@ -123,7 +125,7 @@ internal class RTTIGenerator(override val context: Context) : ContextUtils {
private val EXPORT_TYPE_INFO_FQ_NAME = FqName.fromSegments(listOf("kotlin", "native", "internal", "ExportTypeInfo")) private val EXPORT_TYPE_INFO_FQ_NAME = FqName.fromSegments(listOf("kotlin", "native", "internal", "ExportTypeInfo"))
private fun exportTypeInfoIfRequired(classDesc: ClassDescriptor, typeInfoGlobal: LLVMValueRef?) { private fun exportTypeInfoIfRequired(classDesc: IrClass, typeInfoGlobal: LLVMValueRef?) {
val annot = classDesc.descriptor.annotations.findAnnotation(EXPORT_TYPE_INFO_FQ_NAME) val annot = classDesc.descriptor.annotations.findAnnotation(EXPORT_TYPE_INFO_FQ_NAME)
if (annot != null) { if (annot != null) {
val name = getAnnotationValue(annot)!! val name = getAnnotationValue(annot)!!
@@ -168,7 +170,7 @@ internal class RTTIGenerator(override val context: Context) : ContextUtils {
return LLVMStoreSizeOfType(llvmTargetData, classType).toInt() return LLVMStoreSizeOfType(llvmTargetData, classType).toInt()
} }
fun generate(classDesc: ClassDescriptor) { fun generate(classDesc: IrClass) {
val className = classDesc.fqNameSafe val className = classDesc.fqNameSafe
@@ -241,7 +243,7 @@ internal class RTTIGenerator(override val context: Context) : ContextUtils {
exportTypeInfoIfRequired(classDesc, classDesc.llvmTypeInfoPtr) exportTypeInfoIfRequired(classDesc, classDesc.llvmTypeInfoPtr)
} }
fun vtable(classDesc: ClassDescriptor): ConstArray { fun vtable(classDesc: IrClass): ConstArray {
// TODO: compile-time resolution limits binary compatibility // TODO: compile-time resolution limits binary compatibility
val vtableEntries = context.getVtableBuilder(classDesc).vtableEntries.map { val vtableEntries = context.getVtableBuilder(classDesc).vtableEntries.map {
val implementation = it.implementation val implementation = it.implementation
@@ -254,7 +256,7 @@ internal class RTTIGenerator(override val context: Context) : ContextUtils {
return ConstArray(int8TypePtr, vtableEntries) return ConstArray(int8TypePtr, vtableEntries)
} }
fun methodTableRecords(classDesc: ClassDescriptor): List<MethodTableRecord> { fun methodTableRecords(classDesc: IrClass): List<MethodTableRecord> {
val functionNames = mutableMapOf<Long, OverriddenFunctionDescriptor>() val functionNames = mutableMapOf<Long, OverriddenFunctionDescriptor>()
return context.getVtableBuilder(classDesc).methodTableEntries.map { return context.getVtableBuilder(classDesc).methodTableEntries.map {
val functionName = it.overriddenDescriptor.functionName val functionName = it.overriddenDescriptor.functionName
@@ -273,7 +275,7 @@ internal class RTTIGenerator(override val context: Context) : ContextUtils {
private fun mapRuntimeType(type: LLVMTypeRef): Int = private fun mapRuntimeType(type: LLVMTypeRef): Int =
runtimeTypeMap[type] ?: throw Error("Unmapped type: ${llvmtype2string(type)}") runtimeTypeMap[type] ?: throw Error("Unmapped type: ${llvmtype2string(type)}")
private fun makeExtendedInfo(descriptor: ClassDescriptor): ConstPointer { private fun makeExtendedInfo(descriptor: IrClass): ConstPointer {
// TODO: shall we actually do that? // TODO: shall we actually do that?
if (context.shouldOptimize()) if (context.shouldOptimize())
return NullPointer(runtime.extendedTypeInfoType) return NullPointer(runtime.extendedTypeInfoType)
@@ -311,9 +313,9 @@ internal class RTTIGenerator(override val context: Context) : ContextUtils {
// TODO: extract more code common with generate(). // TODO: extract more code common with generate().
fun generateSyntheticInterfaceImpl( fun generateSyntheticInterfaceImpl(
descriptor: ClassDescriptor, descriptor: IrClass,
methodImpls: Map<FunctionDescriptor, ConstPointer>, methodImpls: Map<IrFunction, ConstPointer>,
immutable: Boolean = false immutable: Boolean = false
): ConstPointer { ): ConstPointer {
assert(descriptor.isInterface) assert(descriptor.isInterface)
@@ -377,7 +379,7 @@ internal class RTTIGenerator(override val context: Context) : ContextUtils {
data class ReflectionInfo(val packageName: String?, val relativeName: String?) data class ReflectionInfo(val packageName: String?, val relativeName: String?)
private fun getReflectionInfo(descriptor: ClassDescriptor): ReflectionInfo { private fun getReflectionInfo(descriptor: IrClass): ReflectionInfo {
return if (descriptor.isAnonymousObject) { return if (descriptor.isAnonymousObject) {
ReflectionInfo(packageName = null, relativeName = null) ReflectionInfo(packageName = null, relativeName = null)
} else if (descriptor.isLocal) { } else if (descriptor.isLocal) {
@@ -385,7 +387,7 @@ internal class RTTIGenerator(override val context: Context) : ContextUtils {
} else { } else {
ReflectionInfo( ReflectionInfo(
packageName = descriptor.findPackage().fqName.asString(), packageName = descriptor.findPackage().fqName.asString(),
relativeName = generateSequence(descriptor, { it.parent as? ClassDescriptor }) relativeName = generateSequence(descriptor, { it.parent as? IrClass })
.toList().reversed() .toList().reversed()
.joinToString(".") { it.name.asString() } .joinToString(".") { it.name.asString() }
) )
@@ -10,6 +10,7 @@ import org.jetbrains.kotlin.backend.common.ir.ir2string
import org.jetbrains.kotlin.backend.konan.Context import org.jetbrains.kotlin.backend.konan.Context
import org.jetbrains.kotlin.backend.konan.irasdescriptors.* import org.jetbrains.kotlin.backend.konan.irasdescriptors.*
import org.jetbrains.kotlin.ir.IrElement import org.jetbrains.kotlin.ir.IrElement
import org.jetbrains.kotlin.ir.declarations.IrValueDeclaration
import org.jetbrains.kotlin.ir.declarations.IrValueParameter import org.jetbrains.kotlin.ir.declarations.IrValueParameter
import org.jetbrains.kotlin.ir.declarations.IrVariable import org.jetbrains.kotlin.ir.declarations.IrVariable
import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.Name
@@ -45,7 +46,7 @@ internal class VariableManager(val functionGenerationContext: FunctionGeneration
} }
val variables: ArrayList<Record> = arrayListOf() val variables: ArrayList<Record> = arrayListOf()
val contextVariablesToIndex: HashMap<ValueDescriptor, Int> = hashMapOf() val contextVariablesToIndex: HashMap<IrValueDeclaration, Int> = hashMapOf()
// Clears inner state of variable manager. // Clears inner state of variable manager.
fun clear() { fun clear() {
@@ -53,8 +54,8 @@ internal class VariableManager(val functionGenerationContext: FunctionGeneration
contextVariablesToIndex.clear() contextVariablesToIndex.clear()
} }
fun createVariable(descriptor: ValueDescriptor, value: LLVMValueRef? = null, variableLocation: VariableDebugLocation?) : Int { fun createVariable(descriptor: IrValueDeclaration, value: LLVMValueRef? = null, variableLocation: VariableDebugLocation?) : Int {
val isVar = descriptor is VariableDescriptor && descriptor.isVar val isVar = descriptor is IrVariable && descriptor.isVar
// Note that we always create slot for object references for memory management. // Note that we always create slot for object references for memory management.
if (!functionGenerationContext.context.shouldContainDebugInfo() && !isVar && value != null) if (!functionGenerationContext.context.shouldContainDebugInfo() && !isVar && value != null)
return createImmutable(descriptor, value) return createImmutable(descriptor, value)
@@ -66,8 +67,8 @@ internal class VariableManager(val functionGenerationContext: FunctionGeneration
return createMutable(descriptor, isVar, value, variableLocation) return createMutable(descriptor, isVar, value, variableLocation)
} }
internal fun createMutable(descriptor: ValueDescriptor, internal fun createMutable(descriptor: IrValueDeclaration,
isVar: Boolean, value: LLVMValueRef? = null, variableLocation: VariableDebugLocation?) : Int { isVar: Boolean, value: LLVMValueRef? = null, variableLocation: VariableDebugLocation?) : Int {
assert(!contextVariablesToIndex.contains(descriptor)) assert(!contextVariablesToIndex.contains(descriptor))
val index = variables.size val index = variables.size
val type = functionGenerationContext.getLLVMType(descriptor.type) val type = functionGenerationContext.getLLVMType(descriptor.type)
@@ -80,7 +81,7 @@ internal class VariableManager(val functionGenerationContext: FunctionGeneration
} }
internal var skip = 0 internal var skip = 0
internal fun createParameter(descriptor: ValueDescriptor, variableLocation: VariableDebugLocation?) : Int { internal fun createParameter(descriptor: IrValueDeclaration, variableLocation: VariableDebugLocation?) : Int {
assert(!contextVariablesToIndex.contains(descriptor)) assert(!contextVariablesToIndex.contains(descriptor))
val index = variables.size val index = variables.size
val type = functionGenerationContext.getLLVMType(descriptor.type) val type = functionGenerationContext.getLLVMType(descriptor.type)
@@ -109,7 +110,7 @@ internal class VariableManager(val functionGenerationContext: FunctionGeneration
return index return index
} }
internal fun createImmutable(descriptor: ValueDescriptor, value: LLVMValueRef) : Int { internal fun createImmutable(descriptor: IrValueDeclaration, value: LLVMValueRef) : Int {
if (contextVariablesToIndex.containsKey(descriptor)) if (contextVariablesToIndex.containsKey(descriptor))
throw Error("${ir2string(descriptor)} is already defined") throw Error("${ir2string(descriptor)} is already defined")
val index = variables.size val index = variables.size
@@ -118,7 +119,7 @@ internal class VariableManager(val functionGenerationContext: FunctionGeneration
return index return index
} }
fun indexOf(descriptor: ValueDescriptor) : Int { fun indexOf(descriptor: IrValueDeclaration) : Int {
return contextVariablesToIndex.getOrElse(descriptor) { -1 } return contextVariablesToIndex.getOrElse(descriptor) { -1 }
} }
@@ -33,7 +33,7 @@ import org.jetbrains.kotlin.ir.visitors.acceptVoid
import org.jetbrains.kotlin.resolve.DescriptorUtils import org.jetbrains.kotlin.resolve.DescriptorUtils
import org.jetbrains.kotlin.util.OperatorNameConventions import org.jetbrains.kotlin.util.OperatorNameConventions
private fun IrClass.getOverridingOf(function: FunctionDescriptor) = (function as? IrSimpleFunction)?.let { private fun IrClass.getOverridingOf(function: IrFunction) = (function as? IrSimpleFunction)?.let {
it.allOverriddenDescriptors.atMostOne { it.parent == this } it.allOverriddenDescriptors.atMostOne { it.parent == this }
} }
@@ -42,18 +42,18 @@ private fun IrTypeOperator.isCast() =
private class VariableValues { private class VariableValues {
val elementData = HashMap<VariableDescriptor, MutableSet<IrExpression>>() val elementData = HashMap<IrVariable, MutableSet<IrExpression>>()
fun addEmpty(variable: VariableDescriptor) = fun addEmpty(variable: IrVariable) =
elementData.getOrPut(variable, { mutableSetOf() }) elementData.getOrPut(variable, { mutableSetOf() })
fun add(variable: VariableDescriptor, element: IrExpression) = fun add(variable: IrVariable, element: IrExpression) =
elementData[variable]?.add(element) elementData[variable]?.add(element)
fun add(variable: VariableDescriptor, elements: Set<IrExpression>) = fun add(variable: IrVariable, elements: Set<IrExpression>) =
elementData[variable]?.addAll(elements) elementData[variable]?.addAll(elements)
fun get(variable: VariableDescriptor): Set<IrExpression>? = fun get(variable: IrVariable): Set<IrExpression>? =
elementData[variable] elementData[variable]
fun computeClosure() { fun computeClosure() {
@@ -63,14 +63,14 @@ private class VariableValues {
} }
// Computes closure of all possible values for given variable. // Computes closure of all possible values for given variable.
private fun computeValueClosure(value: VariableDescriptor): Set<IrExpression> { private fun computeValueClosure(value: IrVariable): Set<IrExpression> {
val result = mutableSetOf<IrExpression>() val result = mutableSetOf<IrExpression>()
val seen = mutableSetOf<VariableDescriptor>() val seen = mutableSetOf<IrVariable>()
dfs(value, seen, result) dfs(value, seen, result)
return result return result
} }
private fun dfs(value: VariableDescriptor, seen: MutableSet<VariableDescriptor>, result: MutableSet<IrExpression>) { private fun dfs(value: IrVariable, seen: MutableSet<IrVariable>, result: MutableSet<IrExpression>) {
seen += value seen += value
val elements = elementData[value] val elements = elementData[value]
?: return ?: return
@@ -79,7 +79,7 @@ private class VariableValues {
result += element result += element
else { else {
val descriptor = element.symbol.owner val descriptor = element.symbol.owner
if (descriptor is VariableDescriptor && !seen.contains(descriptor)) if (descriptor is IrVariable && !seen.contains(descriptor))
dfs(descriptor, seen, result) dfs(descriptor, seen, result)
} }
} }
@@ -230,7 +230,7 @@ internal class ModuleDFGBuilder(val context: Context, val irModule: IrModuleFrag
} }
} }
private fun analyze(descriptor: DeclarationDescriptor, body: IrElement?) { private fun analyze(descriptor: IrDeclaration, body: IrElement?) {
// Find all interesting expressions, variables and functions. // Find all interesting expressions, variables and functions.
val visitor = ElementFinderVisitor() val visitor = ElementFinderVisitor()
body?.acceptVoid(visitor) body?.acceptVoid(visitor)
@@ -297,7 +297,7 @@ internal class ModuleDFGBuilder(val context: Context, val irModule: IrModuleFrag
val variableValues = VariableValues() val variableValues = VariableValues()
val returnValues = mutableListOf<IrExpression>() val returnValues = mutableListOf<IrExpression>()
val thrownValues = mutableListOf<IrExpression>() val thrownValues = mutableListOf<IrExpression>()
val catchParameters = mutableSetOf<VariableDescriptor>() val catchParameters = mutableSetOf<IrVariable>()
private val suspendableExpressionStack = mutableListOf<IrSuspendableExpression>() private val suspendableExpressionStack = mutableListOf<IrSuspendableExpression>()
@@ -305,7 +305,7 @@ internal class ModuleDFGBuilder(val context: Context, val irModule: IrModuleFrag
element.acceptChildrenVoid(this) element.acceptChildrenVoid(this)
} }
private fun assignVariable(variable: VariableDescriptor, value: IrExpression) { private fun assignVariable(variable: IrVariable, value: IrExpression) {
expressionValuesExtractor.forEachValue(value) { expressionValuesExtractor.forEachValue(value) {
variableValues.add(variable, it) variableValues.add(variable, it)
} }
@@ -410,13 +410,13 @@ internal class ModuleDFGBuilder(val context: Context, val irModule: IrModuleFrag
private inner class FunctionDFGBuilder(val expressionValuesExtractor: ExpressionValuesExtractor, private inner class FunctionDFGBuilder(val expressionValuesExtractor: ExpressionValuesExtractor,
val variableValues: VariableValues, val variableValues: VariableValues,
val descriptor: DeclarationDescriptor, val descriptor: IrDeclaration,
val expressions: List<IrExpression>, val expressions: List<IrExpression>,
val returnValues: List<IrExpression>, val returnValues: List<IrExpression>,
val thrownValues: List<IrExpression>, val thrownValues: List<IrExpression>,
val catchParameters: Set<VariableDescriptor>) { val catchParameters: Set<IrVariable>) {
private val allParameters = (descriptor as? FunctionDescriptor)?.allParameters ?: emptyList() private val allParameters = (descriptor as? IrFunction)?.allParameters ?: emptyList()
private val templateParameters = allParameters.withIndex().associateBy({ it.value }, { DataFlowIR.Node.Parameter(it.index) }) private val templateParameters = allParameters.withIndex().associateBy({ it.value }, { DataFlowIR.Node.Parameter(it.index) })
private val continuationParameter = when { private val continuationParameter = when {
@@ -570,7 +570,7 @@ internal class ModuleDFGBuilder(val context: Context, val irModule: IrModuleFrag
else else
it it
} }
if (callee is ConstructorDescriptor) { if (callee is IrConstructor) {
DataFlowIR.Node.NewObject( DataFlowIR.Node.NewObject(
symbolTable.mapFunction(callee), symbolTable.mapFunction(callee),
arguments, arguments,
@@ -580,7 +580,7 @@ internal class ModuleDFGBuilder(val context: Context, val irModule: IrModuleFrag
} else { } else {
callee as IrSimpleFunction callee as IrSimpleFunction
if (callee.isOverridable && value.superQualifier == null) { if (callee.isOverridable && value.superQualifier == null) {
val owner = callee.containingDeclaration as ClassDescriptor val owner = callee.containingDeclaration as IrClass
val actualReceiverType = value.dispatchReceiver!!.type val actualReceiverType = value.dispatchReceiver!!.type
val actualReceiverClassifier = actualReceiverType.classifierOrFail val actualReceiverClassifier = actualReceiverType.classifierOrFail
@@ -634,7 +634,7 @@ internal class ModuleDFGBuilder(val context: Context, val irModule: IrModuleFrag
} }
is IrDelegatingConstructorCall -> { is IrDelegatingConstructorCall -> {
val thisReceiver = (descriptor as ConstructorDescriptor).constructedClass.thisReceiver!! val thisReceiver = (descriptor as IrConstructor).constructedClass.thisReceiver!!
val thiz = IrGetValueImpl(SYNTHETIC_OFFSET, SYNTHETIC_OFFSET, thisReceiver.type, val thiz = IrGetValueImpl(SYNTHETIC_OFFSET, SYNTHETIC_OFFSET, thisReceiver.type,
thisReceiver.symbol) thisReceiver.symbol)
val arguments = listOf(thiz) + value.getArguments().map { it.second } val arguments = listOf(thiz) + value.getArguments().map { it.second }
@@ -441,9 +441,9 @@ internal object DataFlowIR {
private inline fun takeName(block: () -> String) = if (TAKE_NAMES) block() else null private inline fun takeName(block: () -> String) = if (TAKE_NAMES) block() else null
val classMap = mutableMapOf<ClassDescriptor, Type>() val classMap = mutableMapOf<IrClass, Type>()
val primitiveMap = mutableMapOf<PrimitiveBinaryType, Type>() val primitiveMap = mutableMapOf<PrimitiveBinaryType, Type>()
val functionMap = mutableMapOf<DeclarationDescriptor, FunctionSymbol>() val functionMap = mutableMapOf<IrDeclaration, FunctionSymbol>()
private val NAME_ESCAPES = Name.identifier("Escapes") private val NAME_ESCAPES = Name.identifier("Escapes")
private val NAME_POINTS_TO = Name.identifier("PointsTo") private val NAME_POINTS_TO = Name.identifier("PointsTo")
@@ -488,9 +488,9 @@ internal object DataFlowIR {
}, data = null) }, data = null)
} }
private fun ClassDescriptor.isFinal() = modality == Modality.FINAL && kind != ClassKind.ENUM_CLASS private fun IrClass.isFinal() = modality == Modality.FINAL && kind != ClassKind.ENUM_CLASS
fun mapClassReferenceType(descriptor: ClassDescriptor, eraseLocalObjects: Boolean = true): Type { fun mapClassReferenceType(descriptor: IrClass, eraseLocalObjects: Boolean = true): Type {
// Do not try to devirtualize ObjC classes. // Do not try to devirtualize ObjC classes.
if (descriptor.module.name == Name.special("<forward declarations>") || descriptor.isObjCClass()) if (descriptor.module.name == Name.special("<forward declarations>") || descriptor.isObjCClass())
return Type.Virtual return Type.Virtual
@@ -530,7 +530,7 @@ internal object DataFlowIR {
return type return type
} }
private fun choosePrimary(erasure: List<ClassDescriptor>): ClassDescriptor { private fun choosePrimary(erasure: List<IrClass>): IrClass {
if (erasure.size == 1) return erasure[0] if (erasure.size == 1) return erasure[0]
// A parameter with constraints - choose class if exists. // A parameter with constraints - choose class if exists.
return erasure.singleOrNull { !it.isInterface } ?: context.ir.symbols.any.owner return erasure.singleOrNull { !it.isInterface } ?: context.ir.symbols.any.owner
@@ -564,22 +564,22 @@ internal object DataFlowIR {
} }
// TODO: use from LlvmDeclarations. // TODO: use from LlvmDeclarations.
private fun getFqName(descriptor: DeclarationDescriptor): FqName = private fun getFqName(descriptor: IrDeclaration): FqName =
descriptor.parent.fqNameSafe.child(descriptor.name) descriptor.parent.fqNameSafe.child(descriptor.name)
private val FunctionDescriptor.internalName get() = getFqName(this).asString() + "#internal" private val IrFunction.internalName get() = getFqName(this).asString() + "#internal"
fun mapFunction(descriptor: DeclarationDescriptor): FunctionSymbol = when (descriptor) { fun mapFunction(descriptor: IrDeclaration): FunctionSymbol = when (descriptor) {
is FunctionDescriptor -> mapFunction(descriptor) is IrFunction -> mapFunction(descriptor)
is IrField -> mapPropertyInitializer(descriptor) is IrField -> mapPropertyInitializer(descriptor)
else -> error("Unknown descriptor: $descriptor") else -> error("Unknown descriptor: $descriptor")
} }
private fun mapFunction(descriptor: FunctionDescriptor): FunctionSymbol = descriptor.target.let { private fun mapFunction(descriptor: IrFunction): FunctionSymbol = descriptor.target.let {
functionMap[it]?.let { return it } functionMap[it]?.let { return it }
val name = if (it.isExported()) it.symbolName else it.internalName val name = if (it.isExported()) it.symbolName else it.internalName
val returnsUnit = it is ConstructorDescriptor || (!it.isSuspend && it.returnType.isUnit()) val returnsUnit = it is IrConstructor || (!it.isSuspend && it.returnType.isUnit())
val returnsNothing = !it.isSuspend && it.returnType.isNothing() val returnsNothing = !it.isSuspend && it.returnType.isNothing()
var attributes = 0 var attributes = 0
if (returnsUnit) if (returnsUnit)
@@ -602,13 +602,13 @@ internal object DataFlowIR {
else -> { else -> {
val isAbstract = it is IrSimpleFunction && it.modality == Modality.ABSTRACT val isAbstract = it is IrSimpleFunction && it.modality == Modality.ABSTRACT
val classDescriptor = it.containingDeclaration as? ClassDescriptor val classDescriptor = it.containingDeclaration as? IrClass
val bridgeTarget = it.bridgeTarget val bridgeTarget = it.bridgeTarget
val isSpecialBridge = bridgeTarget.let { val isSpecialBridge = bridgeTarget.let {
it != null && BuiltinMethodsWithSpecialGenericSignature.getDefaultValueForOverriddenBuiltinFunction(it.descriptor) != null it != null && BuiltinMethodsWithSpecialGenericSignature.getDefaultValueForOverriddenBuiltinFunction(it.descriptor) != null
} }
val bridgeTargetSymbol = if (isSpecialBridge || bridgeTarget == null) null else mapFunction(bridgeTarget) val bridgeTargetSymbol = if (isSpecialBridge || bridgeTarget == null) null else mapFunction(bridgeTarget)
val placeToFunctionsTable = !isAbstract && it !is ConstructorDescriptor && classDescriptor != null val placeToFunctionsTable = !isAbstract && it !is IrConstructor && classDescriptor != null
&& !classDescriptor.isNonGeneratedAnnotation() && !classDescriptor.isNonGeneratedAnnotation()
&& (it.isOverridableOrOverrides || bridgeTarget != null || descriptor.isSpecial || !classDescriptor.isFinal()) && (it.isOverridableOrOverrides || bridgeTarget != null || descriptor.isSpecial || !classDescriptor.isFinal())
val symbolTableIndex = if (placeToFunctionsTable) module.numberOfFunctions++ else -1 val symbolTableIndex = if (placeToFunctionsTable) module.numberOfFunctions++ else -1
@@ -632,7 +632,7 @@ internal object DataFlowIR {
return symbol return symbol
} }
private val FunctionDescriptor.isSpecial get() = private val IrFunction.isSpecial get() =
name.asString().let { it.startsWith("<bridge-") || it == "<box>" || it == "<unbox>" } name.asString().let { it.startsWith("<bridge-") || it == "<box>" || it == "<unbox>" }
private fun mapPropertyInitializer(descriptor: IrField): FunctionSymbol = descriptor.original.let { private fun mapPropertyInitializer(descriptor: IrField): FunctionSymbol = descriptor.original.let {
@@ -652,7 +652,7 @@ internal object DataFlowIR {
fun getPrivateFunctionsTableForExport() = fun getPrivateFunctionsTableForExport() =
functionMap functionMap
.asSequence() .asSequence()
.filter { it.key is FunctionDescriptor } .filter { it.key is IrFunction }
.filter { it.value.let { it is DataFlowIR.FunctionSymbol.Declared && it.symbolTableIndex >= 0 } } .filter { it.value.let { it is DataFlowIR.FunctionSymbol.Declared && it.symbolTableIndex >= 0 } }
.sortedBy { (it.value as DataFlowIR.FunctionSymbol.Declared).symbolTableIndex } .sortedBy { (it.value as DataFlowIR.FunctionSymbol.Declared).symbolTableIndex }
.apply { .apply {
@@ -660,7 +660,7 @@ internal object DataFlowIR {
assert((entry.value as DataFlowIR.FunctionSymbol.Declared).symbolTableIndex == index) { "Inconsistent function table" } assert((entry.value as DataFlowIR.FunctionSymbol.Declared).symbolTableIndex == index) { "Inconsistent function table" }
} }
} }
.map { (it.key as FunctionDescriptor) to (it.value as DataFlowIR.FunctionSymbol.Declared) } .map { (it.key as IrFunction) to (it.value as DataFlowIR.FunctionSymbol.Declared) }
.toList() .toList()
fun getPrivateClassesTableForExport() = fun getPrivateClassesTableForExport() =