Use runtime bitcode to get size of primitive types
As an alternative to explicitly setting type size in konan.properties or backend code we can "ask" LLVM about it. Unfortunately, there is no Clang/LLVM API for it, so we use a trivial workaround: Create dumb function in runtime code, and then extract info about return type size using LLVM.
This commit is contained in:
committed by
TeamCityServer
parent
790fea635d
commit
9b1498abad
+23
@@ -502,6 +502,9 @@ internal class Llvm(val context: Context, val llvmModule: LLVMModuleRef) {
|
||||
val Kotlin_ObjCExport_createContinuationArgument by lazyRtFunction
|
||||
val Kotlin_ObjCExport_resumeContinuation by lazyRtFunction
|
||||
|
||||
private val Kotlin_ObjCExport_NSIntegerTypeProvider by lazyRtFunction
|
||||
private val Kotlin_longTypeProvider by lazyRtFunction
|
||||
|
||||
val Kotlin_mm_safePointFunctionEpilogue by lazyRtFunction
|
||||
val Kotlin_mm_safePointWhileLoopBody by lazyRtFunction
|
||||
val Kotlin_mm_safePointExceptionUnwind by lazyRtFunction
|
||||
@@ -593,6 +596,26 @@ internal class Llvm(val context: Context, val llvmModule: LLVMModuleRef) {
|
||||
val llvmFloat = floatType
|
||||
val llvmDouble = doubleType
|
||||
val llvmVector128 = vector128Type
|
||||
|
||||
private fun getSizeOfReturnTypeInBits(functionPointer: LLVMValueRef): Long {
|
||||
// LLVMGetElementType is called because we need to dereference a pointer to function.
|
||||
val nsIntegerType = LLVMGetReturnType(LLVMGetElementType(functionPointer.type))
|
||||
return LLVMSizeOfTypeInBits(runtime.targetData, nsIntegerType)
|
||||
}
|
||||
|
||||
/**
|
||||
* Width of NSInteger in bits.
|
||||
*/
|
||||
val nsIntegerTypeWidth: Long by lazy {
|
||||
getSizeOfReturnTypeInBits(Kotlin_ObjCExport_NSIntegerTypeProvider)
|
||||
}
|
||||
|
||||
/**
|
||||
* Width of C long type in bits.
|
||||
*/
|
||||
val longTypeWidth: Long by lazy {
|
||||
getSizeOfReturnTypeInBits(Kotlin_longTypeProvider)
|
||||
}
|
||||
}
|
||||
|
||||
class IrStaticInitializer(val konanLibrary: KotlinLibrary?, val initializer: LLVMValueRef)
|
||||
|
||||
+5
-1
@@ -194,7 +194,11 @@ internal class BlockGenerator(private val codegen: CodeGenerator) {
|
||||
}
|
||||
|
||||
fun org.jetbrains.kotlin.backend.konan.Context.LongInt(value: Long) =
|
||||
if (is64BitLong()) Int64(value) else Int32(value.toInt())
|
||||
when (val longWidth = llvm.longTypeWidth) {
|
||||
32L -> Int32(value.toInt())
|
||||
64L -> Int64(value)
|
||||
else -> error("Unexpected width of long type: $longWidth")
|
||||
}
|
||||
|
||||
private fun generateDescriptorForBlock(blockType: BlockType): ConstValue {
|
||||
val numberOfParameters = blockType.numberOfParameters
|
||||
|
||||
+7
-53
@@ -29,7 +29,7 @@ import org.jetbrains.kotlin.ir.symbols.IrConstructorSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
|
||||
import org.jetbrains.kotlin.ir.types.*
|
||||
import org.jetbrains.kotlin.ir.util.*
|
||||
import org.jetbrains.kotlin.konan.target.KonanTarget
|
||||
import org.jetbrains.kotlin.konan.target.AppleConfigurables
|
||||
import org.jetbrains.kotlin.konan.target.LinkerOutputKind
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.utils.DFS
|
||||
@@ -1669,56 +1669,10 @@ private val TypeBridge.objCEncoding: String get() = when (this) {
|
||||
is ValueTypeBridge -> this.objCValueType.encoding
|
||||
}
|
||||
|
||||
private fun Context.is64BitNSInteger(): Boolean = when (val target = this.config.target) {
|
||||
KonanTarget.IOS_X64,
|
||||
KonanTarget.IOS_ARM64,
|
||||
KonanTarget.TVOS_ARM64,
|
||||
KonanTarget.TVOS_X64,
|
||||
KonanTarget.MACOS_X64,
|
||||
KonanTarget.MACOS_ARM64,
|
||||
KonanTarget.WATCHOS_X64 -> true
|
||||
KonanTarget.WATCHOS_ARM64,
|
||||
KonanTarget.WATCHOS_ARM32,
|
||||
KonanTarget.WATCHOS_X86,
|
||||
KonanTarget.IOS_ARM32 -> false
|
||||
KonanTarget.ANDROID_X64,
|
||||
KonanTarget.ANDROID_X86,
|
||||
KonanTarget.ANDROID_ARM32,
|
||||
KonanTarget.ANDROID_ARM64,
|
||||
KonanTarget.LINUX_X64,
|
||||
KonanTarget.MINGW_X86,
|
||||
KonanTarget.MINGW_X64,
|
||||
KonanTarget.LINUX_ARM64,
|
||||
KonanTarget.LINUX_ARM32_HFP,
|
||||
KonanTarget.LINUX_MIPS32,
|
||||
KonanTarget.LINUX_MIPSEL32,
|
||||
KonanTarget.WASM32,
|
||||
is KonanTarget.ZEPHYR -> error("Target $target has no support for NSInteger type.")
|
||||
}
|
||||
|
||||
internal fun Context.is64BitLong(): Boolean = when (this.config.target) {
|
||||
KonanTarget.IOS_X64,
|
||||
KonanTarget.IOS_ARM64,
|
||||
KonanTarget.TVOS_ARM64,
|
||||
KonanTarget.TVOS_X64,
|
||||
KonanTarget.ANDROID_X64,
|
||||
KonanTarget.ANDROID_ARM64,
|
||||
KonanTarget.LINUX_ARM64,
|
||||
KonanTarget.MINGW_X64,
|
||||
KonanTarget.LINUX_X64,
|
||||
KonanTarget.MACOS_X64,
|
||||
KonanTarget.MACOS_ARM64,
|
||||
KonanTarget.WATCHOS_X64 -> true
|
||||
KonanTarget.WATCHOS_ARM64,
|
||||
KonanTarget.WATCHOS_ARM32,
|
||||
KonanTarget.ANDROID_X86,
|
||||
KonanTarget.ANDROID_ARM32,
|
||||
KonanTarget.WATCHOS_X86,
|
||||
KonanTarget.MINGW_X86,
|
||||
KonanTarget.LINUX_ARM32_HFP,
|
||||
KonanTarget.LINUX_MIPS32,
|
||||
KonanTarget.LINUX_MIPSEL32,
|
||||
KonanTarget.WASM32,
|
||||
is KonanTarget.ZEPHYR,
|
||||
KonanTarget.IOS_ARM32 -> false
|
||||
private fun Context.is64BitNSInteger(): Boolean {
|
||||
val configurables = this.config.platform.configurables
|
||||
require(configurables is AppleConfigurables) {
|
||||
"Target ${configurables.target} has no support for NSInteger type."
|
||||
}
|
||||
return llvm.nsIntegerTypeWidth == 64L
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user