[K/N] Introduce intrinsic constant constructors
This commit is contained in:
+1
@@ -29,6 +29,7 @@ object KonanFqNames {
|
||||
val leakDetectorCandidate = FqName("kotlin.native.internal.LeakDetectorCandidate")
|
||||
val canBePrecreated = FqName("kotlin.native.internal.CanBePrecreated")
|
||||
val typedIntrinsic = FqName("kotlin.native.internal.TypedIntrinsic")
|
||||
val constantConstructorIntrinsic = FqName("kotlin.native.internal.ConstantConstructorIntrinsic")
|
||||
val objCMethod = FqName("kotlinx.cinterop.ObjCMethod")
|
||||
val hasFinalizer = FqName("kotlin.native.internal.HasFinalizer")
|
||||
val hasFreezeHook = FqName("kotlin.native.internal.HasFreezeHook")
|
||||
|
||||
+3
@@ -43,6 +43,9 @@ internal val IrClass.implementedInterfaces: List<IrClass>
|
||||
internal val IrFunction.isTypedIntrinsic: Boolean
|
||||
get() = annotations.hasAnnotation(KonanFqNames.typedIntrinsic)
|
||||
|
||||
internal val IrConstructor.isConstantConstructorIntrinsic: Boolean
|
||||
get() = annotations.hasAnnotation(KonanFqNames.constantConstructorIntrinsic)
|
||||
|
||||
internal val arrayTypes = setOf(
|
||||
"kotlin.Array",
|
||||
"kotlin.ByteArray",
|
||||
|
||||
+4
-5
@@ -29,10 +29,7 @@ import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
|
||||
import org.jetbrains.kotlin.ir.types.IrType
|
||||
import org.jetbrains.kotlin.ir.types.defaultType
|
||||
import org.jetbrains.kotlin.ir.types.typeWith
|
||||
import org.jetbrains.kotlin.ir.util.ReferenceSymbolTable
|
||||
import org.jetbrains.kotlin.ir.util.SymbolTable
|
||||
import org.jetbrains.kotlin.ir.util.constructors
|
||||
import org.jetbrains.kotlin.ir.util.referenceFunction
|
||||
import org.jetbrains.kotlin.ir.util.*
|
||||
import org.jetbrains.kotlin.name.ClassId
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
@@ -447,11 +444,13 @@ internal class KonanSymbols(
|
||||
val getClassTypeInfo = internalFunction("getClassTypeInfo")
|
||||
val getObjectTypeInfo = internalFunction("getObjectTypeInfo")
|
||||
val kClassImpl = internalClass("KClassImpl")
|
||||
val kClassImplConstructor by lazy { kClassImpl.constructors.single() }
|
||||
val kClassImplConstructor by lazy { kClassImpl.constructors.single { it.descriptor.isPrimary } }
|
||||
val kClassImplIntrinsicConstructor by lazy { kClassImpl.constructors.single { it.descriptor.valueParameters.isEmpty() } }
|
||||
val kClassUnsupportedImpl = internalClass("KClassUnsupportedImpl")
|
||||
val kClassUnsupportedImplConstructor by lazy { kClassUnsupportedImpl.constructors.single() }
|
||||
val kTypeParameterImpl = internalClass("KTypeParameterImpl")
|
||||
val kTypeImpl = internalClass("KTypeImpl")
|
||||
val kTypeImplIntrinsicConstructor by lazy { kTypeImpl.constructors.single { it.descriptor.valueParameters.isEmpty() } }
|
||||
val kTypeImplForTypeParametersWithRecursiveBounds = internalClass("KTypeImplForTypeParametersWithRecursiveBounds")
|
||||
|
||||
val kTypeProjection = symbolTable.referenceClass(context.reflectionTypes.kTypeProjection)
|
||||
|
||||
+36
-1
@@ -2,9 +2,11 @@ package org.jetbrains.kotlin.backend.konan.llvm
|
||||
|
||||
import kotlinx.cinterop.cValuesOf
|
||||
import llvm.*
|
||||
import org.jetbrains.kotlin.backend.konan.KonanFqNames
|
||||
import org.jetbrains.kotlin.backend.konan.MemoryModel
|
||||
import org.jetbrains.kotlin.backend.konan.RuntimeNames
|
||||
import org.jetbrains.kotlin.backend.konan.descriptors.getAnnotationStringValue
|
||||
import org.jetbrains.kotlin.backend.konan.descriptors.isConstantConstructorIntrinsic
|
||||
import org.jetbrains.kotlin.backend.konan.descriptors.isTypedIntrinsic
|
||||
import org.jetbrains.kotlin.backend.konan.llvm.objc.genObjCSelector
|
||||
import org.jetbrains.kotlin.backend.konan.reportCompilationError
|
||||
@@ -12,6 +14,7 @@ import org.jetbrains.kotlin.ir.IrElement
|
||||
import org.jetbrains.kotlin.ir.declarations.IrClass
|
||||
import org.jetbrains.kotlin.ir.declarations.IrFunction
|
||||
import org.jetbrains.kotlin.ir.expressions.*
|
||||
import org.jetbrains.kotlin.ir.symbols.IrConstructorSymbol
|
||||
import org.jetbrains.kotlin.ir.types.getClass
|
||||
import org.jetbrains.kotlin.ir.util.dump
|
||||
import org.jetbrains.kotlin.ir.util.findAnnotation
|
||||
@@ -93,6 +96,11 @@ internal enum class IntrinsicType {
|
||||
WORKER_EXECUTE
|
||||
}
|
||||
|
||||
internal enum class ConstantConstructorIntrinsicType {
|
||||
KCLASS_IMPL,
|
||||
KTYPE_IMPL,
|
||||
}
|
||||
|
||||
// Explicit and single interface between Intrinsic Generator and IrToBitcode.
|
||||
internal interface IntrinsicGeneratorEnvironment {
|
||||
|
||||
@@ -125,6 +133,16 @@ private fun getIntrinsicType(callSite: IrFunctionAccessExpression): IntrinsicTyp
|
||||
return IntrinsicType.valueOf(value)
|
||||
}
|
||||
|
||||
internal fun tryGetConstantConstructorIntrinsicType(constructor: IrConstructorSymbol): ConstantConstructorIntrinsicType? =
|
||||
if (constructor.owner.isConstantConstructorIntrinsic) getConstantConstructorIntrinsicType(constructor) else null
|
||||
|
||||
private fun getConstantConstructorIntrinsicType(constructor: IrConstructorSymbol): ConstantConstructorIntrinsicType {
|
||||
val annotation = constructor.owner.annotations.findAnnotation(KonanFqNames.constantConstructorIntrinsic)!!
|
||||
val value = annotation.getAnnotationStringValue()!!
|
||||
return ConstantConstructorIntrinsicType.valueOf(value)
|
||||
}
|
||||
|
||||
|
||||
internal class IntrinsicGenerator(private val environment: IntrinsicGeneratorEnvironment) {
|
||||
|
||||
private val codegen = environment.codegen
|
||||
@@ -260,11 +278,28 @@ internal class IntrinsicGenerator(private val environment: IntrinsicGeneratorEnv
|
||||
reportSpecialIntrinsic(intrinsicType)
|
||||
}
|
||||
|
||||
fun evaluateConstantConstructorFields(constant: IrConstantObject, args: List<ConstValue>) : List<ConstValue> {
|
||||
return when (val intrinsicType = getConstantConstructorIntrinsicType(constant.constructor)) {
|
||||
ConstantConstructorIntrinsicType.KCLASS_IMPL -> {
|
||||
require(args.isEmpty())
|
||||
val typeArgument = constant.typeArguments[0]
|
||||
val typeArgumentClass = typeArgument.getClass()!!
|
||||
val typeInfo = codegen.typeInfoValue(typeArgumentClass)
|
||||
listOf(constPointer(typeInfo).bitcast(int8TypePtr))
|
||||
}
|
||||
ConstantConstructorIntrinsicType.KTYPE_IMPL ->
|
||||
reportNonLoweredIntrinsic(intrinsicType)
|
||||
}
|
||||
}
|
||||
|
||||
private fun reportSpecialIntrinsic(intrinsicType: IntrinsicType): Nothing =
|
||||
context.reportCompilationError("$intrinsicType should be handled by `tryEvaluateSpecialCall`")
|
||||
|
||||
private fun reportNonLoweredIntrinsic(intrinsicType: IntrinsicType): Nothing =
|
||||
context.reportCompilationError("Intrinsic of type $intrinsicType should be handled by previos lowering phase")
|
||||
context.reportCompilationError("Intrinsic of type $intrinsicType should be handled by previous lowering phase")
|
||||
|
||||
private fun reportNonLoweredIntrinsic(intrinsicType: ConstantConstructorIntrinsicType): Nothing =
|
||||
context.reportCompilationError("Constant constructor intrinsic of type $intrinsicType should be handled by previous lowering phase")
|
||||
|
||||
private fun FunctionGenerationContext.emitGetContinuation(): LLVMValueRef =
|
||||
environment.continuation
|
||||
|
||||
@@ -100,6 +100,10 @@ internal annotation class PointsTo(vararg val onWhom: Int)
|
||||
@Retention(AnnotationRetention.BINARY)
|
||||
internal annotation class TypedIntrinsic(val kind: String)
|
||||
|
||||
@Target(AnnotationTarget.CONSTRUCTOR)
|
||||
@Retention(AnnotationRetention.BINARY)
|
||||
internal annotation class ConstantConstructorIntrinsic(val kind: String)
|
||||
|
||||
/**
|
||||
* Indicates that `@SymbolName external` function is implemented in library-stored bitcode
|
||||
* and doesn't have native dependencies.
|
||||
|
||||
@@ -9,6 +9,11 @@ import kotlin.reflect.KClass
|
||||
|
||||
@ExportForCompiler
|
||||
internal class KClassImpl<T : Any>(private val typeInfo: NativePtr) : KClass<T> {
|
||||
|
||||
@ExportForCompiler
|
||||
@ConstantConstructorIntrinsic("KCLASS_IMPL")
|
||||
constructor() : this(TODO("This is intrinsic constructor and it shouldn't be used directly"))
|
||||
|
||||
// TODO: consider replacing '$' by another delimeter that can't be used in class name specified with backticks (``)
|
||||
override val simpleName: String?
|
||||
get() = getRelativeName(typeInfo, true)?.substringAfterLast('.')?.substringAfterLast('$')
|
||||
|
||||
Reference in New Issue
Block a user