[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 leakDetectorCandidate = FqName("kotlin.native.internal.LeakDetectorCandidate")
|
||||||
val canBePrecreated = FqName("kotlin.native.internal.CanBePrecreated")
|
val canBePrecreated = FqName("kotlin.native.internal.CanBePrecreated")
|
||||||
val typedIntrinsic = FqName("kotlin.native.internal.TypedIntrinsic")
|
val typedIntrinsic = FqName("kotlin.native.internal.TypedIntrinsic")
|
||||||
|
val constantConstructorIntrinsic = FqName("kotlin.native.internal.ConstantConstructorIntrinsic")
|
||||||
val objCMethod = FqName("kotlinx.cinterop.ObjCMethod")
|
val objCMethod = FqName("kotlinx.cinterop.ObjCMethod")
|
||||||
val hasFinalizer = FqName("kotlin.native.internal.HasFinalizer")
|
val hasFinalizer = FqName("kotlin.native.internal.HasFinalizer")
|
||||||
val hasFreezeHook = FqName("kotlin.native.internal.HasFreezeHook")
|
val hasFreezeHook = FqName("kotlin.native.internal.HasFreezeHook")
|
||||||
|
|||||||
+3
@@ -43,6 +43,9 @@ internal val IrClass.implementedInterfaces: List<IrClass>
|
|||||||
internal val IrFunction.isTypedIntrinsic: Boolean
|
internal val IrFunction.isTypedIntrinsic: Boolean
|
||||||
get() = annotations.hasAnnotation(KonanFqNames.typedIntrinsic)
|
get() = annotations.hasAnnotation(KonanFqNames.typedIntrinsic)
|
||||||
|
|
||||||
|
internal val IrConstructor.isConstantConstructorIntrinsic: Boolean
|
||||||
|
get() = annotations.hasAnnotation(KonanFqNames.constantConstructorIntrinsic)
|
||||||
|
|
||||||
internal val arrayTypes = setOf(
|
internal val arrayTypes = setOf(
|
||||||
"kotlin.Array",
|
"kotlin.Array",
|
||||||
"kotlin.ByteArray",
|
"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.IrType
|
||||||
import org.jetbrains.kotlin.ir.types.defaultType
|
import org.jetbrains.kotlin.ir.types.defaultType
|
||||||
import org.jetbrains.kotlin.ir.types.typeWith
|
import org.jetbrains.kotlin.ir.types.typeWith
|
||||||
import org.jetbrains.kotlin.ir.util.ReferenceSymbolTable
|
import org.jetbrains.kotlin.ir.util.*
|
||||||
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.name.ClassId
|
import org.jetbrains.kotlin.name.ClassId
|
||||||
import org.jetbrains.kotlin.name.FqName
|
import org.jetbrains.kotlin.name.FqName
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
@@ -447,11 +444,13 @@ internal class KonanSymbols(
|
|||||||
val getClassTypeInfo = internalFunction("getClassTypeInfo")
|
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() }
|
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 kClassUnsupportedImpl = internalClass("KClassUnsupportedImpl")
|
||||||
val kClassUnsupportedImplConstructor by lazy { kClassUnsupportedImpl.constructors.single() }
|
val kClassUnsupportedImplConstructor by lazy { kClassUnsupportedImpl.constructors.single() }
|
||||||
val kTypeParameterImpl = internalClass("KTypeParameterImpl")
|
val kTypeParameterImpl = internalClass("KTypeParameterImpl")
|
||||||
val kTypeImpl = internalClass("KTypeImpl")
|
val kTypeImpl = internalClass("KTypeImpl")
|
||||||
|
val kTypeImplIntrinsicConstructor by lazy { kTypeImpl.constructors.single { it.descriptor.valueParameters.isEmpty() } }
|
||||||
val kTypeImplForTypeParametersWithRecursiveBounds = internalClass("KTypeImplForTypeParametersWithRecursiveBounds")
|
val kTypeImplForTypeParametersWithRecursiveBounds = internalClass("KTypeImplForTypeParametersWithRecursiveBounds")
|
||||||
|
|
||||||
val kTypeProjection = symbolTable.referenceClass(context.reflectionTypes.kTypeProjection)
|
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 kotlinx.cinterop.cValuesOf
|
||||||
import llvm.*
|
import llvm.*
|
||||||
|
import org.jetbrains.kotlin.backend.konan.KonanFqNames
|
||||||
import org.jetbrains.kotlin.backend.konan.MemoryModel
|
import org.jetbrains.kotlin.backend.konan.MemoryModel
|
||||||
import org.jetbrains.kotlin.backend.konan.RuntimeNames
|
import org.jetbrains.kotlin.backend.konan.RuntimeNames
|
||||||
import org.jetbrains.kotlin.backend.konan.descriptors.getAnnotationStringValue
|
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.descriptors.isTypedIntrinsic
|
||||||
import org.jetbrains.kotlin.backend.konan.llvm.objc.genObjCSelector
|
import org.jetbrains.kotlin.backend.konan.llvm.objc.genObjCSelector
|
||||||
import org.jetbrains.kotlin.backend.konan.reportCompilationError
|
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.IrClass
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrFunction
|
import org.jetbrains.kotlin.ir.declarations.IrFunction
|
||||||
import org.jetbrains.kotlin.ir.expressions.*
|
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.types.getClass
|
||||||
import org.jetbrains.kotlin.ir.util.dump
|
import org.jetbrains.kotlin.ir.util.dump
|
||||||
import org.jetbrains.kotlin.ir.util.findAnnotation
|
import org.jetbrains.kotlin.ir.util.findAnnotation
|
||||||
@@ -93,6 +96,11 @@ internal enum class IntrinsicType {
|
|||||||
WORKER_EXECUTE
|
WORKER_EXECUTE
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal enum class ConstantConstructorIntrinsicType {
|
||||||
|
KCLASS_IMPL,
|
||||||
|
KTYPE_IMPL,
|
||||||
|
}
|
||||||
|
|
||||||
// Explicit and single interface between Intrinsic Generator and IrToBitcode.
|
// Explicit and single interface between Intrinsic Generator and IrToBitcode.
|
||||||
internal interface IntrinsicGeneratorEnvironment {
|
internal interface IntrinsicGeneratorEnvironment {
|
||||||
|
|
||||||
@@ -125,6 +133,16 @@ private fun getIntrinsicType(callSite: IrFunctionAccessExpression): IntrinsicTyp
|
|||||||
return IntrinsicType.valueOf(value)
|
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) {
|
internal class IntrinsicGenerator(private val environment: IntrinsicGeneratorEnvironment) {
|
||||||
|
|
||||||
private val codegen = environment.codegen
|
private val codegen = environment.codegen
|
||||||
@@ -260,11 +278,28 @@ internal class IntrinsicGenerator(private val environment: IntrinsicGeneratorEnv
|
|||||||
reportSpecialIntrinsic(intrinsicType)
|
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 =
|
private fun reportSpecialIntrinsic(intrinsicType: IntrinsicType): Nothing =
|
||||||
context.reportCompilationError("$intrinsicType should be handled by `tryEvaluateSpecialCall`")
|
context.reportCompilationError("$intrinsicType should be handled by `tryEvaluateSpecialCall`")
|
||||||
|
|
||||||
private fun reportNonLoweredIntrinsic(intrinsicType: IntrinsicType): Nothing =
|
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 =
|
private fun FunctionGenerationContext.emitGetContinuation(): LLVMValueRef =
|
||||||
environment.continuation
|
environment.continuation
|
||||||
|
|||||||
@@ -100,6 +100,10 @@ internal annotation class PointsTo(vararg val onWhom: Int)
|
|||||||
@Retention(AnnotationRetention.BINARY)
|
@Retention(AnnotationRetention.BINARY)
|
||||||
internal annotation class TypedIntrinsic(val kind: String)
|
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
|
* Indicates that `@SymbolName external` function is implemented in library-stored bitcode
|
||||||
* and doesn't have native dependencies.
|
* and doesn't have native dependencies.
|
||||||
|
|||||||
@@ -9,6 +9,11 @@ import kotlin.reflect.KClass
|
|||||||
|
|
||||||
@ExportForCompiler
|
@ExportForCompiler
|
||||||
internal class KClassImpl<T : Any>(private val typeInfo: NativePtr) : KClass<T> {
|
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 (``)
|
// TODO: consider replacing '$' by another delimeter that can't be used in class name specified with backticks (``)
|
||||||
override val simpleName: String?
|
override val simpleName: String?
|
||||||
get() = getRelativeName(typeInfo, true)?.substringAfterLast('.')?.substringAfterLast('$')
|
get() = getRelativeName(typeInfo, true)?.substringAfterLast('.')?.substringAfterLast('$')
|
||||||
|
|||||||
Reference in New Issue
Block a user