@@ -4723,4 +4723,4 @@ private external fun kniBridge335(p0: NativePtr, p1: Int, p2: NativePtr): Unit
|
|||||||
private external fun kniBridge336(p0: NativePtr): Int
|
private external fun kniBridge336(p0: NativePtr): Int
|
||||||
private external fun kniBridge337(p0: NativePtr): Int
|
private external fun kniBridge337(p0: NativePtr): Int
|
||||||
private external fun kniBridge338(p0: NativePtr): Int
|
private external fun kniBridge338(p0: NativePtr): Int
|
||||||
private val loadLibrary = loadKonanLibrary("clangstubs")
|
private val loadLibrary = System.loadLibrary("clangstubs")
|
||||||
|
|||||||
@@ -371,7 +371,11 @@ private class CEnumType(private val rawValueCType: CType<Any>) : CType<CEnum>(ra
|
|||||||
private typealias FfiClosureImpl = LongConsumer
|
private typealias FfiClosureImpl = LongConsumer
|
||||||
private typealias UserData = FfiClosureImpl
|
private typealias UserData = FfiClosureImpl
|
||||||
|
|
||||||
private val topLevelInitializer = loadKonanLibrary("callbacks")
|
private fun loadCallbacksLibrary() {
|
||||||
|
System.loadLibrary("callbacks")
|
||||||
|
}
|
||||||
|
|
||||||
|
private val topLevelInitializer = loadCallbacksLibrary()
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -16,10 +16,6 @@
|
|||||||
|
|
||||||
package kotlinx.cinterop
|
package kotlinx.cinterop
|
||||||
|
|
||||||
import java.io.File
|
|
||||||
import java.nio.file.Files
|
|
||||||
import java.nio.file.Paths
|
|
||||||
|
|
||||||
internal fun decodeFromUtf8(bytes: ByteArray) = String(bytes)
|
internal fun decodeFromUtf8(bytes: ByteArray) = String(bytes)
|
||||||
internal fun encodeToUtf8(str: String) = str.toByteArray()
|
internal fun encodeToUtf8(str: String) = str.toByteArray()
|
||||||
|
|
||||||
@@ -86,23 +82,4 @@ inline fun <reified R : Number> Long.narrow(): R = when (R::class.java) {
|
|||||||
|
|
||||||
inline fun <reified R : Number> Number.invalidNarrowing(): R {
|
inline fun <reified R : Number> Number.invalidNarrowing(): R {
|
||||||
throw Error("unable to narrow ${this.javaClass.simpleName} \"${this}\" to ${R::class.java.simpleName}")
|
throw Error("unable to narrow ${this.javaClass.simpleName} \"${this}\" to ${R::class.java.simpleName}")
|
||||||
}
|
|
||||||
|
|
||||||
fun loadKonanLibrary(name: String) {
|
|
||||||
try {
|
|
||||||
System.loadLibrary(name)
|
|
||||||
} catch (e: UnsatisfiedLinkError) {
|
|
||||||
val fullLibraryName = System.mapLibraryName(name)
|
|
||||||
val dir = "${System.getProperty("konan.home")}/konan/nativelib"
|
|
||||||
try {
|
|
||||||
System.load("$dir/$fullLibraryName")
|
|
||||||
} catch (e: UnsatisfiedLinkError) {
|
|
||||||
val tempDir = createTempDir(directory = File(dir)).absolutePath
|
|
||||||
Files.createLink(Paths.get(tempDir, fullLibraryName), Paths.get(dir, fullLibraryName))
|
|
||||||
// TODO: Does not work on Windows. May be use FILE_FLAG_DELETE_ON_CLOSE?
|
|
||||||
File(tempDir).deleteOnExit()
|
|
||||||
File("$tempDir/$fullLibraryName").deleteOnExit()
|
|
||||||
System.load("$tempDir/$fullLibraryName")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
+3
-2
@@ -180,8 +180,9 @@ class StubIrTextEmitter(
|
|||||||
emitKotlinFileHeader()
|
emitKotlinFileHeader()
|
||||||
stubLines.forEach(out)
|
stubLines.forEach(out)
|
||||||
nativeBridges.kotlinLines.forEach(out)
|
nativeBridges.kotlinLines.forEach(out)
|
||||||
if (context.platform == KotlinPlatform.JVM)
|
if (context.platform == KotlinPlatform.JVM) {
|
||||||
out("private val loadLibrary = loadKonanLibrary(\"${context.libName}\")")
|
out("private val loadLibrary = System.loadLibrary(\"${context.libName}\")")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
private val printer = object : StubIrVisitor<StubContainer?, Unit> {
|
private val printer = object : StubIrVisitor<StubContainer?, Unit> {
|
||||||
|
|||||||
@@ -230,12 +230,6 @@ class K2Native : CLICompiler<K2NativeCompilerArguments>() {
|
|||||||
doMain(K2Native(), args)
|
doMain(K2Native(), args)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@JvmStatic fun mainNoExit(args: Array<String>) {
|
|
||||||
profile("Total compiler main()") {
|
|
||||||
if (CLITool.doMainNoExit(K2Native(), args) != ExitCode.OK)
|
|
||||||
throw KonanCompilationException("Compilation finished with errors")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -344,4 +338,4 @@ private fun parseLibrariesToCache(
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun main(args: Array<String>) = K2Native.main(args)
|
fun main(args: Array<String>) = K2Native.main(args)
|
||||||
fun mainNoExit(args: Array<String>) = K2Native.mainNoExit(args)
|
|
||||||
|
|||||||
+2
-2
@@ -233,8 +233,8 @@ private class ExportedElement(val kind: ElementKind,
|
|||||||
cname = "_konan_function_${owner.nextFunctionIndex()}"
|
cname = "_konan_function_${owner.nextFunctionIndex()}"
|
||||||
// Produce type getter.
|
// Produce type getter.
|
||||||
val getTypeFunction = LLVMAddFunction(context.llvmModule, "${cname}_type", owner.kGetTypeFuncType)!!
|
val getTypeFunction = LLVMAddFunction(context.llvmModule, "${cname}_type", owner.kGetTypeFuncType)!!
|
||||||
val builder = LLVMCreateBuilderInContext(llvmContext)!!
|
val builder = LLVMCreateBuilder()!!
|
||||||
val bb = LLVMAppendBasicBlockInContext(llvmContext, getTypeFunction, "")!!
|
val bb = LLVMAppendBasicBlock(getTypeFunction, "")!!
|
||||||
LLVMPositionBuilderAtEnd(builder, bb)
|
LLVMPositionBuilderAtEnd(builder, bb)
|
||||||
LLVMBuildRet(builder, irClass.typeInfoPtr.llvm)
|
LLVMBuildRet(builder, irClass.typeInfoPtr.llvm)
|
||||||
LLVMDisposeBuilder(builder)
|
LLVMDisposeBuilder(builder)
|
||||||
|
|||||||
+2
-15
@@ -5,7 +5,8 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.backend.konan
|
package org.jetbrains.kotlin.backend.konan
|
||||||
|
|
||||||
import llvm.*
|
import llvm.LLVMDumpModule
|
||||||
|
import llvm.LLVMModuleRef
|
||||||
import org.jetbrains.kotlin.backend.common.DumpIrTreeWithDescriptorsVisitor
|
import org.jetbrains.kotlin.backend.common.DumpIrTreeWithDescriptorsVisitor
|
||||||
import org.jetbrains.kotlin.backend.common.descriptors.WrappedSimpleFunctionDescriptor
|
import org.jetbrains.kotlin.backend.common.descriptors.WrappedSimpleFunctionDescriptor
|
||||||
import org.jetbrains.kotlin.backend.common.descriptors.WrappedTypeParameterDescriptor
|
import org.jetbrains.kotlin.backend.common.descriptors.WrappedTypeParameterDescriptor
|
||||||
@@ -327,20 +328,6 @@ internal class Context(config: KonanConfig) : KonanBackendContext(config) {
|
|||||||
lateinit var bitcodeFileName: String
|
lateinit var bitcodeFileName: String
|
||||||
lateinit var library: KonanLibraryLayout
|
lateinit var library: KonanLibraryLayout
|
||||||
|
|
||||||
private var llvmDisposed = false
|
|
||||||
|
|
||||||
fun disposeLlvm() {
|
|
||||||
if (llvmDisposed) return
|
|
||||||
if (::debugInfo.isInitialized)
|
|
||||||
DIDispose(debugInfo.builder)
|
|
||||||
if (llvmModule != null)
|
|
||||||
LLVMDisposeModule(llvmModule)
|
|
||||||
if (::llvm.isInitialized)
|
|
||||||
LLVMDisposeModule(llvm.runtime.llvmModule)
|
|
||||||
tryDisposeLLVMContext()
|
|
||||||
llvmDisposed = true
|
|
||||||
}
|
|
||||||
|
|
||||||
val cStubsManager = CStubsManager(config.target)
|
val cStubsManager = CStubsManager(config.target)
|
||||||
|
|
||||||
val coverage = CoverageManager(this)
|
val coverage = CoverageManager(this)
|
||||||
|
|||||||
+7
-7
@@ -6,7 +6,6 @@
|
|||||||
package org.jetbrains.kotlin.backend.konan
|
package org.jetbrains.kotlin.backend.konan
|
||||||
|
|
||||||
import org.jetbrains.kotlin.backend.konan.ir.containsNull
|
import org.jetbrains.kotlin.backend.konan.ir.containsNull
|
||||||
import org.jetbrains.kotlin.backend.konan.ir.getSuperClassNotAny
|
|
||||||
import org.jetbrains.kotlin.builtins.PrimitiveType
|
import org.jetbrains.kotlin.builtins.PrimitiveType
|
||||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrClass
|
import org.jetbrains.kotlin.ir.declarations.IrClass
|
||||||
@@ -212,6 +211,11 @@ private val implicitInlineClasses =
|
|||||||
KonanFqNames.nativePtr +
|
KonanFqNames.nativePtr +
|
||||||
InteropFqNames.cPointer).toSet()
|
InteropFqNames.cPointer).toSet()
|
||||||
|
|
||||||
|
private val superQualifierTable = mutableMapOf<IrClass, List<IrClass>>()
|
||||||
|
private fun IrClass.getAllSuperClassifiers(): List<IrClass> = superQualifierTable.getOrPut(this) {
|
||||||
|
listOf(this) + this.superTypes.flatMap { (it.classifierOrFail.owner as IrClass).getAllSuperClassifiers() }
|
||||||
|
}
|
||||||
|
|
||||||
internal object KotlinTypeInlineClassesSupport : InlineClassesSupport<ClassDescriptor, KotlinType>() {
|
internal object KotlinTypeInlineClassesSupport : InlineClassesSupport<ClassDescriptor, KotlinType>() {
|
||||||
|
|
||||||
override fun isNullable(type: KotlinType): Boolean = type.isNullable()
|
override fun isNullable(type: KotlinType): Boolean = type.isNullable()
|
||||||
@@ -268,12 +272,8 @@ private object IrTypeInlineClassesSupport : InlineClassesSupport<IrClass, IrType
|
|||||||
override fun getFqName(clazz: IrClass): FqNameUnsafe = clazz.descriptor.fqNameUnsafe
|
override fun getFqName(clazz: IrClass): FqNameUnsafe = clazz.descriptor.fqNameUnsafe
|
||||||
override fun hasInlineModifier(clazz: IrClass): Boolean = clazz.descriptor.isInline
|
override fun hasInlineModifier(clazz: IrClass): Boolean = clazz.descriptor.isInline
|
||||||
|
|
||||||
override fun getNativePointedSuperclass(clazz: IrClass): IrClass? {
|
override fun getNativePointedSuperclass(clazz: IrClass): IrClass? = clazz.getAllSuperClassifiers()
|
||||||
var superClass: IrClass? = clazz
|
.firstOrNull { it.descriptor.fqNameUnsafe == InteropFqNames.nativePointed }
|
||||||
while (superClass != null && superClass.descriptor.fqNameUnsafe != InteropFqNames.nativePointed)
|
|
||||||
superClass = superClass.getSuperClassNotAny()
|
|
||||||
return superClass
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun getInlinedClassUnderlyingType(clazz: IrClass): IrType =
|
override fun getInlinedClassUnderlyingType(clazz: IrClass): IrType =
|
||||||
clazz.constructors.firstOrNull { it.isPrimary }?.valueParameters?.single()?.type
|
clazz.constructors.firstOrNull { it.isPrimary }?.valueParameters?.single()?.type
|
||||||
|
|||||||
+1
-5
@@ -24,10 +24,6 @@ fun runTopLevelPhases(konanConfig: KonanConfig, environment: KotlinCoreEnvironme
|
|||||||
|
|
||||||
if (konanConfig.infoArgsOnly) return
|
if (konanConfig.infoArgsOnly) return
|
||||||
|
|
||||||
try {
|
(toplevelPhase as CompilerPhase<Context, Unit, Unit>).invokeToplevel(context.phaseConfig, context, Unit)
|
||||||
(toplevelPhase as CompilerPhase<Context, Unit, Unit>).invokeToplevel(context.phaseConfig, context, Unit)
|
|
||||||
} finally {
|
|
||||||
context.disposeLlvm()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+2
-4
@@ -378,13 +378,12 @@ internal val entryPointPhase = SameTypeNamedPhaseWrapper(
|
|||||||
internal val bitcodePhase = namedIrModulePhase(
|
internal val bitcodePhase = namedIrModulePhase(
|
||||||
name = "Bitcode",
|
name = "Bitcode",
|
||||||
description = "LLVM Bitcode generation",
|
description = "LLVM Bitcode generation",
|
||||||
lower = contextLLVMSetupPhase then
|
lower = buildDFGPhase then
|
||||||
buildDFGPhase then
|
|
||||||
serializeDFGPhase then
|
serializeDFGPhase then
|
||||||
deserializeDFGPhase then
|
deserializeDFGPhase then
|
||||||
devirtualizationPhase then
|
devirtualizationPhase then
|
||||||
dcePhase then
|
dcePhase then
|
||||||
createLLVMDeclarationsPhase then
|
contextLLVMSetupPhase then
|
||||||
ghaPhase then
|
ghaPhase then
|
||||||
RTTIPhase then
|
RTTIPhase then
|
||||||
generateDebugInfoHeaderPhase then
|
generateDebugInfoHeaderPhase then
|
||||||
@@ -419,7 +418,6 @@ val toplevelPhase: CompilerPhase<*, Unit, Unit> = namedUnitPhase(
|
|||||||
verifyBitcodePhase then
|
verifyBitcodePhase then
|
||||||
printBitcodePhase then
|
printBitcodePhase then
|
||||||
produceOutputPhase then
|
produceOutputPhase then
|
||||||
disposeLLVMPhase then
|
|
||||||
unitSink()
|
unitSink()
|
||||||
) then
|
) then
|
||||||
linkPhase
|
linkPhase
|
||||||
|
|||||||
+1
-16
@@ -26,30 +26,15 @@ internal val contextLLVMSetupPhase = makeKonanModuleOpPhase(
|
|||||||
// (see Llvm class in ContextUtils)
|
// (see Llvm class in ContextUtils)
|
||||||
// Which in turn is determined by the clang flags
|
// Which in turn is determined by the clang flags
|
||||||
// used to compile runtime.bc.
|
// used to compile runtime.bc.
|
||||||
llvmContext = LLVMContextCreate()!!
|
val llvmModule = LLVMModuleCreateWithName("out")!! // TODO: dispose
|
||||||
val llvmModule = LLVMModuleCreateWithNameInContext("out", llvmContext)!!
|
|
||||||
context.llvmModule = llvmModule
|
context.llvmModule = llvmModule
|
||||||
context.debugInfo.builder = DICreateBuilder(llvmModule)
|
context.debugInfo.builder = DICreateBuilder(llvmModule)
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
internal val createLLVMDeclarationsPhase = makeKonanModuleOpPhase(
|
|
||||||
name = "CreateLLVMDeclarations",
|
|
||||||
description = "Map IR declarations to LLVM",
|
|
||||||
prerequisite = setOf(contextLLVMSetupPhase),
|
|
||||||
op = { context, _ ->
|
|
||||||
context.llvmDeclarations = createLlvmDeclarations(context)
|
context.llvmDeclarations = createLlvmDeclarations(context)
|
||||||
context.lifetimes = mutableMapOf()
|
context.lifetimes = mutableMapOf()
|
||||||
context.codegenVisitor = CodeGeneratorVisitor(context, context.lifetimes)
|
context.codegenVisitor = CodeGeneratorVisitor(context, context.lifetimes)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
internal val disposeLLVMPhase = makeKonanModuleOpPhase(
|
|
||||||
name = "DisposeLLVM",
|
|
||||||
description = "Dispose LLVM",
|
|
||||||
op = { context, _ -> context.disposeLlvm() }
|
|
||||||
)
|
|
||||||
|
|
||||||
internal val RTTIPhase = makeKonanModuleOpPhase(
|
internal val RTTIPhase = makeKonanModuleOpPhase(
|
||||||
name = "RTTI",
|
name = "RTTI",
|
||||||
description = "RTTI generation",
|
description = "RTTI generation",
|
||||||
|
|||||||
+7
-21
@@ -23,7 +23,7 @@ internal class CodeGenerator(override val context: Context) : ContextUtils {
|
|||||||
|
|
||||||
fun llvmFunction(function: IrFunction): LLVMValueRef = llvmFunctionOrNull(function) ?: error("no function ${function.name} in ${function.file.fqName}")
|
fun llvmFunction(function: IrFunction): LLVMValueRef = llvmFunctionOrNull(function) ?: error("no function ${function.name} in ${function.file.fqName}")
|
||||||
fun llvmFunctionOrNull(function: IrFunction): LLVMValueRef? = function.llvmFunctionOrNull
|
fun llvmFunctionOrNull(function: IrFunction): LLVMValueRef? = function.llvmFunctionOrNull
|
||||||
val intPtrType = LLVMIntPtrTypeInContext(llvmContext, llvmTargetData)!!
|
val intPtrType = LLVMIntPtrType(llvmTargetData)!!
|
||||||
internal val immOneIntPtrType = LLVMConstInt(intPtrType, 1, 1)!!
|
internal val immOneIntPtrType = LLVMConstInt(intPtrType, 1, 1)!!
|
||||||
// Keep in sync with OBJECT_TAG_MASK in C++.
|
// Keep in sync with OBJECT_TAG_MASK in C++.
|
||||||
internal val immTypeInfoMask = LLVMConstNot(LLVMConstInt(intPtrType, 3, 0)!!)!!
|
internal val immTypeInfoMask = LLVMConstNot(LLVMConstInt(intPtrType, 3, 0)!!)!!
|
||||||
@@ -120,17 +120,12 @@ internal inline fun<R> generateFunction(codegen: CodeGenerator,
|
|||||||
code: FunctionGenerationContext.(FunctionGenerationContext) -> R) {
|
code: FunctionGenerationContext.(FunctionGenerationContext) -> R) {
|
||||||
val llvmFunction = codegen.llvmFunction(function)
|
val llvmFunction = codegen.llvmFunction(function)
|
||||||
|
|
||||||
val functionGenerationContext = FunctionGenerationContext(
|
generateFunctionBody(FunctionGenerationContext(
|
||||||
llvmFunction,
|
llvmFunction,
|
||||||
codegen,
|
codegen,
|
||||||
startLocation,
|
startLocation,
|
||||||
endLocation,
|
endLocation,
|
||||||
function)
|
function), code)
|
||||||
try {
|
|
||||||
generateFunctionBody(functionGenerationContext, code)
|
|
||||||
} finally {
|
|
||||||
functionGenerationContext.dispose()
|
|
||||||
}
|
|
||||||
|
|
||||||
// To perform per-function validation.
|
// To perform per-function validation.
|
||||||
if (false)
|
if (false)
|
||||||
@@ -140,12 +135,7 @@ internal inline fun<R> generateFunction(codegen: CodeGenerator,
|
|||||||
|
|
||||||
internal inline fun<R> generateFunction(codegen: CodeGenerator, function: LLVMValueRef,
|
internal inline fun<R> generateFunction(codegen: CodeGenerator, function: LLVMValueRef,
|
||||||
code:FunctionGenerationContext.(FunctionGenerationContext) -> R) {
|
code:FunctionGenerationContext.(FunctionGenerationContext) -> R) {
|
||||||
val functionGenerationContext = FunctionGenerationContext(function, codegen, null, null)
|
generateFunctionBody(FunctionGenerationContext(function, codegen, null, null), code)
|
||||||
try {
|
|
||||||
generateFunctionBody(functionGenerationContext, code)
|
|
||||||
} finally {
|
|
||||||
functionGenerationContext.dispose()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
internal inline fun generateFunction(
|
internal inline fun generateFunction(
|
||||||
@@ -228,18 +218,14 @@ internal class FunctionGenerationContext(val function: LLVMValueRef,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun dispose() {
|
|
||||||
currentPositionHolder.dispose()
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun basicBlockInFunction(name: String, locationInfo: LocationInfo?): LLVMBasicBlockRef {
|
private fun basicBlockInFunction(name: String, locationInfo: LocationInfo?): LLVMBasicBlockRef {
|
||||||
val bb = LLVMAppendBasicBlockInContext(llvmContext, function, name)!!
|
val bb = LLVMAppendBasicBlock(function, name)!!
|
||||||
update(bb, locationInfo)
|
update(bb, locationInfo)
|
||||||
return bb
|
return bb
|
||||||
}
|
}
|
||||||
|
|
||||||
fun basicBlock(name:String = "label_", startLocationInfo:LocationInfo?, endLocationInfo: LocationInfo? = startLocationInfo): LLVMBasicBlockRef {
|
fun basicBlock(name:String = "label_", startLocationInfo:LocationInfo?, endLocationInfo: LocationInfo? = startLocationInfo): LLVMBasicBlockRef {
|
||||||
val result = LLVMInsertBasicBlockInContext(llvmContext, this.currentBlock, name)!!
|
val result = LLVMInsertBasicBlock(this.currentBlock, name)!!
|
||||||
update(result, startLocationInfo, endLocationInfo)
|
update(result, startLocationInfo, endLocationInfo)
|
||||||
LLVMMoveBasicBlockAfter(result, this.currentBlock)
|
LLVMMoveBasicBlockAfter(result, this.currentBlock)
|
||||||
return result
|
return result
|
||||||
@@ -1090,7 +1076,7 @@ internal class FunctionGenerationContext(val function: LLVMValueRef,
|
|||||||
* This class is introduced to workaround unreachable code handling.
|
* This class is introduced to workaround unreachable code handling.
|
||||||
*/
|
*/
|
||||||
inner class PositionHolder {
|
inner class PositionHolder {
|
||||||
private val builder: LLVMBuilderRef = LLVMCreateBuilderInContext(llvmContext)!!
|
private val builder: LLVMBuilderRef = LLVMCreateBuilder()!!
|
||||||
|
|
||||||
|
|
||||||
fun getBuilder(): LLVMBuilderRef {
|
fun getBuilder(): LLVMBuilderRef {
|
||||||
|
|||||||
+10
-8
@@ -296,12 +296,14 @@ internal class Llvm(val context: Context, val llvmModule: LLVMModuleRef) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun importMemset(): LLVMValueRef {
|
private fun importMemset(): LLVMValueRef {
|
||||||
val functionType = functionType(voidType, false, int8TypePtr, int8Type, int32Type, int1Type)
|
val parameterTypes = cValuesOf(int8TypePtr, int8Type, int32Type, int1Type)
|
||||||
|
val functionType = LLVMFunctionType(LLVMVoidType(), parameterTypes, 4, 0)
|
||||||
return LLVMAddFunction(llvmModule, "llvm.memset.p0i8.i32", functionType)!!
|
return LLVMAddFunction(llvmModule, "llvm.memset.p0i8.i32", functionType)!!
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun importMemcpy(): LLVMValueRef {
|
private fun importMemcpy(): LLVMValueRef {
|
||||||
val functionType = functionType(voidType, false, int8TypePtr, int8TypePtr, int32Type, int1Type)
|
val parameterTypes = cValuesOf(int8TypePtr, int8TypePtr, int32Type, int1Type)
|
||||||
|
val functionType = LLVMFunctionType(LLVMVoidType(), parameterTypes, 4, 0)
|
||||||
return LLVMAddFunction(llvmModule, "llvm.memcpy.p0i8.p0i8.i32", functionType)!!
|
return LLVMAddFunction(llvmModule, "llvm.memcpy.p0i8.p0i8.i32", functionType)!!
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -553,12 +555,12 @@ internal class Llvm(val context: Context, val llvmModule: LLVMModuleRef) {
|
|||||||
override fun getValue(thisRef: Llvm, property: KProperty<*>): LLVMValueRef = value
|
override fun getValue(thisRef: Llvm, property: KProperty<*>): LLVMValueRef = value
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
val llvmInt8 = int8Type
|
val llvmInt8 = LLVMInt8Type()!!
|
||||||
val llvmInt16 = int16Type
|
val llvmInt16 = LLVMInt16Type()!!
|
||||||
val llvmInt32 = int32Type
|
val llvmInt32 = LLVMInt32Type()!!
|
||||||
val llvmInt64 = int64Type
|
val llvmInt64 = LLVMInt64Type()!!
|
||||||
val llvmFloat = floatType
|
val llvmFloat = LLVMFloatType()!!
|
||||||
val llvmDouble = doubleType
|
val llvmDouble = LLVMDoubleType()!!
|
||||||
}
|
}
|
||||||
|
|
||||||
class StaticInitializer(val file: IrFile, val initializer: LLVMValueRef)
|
class StaticInitializer(val file: IrFile, val initializer: LLVMValueRef)
|
||||||
|
|||||||
+15
-12
@@ -12,20 +12,23 @@ import org.jetbrains.kotlin.ir.types.IrType
|
|||||||
import org.jetbrains.kotlin.ir.types.isNothing
|
import org.jetbrains.kotlin.ir.types.isNothing
|
||||||
import org.jetbrains.kotlin.ir.types.isUnit
|
import org.jetbrains.kotlin.ir.types.isUnit
|
||||||
|
|
||||||
private fun RuntimeAware.getLlvmType(primitiveBinaryType: PrimitiveBinaryType?) = when (primitiveBinaryType) {
|
private val primitiveToLlvm = PrimitiveBinaryType.values().associate {
|
||||||
null -> this.kObjHeaderPtr
|
it to when (it) {
|
||||||
|
PrimitiveBinaryType.BOOLEAN -> LLVMInt1Type()
|
||||||
|
PrimitiveBinaryType.BYTE -> LLVMInt8Type()
|
||||||
|
PrimitiveBinaryType.SHORT -> LLVMInt16Type()
|
||||||
|
PrimitiveBinaryType.INT -> LLVMInt32Type()
|
||||||
|
PrimitiveBinaryType.LONG -> LLVMInt64Type()
|
||||||
|
PrimitiveBinaryType.FLOAT -> LLVMFloatType()
|
||||||
|
PrimitiveBinaryType.DOUBLE -> LLVMDoubleType()
|
||||||
|
|
||||||
PrimitiveBinaryType.BOOLEAN -> int1Type
|
PrimitiveBinaryType.POINTER -> int8TypePtr
|
||||||
PrimitiveBinaryType.BYTE -> int8Type
|
}!!
|
||||||
PrimitiveBinaryType.SHORT -> int16Type
|
|
||||||
PrimitiveBinaryType.INT -> int32Type
|
|
||||||
PrimitiveBinaryType.LONG -> int64Type
|
|
||||||
PrimitiveBinaryType.FLOAT -> floatType
|
|
||||||
PrimitiveBinaryType.DOUBLE -> doubleType
|
|
||||||
|
|
||||||
PrimitiveBinaryType.POINTER -> int8TypePtr
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun RuntimeAware.getLlvmType(primitiveBinaryType: PrimitiveBinaryType?) =
|
||||||
|
primitiveBinaryType?.let { primitiveToLlvm[it]!! } ?: this.kObjHeaderPtr
|
||||||
|
|
||||||
internal fun RuntimeAware.getLLVMType(type: IrType): LLVMTypeRef =
|
internal fun RuntimeAware.getLLVMType(type: IrType): LLVMTypeRef =
|
||||||
getLlvmType(type.computePrimitiveBinaryTypeOrNull())
|
getLlvmType(type.computePrimitiveBinaryTypeOrNull())
|
||||||
|
|
||||||
@@ -34,7 +37,7 @@ internal fun RuntimeAware.getLLVMType(type: DataFlowIR.Type) =
|
|||||||
|
|
||||||
internal fun RuntimeAware.getLLVMReturnType(type: IrType): LLVMTypeRef {
|
internal fun RuntimeAware.getLLVMReturnType(type: IrType): LLVMTypeRef {
|
||||||
return when {
|
return when {
|
||||||
type.isUnit() || type.isNothing() -> voidType
|
type.isUnit() || type.isNothing() -> LLVMVoidType()!!
|
||||||
else -> getLLVMType(type)
|
else -> getLLVMType(type)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+3
-3
@@ -26,8 +26,8 @@ import org.jetbrains.kotlin.konan.file.File
|
|||||||
internal object DWARF {
|
internal object DWARF {
|
||||||
val producer = "konanc ${KonanVersion.CURRENT} / kotlin-compiler: ${KotlinVersion.CURRENT}"
|
val producer = "konanc ${KonanVersion.CURRENT} / kotlin-compiler: ${KotlinVersion.CURRENT}"
|
||||||
/* TODO: from LLVM sources is unclear what runtimeVersion corresponds to term in terms of dwarf specification. */
|
/* TODO: from LLVM sources is unclear what runtimeVersion corresponds to term in terms of dwarf specification. */
|
||||||
val dwarfVersionMetaDataNodeName get() = "Dwarf Version".mdString()
|
val dwarfVersionMetaDataNodeName = "Dwarf Version".mdString()
|
||||||
val dwarfDebugInfoMetaDataNodeName get() = "Debug Info Version".mdString()
|
val dwarfDebugInfoMetaDataNodeName = "Debug Info Version".mdString()
|
||||||
const val debugInfoVersion = 3 /* TODO: configurable? */
|
const val debugInfoVersion = 3 /* TODO: configurable? */
|
||||||
/**
|
/**
|
||||||
* This is the value taken from [DIFlags.FlagFwdDecl], to mark type declaration as
|
* This is the value taken from [DIFlags.FlagFwdDecl], to mark type declaration as
|
||||||
@@ -80,7 +80,7 @@ internal class DebugInfo internal constructor(override val context: Context):Con
|
|||||||
context.irBuiltIns.doubleType to context.llvm.llvmDouble)
|
context.irBuiltIns.doubleType to context.llvm.llvmDouble)
|
||||||
val llvmTypeSizes = llvmTypes.map { it.key to LLVMSizeOfTypeInBits(llvmTargetData, it.value) }.toMap()
|
val llvmTypeSizes = llvmTypes.map { it.key to LLVMSizeOfTypeInBits(llvmTargetData, it.value) }.toMap()
|
||||||
val llvmTypeAlignments = llvmTypes.map {it.key to LLVMPreferredAlignmentOfType(llvmTargetData, it.value)}.toMap()
|
val llvmTypeAlignments = llvmTypes.map {it.key to LLVMPreferredAlignmentOfType(llvmTargetData, it.value)}.toMap()
|
||||||
val otherLlvmType = LLVMPointerType(int64Type, 0)!!
|
val otherLlvmType = LLVMPointerType(LLVMInt64Type(), 0)!!
|
||||||
val otherTypeSize = LLVMSizeOfTypeInBits(llvmTargetData, otherLlvmType)
|
val otherTypeSize = LLVMSizeOfTypeInBits(llvmTargetData, otherLlvmType)
|
||||||
val otherTypeAlignment = LLVMPreferredAlignmentOfType(llvmTargetData, otherLlvmType)
|
val otherTypeAlignment = LLVMPreferredAlignmentOfType(llvmTargetData, otherLlvmType)
|
||||||
|
|
||||||
|
|||||||
+6
-6
@@ -344,7 +344,7 @@ internal class IntrinsicGenerator(private val environment: IntrinsicGeneratorEnv
|
|||||||
// Note: LLVM allows to read without padding tail up to byte boundary, but the result seems to be incorrect.
|
// Note: LLVM allows to read without padding tail up to byte boundary, but the result seems to be incorrect.
|
||||||
|
|
||||||
val bitsWithPaddingNum = prefixBitsNum + size + suffixBitsNum
|
val bitsWithPaddingNum = prefixBitsNum + size + suffixBitsNum
|
||||||
val bitsWithPaddingType = LLVMIntTypeInContext(llvmContext, bitsWithPaddingNum)!!
|
val bitsWithPaddingType = LLVMIntType(bitsWithPaddingNum)!!
|
||||||
|
|
||||||
val bitsWithPaddingPtr = bitcast(org.jetbrains.kotlin.backend.konan.llvm.pointerType(bitsWithPaddingType), gep(ptr, org.jetbrains.kotlin.backend.konan.llvm.Int64(offset / 8).llvm))
|
val bitsWithPaddingPtr = bitcast(org.jetbrains.kotlin.backend.konan.llvm.pointerType(bitsWithPaddingType), gep(ptr, org.jetbrains.kotlin.backend.konan.llvm.Int64(offset / 8).llvm))
|
||||||
val bitsWithPadding = load(bitsWithPaddingPtr).setUnaligned()
|
val bitsWithPadding = load(bitsWithPaddingPtr).setUnaligned()
|
||||||
@@ -370,13 +370,13 @@ internal class IntrinsicGenerator(private val environment: IntrinsicGeneratorEnv
|
|||||||
val value = args[3]
|
val value = args[3]
|
||||||
assert(value.type == int64Type)
|
assert(value.type == int64Type)
|
||||||
|
|
||||||
val bitsType = LLVMIntTypeInContext(llvmContext, size)!!
|
val bitsType = LLVMIntType(size)!!
|
||||||
|
|
||||||
val prefixBitsNum = (offset % 8).toInt()
|
val prefixBitsNum = (offset % 8).toInt()
|
||||||
val suffixBitsNum = (8 - ((size + offset) % 8).toInt()) % 8
|
val suffixBitsNum = (8 - ((size + offset) % 8).toInt()) % 8
|
||||||
|
|
||||||
val bitsWithPaddingNum = prefixBitsNum + size + suffixBitsNum
|
val bitsWithPaddingNum = prefixBitsNum + size + suffixBitsNum
|
||||||
val bitsWithPaddingType = LLVMIntTypeInContext(llvmContext, bitsWithPaddingNum)!!
|
val bitsWithPaddingType = LLVMIntType(bitsWithPaddingNum)!!
|
||||||
|
|
||||||
// 0011111000:
|
// 0011111000:
|
||||||
val discardBitsMask = LLVMConstShl(
|
val discardBitsMask = LLVMConstShl(
|
||||||
@@ -443,8 +443,8 @@ internal class IntrinsicGenerator(private val environment: IntrinsicGeneratorEnv
|
|||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Find better place for these guys.
|
// TODO: Find better place for these guys.
|
||||||
private val kImmZero = LLVMConstInt(int32Type, 0, 1)!!
|
private val kImmZero = LLVMConstInt(LLVMInt32Type(), 0, 1)!!
|
||||||
private val kImmOne = LLVMConstInt(int32Type, 1, 1)!!
|
private val kImmOne = LLVMConstInt(LLVMInt32Type(), 1, 1)!!
|
||||||
|
|
||||||
private fun FunctionGenerationContext.emitGetObjCClass(callSite: IrCall): LLVMValueRef {
|
private fun FunctionGenerationContext.emitGetObjCClass(callSite: IrCall): LLVMValueRef {
|
||||||
val descriptor = callSite.descriptor.original
|
val descriptor = callSite.descriptor.original
|
||||||
@@ -487,7 +487,7 @@ internal class IntrinsicGenerator(private val environment: IntrinsicGeneratorEnv
|
|||||||
return when (val typeKind = LLVMGetTypeKind(first.type)) {
|
return when (val typeKind = LLVMGetTypeKind(first.type)) {
|
||||||
llvm.LLVMTypeKind.LLVMFloatTypeKind, llvm.LLVMTypeKind.LLVMDoubleTypeKind -> {
|
llvm.LLVMTypeKind.LLVMFloatTypeKind, llvm.LLVMTypeKind.LLVMDoubleTypeKind -> {
|
||||||
val numBits = llvm.LLVMSizeOfTypeInBits(codegen.llvmTargetData, first.type).toInt()
|
val numBits = llvm.LLVMSizeOfTypeInBits(codegen.llvmTargetData, first.type).toInt()
|
||||||
val integerType = LLVMIntTypeInContext(llvmContext, numBits)!!
|
val integerType = llvm.LLVMIntType(numBits)!!
|
||||||
icmpEq(bitcast(integerType, first), bitcast(integerType, second))
|
icmpEq(bitcast(integerType, first), bitcast(integerType, second))
|
||||||
}
|
}
|
||||||
llvm.LLVMTypeKind.LLVMIntegerTypeKind, llvm.LLVMTypeKind.LLVMPointerTypeKind -> icmpEq(first, second)
|
llvm.LLVMTypeKind.LLVMIntegerTypeKind, llvm.LLVMTypeKind.LLVMPointerTypeKind -> icmpEq(first, second)
|
||||||
|
|||||||
+23
-18
@@ -65,10 +65,9 @@ val IrField.isMainOnlyNonPrimitive get() = when {
|
|||||||
internal fun verifyModule(llvmModule: LLVMModuleRef, current: String = "") {
|
internal fun verifyModule(llvmModule: LLVMModuleRef, current: String = "") {
|
||||||
memScoped {
|
memScoped {
|
||||||
val errorRef = allocPointerTo<ByteVar>()
|
val errorRef = allocPointerTo<ByteVar>()
|
||||||
val verificationResult = LLVMVerifyModule(
|
// TODO: use LLVMDisposeMessage() on errorRef, once possible in interop.
|
||||||
llvmModule, LLVMVerifierFailureAction.LLVMPrintMessageAction, errorRef.ptr)
|
if (LLVMVerifyModule(
|
||||||
LLVMDisposeMessage(errorRef.value)
|
llvmModule, LLVMVerifierFailureAction.LLVMPrintMessageAction, errorRef.ptr) == 1) {
|
||||||
if (verificationResult == 1) {
|
|
||||||
if (current.isNotEmpty())
|
if (current.isNotEmpty())
|
||||||
println("Error in $current")
|
println("Error in $current")
|
||||||
LLVMDumpModule(llvmModule)
|
LLVMDumpModule(llvmModule)
|
||||||
@@ -350,8 +349,8 @@ internal class CodeGeneratorVisitor(val context: Context, val lifetimes: Map<IrE
|
|||||||
|
|
||||||
//-------------------------------------------------------------------------//
|
//-------------------------------------------------------------------------//
|
||||||
|
|
||||||
val kVoidFuncType = functionType(voidType)
|
val kVoidFuncType = LLVMFunctionType(LLVMVoidType(), null, 0, 0)!!
|
||||||
val kInitFuncType = functionType(voidType, false, int32Type)
|
val kInitFuncType = LLVMFunctionType(LLVMVoidType(), cValuesOf(LLVMInt32Type()), 1, 0)!!
|
||||||
val kNodeInitType = LLVMGetTypeByName(context.llvmModule, "struct.InitNode")!!
|
val kNodeInitType = LLVMGetTypeByName(context.llvmModule, "struct.InitNode")!!
|
||||||
//-------------------------------------------------------------------------//
|
//-------------------------------------------------------------------------//
|
||||||
|
|
||||||
@@ -1574,14 +1573,14 @@ internal class CodeGeneratorVisitor(val context: Context, val lifetimes: Map<IrE
|
|||||||
true -> return kTrue
|
true -> return kTrue
|
||||||
false -> return kFalse
|
false -> return kFalse
|
||||||
}
|
}
|
||||||
IrConstKind.Char -> return Char16(value.value as Char).llvm
|
IrConstKind.Char -> return LLVMConstInt(LLVMInt16Type(), (value.value as Char).toLong(), 0)!!
|
||||||
IrConstKind.Byte -> return Int8(value.value as Byte).llvm
|
IrConstKind.Byte -> return LLVMConstInt(LLVMInt8Type(), (value.value as Byte).toLong(), 1)!!
|
||||||
IrConstKind.Short -> return Int16(value.value as Short).llvm
|
IrConstKind.Short -> return LLVMConstInt(LLVMInt16Type(), (value.value as Short).toLong(), 1)!!
|
||||||
IrConstKind.Int -> return Int32(value.value as Int).llvm
|
IrConstKind.Int -> return LLVMConstInt(LLVMInt32Type(), (value.value as Int).toLong(), 1)!!
|
||||||
IrConstKind.Long -> return Int64(value.value as Long).llvm
|
IrConstKind.Long -> return LLVMConstInt(LLVMInt64Type(), value.value as Long, 1)!!
|
||||||
IrConstKind.String -> return evaluateStringConst(value as IrConst<String>)
|
IrConstKind.String -> return evaluateStringConst(value as IrConst<String>)
|
||||||
IrConstKind.Float -> return LLVMConstRealOfString(floatType, (value.value as Float).toString())!!
|
IrConstKind.Float -> return LLVMConstRealOfString(LLVMFloatType(), (value.value as Float).toString())!!
|
||||||
IrConstKind.Double -> return LLVMConstRealOfString(doubleType, (value.value as Double).toString())!!
|
IrConstKind.Double -> return LLVMConstRealOfString(LLVMDoubleType(), (value.value as Double).toString())!!
|
||||||
}
|
}
|
||||||
TODO(ir2string(value))
|
TODO(ir2string(value))
|
||||||
}
|
}
|
||||||
@@ -2151,10 +2150,10 @@ internal class CodeGeneratorVisitor(val context: Context, val lifetimes: Map<IrE
|
|||||||
}
|
}
|
||||||
|
|
||||||
//-------------------------------------------------------------------------//
|
//-------------------------------------------------------------------------//
|
||||||
private val kImmZero = Int32(0).llvm
|
private val kImmZero = LLVMConstInt(LLVMInt32Type(), 0, 1)!!
|
||||||
private val kImmOne = Int32(1).llvm
|
private val kImmOne = LLVMConstInt(LLVMInt32Type(), 1, 1)!!
|
||||||
private val kTrue = Int1(1).llvm
|
private val kTrue = LLVMConstInt(LLVMInt1Type(), 1, 1)!!
|
||||||
private val kFalse = Int1(0).llvm
|
private val kFalse = LLVMConstInt(LLVMInt1Type(), 0, 1)!!
|
||||||
|
|
||||||
// TODO: Intrinsify?
|
// TODO: Intrinsify?
|
||||||
private fun evaluateOperatorCall(callee: IrCall, args: List<LLVMValueRef>): LLVMValueRef {
|
private fun evaluateOperatorCall(callee: IrCall, args: List<LLVMValueRef>): LLVMValueRef {
|
||||||
@@ -2318,7 +2317,13 @@ internal class CodeGeneratorVisitor(val context: Context, val lifetimes: Map<IrE
|
|||||||
//-------------------------------------------------------------------------//
|
//-------------------------------------------------------------------------//
|
||||||
// Create type { i32, void ()*, i8* }
|
// Create type { i32, void ()*, i8* }
|
||||||
|
|
||||||
val kCtorType = structType(int32Type, pointerType(kVoidFuncType), kInt8Ptr)
|
val kCtorType = LLVMStructType(
|
||||||
|
cValuesOf(
|
||||||
|
LLVMInt32Type(),
|
||||||
|
LLVMPointerType(kVoidFuncType, 0),
|
||||||
|
kInt8Ptr
|
||||||
|
),
|
||||||
|
3, 0)!!
|
||||||
|
|
||||||
//-------------------------------------------------------------------------//
|
//-------------------------------------------------------------------------//
|
||||||
// Create object { i32, void ()*, i8* } { i32 1, void ()* @ctorFunction, i8* null }
|
// Create object { i32, void ()*, i8* } { i32 1, void ()* @ctorFunction, i8* null }
|
||||||
|
|||||||
+29
-58
@@ -9,31 +9,6 @@ import kotlinx.cinterop.*
|
|||||||
import llvm.*
|
import llvm.*
|
||||||
import org.jetbrains.kotlin.descriptors.konan.CompiledKlibModuleOrigin
|
import org.jetbrains.kotlin.descriptors.konan.CompiledKlibModuleOrigin
|
||||||
|
|
||||||
private val llvmContextHolder = ThreadLocal<LLVMContextRef>()
|
|
||||||
internal var llvmContext: LLVMContextRef
|
|
||||||
get() = llvmContextHolder.get()
|
|
||||||
set(value) { llvmContextHolder.set(value) }
|
|
||||||
|
|
||||||
internal fun tryDisposeLLVMContext() {
|
|
||||||
val llvmContext = llvmContextHolder.get()
|
|
||||||
if (llvmContext != null)
|
|
||||||
LLVMContextDispose(llvmContext)
|
|
||||||
llvmContextHolder.remove()
|
|
||||||
}
|
|
||||||
|
|
||||||
internal val LLVMTypeRef.context: LLVMContextRef
|
|
||||||
get() = LLVMGetTypeContext(this)!!
|
|
||||||
|
|
||||||
internal val List<LLVMTypeRef>.context: LLVMContextRef
|
|
||||||
get() {
|
|
||||||
val context = this[0].context
|
|
||||||
for (i in 1 until this.size)
|
|
||||||
assert(this[i].context == context) {
|
|
||||||
"Expected the same context for all types in a list"
|
|
||||||
}
|
|
||||||
return context
|
|
||||||
}
|
|
||||||
|
|
||||||
internal val LLVMValueRef.type: LLVMTypeRef
|
internal val LLVMValueRef.type: LLVMTypeRef
|
||||||
get() = LLVMTypeOf(this)!!
|
get() = LLVMTypeOf(this)!!
|
||||||
|
|
||||||
@@ -102,47 +77,32 @@ internal open class Struct(val type: LLVMTypeRef?, val elements: List<ConstValue
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal val int1Type get() = LLVMInt1TypeInContext(llvmContext)!!
|
|
||||||
internal val int8Type get() = LLVMInt8TypeInContext(llvmContext)!!
|
|
||||||
internal val int16Type get() = LLVMInt16TypeInContext(llvmContext)!!
|
|
||||||
internal val int32Type get() = LLVMInt32TypeInContext(llvmContext)!!
|
|
||||||
internal val int64Type get() = LLVMInt64TypeInContext(llvmContext)!!
|
|
||||||
internal val int8TypePtr get() = pointerType(int8Type)
|
|
||||||
internal val floatType get() = LLVMFloatTypeInContext(llvmContext)!!
|
|
||||||
internal val doubleType get() = LLVMDoubleTypeInContext(llvmContext)!!
|
|
||||||
|
|
||||||
internal val voidType get() = LLVMVoidTypeInContext(llvmContext)!!
|
|
||||||
|
|
||||||
internal class Int1(val value: Byte) : ConstValue {
|
internal class Int1(val value: Byte) : ConstValue {
|
||||||
override val llvm = LLVMConstInt(int1Type, value.toLong(), 1)!!
|
override val llvm = LLVMConstInt(LLVMInt1Type(), value.toLong(), 1)!!
|
||||||
}
|
}
|
||||||
|
|
||||||
internal class Int8(val value: Byte) : ConstValue {
|
internal class Int8(val value: Byte) : ConstValue {
|
||||||
override val llvm = LLVMConstInt(int8Type, value.toLong(), 1)!!
|
override val llvm = LLVMConstInt(LLVMInt8Type(), value.toLong(), 1)!!
|
||||||
}
|
|
||||||
|
|
||||||
internal class Int16(val value: Short) : ConstValue {
|
|
||||||
override val llvm = LLVMConstInt(int16Type, value.toLong(), 1)!!
|
|
||||||
}
|
}
|
||||||
|
|
||||||
internal class Char16(val value: Char) : ConstValue {
|
internal class Char16(val value: Char) : ConstValue {
|
||||||
override val llvm = LLVMConstInt(int16Type, value.toLong(), 1)!!
|
override val llvm = LLVMConstInt(LLVMInt16Type(), value.toLong(), 1)!!
|
||||||
}
|
}
|
||||||
|
|
||||||
internal class Int32(val value: Int) : ConstValue {
|
internal class Int32(val value: Int) : ConstValue {
|
||||||
override val llvm = LLVMConstInt(int32Type, value.toLong(), 1)!!
|
override val llvm = LLVMConstInt(LLVMInt32Type(), value.toLong(), 1)!!
|
||||||
}
|
}
|
||||||
|
|
||||||
internal class Int64(val value: Long) : ConstValue {
|
internal class Int64(val value: Long) : ConstValue {
|
||||||
override val llvm = LLVMConstInt(int64Type, value, 1)!!
|
override val llvm = LLVMConstInt(LLVMInt64Type(), value, 1)!!
|
||||||
}
|
}
|
||||||
|
|
||||||
internal class Float32(val value: Float) : ConstValue {
|
internal class Float32(val value: Float) : ConstValue {
|
||||||
override val llvm = LLVMConstReal(floatType, value.toDouble())!!
|
override val llvm = LLVMConstReal(LLVMFloatType(), value.toDouble())!!
|
||||||
}
|
}
|
||||||
|
|
||||||
internal class Float64(val value: Double) : ConstValue {
|
internal class Float64(val value: Double) : ConstValue {
|
||||||
override val llvm = LLVMConstReal(doubleType, value)!!
|
override val llvm = LLVMConstReal(LLVMDoubleType(), value)!!
|
||||||
}
|
}
|
||||||
|
|
||||||
internal class Zero(val type: LLVMTypeRef) : ConstValue {
|
internal class Zero(val type: LLVMTypeRef) : ConstValue {
|
||||||
@@ -161,6 +121,17 @@ internal fun constValue(value: LLVMValueRef) = object : ConstValue {
|
|||||||
override val llvm = value
|
override val llvm = value
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal val int1Type = LLVMInt1Type()!!
|
||||||
|
internal val int8Type = LLVMInt8Type()!!
|
||||||
|
internal val int16Type = LLVMInt16Type()!!
|
||||||
|
internal val int32Type = LLVMInt32Type()!!
|
||||||
|
internal val int64Type = LLVMInt64Type()!!
|
||||||
|
internal val int8TypePtr = pointerType(int8Type)
|
||||||
|
internal val floatType = LLVMFloatType()!!
|
||||||
|
internal val doubleType = LLVMDoubleType()!!
|
||||||
|
|
||||||
|
internal val voidType = LLVMVoidType()!!
|
||||||
|
|
||||||
internal val RuntimeAware.kTypeInfo: LLVMTypeRef
|
internal val RuntimeAware.kTypeInfo: LLVMTypeRef
|
||||||
get() = runtime.typeInfoType
|
get() = runtime.typeInfoType
|
||||||
internal val RuntimeAware.kObjHeader: LLVMTypeRef
|
internal val RuntimeAware.kObjHeader: LLVMTypeRef
|
||||||
@@ -175,13 +146,13 @@ internal val RuntimeAware.kArrayHeaderPtr: LLVMTypeRef
|
|||||||
get() = pointerType(kArrayHeader)
|
get() = pointerType(kArrayHeader)
|
||||||
internal val RuntimeAware.kTypeInfoPtr: LLVMTypeRef
|
internal val RuntimeAware.kTypeInfoPtr: LLVMTypeRef
|
||||||
get() = pointerType(kTypeInfo)
|
get() = pointerType(kTypeInfo)
|
||||||
internal val kInt1 get() = int1Type
|
internal val kInt1 = LLVMInt1Type()!!
|
||||||
internal val kBoolean get() = kInt1
|
internal val kBoolean = kInt1
|
||||||
internal val kInt8Ptr get() = pointerType(int8Type)
|
internal val kInt8Ptr = pointerType(int8Type)
|
||||||
internal val kInt8PtrPtr get() = pointerType(kInt8Ptr)
|
internal val kInt8PtrPtr = pointerType(kInt8Ptr)
|
||||||
internal val kNullInt8Ptr get() = LLVMConstNull(kInt8Ptr)!!
|
internal val kNullInt8Ptr = LLVMConstNull(kInt8Ptr)!!
|
||||||
internal val kImmInt32Zero get() = Int32(0).llvm
|
internal val kImmInt32Zero = Int32(0).llvm
|
||||||
internal val kImmInt32One get() = Int32(1).llvm
|
internal val kImmInt32One = Int32(1).llvm
|
||||||
internal val ContextUtils.kNullObjHeaderPtr: LLVMValueRef
|
internal val ContextUtils.kNullObjHeaderPtr: LLVMValueRef
|
||||||
get() = LLVMConstNull(this.kObjHeaderPtr)!!
|
get() = LLVMConstNull(this.kObjHeaderPtr)!!
|
||||||
internal val ContextUtils.kNullObjHeaderPtrPtr: LLVMValueRef
|
internal val ContextUtils.kNullObjHeaderPtrPtr: LLVMValueRef
|
||||||
@@ -196,7 +167,7 @@ internal fun pointerType(pointeeType: LLVMTypeRef) = LLVMPointerType(pointeeType
|
|||||||
internal fun structType(vararg types: LLVMTypeRef): LLVMTypeRef = structType(types.toList())
|
internal fun structType(vararg types: LLVMTypeRef): LLVMTypeRef = structType(types.toList())
|
||||||
|
|
||||||
internal fun structType(types: List<LLVMTypeRef>): LLVMTypeRef =
|
internal fun structType(types: List<LLVMTypeRef>): LLVMTypeRef =
|
||||||
LLVMStructTypeInContext(llvmContext, types.toCValues(), types.size, 0)!!
|
LLVMStructType(types.toCValues(), types.size, 0)!!
|
||||||
|
|
||||||
internal fun ContextUtils.numParameters(functionType: LLVMTypeRef) : Int {
|
internal fun ContextUtils.numParameters(functionType: LLVMTypeRef) : Int {
|
||||||
// Note that type is usually function pointer, so we have to dereference it.
|
// Note that type is usually function pointer, so we have to dereference it.
|
||||||
@@ -302,7 +273,7 @@ fun parseBitcodeFile(path: String): LLVMModuleRef = memScoped {
|
|||||||
try {
|
try {
|
||||||
|
|
||||||
val moduleRef = alloc<LLVMModuleRefVar>()
|
val moduleRef = alloc<LLVMModuleRefVar>()
|
||||||
val parseRes = LLVMParseBitcodeInContext2(llvmContext, memoryBuffer, moduleRef.ptr)
|
val parseRes = LLVMParseBitcode2(memoryBuffer, moduleRef.ptr)
|
||||||
if (parseRes != 0) {
|
if (parseRes != 0) {
|
||||||
throw Error(parseRes.toString())
|
throw Error(parseRes.toString())
|
||||||
}
|
}
|
||||||
@@ -376,8 +347,8 @@ fun addFunctionSignext(function: LLVMValueRef, index: Int, type: LLVMTypeRef?) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal fun String.mdString() = LLVMMDStringInContext(llvmContext, this, this.length)!!
|
internal fun String.mdString() = LLVMMDString(this, this.length)!!
|
||||||
internal fun node(vararg it:LLVMValueRef) = LLVMMDNodeInContext(llvmContext, it.toList().toCValues(), it.size)
|
internal fun node(vararg it:LLVMValueRef) = LLVMMDNode(it.toList().toCValues(), it.size)
|
||||||
|
|
||||||
internal fun LLVMValueRef.setUnaligned() = apply { LLVMSetAlignment(this, 1) }
|
internal fun LLVMValueRef.setUnaligned() = apply { LLVMSetAlignment(this, 1) }
|
||||||
|
|
||||||
|
|||||||
+17
-17
@@ -149,30 +149,30 @@ internal class RTTIGenerator(override val context: Context) : ContextUtils {
|
|||||||
|
|
||||||
private val arrayClasses = mapOf(
|
private val arrayClasses = mapOf(
|
||||||
"kotlin.Array" to kObjHeaderPtr,
|
"kotlin.Array" to kObjHeaderPtr,
|
||||||
"kotlin.ByteArray" to int8Type,
|
"kotlin.ByteArray" to LLVMInt8Type()!!,
|
||||||
"kotlin.CharArray" to int16Type,
|
"kotlin.CharArray" to LLVMInt16Type()!!,
|
||||||
"kotlin.ShortArray" to int16Type,
|
"kotlin.ShortArray" to LLVMInt16Type()!!,
|
||||||
"kotlin.IntArray" to int32Type,
|
"kotlin.IntArray" to LLVMInt32Type()!!,
|
||||||
"kotlin.LongArray" to int64Type,
|
"kotlin.LongArray" to LLVMInt64Type()!!,
|
||||||
"kotlin.FloatArray" to floatType,
|
"kotlin.FloatArray" to LLVMFloatType()!!,
|
||||||
"kotlin.DoubleArray" to doubleType,
|
"kotlin.DoubleArray" to LLVMDoubleType()!!,
|
||||||
"kotlin.BooleanArray" to int8Type,
|
"kotlin.BooleanArray" to LLVMInt8Type()!!,
|
||||||
"kotlin.String" to int16Type,
|
"kotlin.String" to LLVMInt16Type()!!,
|
||||||
"kotlin.native.ImmutableBlob" to int8Type,
|
"kotlin.native.ImmutableBlob" to LLVMInt8Type()!!,
|
||||||
"kotlin.native.internal.NativePtrArray" to kInt8Ptr
|
"kotlin.native.internal.NativePtrArray" to kInt8Ptr
|
||||||
)
|
)
|
||||||
|
|
||||||
// Keep in sync with Konan_RuntimeType.
|
// Keep in sync with Konan_RuntimeType.
|
||||||
private val runtimeTypeMap = mapOf(
|
private val runtimeTypeMap = mapOf(
|
||||||
kObjHeaderPtr to 1,
|
kObjHeaderPtr to 1,
|
||||||
int8Type to 2,
|
LLVMInt8Type()!! to 2,
|
||||||
int16Type to 3,
|
LLVMInt16Type()!! to 3,
|
||||||
int32Type to 4,
|
LLVMInt32Type()!! to 4,
|
||||||
int64Type to 5,
|
LLVMInt64Type()!! to 5,
|
||||||
floatType to 6,
|
LLVMFloatType()!! to 6,
|
||||||
doubleType to 7,
|
LLVMDoubleType()!! to 7,
|
||||||
kInt8Ptr to 8,
|
kInt8Ptr to 8,
|
||||||
int1Type to 9
|
LLVMInt1Type()!! to 9
|
||||||
)
|
)
|
||||||
|
|
||||||
private fun getInstanceSize(classType: LLVMTypeRef?, className: FqName) : Int {
|
private fun getInstanceSize(classType: LLVMTypeRef?, className: FqName) : Int {
|
||||||
|
|||||||
+2
-2
@@ -1241,8 +1241,8 @@ private val ObjCValueType.llvmType: LLVMTypeRef get() = when (this) {
|
|||||||
ObjCValueType.UNSIGNED_SHORT -> int16Type
|
ObjCValueType.UNSIGNED_SHORT -> int16Type
|
||||||
ObjCValueType.UNSIGNED_INT -> int32Type
|
ObjCValueType.UNSIGNED_INT -> int32Type
|
||||||
ObjCValueType.UNSIGNED_LONG_LONG -> int64Type
|
ObjCValueType.UNSIGNED_LONG_LONG -> int64Type
|
||||||
ObjCValueType.FLOAT -> floatType
|
ObjCValueType.FLOAT -> LLVMFloatType()!!
|
||||||
ObjCValueType.DOUBLE -> doubleType
|
ObjCValueType.DOUBLE -> LLVMDoubleType()!!
|
||||||
ObjCValueType.POINTER -> kInt8Ptr
|
ObjCValueType.POINTER -> kInt8Ptr
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -74,15 +74,10 @@ linkerOpts.mingw = -lLLVMX86Disassembler -lLLVMX86AsmParser -lLLVMX86CodeGen -lL
|
|||||||
# ld: -r and -shared may not be used together
|
# ld: -r and -shared may not be used together
|
||||||
excludedFunctions.mingw = LLVMDumpType
|
excludedFunctions.mingw = LLVMDumpType
|
||||||
|
|
||||||
# Functions from LLVMIntPtrType to LLVMModuleCreateWithName are excluded because they work with the GlobalContext.
|
|
||||||
# This might not be safe if the compiler is called from a daemon process.
|
|
||||||
excludedFunctions = LLVMInitializeAllAsmParsers LLVMInitializeAllAsmPrinters LLVMInitializeAllDisassemblers \
|
excludedFunctions = LLVMInitializeAllAsmParsers LLVMInitializeAllAsmPrinters LLVMInitializeAllDisassemblers \
|
||||||
LLVMInitializeAllTargetInfos LLVMInitializeAllTargetMCs LLVMInitializeAllTargets LLVMInitializeNativeTarget \
|
LLVMInitializeAllTargetInfos LLVMInitializeAllTargetMCs LLVMInitializeAllTargets LLVMInitializeNativeTarget \
|
||||||
LLVMInitializeNativeAsmParser LLVMInitializeNativeAsmPrinter LLVMInitializeNativeDisassembler \
|
LLVMInitializeNativeAsmParser LLVMInitializeNativeAsmPrinter LLVMInitializeNativeDisassembler \
|
||||||
LLVMConstInBoundsGEP2 LLVMConstGEP2 LLVMIntPtrType LLVMIntPtrTypeForAS LLVMGetMDKindID LLVMInt1Type LLVMInt8Type \
|
LLVMConstInBoundsGEP2 LLVMConstGEP2
|
||||||
LLVMInt16Type LLVMInt32Type LLVMInt64Type LLVMInt128Type LLVMIntType LLVMHalfType LLVMFloatType LLVMDoubleType \
|
|
||||||
LLVMX86FP80Type LLVMFP128Type LLVMPPCFP128Type LLVMX86MMXType LLVMStructType LLVMVoidType LLVMLabelType \
|
|
||||||
LLVMMDString LLVMMDNode LLVMConstString LLVMConstStruct LLVMAppendBasicBlock LLVMInsertBasicBlock LLVMCreateBuilder \
|
|
||||||
LLVMParseBitcode LLVMParseBitcode2 LLVMGetBitcodeModule LLVMGetBitcodeModule2 LLVMGetGlobalContext LLVMModuleCreateWithName
|
|
||||||
|
|
||||||
strictEnums = LLVMIntPredicate LLVMOpcode LLVMDLLStorageClass LLVMCallConv LLVMThreadLocalMode LLVMAtomicOrdering
|
strictEnums = LLVMIntPredicate LLVMOpcode LLVMDLLStorageClass LLVMCallConv LLVMThreadLocalMode LLVMAtomicOrdering
|
||||||
|
|||||||
@@ -59,10 +59,6 @@ DIBuilderRef DICreateBuilder(LLVMModuleRef module) {
|
|||||||
void DIFinalize(DIBuilderRef builder) {
|
void DIFinalize(DIBuilderRef builder) {
|
||||||
auto diBuilder = llvm::unwrap(builder);
|
auto diBuilder = llvm::unwrap(builder);
|
||||||
diBuilder->finalize();
|
diBuilder->finalize();
|
||||||
}
|
|
||||||
|
|
||||||
void DIDispose(DIBuilderRef builder) {
|
|
||||||
auto diBuilder = llvm::unwrap(builder);
|
|
||||||
delete diBuilder;
|
delete diBuilder;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -40,7 +40,6 @@ typedef struct DIExpression *DIExpressionRef;
|
|||||||
|
|
||||||
DIBuilderRef DICreateBuilder(LLVMModuleRef module);
|
DIBuilderRef DICreateBuilder(LLVMModuleRef module);
|
||||||
void DIFinalize(DIBuilderRef builder);
|
void DIFinalize(DIBuilderRef builder);
|
||||||
void DIDispose(DIBuilderRef builder);
|
|
||||||
|
|
||||||
DICompileUnitRef DICreateCompilationUnit(DIBuilderRef builder, unsigned int lang, const char *File, const char* dir, const char * producer, int isOptimized, const char * flags, unsigned int rv);
|
DICompileUnitRef DICreateCompilationUnit(DIBuilderRef builder, unsigned int lang, const char *File, const char* dir, const char * producer, int isOptimized, const char * flags, unsigned int rv);
|
||||||
|
|
||||||
|
|||||||
@@ -7,9 +7,8 @@ package org.jetbrains.kotlin.cli.utilities
|
|||||||
import org.jetbrains.kotlin.native.interop.gen.defFileDependencies
|
import org.jetbrains.kotlin.native.interop.gen.defFileDependencies
|
||||||
import org.jetbrains.kotlin.cli.bc.main as konancMain
|
import org.jetbrains.kotlin.cli.bc.main as konancMain
|
||||||
import org.jetbrains.kotlin.cli.klib.main as klibMain
|
import org.jetbrains.kotlin.cli.klib.main as klibMain
|
||||||
import org.jetbrains.kotlin.cli.bc.mainNoExit as konancMainNoExit
|
|
||||||
|
|
||||||
private fun mainImpl(args: Array<String>, konancMain: (Array<String>) -> Unit) {
|
fun main(args: Array<String>) {
|
||||||
val utilityName = args[0]
|
val utilityName = args[0]
|
||||||
val utilityArgs = args.drop(1).toTypedArray()
|
val utilityArgs = args.drop(1).toTypedArray()
|
||||||
when (utilityName) {
|
when (utilityName) {
|
||||||
@@ -32,7 +31,3 @@ private fun mainImpl(args: Array<String>, konancMain: (Array<String>) -> Unit) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun main(args: Array<String>) = mainImpl(args, ::konancMain)
|
|
||||||
|
|
||||||
fun daemonMain(args: Array<String>) = mainImpl(args, ::konancMainNoExit)
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user