[K/N] Support kType generation as ConstantValue
This commit is contained in:
+3
-1
@@ -442,7 +442,6 @@ internal class KonanSymbols(
|
|||||||
return symbolTable.referenceEnumEntry(descriptor)
|
return symbolTable.referenceEnumEntry(descriptor)
|
||||||
}
|
}
|
||||||
|
|
||||||
val getClassTypeInfo = internalFunction("getClassTypeInfo")
|
|
||||||
val getObjectTypeInfo = internalFunction("getObjectTypeInfo")
|
val getObjectTypeInfo = internalFunction("getObjectTypeInfo")
|
||||||
val kClassImpl = internalClass("KClassImpl")
|
val kClassImpl = internalClass("KClassImpl")
|
||||||
val kClassImplConstructor by lazy { kClassImpl.constructors.single { it.descriptor.isPrimary } }
|
val kClassImplConstructor by lazy { kClassImpl.constructors.single { it.descriptor.isPrimary } }
|
||||||
@@ -453,6 +452,7 @@ internal class KonanSymbols(
|
|||||||
val kTypeImpl = internalClass("KTypeImpl")
|
val kTypeImpl = internalClass("KTypeImpl")
|
||||||
val kTypeImplIntrinsicConstructor by lazy { kTypeImpl.constructors.single { it.descriptor.valueParameters.isEmpty() } }
|
val kTypeImplIntrinsicConstructor by lazy { kTypeImpl.constructors.single { it.descriptor.valueParameters.isEmpty() } }
|
||||||
val kTypeImplForTypeParametersWithRecursiveBounds = internalClass("KTypeImplForTypeParametersWithRecursiveBounds")
|
val kTypeImplForTypeParametersWithRecursiveBounds = internalClass("KTypeImplForTypeParametersWithRecursiveBounds")
|
||||||
|
val kTypeProjectionList = internalClass("KTypeProjectionList")
|
||||||
|
|
||||||
val kTypeProjection = symbolTable.referenceClass(context.reflectionTypes.kTypeProjection)
|
val kTypeProjection = symbolTable.referenceClass(context.reflectionTypes.kTypeProjection)
|
||||||
|
|
||||||
@@ -484,6 +484,8 @@ internal class KonanSymbols(
|
|||||||
val listOf = irBuiltIns.findFunctions(Name.identifier("listOf"), "kotlin", "collections")
|
val listOf = irBuiltIns.findFunctions(Name.identifier("listOf"), "kotlin", "collections")
|
||||||
.single { it.descriptor.valueParameters.size == 1 && it.descriptor.valueParameters[0].isVararg }
|
.single { it.descriptor.valueParameters.size == 1 && it.descriptor.valueParameters[0].isVararg }
|
||||||
|
|
||||||
|
val arrayAsList = internalClass("ArrayAsList")
|
||||||
|
|
||||||
val threadLocal = symbolTable.referenceClass(
|
val threadLocal = symbolTable.referenceClass(
|
||||||
context.builtIns.builtInsModule.findClassAcrossModuleDependencies(
|
context.builtIns.builtInsModule.findClassAcrossModuleDependencies(
|
||||||
ClassId.topLevel(KonanFqNames.threadLocal))!!)
|
ClassId.topLevel(KonanFqNames.threadLocal))!!)
|
||||||
|
|||||||
-15
@@ -61,7 +61,6 @@ internal enum class IntrinsicType {
|
|||||||
OBJC_INIT_BY,
|
OBJC_INIT_BY,
|
||||||
OBJC_GET_SELECTOR,
|
OBJC_GET_SELECTOR,
|
||||||
// Other
|
// Other
|
||||||
GET_CLASS_TYPE_INFO,
|
|
||||||
CREATE_UNINITIALIZED_INSTANCE,
|
CREATE_UNINITIALIZED_INSTANCE,
|
||||||
IDENTITY,
|
IDENTITY,
|
||||||
IMMUTABLE_BLOB,
|
IMMUTABLE_BLOB,
|
||||||
@@ -242,7 +241,6 @@ internal class IntrinsicGenerator(private val environment: IntrinsicGeneratorEnv
|
|||||||
IntrinsicType.OBJC_GET_MESSENGER_STRET -> emitObjCGetMessenger(args, isStret = true)
|
IntrinsicType.OBJC_GET_MESSENGER_STRET -> emitObjCGetMessenger(args, isStret = true)
|
||||||
IntrinsicType.OBJC_GET_OBJC_CLASS -> emitGetObjCClass(callSite)
|
IntrinsicType.OBJC_GET_OBJC_CLASS -> emitGetObjCClass(callSite)
|
||||||
IntrinsicType.OBJC_CREATE_SUPER_STRUCT -> emitObjCCreateSuperStruct(args)
|
IntrinsicType.OBJC_CREATE_SUPER_STRUCT -> emitObjCCreateSuperStruct(args)
|
||||||
IntrinsicType.GET_CLASS_TYPE_INFO -> emitGetClassTypeInfo(callSite)
|
|
||||||
IntrinsicType.INTEROP_READ_BITS -> emitReadBits(args)
|
IntrinsicType.INTEROP_READ_BITS -> emitReadBits(args)
|
||||||
IntrinsicType.INTEROP_WRITE_BITS -> emitWriteBits(args)
|
IntrinsicType.INTEROP_WRITE_BITS -> emitWriteBits(args)
|
||||||
IntrinsicType.INTEROP_READ_PRIMITIVE -> emitReadPrimitive(callSite, args)
|
IntrinsicType.INTEROP_READ_PRIMITIVE -> emitReadPrimitive(callSite, args)
|
||||||
@@ -432,19 +430,6 @@ internal class IntrinsicGenerator(private val environment: IntrinsicGeneratorEnv
|
|||||||
TODO("Implement me")
|
TODO("Implement me")
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun FunctionGenerationContext.emitGetClassTypeInfo(callSite: IrCall): LLVMValueRef {
|
|
||||||
val typeArgument = callSite.getTypeArgument(0)!!
|
|
||||||
val typeArgumentClass = typeArgument.getClass()
|
|
||||||
return if (typeArgumentClass == null) {
|
|
||||||
// Should not happen anymore, but it is safer to handle this case.
|
|
||||||
unreachable()
|
|
||||||
kNullInt8Ptr
|
|
||||||
} else {
|
|
||||||
val typeInfo = codegen.typeInfoValue(typeArgumentClass)
|
|
||||||
LLVMConstBitCast(typeInfo, kInt8Ptr)!!
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun FunctionGenerationContext.emitObjCCreateSuperStruct(args: List<LLVMValueRef>): LLVMValueRef {
|
private fun FunctionGenerationContext.emitObjCCreateSuperStruct(args: List<LLVMValueRef>): LLVMValueRef {
|
||||||
assert(args.size == 2)
|
assert(args.size == 2)
|
||||||
val receiver = args[0]
|
val receiver = args[0]
|
||||||
|
|||||||
+15
-7
@@ -10,6 +10,8 @@ import org.jetbrains.kotlin.backend.common.ir.Symbols
|
|||||||
import org.jetbrains.kotlin.backend.common.lower.at
|
import org.jetbrains.kotlin.backend.common.lower.at
|
||||||
import org.jetbrains.kotlin.backend.common.lower.createIrBuilder
|
import org.jetbrains.kotlin.backend.common.lower.createIrBuilder
|
||||||
import org.jetbrains.kotlin.backend.konan.Context
|
import org.jetbrains.kotlin.backend.konan.Context
|
||||||
|
import org.jetbrains.kotlin.backend.konan.llvm.ConstantConstructorIntrinsicType
|
||||||
|
import org.jetbrains.kotlin.backend.konan.llvm.tryGetConstantConstructorIntrinsicType
|
||||||
import org.jetbrains.kotlin.backend.konan.renderCompilerError
|
import org.jetbrains.kotlin.backend.konan.renderCompilerError
|
||||||
import org.jetbrains.kotlin.ir.builders.IrBuilderWithScope
|
import org.jetbrains.kotlin.ir.builders.IrBuilderWithScope
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrDeclaration
|
import org.jetbrains.kotlin.ir.declarations.IrDeclaration
|
||||||
@@ -93,17 +95,23 @@ internal class PostInlineLowering(val context: Context) : BodyLoweringPass {
|
|||||||
expression.startOffset, expression.endOffset,
|
expression.startOffset, expression.endOffset,
|
||||||
context.irBuiltIns.stringType,
|
context.irBuiltIns.stringType,
|
||||||
IrConstKind.String, builder.toString()))
|
IrConstKind.String, builder.toString()))
|
||||||
} else if (Symbols.isTypeOfIntrinsic(expression.symbol)) {
|
|
||||||
// Inline functions themselves are not called (they have been inlined at all call sites),
|
|
||||||
// so it is ok not to build exact type parameters for them.
|
|
||||||
val needExactTypeParameters = (container as? IrSimpleFunction)?.isInline != true
|
|
||||||
return with (KTypeGenerator(context, irFile, expression, needExactTypeParameters)) {
|
|
||||||
data.at(expression).irKType(expression.getTypeArgument(0)!!, leaveReifiedForLater = false)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return expression
|
return expression
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun visitConstantObject(expression: IrConstantObject, data: IrBuilderWithScope): IrConstantValue {
|
||||||
|
return if (tryGetConstantConstructorIntrinsicType(expression.constructor) == ConstantConstructorIntrinsicType.KTYPE_IMPL) {
|
||||||
|
// Inline functions themselves are not called (they have been inlined at all call sites),
|
||||||
|
// so it is ok not to build exact type parameters for them.
|
||||||
|
val needExactTypeParameters = (container as? IrSimpleFunction)?.isInline != true
|
||||||
|
with(KTypeGenerator(context, irFile, expression, needExactTypeParameters)) {
|
||||||
|
data.at(expression).irKType(expression.typeArguments[0], leaveReifiedForLater = false)
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
super.visitConstantObject(expression, data)
|
||||||
|
}
|
||||||
|
|
||||||
}, data = context.createIrBuilder((container as IrSymbolOwner).symbol, irBody.startOffset, irBody.endOffset))
|
}, data = context.createIrBuilder((container as IrSymbolOwner).symbol, irBody.startOffset, irBody.endOffset))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+86
-95
@@ -8,30 +8,26 @@ package org.jetbrains.kotlin.backend.konan.lower
|
|||||||
import org.jetbrains.kotlin.backend.konan.InteropFqNames
|
import org.jetbrains.kotlin.backend.konan.InteropFqNames
|
||||||
import org.jetbrains.kotlin.backend.konan.KonanBackendContext
|
import org.jetbrains.kotlin.backend.konan.KonanBackendContext
|
||||||
import org.jetbrains.kotlin.backend.konan.ir.typeWithStarProjections
|
import org.jetbrains.kotlin.backend.konan.ir.typeWithStarProjections
|
||||||
import org.jetbrains.kotlin.backend.konan.ir.typeWithoutArguments
|
|
||||||
import org.jetbrains.kotlin.backend.konan.isObjCClass
|
import org.jetbrains.kotlin.backend.konan.isObjCClass
|
||||||
import org.jetbrains.kotlin.backend.konan.llvm.computeFullName
|
import org.jetbrains.kotlin.backend.konan.llvm.computeFullName
|
||||||
import org.jetbrains.kotlin.backend.konan.reportCompilationError
|
import org.jetbrains.kotlin.backend.konan.reportCompilationError
|
||||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||||
import org.jetbrains.kotlin.ir.IrElement
|
import org.jetbrains.kotlin.ir.IrElement
|
||||||
import org.jetbrains.kotlin.ir.builders.*
|
import org.jetbrains.kotlin.ir.builders.*
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrEnumEntry
|
import org.jetbrains.kotlin.ir.declarations.*
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrFile
|
import org.jetbrains.kotlin.ir.expressions.*
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrFunction
|
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrTypeParameter
|
|
||||||
import org.jetbrains.kotlin.ir.expressions.IrExpression
|
|
||||||
import org.jetbrains.kotlin.ir.expressions.IrMemberAccessExpression
|
|
||||||
import org.jetbrains.kotlin.ir.expressions.impl.IrGetEnumValueImpl
|
|
||||||
import org.jetbrains.kotlin.ir.expressions.impl.IrVarargImpl
|
|
||||||
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
|
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
|
||||||
import org.jetbrains.kotlin.ir.symbols.IrTypeParameterSymbol
|
import org.jetbrains.kotlin.ir.symbols.IrTypeParameterSymbol
|
||||||
import org.jetbrains.kotlin.ir.types.*
|
import org.jetbrains.kotlin.ir.types.*
|
||||||
import org.jetbrains.kotlin.ir.util.*
|
import org.jetbrains.kotlin.ir.util.*
|
||||||
import org.jetbrains.kotlin.ir.util.irCall
|
|
||||||
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameUnsafe
|
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameUnsafe
|
||||||
import org.jetbrains.kotlin.resolve.descriptorUtil.getAllSuperClassifiers
|
import org.jetbrains.kotlin.resolve.descriptorUtil.getAllSuperClassifiers
|
||||||
import org.jetbrains.kotlin.types.Variance
|
import org.jetbrains.kotlin.types.Variance
|
||||||
|
|
||||||
|
private fun IrBuilderWithScope.irConstantString(string: String) = irConstantPrimitive(irString(string))
|
||||||
|
private fun IrBuilderWithScope.irConstantInt(int: Int) = irConstantPrimitive(irInt(int))
|
||||||
|
private fun IrBuilderWithScope.irConstantBoolean(boolean: Boolean) = irConstantPrimitive(irBoolean(boolean))
|
||||||
|
|
||||||
internal class KTypeGenerator(
|
internal class KTypeGenerator(
|
||||||
val context: KonanBackendContext,
|
val context: KonanBackendContext,
|
||||||
val irFile: IrFile,
|
val irFile: IrFile,
|
||||||
@@ -49,15 +45,16 @@ internal class KTypeGenerator(
|
|||||||
type: IrType,
|
type: IrType,
|
||||||
leaveReifiedForLater: Boolean,
|
leaveReifiedForLater: Boolean,
|
||||||
seenTypeParameters: MutableSet<IrTypeParameter>
|
seenTypeParameters: MutableSet<IrTypeParameter>
|
||||||
): IrExpression {
|
): IrConstantValue {
|
||||||
if (type !is IrSimpleType) {
|
if (type !is IrSimpleType) {
|
||||||
// Represent as non-denotable type:
|
// Represent as non-denotable type:
|
||||||
return irKTypeImpl(
|
return irKTypeImpl(
|
||||||
kClassifier = irNull(),
|
kClassifier = irConstantPrimitive(irNull()),
|
||||||
irTypeArguments = emptyList(),
|
irTypeArguments = emptyList(),
|
||||||
isMarkedNullable = false,
|
isMarkedNullable = false,
|
||||||
leaveReifiedForLater = leaveReifiedForLater,
|
leaveReifiedForLater = leaveReifiedForLater,
|
||||||
seenTypeParameters = seenTypeParameters
|
seenTypeParameters = seenTypeParameters,
|
||||||
|
type = type,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
@@ -66,7 +63,7 @@ internal class KTypeGenerator(
|
|||||||
is IrTypeParameterSymbol -> {
|
is IrTypeParameterSymbol -> {
|
||||||
if (classifier.owner.isReified && leaveReifiedForLater) {
|
if (classifier.owner.isReified && leaveReifiedForLater) {
|
||||||
// Leave as is for reification.
|
// Leave as is for reification.
|
||||||
return irCall(symbols.typeOf).apply { putTypeArgument(0, type) }
|
return irConstantObject(symbols.kTypeImplIntrinsicConstructor, emptyList(), listOf(type))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Leave upper bounds of non-reified type parameters as is, even if they are reified themselves.
|
// Leave upper bounds of non-reified type parameters as is, even if they are reified themselves.
|
||||||
@@ -80,26 +77,28 @@ internal class KTypeGenerator(
|
|||||||
irTypeArguments = type.arguments,
|
irTypeArguments = type.arguments,
|
||||||
isMarkedNullable = type.hasQuestionMark,
|
isMarkedNullable = type.hasQuestionMark,
|
||||||
leaveReifiedForLater = leaveReifiedForLater,
|
leaveReifiedForLater = leaveReifiedForLater,
|
||||||
seenTypeParameters = seenTypeParameters
|
seenTypeParameters = seenTypeParameters,
|
||||||
|
type = type,
|
||||||
)
|
)
|
||||||
} catch (t: RecursiveBoundsException) {
|
} catch (t: RecursiveBoundsException) {
|
||||||
if (needExactTypeParameters)
|
if (needExactTypeParameters)
|
||||||
this@KTypeGenerator.context.reportCompilationError(t.message!!, irFile, irElement)
|
this@KTypeGenerator.context.reportCompilationError(t.message!!, irFile, irElement)
|
||||||
return irCall(symbols.kTypeImplForTypeParametersWithRecursiveBounds.constructors.single())
|
return irConstantObject(symbols.kTypeImplForTypeParametersWithRecursiveBounds.owner, emptyMap())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun IrBuilderWithScope.irKTypeImpl(
|
private fun IrBuilderWithScope.irKTypeImpl(
|
||||||
kClassifier: IrExpression,
|
kClassifier: IrConstantValue,
|
||||||
irTypeArguments: List<IrTypeArgument>,
|
irTypeArguments: List<IrTypeArgument>,
|
||||||
isMarkedNullable: Boolean,
|
isMarkedNullable: Boolean,
|
||||||
leaveReifiedForLater: Boolean,
|
leaveReifiedForLater: Boolean,
|
||||||
seenTypeParameters: MutableSet<IrTypeParameter>
|
seenTypeParameters: MutableSet<IrTypeParameter>,
|
||||||
): IrExpression = irCall(symbols.kTypeImpl.constructors.single()).apply {
|
type: IrType,
|
||||||
putValueArgument(0, kClassifier)
|
): IrConstantValue = irConstantObject(symbols.kTypeImpl.owner, mapOf(
|
||||||
putValueArgument(1, irKTypeProjectionsList(irTypeArguments, leaveReifiedForLater, seenTypeParameters))
|
"classifier" to kClassifier,
|
||||||
putValueArgument(2, irBoolean(isMarkedNullable))
|
"arguments" to irKTypeProjectionsList(irTypeArguments, leaveReifiedForLater, seenTypeParameters),
|
||||||
}
|
"isMarkedNullable" to irConstantPrimitive(irBoolean(isMarkedNullable)),
|
||||||
|
), listOf(type))
|
||||||
|
|
||||||
private fun IrBuilderWithScope.irKClass(symbol: IrClassSymbol) = irKClass(this@KTypeGenerator.context, symbol)
|
private fun IrBuilderWithScope.irKClass(symbol: IrClassSymbol) = irKClass(this@KTypeGenerator.context, symbol)
|
||||||
|
|
||||||
@@ -107,86 +106,80 @@ internal class KTypeGenerator(
|
|||||||
typeParameter: IrTypeParameter,
|
typeParameter: IrTypeParameter,
|
||||||
leaveReifiedForLater: Boolean,
|
leaveReifiedForLater: Boolean,
|
||||||
seenTypeParameters: MutableSet<IrTypeParameter>
|
seenTypeParameters: MutableSet<IrTypeParameter>
|
||||||
): IrMemberAccessExpression<*> {
|
): IrConstantValue {
|
||||||
if (!seenTypeParameters.add(typeParameter))
|
if (!seenTypeParameters.add(typeParameter))
|
||||||
throw RecursiveBoundsException("Non-reified type parameters with recursive bounds are not supported yet: ${typeParameter.render()}")
|
throw RecursiveBoundsException("Non-reified type parameters with recursive bounds are not supported yet: ${typeParameter.render()}")
|
||||||
val result = irCall(symbols.kTypeParameterImpl.constructors.single()).apply {
|
val result = irConstantObject(symbols.kTypeParameterImpl.owner, mapOf(
|
||||||
putValueArgument(0, irString(typeParameter.name.asString()))
|
"name" to irConstantString(typeParameter.name.asString()),
|
||||||
putValueArgument(1, irString(typeParameter.parentUniqueName))
|
"containerFqName" to irConstantString(typeParameter.parentUniqueName),
|
||||||
putValueArgument(2, irKTypeList(typeParameter.superTypes, leaveReifiedForLater, seenTypeParameters))
|
"upperBounds" to irKTypeList(typeParameter.superTypes, leaveReifiedForLater, seenTypeParameters),
|
||||||
putValueArgument(3, irKVariance(typeParameter.variance))
|
"varianceId" to irConstantInt(mapVariance(typeParameter.variance)),
|
||||||
putValueArgument(4, irBoolean(typeParameter.isReified))
|
"isReified" to irConstantBoolean(typeParameter.isReified),
|
||||||
}
|
))
|
||||||
seenTypeParameters.remove(typeParameter)
|
seenTypeParameters.remove(typeParameter)
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
private val IrTypeParameter.parentUniqueName get() = when (val parent = parent) {
|
private val IrTypeParameter.parentUniqueName
|
||||||
is IrFunction -> parent.computeFullName()
|
get() = when (val parent = parent) {
|
||||||
else -> parent.fqNameForIrSerialization.asString()
|
is IrFunction -> parent.computeFullName()
|
||||||
}
|
else -> parent.fqNameForIrSerialization.asString()
|
||||||
|
|
||||||
private fun IrBuilderWithScope.irKVariance(variance: Variance) =
|
|
||||||
IrGetEnumValueImpl(
|
|
||||||
startOffset, endOffset,
|
|
||||||
symbols.kVariance.defaultType,
|
|
||||||
when (variance) {
|
|
||||||
Variance.INVARIANT -> symbols.kVarianceInvariant
|
|
||||||
Variance.IN_VARIANCE -> symbols.kVarianceIn
|
|
||||||
Variance.OUT_VARIANCE -> symbols.kVarianceOut
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
private fun <T> IrBuilderWithScope.irKTypeLikeList(
|
|
||||||
types: List<T>,
|
|
||||||
itemType: IrType,
|
|
||||||
itemBuilder: (T) -> IrExpression
|
|
||||||
) = if (types.isEmpty()) {
|
|
||||||
irCall(symbols.emptyList, listOf(itemType))
|
|
||||||
} else {
|
|
||||||
irCall(symbols.listOf, listOf(itemType)).apply {
|
|
||||||
putValueArgument(0, IrVarargImpl(
|
|
||||||
startOffset, endOffset,
|
|
||||||
type = symbols.array.typeWith(itemType),
|
|
||||||
varargElementType = itemType,
|
|
||||||
elements = types.map { itemBuilder(it) }
|
|
||||||
))
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
private fun IrBuilderWithScope.irKTypeList(
|
private fun IrBuilderWithScope.irKTypeList(
|
||||||
types: List<IrType>,
|
types: List<IrType>,
|
||||||
leaveReifiedForLater: Boolean,
|
leaveReifiedForLater: Boolean,
|
||||||
seenTypeParameters: MutableSet<IrTypeParameter>
|
seenTypeParameters: MutableSet<IrTypeParameter>
|
||||||
) = irKTypeLikeList(types, symbols.kType.defaultType) { irKType(it, leaveReifiedForLater, seenTypeParameters) }
|
): IrConstantValue {
|
||||||
|
val itemType = symbols.kType.defaultType
|
||||||
|
val elements = irConstantArray(symbols.array.typeWith(itemType),
|
||||||
|
types.map { irKType(it, leaveReifiedForLater, seenTypeParameters) }
|
||||||
|
)
|
||||||
|
return irConstantObject(symbols.arrayAsList.owner, mapOf(
|
||||||
|
"array" to elements
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
||||||
|
// this constants are copypasted from KVarianceMapper.Companion in KTypeImpl.kt
|
||||||
|
private fun mapVariance(variance: Variance) = when (variance) {
|
||||||
|
Variance.INVARIANT -> 0
|
||||||
|
Variance.IN_VARIANCE -> 1
|
||||||
|
Variance.OUT_VARIANCE -> 2
|
||||||
|
}
|
||||||
|
|
||||||
private fun IrBuilderWithScope.irKTypeProjectionsList(
|
private fun IrBuilderWithScope.irKTypeProjectionsList(
|
||||||
irTypeArguments: List<IrTypeArgument>,
|
irTypeArguments: List<IrTypeArgument>,
|
||||||
leaveReifiedForLater: Boolean,
|
leaveReifiedForLater: Boolean,
|
||||||
seenTypeParameters: MutableSet<IrTypeParameter>
|
seenTypeParameters: MutableSet<IrTypeParameter>
|
||||||
) = irKTypeLikeList(irTypeArguments, symbols.kTypeProjection.typeWithoutArguments) {
|
): IrConstantValue {
|
||||||
irKTypeProjection(it, leaveReifiedForLater, seenTypeParameters)
|
val variance = irConstantArray(
|
||||||
}
|
symbols.intArrayType,
|
||||||
|
irTypeArguments.map { argument ->
|
||||||
private fun IrBuilderWithScope.irKTypeProjection(
|
when (argument) {
|
||||||
argument: IrTypeArgument,
|
is IrStarProjection -> irConstantInt(-1)
|
||||||
leaveReifiedForLater: Boolean,
|
is IrTypeProjection -> irConstantInt(mapVariance(argument.variance))
|
||||||
seenTypeParameters: MutableSet<IrTypeParameter>
|
else -> error("Unexpected IrTypeArgument: $argument (${argument::class})")
|
||||||
) = when (argument) {
|
}
|
||||||
is IrTypeProjection -> irCall(symbols.kTypeProjectionFactories.getValue(argument.variance)).apply {
|
})
|
||||||
dispatchReceiver = irGetObject(symbols.kTypeProjectionCompanion)
|
val type = irConstantArray(
|
||||||
putValueArgument(0, irKType(argument.type, leaveReifiedForLater, seenTypeParameters))
|
symbols.array.typeWith(symbols.kType.defaultType.makeNullable()),
|
||||||
}
|
irTypeArguments.map { argument ->
|
||||||
|
when (argument) {
|
||||||
is IrStarProjection -> irCall(symbols.kTypeProjectionStar.owner.getter!!).apply {
|
is IrStarProjection -> irConstantPrimitive(irNull())
|
||||||
dispatchReceiver = irGetObject(symbols.kTypeProjectionCompanion)
|
is IrTypeProjection -> irKType(argument.type, leaveReifiedForLater, seenTypeParameters)
|
||||||
}
|
else -> error("Unexpected IrTypeArgument: $argument (${argument::class})")
|
||||||
|
}
|
||||||
else -> error("Unexpected IrTypeArgument: $argument (${argument::class})")
|
})
|
||||||
|
return irConstantObject(
|
||||||
|
symbols.kTypeProjectionList.owner,
|
||||||
|
mapOf(
|
||||||
|
"variance" to variance,
|
||||||
|
"type" to type
|
||||||
|
))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal fun IrBuilderWithScope.irKClass(context: KonanBackendContext, symbol: IrClassSymbol): IrExpression {
|
internal fun IrBuilderWithScope.irKClass(context: KonanBackendContext, symbol: IrClassSymbol): IrConstantValue {
|
||||||
val symbols = context.ir.symbols
|
val symbols = context.ir.symbols
|
||||||
return when {
|
return when {
|
||||||
symbol.descriptor.isObjCClass() ->
|
symbol.descriptor.isObjCClass() ->
|
||||||
@@ -196,13 +189,11 @@ internal fun IrBuilderWithScope.irKClass(context: KonanBackendContext, symbol: I
|
|||||||
it is ClassDescriptor && it.fqNameUnsafe == InteropFqNames.nativePointed
|
it is ClassDescriptor && it.fqNameUnsafe == InteropFqNames.nativePointed
|
||||||
} -> irKClassUnsupported(context, "KClass for interop types is not supported yet")
|
} -> irKClassUnsupported(context, "KClass for interop types is not supported yet")
|
||||||
|
|
||||||
else -> irCall(symbols.kClassImplConstructor.owner).apply {
|
else -> irConstantObject(symbols.kClassImplIntrinsicConstructor, emptyList(), listOf(symbol.typeWithStarProjections))
|
||||||
putValueArgument(0, irCall(symbols.getClassTypeInfo, listOf(symbol.typeWithStarProjections)))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun IrBuilderWithScope.irKClassUnsupported(context: KonanBackendContext, message: String) =
|
private fun IrBuilderWithScope.irKClassUnsupported(context: KonanBackendContext, message: String) =
|
||||||
irCall(context.ir.symbols.kClassUnsupportedImplConstructor.owner).apply {
|
irConstantObject(context.ir.symbols.kClassUnsupportedImpl.owner, mapOf(
|
||||||
putValueArgument(0, irString(message))
|
"message" to irConstantString(message)
|
||||||
}
|
))
|
||||||
|
|||||||
@@ -0,0 +1,15 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||||
|
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package kotlin.native.internal
|
||||||
|
|
||||||
|
class ArrayAsList<T>(val array: Array<T>) : AbstractList<T>(), RandomAccess {
|
||||||
|
override val size: Int get() = array.size
|
||||||
|
override fun isEmpty(): Boolean = array.isEmpty()
|
||||||
|
override fun contains(element: T): Boolean = array.contains(element)
|
||||||
|
override fun get(index: Int): T = array[index]
|
||||||
|
override fun indexOf(element: T): Int = array.indexOf(element)
|
||||||
|
override fun lastIndexOf(element: T): Int = array.lastIndexOf(element)
|
||||||
|
}
|
||||||
@@ -46,7 +46,6 @@ class IntrinsicType {
|
|||||||
const val OBJC_GET_SELECTOR = "OBJC_GET_SELECTOR"
|
const val OBJC_GET_SELECTOR = "OBJC_GET_SELECTOR"
|
||||||
|
|
||||||
// Other
|
// Other
|
||||||
const val GET_CLASS_TYPE_INFO = "GET_CLASS_TYPE_INFO"
|
|
||||||
const val INTEROP_READ_BITS = "INTEROP_READ_BITS"
|
const val INTEROP_READ_BITS = "INTEROP_READ_BITS"
|
||||||
const val INTEROP_WRITE_BITS = "INTEROP_WRITE_BITS"
|
const val INTEROP_WRITE_BITS = "INTEROP_WRITE_BITS"
|
||||||
const val CREATE_UNINITIALIZED_INSTANCE = "CREATE_UNINITIALIZED_INSTANCE"
|
const val CREATE_UNINITIALIZED_INSTANCE = "CREATE_UNINITIALIZED_INSTANCE"
|
||||||
|
|||||||
@@ -78,10 +78,6 @@ private external fun findAssociatedObjectImpl(typeInfo: NativePtr, key: NativePt
|
|||||||
@GCUnsafeCall("Kotlin_Any_getTypeInfo")
|
@GCUnsafeCall("Kotlin_Any_getTypeInfo")
|
||||||
internal external fun getObjectTypeInfo(obj: Any): NativePtr
|
internal external fun getObjectTypeInfo(obj: Any): NativePtr
|
||||||
|
|
||||||
@ExportForCompiler
|
|
||||||
@TypedIntrinsic(IntrinsicType.GET_CLASS_TYPE_INFO)
|
|
||||||
internal external inline fun <reified T : Any> getClassTypeInfo(): NativePtr
|
|
||||||
|
|
||||||
@GCUnsafeCall("Kotlin_TypeInfo_getPackageName")
|
@GCUnsafeCall("Kotlin_TypeInfo_getPackageName")
|
||||||
private external fun getPackageName(typeInfo: NativePtr, checkFlags: Boolean): String?
|
private external fun getPackageName(typeInfo: NativePtr, checkFlags: Boolean): String?
|
||||||
|
|
||||||
|
|||||||
@@ -7,13 +7,60 @@ package kotlin.native.internal
|
|||||||
|
|
||||||
import kotlin.reflect.*
|
import kotlin.reflect.*
|
||||||
|
|
||||||
internal class KTypeImpl(
|
internal object KVarianceMapper {
|
||||||
|
// this constants are copypasted to ReflectionSupport.kt
|
||||||
|
const val VARIANCE_STAR = -1
|
||||||
|
const val VARIANCE_INVARIANT = 0
|
||||||
|
const val VARIANCE_IN = 1
|
||||||
|
const val VARIANCE_OUT = 2
|
||||||
|
|
||||||
|
fun idByVariance(variance: KVariance) = when (variance) {
|
||||||
|
KVariance.INVARIANT -> VARIANCE_INVARIANT
|
||||||
|
KVariance.IN -> VARIANCE_IN
|
||||||
|
KVariance.OUT -> VARIANCE_OUT
|
||||||
|
}
|
||||||
|
|
||||||
|
fun varianceById(id: Int) = when (id) {
|
||||||
|
VARIANCE_STAR -> null
|
||||||
|
VARIANCE_INVARIANT -> KVariance.INVARIANT
|
||||||
|
VARIANCE_IN -> KVariance.IN
|
||||||
|
VARIANCE_OUT -> KVariance.OUT
|
||||||
|
else -> throw IllegalStateException("Unknown variance id ${id}")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This class is used to avoid having enum inside KType class
|
||||||
|
* Static initialization for enum objects is not supported yet,
|
||||||
|
* so to initialize KType statically we need to avoid them.
|
||||||
|
*
|
||||||
|
* When this issue is resolved, this class can be replaced with just ArrayList
|
||||||
|
*/
|
||||||
|
internal class KTypeProjectionList(val variance: IntArray, val type: Array<KType?>) : AbstractList<KTypeProjection>() {
|
||||||
|
override val size
|
||||||
|
get() = variance.size
|
||||||
|
|
||||||
|
|
||||||
|
override fun get(index: Int) : KTypeProjection {
|
||||||
|
AbstractList.checkElementIndex(index, size)
|
||||||
|
val kVariance = KVarianceMapper.varianceById(variance[index]) ?: return KTypeProjection.STAR
|
||||||
|
return KTypeProjection(kVariance, type[index])
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
internal class KTypeImpl<T>(
|
||||||
override val classifier: KClassifier?,
|
override val classifier: KClassifier?,
|
||||||
override val arguments: List<KTypeProjection>,
|
override val arguments: List<KTypeProjection>,
|
||||||
override val isMarkedNullable: Boolean
|
override val isMarkedNullable: Boolean
|
||||||
) : KType {
|
) : KType {
|
||||||
|
|
||||||
|
@ExportForCompiler
|
||||||
|
@ConstantConstructorIntrinsic("KTYPE_IMPL")
|
||||||
|
constructor() : this(null, TODO("This is intrinsic constructor and it shouldn't be used directly"), false)
|
||||||
|
|
||||||
override fun equals(other: Any?) =
|
override fun equals(other: Any?) =
|
||||||
other is KTypeImpl &&
|
other is KTypeImpl<*> &&
|
||||||
this.classifier == other.classifier &&
|
this.classifier == other.classifier &&
|
||||||
this.arguments == other.arguments &&
|
this.arguments == other.arguments &&
|
||||||
this.isMarkedNullable == other.isMarkedNullable
|
this.isMarkedNullable == other.isMarkedNullable
|
||||||
|
|||||||
@@ -11,9 +11,15 @@ internal class KTypeParameterImpl(
|
|||||||
override val name: String,
|
override val name: String,
|
||||||
private val containerFqName: String,
|
private val containerFqName: String,
|
||||||
override val upperBounds: List<KType>,
|
override val upperBounds: List<KType>,
|
||||||
override val variance: KVariance,
|
val varianceId: Int, // mapping is used to make static initialization possible
|
||||||
override val isReified: Boolean
|
override val isReified: Boolean
|
||||||
) : KTypeParameter {
|
) : KTypeParameter {
|
||||||
|
override val variance: KVariance
|
||||||
|
get() = KVarianceMapper.varianceById(varianceId)!!
|
||||||
|
|
||||||
|
constructor(name: String, containerFqName: String, upperBounds: List<KType>, variance: KVariance, isReified: Boolean) :
|
||||||
|
this(name, containerFqName, upperBounds, KVarianceMapper.idByVariance(variance), isReified)
|
||||||
|
|
||||||
override fun toString(): String = when (variance) {
|
override fun toString(): String = when (variance) {
|
||||||
KVariance.INVARIANT -> ""
|
KVariance.INVARIANT -> ""
|
||||||
KVariance.IN -> "in "
|
KVariance.IN -> "in "
|
||||||
|
|||||||
Reference in New Issue
Block a user