Get rid of unsafe cast function usages in :kotlin-native:backend.native

This commit is contained in:
Svyatoslav Scherbina
2022-10-07 12:25:24 +02:00
committed by Space Team
parent 3e1eddcf54
commit 2987340edd
12 changed files with 30 additions and 39 deletions
-1
View File
@@ -410,7 +410,6 @@ val projectsWithOptInToUnsafeCastFunctionsFromAddToStdLib by extra {
":js:js.tests",
":kotlin-build-common",
":kotlin-gradle-plugin",
":kotlin-native:backend.native",
":kotlin-reflect-api",
":kotlin-scripting-jvm-host-test",
":native:frontend.native",
@@ -67,7 +67,7 @@ class K2Native : CLICompiler<K2NativeCompilerArguments>() {
messageCollector.report(ERROR, "K2 does not support Native target right now")
return ExitCode.COMPILATION_ERROR
}
configuration.put(CLIConfigurationKeys.PHASE_CONFIG, createPhaseConfig(toplevelPhase, arguments, messageCollector))
configuration.put(CLIConfigurationKeys.PHASE_CONFIG, createPhaseConfig(toplevelPhaseErased, arguments, messageCollector))
val enoughArguments = arguments.freeArgs.isNotEmpty() || arguments.isUsefulWithoutFreeArgs
if (!enoughArguments) {
@@ -15,7 +15,6 @@ import org.jetbrains.kotlin.konan.library.KonanLibrary
import org.jetbrains.kotlin.library.SearchPathResolver
import org.jetbrains.kotlin.library.isInterop
import org.jetbrains.kotlin.library.toUnresolvedLibraries
import org.jetbrains.kotlin.utils.addToStdlib.cast
internal fun Context.getExportedDependencies(): List<ModuleDescriptor> = getDescriptorsFromLibraries((config.resolve.exportedLibraries + config.resolve.includedLibraries).toSet())
internal fun Context.getIncludedLibraryDescriptors(): List<ModuleDescriptor> = getDescriptorsFromLibraries(config.resolve.includedLibraries.toSet())
@@ -165,7 +164,7 @@ private fun getFeaturedLibraries(
val remainingFeaturedLibraries = featuredLibraryFiles.toMutableSet()
val result = mutableListOf<KonanLibrary>()
//TODO: please add type checks before cast.
val libraries = resolvedLibraries.getFullList(null).cast<List<KonanLibrary>>()
val libraries = resolvedLibraries.getFullList(null).map { it as KonanLibrary }
for (library in libraries) {
val libraryFile = library.libraryFile
@@ -25,7 +25,6 @@ import org.jetbrains.kotlin.konan.util.KonanHomeProvider
import org.jetbrains.kotlin.konan.util.visibleName
import org.jetbrains.kotlin.library.resolver.TopologicalLibraryOrder
import org.jetbrains.kotlin.util.removeSuffixIfPresent
import org.jetbrains.kotlin.utils.addToStdlib.cast
class KonanConfig(val project: Project, val configuration: CompilerConfiguration) {
@@ -241,7 +240,7 @@ class KonanConfig(val project: Project, val configuration: CompilerConfiguration
fun librariesWithDependencies(moduleDescriptor: ModuleDescriptor?): List<KonanLibrary> {
if (moduleDescriptor == null) error("purgeUnneeded() only works correctly after resolve is over, and we have successfully marked package files as needed or not needed.")
return resolvedLibraries.filterRoots { (!it.isDefault && !this.purgeUserLibs) || it.isNeededForLink }.getFullList(TopologicalLibraryOrder).cast()
return resolvedLibraries.filterRoots { (!it.isDefault && !this.purgeUserLibs) || it.isNeededForLink }.getFullList(TopologicalLibraryOrder).map { it as KonanLibrary }
}
val shouldCoverSources = configuration.getBoolean(KonanConfigKeys.COVERAGE)
@@ -9,7 +9,6 @@ import org.jetbrains.kotlin.konan.library.KonanLibrary
import org.jetbrains.kotlin.konan.target.*
import org.jetbrains.kotlin.library.resolver.TopologicalLibraryOrder
import org.jetbrains.kotlin.library.uniqueName
import org.jetbrains.kotlin.utils.addToStdlib.cast
internal fun determineLinkerOutput(context: Context): LinkerOutputKind =
when (context.config.produce) {
@@ -56,11 +55,11 @@ internal class CacheStorage(val context: Context) {
private fun saveCacheBitcodeDependencies() {
val bitcodeDependencies = context.config.resolvedLibraries
.getFullList(TopologicalLibraryOrder)
.map { it as KonanLibrary }
.filter {
require(it is KonanLibrary)
context.generationState.llvmImports.bitcodeIsUsed(it)
&& it != context.config.cacheSupport.libraryToCache?.klib // Skip loops.
}.cast<List<KonanLibrary>>()
}
outputFiles.bitcodeDependenciesFile!!.writeLines(bitcodeDependencies.map { it.uniqueName })
}
@@ -500,8 +500,7 @@ private val singleCompilation = NamedCompilerPhase(
lower = entireBackend
)
// Have to hide Context as type parameter in order to expose toplevelPhase outside of this module.
val toplevelPhase: CompilerPhase<*, Unit, Unit> = namedUnitPhase(
internal val toplevelPhase: CompilerPhase<Context, Unit, Unit> = namedUnitPhase(
name = "Compiler",
description = "The whole compilation process",
lower = middleEnd then
@@ -509,6 +508,10 @@ val toplevelPhase: CompilerPhase<*, Unit, Unit> = namedUnitPhase(
umbrellaCompilation
)
// Have to hide Context as type parameter in order to expose toplevelPhase outside of this module.
val toplevelPhaseErased: CompilerPhase<*, Unit, Unit>
get() = toplevelPhase
internal fun PhaseConfig.disableIf(phase: AnyNamedPhase, condition: Boolean) {
if (condition) disable(phase)
}
@@ -24,8 +24,6 @@ import org.jetbrains.kotlin.ir.util.*
import org.jetbrains.kotlin.resolve.annotations.argumentValue
import org.jetbrains.kotlin.resolve.constants.StringValue
import org.jetbrains.kotlin.resolve.descriptorUtil.module
import org.jetbrains.kotlin.utils.addToStdlib.cast
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
/**
* List of all implemented interfaces (including those which implemented by a super class)
@@ -271,20 +269,20 @@ internal fun IrClass.isFrozen(context: Context): Boolean {
}
}
fun IrConstructorCall.getAnnotationStringValue() = getValueArgument(0).safeAs<IrConst<String>>()?.value
fun IrConstructorCall.getAnnotationStringValue() = (getValueArgument(0) as? IrConst<*>)?.value as String?
fun IrConstructorCall.getAnnotationStringValue(name: String): String {
val parameter = symbol.owner.valueParameters.single { it.name.asString() == name }
return getValueArgument(parameter.index).cast<IrConst<String>>().value
return (getValueArgument(parameter.index) as IrConst<*>).value as String
}
fun AnnotationDescriptor.getAnnotationStringValue(name: String): String {
return argumentValue(name)?.safeAs<StringValue>()?.value ?: error("Expected value $name at annotation $this")
return (argumentValue(name) as? StringValue)?.value ?: error("Expected value $name at annotation $this")
}
fun <T> IrConstructorCall.getAnnotationValueOrNull(name: String): T? {
inline fun <reified T> IrConstructorCall.getAnnotationValueOrNull(name: String): T? {
val parameter = symbol.owner.valueParameters.atMostOne { it.name.asString() == name }
return parameter?.let { getValueArgument(it.index)?.let { (it.cast<IrConst<T>>()).value } }
return parameter?.let { getValueArgument(it.index)?.let { (it as IrConst<*>).value as T } }
}
fun IrFunction.externalSymbolOrThrow(): String? {
@@ -7,7 +7,6 @@ package org.jetbrains.kotlin.backend.konan.driver
import kotlinx.cinterop.usingJvmCInteropCallbacks
import org.jetbrains.kotlin.analyzer.AnalysisResult
import org.jetbrains.kotlin.backend.common.phaser.CompilerPhase
import org.jetbrains.kotlin.backend.common.phaser.invokeToplevel
import org.jetbrains.kotlin.backend.konan.*
import org.jetbrains.kotlin.cli.common.CLIConfigurationKeys
@@ -15,7 +14,6 @@ import org.jetbrains.kotlin.cli.common.messages.AnalyzerWithCompilerReport
import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment
import org.jetbrains.kotlin.config.languageVersionSettings
import org.jetbrains.kotlin.konan.util.usingNativeMemoryAllocator
import org.jetbrains.kotlin.utils.addToStdlib.cast
/**
* Static compiler uses statically-defined compilation pipeline and a single Context during whole compilation.
@@ -46,7 +44,7 @@ internal class StaticCompilerDriver : CompilerDriver() {
usingNativeMemoryAllocator {
usingJvmCInteropCallbacks {
try {
toplevelPhase.cast<CompilerPhase<Context, Unit, Unit>>().invokeToplevel(context.phaseConfig, context, Unit)
toplevelPhase.invokeToplevel(context.phaseConfig, context, Unit)
} finally {
context.disposeGenerationState()
}
@@ -12,8 +12,6 @@ import org.jetbrains.kotlin.backend.konan.descriptors.isInteropLibrary
import org.jetbrains.kotlin.backend.konan.llvm.KonanMetadata
import org.jetbrains.kotlin.backend.konan.serialization.KonanFileMetadataSource
import org.jetbrains.kotlin.backend.konan.serialization.KonanIrModuleFragmentImpl
import org.jetbrains.kotlin.descriptors.DescriptorVisibilities
import org.jetbrains.kotlin.descriptors.Modality
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
import org.jetbrains.kotlin.descriptors.konan.DeserializedKlibModuleOrigin
import org.jetbrains.kotlin.descriptors.konan.klibModuleOrigin
@@ -29,7 +27,6 @@ import org.jetbrains.kotlin.ir.util.*
import org.jetbrains.kotlin.library.KotlinLibrary
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
private fun IrClass.isClassTypeWithSignature(signature: IdSignature.CommonSignature): Boolean {
return signature == symbol.signature
@@ -59,8 +56,8 @@ inline fun <reified T> IrDeclaration.getAnnotationArgumentValue(fqName: FqName,
for (index in 0 until annotation.valueArgumentsCount) {
val parameter = annotation.symbol.owner.valueParameters[index]
if (parameter.name == Name.identifier(argumentName)) {
val actual = annotation.getValueArgument(index).safeAs<IrConst<T>>()
return actual?.value
val actual = annotation.getValueArgument(index) as? IrConst<*> ?: return null
return actual.value as T
}
}
return null
@@ -390,14 +390,14 @@ internal class Llvm(private val context: Context, val module: LLVMModuleRef) : R
val nativeDependenciesToLink: List<KonanLibrary> by lazy {
context.config.resolvedLibraries
.getFullList(TopologicalLibraryOrder)
.map { it as KonanLibrary }
.filter {
require(it is KonanLibrary)
(!it.isDefault && !context.config.purgeUserLibs) || imports.nativeDependenciesAreUsed(it)
}.cast<List<KonanLibrary>>()
}
}
private val immediateBitcodeDependencies: List<KonanLibrary> by lazy {
context.config.resolvedLibraries.getFullList(TopologicalLibraryOrder).cast<List<KonanLibrary>>()
context.config.resolvedLibraries.getFullList(TopologicalLibraryOrder).map { it as KonanLibrary }
.filter { (!it.isDefault && !context.config.purgeUserLibs) || imports.bitcodeIsUsed(it) }
}
@@ -440,12 +440,12 @@ internal class Llvm(private val context: Context, val module: LLVMModuleRef) : R
// libraries list being returned is also toposorted.
context.config.resolvedLibraries
.getFullList(TopologicalLibraryOrder)
.cast<List<KonanLibrary>>()
.map { it as KonanLibrary }
.filter { it in set }
}
val bitcodeToLink: List<KonanLibrary> by lazy {
(context.config.resolvedLibraries.getFullList(TopologicalLibraryOrder).cast<List<KonanLibrary>>())
context.config.resolvedLibraries.getFullList(TopologicalLibraryOrder).map { it as KonanLibrary }
.filter { shouldContainBitcode(it) }
}
@@ -22,7 +22,6 @@ import org.jetbrains.kotlin.ir.types.classOrNull
import org.jetbrains.kotlin.ir.types.defaultType
import org.jetbrains.kotlin.ir.types.getClass
import org.jetbrains.kotlin.ir.util.*
import org.jetbrains.kotlin.utils.addToStdlib.cast
private class InteropCallContext(
val symbols: KonanSymbols,
@@ -329,7 +328,7 @@ private fun InteropCallContext.generateEnumVarValueAccess(callSite: IrCall): IrE
private fun InteropCallContext.generateMemberAtAccess(callSite: IrCall): IrExpression {
val accessor = callSite.symbol.owner
val memberAt = accessor.getAnnotation(RuntimeNames.cStructMemberAt)!!
val offset = memberAt.getValueArgument(0).cast<IrConst<Long>>().value
val offset = (memberAt.getValueArgument(0) as IrConst<*>).value as Long
val fieldPointer = calculateFieldPointer(callSite.dispatchReceiver!!, offset)
return when {
accessor.isGetter -> {
@@ -361,7 +360,7 @@ private fun InteropCallContext.generateMemberAtAccess(callSite: IrCall): IrExpre
private fun InteropCallContext.generateArrayMemberAtAccess(callSite: IrCall): IrExpression {
val accessor = callSite.symbol.owner
val memberAt = accessor.getAnnotation(RuntimeNames.cStructArrayMemberAt)!!
val offset = memberAt.getValueArgument(0).cast<IrConst<Long>>().value
val offset = (memberAt.getValueArgument(0) as IrConst<*>).value as Long
val fieldPointer = calculateFieldPointer(callSite.dispatchReceiver!!, offset)
return builder.irCall(symbols.interopInterpretCPointer).also {
it.putValueArgument(0, fieldPointer)
@@ -420,8 +419,8 @@ private fun InteropCallContext.readBits(
private fun InteropCallContext.generateBitFieldAccess(callSite: IrCall): IrExpression {
val accessor = callSite.symbol.owner
val bitField = accessor.getAnnotation(RuntimeNames.cStructBitField)!!
val offset = bitField.getValueArgument(0).cast<IrConst<Long>>().value
val size = bitField.getValueArgument(1).cast<IrConst<Int>>().value
val offset = (bitField.getValueArgument(0) as IrConst<*>).value as Long
val size = (bitField.getValueArgument(1) as IrConst<*>).value as Int
val base = builder.irCall(symbols.interopNativePointedRawPtrGetter).also {
it.dispatchReceiver = callSite.dispatchReceiver!!
}
@@ -964,9 +964,9 @@ private fun DeclarationDescriptor.getObjCName(): ObjCName {
var swiftName: String? = null
var isExact = false
annotations.findAnnotation(KonanFqNames.objCName)?.let { annotation ->
objCName = annotation.argumentValue("name")?.value?.cast()
swiftName = annotation.argumentValue("swiftName")?.value?.cast()
isExact = annotation.argumentValue("exact")?.value?.cast() ?: false
objCName = annotation.argumentValue("name")?.value as String?
swiftName = annotation.argumentValue("swiftName")?.value as String?
isExact = annotation.argumentValue("exact")?.value as Boolean? ?: false
}
return ObjCName(name.asString(), objCName, swiftName, isExact)
}