@@ -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 kniBridge337(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 UserData = FfiClosureImpl
|
||||
|
||||
private val topLevelInitializer = loadKonanLibrary("callbacks")
|
||||
private fun loadCallbacksLibrary() {
|
||||
System.loadLibrary("callbacks")
|
||||
}
|
||||
|
||||
private val topLevelInitializer = loadCallbacksLibrary()
|
||||
|
||||
|
||||
/**
|
||||
|
||||
@@ -16,10 +16,6 @@
|
||||
|
||||
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 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 {
|
||||
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()
|
||||
stubLines.forEach(out)
|
||||
nativeBridges.kotlinLines.forEach(out)
|
||||
if (context.platform == KotlinPlatform.JVM)
|
||||
out("private val loadLibrary = loadKonanLibrary(\"${context.libName}\")")
|
||||
if (context.platform == KotlinPlatform.JVM) {
|
||||
out("private val loadLibrary = System.loadLibrary(\"${context.libName}\")")
|
||||
}
|
||||
}
|
||||
}
|
||||
private val printer = object : StubIrVisitor<StubContainer?, Unit> {
|
||||
|
||||
@@ -230,12 +230,6 @@ class K2Native : CLICompiler<K2NativeCompilerArguments>() {
|
||||
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 mainNoExit(args: Array<String>) = K2Native.mainNoExit(args)
|
||||
|
||||
|
||||
+2
-2
@@ -233,8 +233,8 @@ private class ExportedElement(val kind: ElementKind,
|
||||
cname = "_konan_function_${owner.nextFunctionIndex()}"
|
||||
// Produce type getter.
|
||||
val getTypeFunction = LLVMAddFunction(context.llvmModule, "${cname}_type", owner.kGetTypeFuncType)!!
|
||||
val builder = LLVMCreateBuilderInContext(llvmContext)!!
|
||||
val bb = LLVMAppendBasicBlockInContext(llvmContext, getTypeFunction, "")!!
|
||||
val builder = LLVMCreateBuilder()!!
|
||||
val bb = LLVMAppendBasicBlock(getTypeFunction, "")!!
|
||||
LLVMPositionBuilderAtEnd(builder, bb)
|
||||
LLVMBuildRet(builder, irClass.typeInfoPtr.llvm)
|
||||
LLVMDisposeBuilder(builder)
|
||||
|
||||
+2
-15
@@ -5,7 +5,8 @@
|
||||
|
||||
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.descriptors.WrappedSimpleFunctionDescriptor
|
||||
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 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 coverage = CoverageManager(this)
|
||||
|
||||
+7
-7
@@ -6,7 +6,6 @@
|
||||
package org.jetbrains.kotlin.backend.konan
|
||||
|
||||
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.descriptors.ClassDescriptor
|
||||
import org.jetbrains.kotlin.ir.declarations.IrClass
|
||||
@@ -212,6 +211,11 @@ private val implicitInlineClasses =
|
||||
KonanFqNames.nativePtr +
|
||||
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>() {
|
||||
|
||||
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 hasInlineModifier(clazz: IrClass): Boolean = clazz.descriptor.isInline
|
||||
|
||||
override fun getNativePointedSuperclass(clazz: IrClass): IrClass? {
|
||||
var superClass: IrClass? = clazz
|
||||
while (superClass != null && superClass.descriptor.fqNameUnsafe != InteropFqNames.nativePointed)
|
||||
superClass = superClass.getSuperClassNotAny()
|
||||
return superClass
|
||||
}
|
||||
override fun getNativePointedSuperclass(clazz: IrClass): IrClass? = clazz.getAllSuperClassifiers()
|
||||
.firstOrNull { it.descriptor.fqNameUnsafe == InteropFqNames.nativePointed }
|
||||
|
||||
override fun getInlinedClassUnderlyingType(clazz: IrClass): IrType =
|
||||
clazz.constructors.firstOrNull { it.isPrimary }?.valueParameters?.single()?.type
|
||||
|
||||
+1
-5
@@ -24,10 +24,6 @@ fun runTopLevelPhases(konanConfig: KonanConfig, environment: KotlinCoreEnvironme
|
||||
|
||||
if (konanConfig.infoArgsOnly) return
|
||||
|
||||
try {
|
||||
(toplevelPhase as CompilerPhase<Context, Unit, Unit>).invokeToplevel(context.phaseConfig, context, Unit)
|
||||
} finally {
|
||||
context.disposeLlvm()
|
||||
}
|
||||
(toplevelPhase as CompilerPhase<Context, Unit, Unit>).invokeToplevel(context.phaseConfig, context, Unit)
|
||||
}
|
||||
|
||||
|
||||
+2
-4
@@ -378,13 +378,12 @@ internal val entryPointPhase = SameTypeNamedPhaseWrapper(
|
||||
internal val bitcodePhase = namedIrModulePhase(
|
||||
name = "Bitcode",
|
||||
description = "LLVM Bitcode generation",
|
||||
lower = contextLLVMSetupPhase then
|
||||
buildDFGPhase then
|
||||
lower = buildDFGPhase then
|
||||
serializeDFGPhase then
|
||||
deserializeDFGPhase then
|
||||
devirtualizationPhase then
|
||||
dcePhase then
|
||||
createLLVMDeclarationsPhase then
|
||||
contextLLVMSetupPhase then
|
||||
ghaPhase then
|
||||
RTTIPhase then
|
||||
generateDebugInfoHeaderPhase then
|
||||
@@ -419,7 +418,6 @@ val toplevelPhase: CompilerPhase<*, Unit, Unit> = namedUnitPhase(
|
||||
verifyBitcodePhase then
|
||||
printBitcodePhase then
|
||||
produceOutputPhase then
|
||||
disposeLLVMPhase then
|
||||
unitSink()
|
||||
) then
|
||||
linkPhase
|
||||
|
||||
+1
-16
@@ -26,30 +26,15 @@ internal val contextLLVMSetupPhase = makeKonanModuleOpPhase(
|
||||
// (see Llvm class in ContextUtils)
|
||||
// Which in turn is determined by the clang flags
|
||||
// used to compile runtime.bc.
|
||||
llvmContext = LLVMContextCreate()!!
|
||||
val llvmModule = LLVMModuleCreateWithNameInContext("out", llvmContext)!!
|
||||
val llvmModule = LLVMModuleCreateWithName("out")!! // TODO: dispose
|
||||
context.llvmModule = 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.lifetimes = mutableMapOf()
|
||||
context.codegenVisitor = CodeGeneratorVisitor(context, context.lifetimes)
|
||||
}
|
||||
)
|
||||
|
||||
internal val disposeLLVMPhase = makeKonanModuleOpPhase(
|
||||
name = "DisposeLLVM",
|
||||
description = "Dispose LLVM",
|
||||
op = { context, _ -> context.disposeLlvm() }
|
||||
)
|
||||
|
||||
internal val RTTIPhase = makeKonanModuleOpPhase(
|
||||
name = "RTTI",
|
||||
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 llvmFunctionOrNull(function: IrFunction): LLVMValueRef? = function.llvmFunctionOrNull
|
||||
val intPtrType = LLVMIntPtrTypeInContext(llvmContext, llvmTargetData)!!
|
||||
val intPtrType = LLVMIntPtrType(llvmTargetData)!!
|
||||
internal val immOneIntPtrType = LLVMConstInt(intPtrType, 1, 1)!!
|
||||
// Keep in sync with OBJECT_TAG_MASK in C++.
|
||||
internal val immTypeInfoMask = LLVMConstNot(LLVMConstInt(intPtrType, 3, 0)!!)!!
|
||||
@@ -120,17 +120,12 @@ internal inline fun<R> generateFunction(codegen: CodeGenerator,
|
||||
code: FunctionGenerationContext.(FunctionGenerationContext) -> R) {
|
||||
val llvmFunction = codegen.llvmFunction(function)
|
||||
|
||||
val functionGenerationContext = FunctionGenerationContext(
|
||||
generateFunctionBody(FunctionGenerationContext(
|
||||
llvmFunction,
|
||||
codegen,
|
||||
startLocation,
|
||||
endLocation,
|
||||
function)
|
||||
try {
|
||||
generateFunctionBody(functionGenerationContext, code)
|
||||
} finally {
|
||||
functionGenerationContext.dispose()
|
||||
}
|
||||
function), code)
|
||||
|
||||
// To perform per-function validation.
|
||||
if (false)
|
||||
@@ -140,12 +135,7 @@ internal inline fun<R> generateFunction(codegen: CodeGenerator,
|
||||
|
||||
internal inline fun<R> generateFunction(codegen: CodeGenerator, function: LLVMValueRef,
|
||||
code:FunctionGenerationContext.(FunctionGenerationContext) -> R) {
|
||||
val functionGenerationContext = FunctionGenerationContext(function, codegen, null, null)
|
||||
try {
|
||||
generateFunctionBody(functionGenerationContext, code)
|
||||
} finally {
|
||||
functionGenerationContext.dispose()
|
||||
}
|
||||
generateFunctionBody(FunctionGenerationContext(function, codegen, null, null), code)
|
||||
}
|
||||
|
||||
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 {
|
||||
val bb = LLVMAppendBasicBlockInContext(llvmContext, function, name)!!
|
||||
val bb = LLVMAppendBasicBlock(function, name)!!
|
||||
update(bb, locationInfo)
|
||||
return bb
|
||||
}
|
||||
|
||||
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)
|
||||
LLVMMoveBasicBlockAfter(result, this.currentBlock)
|
||||
return result
|
||||
@@ -1090,7 +1076,7 @@ internal class FunctionGenerationContext(val function: LLVMValueRef,
|
||||
* This class is introduced to workaround unreachable code handling.
|
||||
*/
|
||||
inner class PositionHolder {
|
||||
private val builder: LLVMBuilderRef = LLVMCreateBuilderInContext(llvmContext)!!
|
||||
private val builder: LLVMBuilderRef = LLVMCreateBuilder()!!
|
||||
|
||||
|
||||
fun getBuilder(): LLVMBuilderRef {
|
||||
|
||||
+10
-8
@@ -296,12 +296,14 @@ internal class Llvm(val context: Context, val llvmModule: LLVMModuleRef) {
|
||||
}
|
||||
|
||||
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)!!
|
||||
}
|
||||
|
||||
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)!!
|
||||
}
|
||||
|
||||
@@ -553,12 +555,12 @@ internal class Llvm(val context: Context, val llvmModule: LLVMModuleRef) {
|
||||
override fun getValue(thisRef: Llvm, property: KProperty<*>): LLVMValueRef = value
|
||||
}
|
||||
}
|
||||
val llvmInt8 = int8Type
|
||||
val llvmInt16 = int16Type
|
||||
val llvmInt32 = int32Type
|
||||
val llvmInt64 = int64Type
|
||||
val llvmFloat = floatType
|
||||
val llvmDouble = doubleType
|
||||
val llvmInt8 = LLVMInt8Type()!!
|
||||
val llvmInt16 = LLVMInt16Type()!!
|
||||
val llvmInt32 = LLVMInt32Type()!!
|
||||
val llvmInt64 = LLVMInt64Type()!!
|
||||
val llvmFloat = LLVMFloatType()!!
|
||||
val llvmDouble = LLVMDoubleType()!!
|
||||
}
|
||||
|
||||
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.isUnit
|
||||
|
||||
private fun RuntimeAware.getLlvmType(primitiveBinaryType: PrimitiveBinaryType?) = when (primitiveBinaryType) {
|
||||
null -> this.kObjHeaderPtr
|
||||
private val primitiveToLlvm = PrimitiveBinaryType.values().associate {
|
||||
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.BYTE -> int8Type
|
||||
PrimitiveBinaryType.SHORT -> int16Type
|
||||
PrimitiveBinaryType.INT -> int32Type
|
||||
PrimitiveBinaryType.LONG -> int64Type
|
||||
PrimitiveBinaryType.FLOAT -> floatType
|
||||
PrimitiveBinaryType.DOUBLE -> doubleType
|
||||
|
||||
PrimitiveBinaryType.POINTER -> int8TypePtr
|
||||
PrimitiveBinaryType.POINTER -> int8TypePtr
|
||||
}!!
|
||||
}
|
||||
|
||||
private fun RuntimeAware.getLlvmType(primitiveBinaryType: PrimitiveBinaryType?) =
|
||||
primitiveBinaryType?.let { primitiveToLlvm[it]!! } ?: this.kObjHeaderPtr
|
||||
|
||||
internal fun RuntimeAware.getLLVMType(type: IrType): LLVMTypeRef =
|
||||
getLlvmType(type.computePrimitiveBinaryTypeOrNull())
|
||||
|
||||
@@ -34,7 +37,7 @@ internal fun RuntimeAware.getLLVMType(type: DataFlowIR.Type) =
|
||||
|
||||
internal fun RuntimeAware.getLLVMReturnType(type: IrType): LLVMTypeRef {
|
||||
return when {
|
||||
type.isUnit() || type.isNothing() -> voidType
|
||||
type.isUnit() || type.isNothing() -> LLVMVoidType()!!
|
||||
else -> getLLVMType(type)
|
||||
}
|
||||
}
|
||||
+3
-3
@@ -26,8 +26,8 @@ import org.jetbrains.kotlin.konan.file.File
|
||||
internal object DWARF {
|
||||
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. */
|
||||
val dwarfVersionMetaDataNodeName get() = "Dwarf Version".mdString()
|
||||
val dwarfDebugInfoMetaDataNodeName get() = "Debug Info Version".mdString()
|
||||
val dwarfVersionMetaDataNodeName = "Dwarf Version".mdString()
|
||||
val dwarfDebugInfoMetaDataNodeName = "Debug Info Version".mdString()
|
||||
const val debugInfoVersion = 3 /* TODO: configurable? */
|
||||
/**
|
||||
* 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)
|
||||
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 otherLlvmType = LLVMPointerType(int64Type, 0)!!
|
||||
val otherLlvmType = LLVMPointerType(LLVMInt64Type(), 0)!!
|
||||
val otherTypeSize = LLVMSizeOfTypeInBits(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.
|
||||
|
||||
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 bitsWithPadding = load(bitsWithPaddingPtr).setUnaligned()
|
||||
@@ -370,13 +370,13 @@ internal class IntrinsicGenerator(private val environment: IntrinsicGeneratorEnv
|
||||
val value = args[3]
|
||||
assert(value.type == int64Type)
|
||||
|
||||
val bitsType = LLVMIntTypeInContext(llvmContext, size)!!
|
||||
val bitsType = LLVMIntType(size)!!
|
||||
|
||||
val prefixBitsNum = (offset % 8).toInt()
|
||||
val suffixBitsNum = (8 - ((size + offset) % 8).toInt()) % 8
|
||||
|
||||
val bitsWithPaddingNum = prefixBitsNum + size + suffixBitsNum
|
||||
val bitsWithPaddingType = LLVMIntTypeInContext(llvmContext, bitsWithPaddingNum)!!
|
||||
val bitsWithPaddingType = LLVMIntType(bitsWithPaddingNum)!!
|
||||
|
||||
// 0011111000:
|
||||
val discardBitsMask = LLVMConstShl(
|
||||
@@ -443,8 +443,8 @@ internal class IntrinsicGenerator(private val environment: IntrinsicGeneratorEnv
|
||||
}
|
||||
|
||||
// TODO: Find better place for these guys.
|
||||
private val kImmZero = LLVMConstInt(int32Type, 0, 1)!!
|
||||
private val kImmOne = LLVMConstInt(int32Type, 1, 1)!!
|
||||
private val kImmZero = LLVMConstInt(LLVMInt32Type(), 0, 1)!!
|
||||
private val kImmOne = LLVMConstInt(LLVMInt32Type(), 1, 1)!!
|
||||
|
||||
private fun FunctionGenerationContext.emitGetObjCClass(callSite: IrCall): LLVMValueRef {
|
||||
val descriptor = callSite.descriptor.original
|
||||
@@ -487,7 +487,7 @@ internal class IntrinsicGenerator(private val environment: IntrinsicGeneratorEnv
|
||||
return when (val typeKind = LLVMGetTypeKind(first.type)) {
|
||||
llvm.LLVMTypeKind.LLVMFloatTypeKind, llvm.LLVMTypeKind.LLVMDoubleTypeKind -> {
|
||||
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))
|
||||
}
|
||||
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 = "") {
|
||||
memScoped {
|
||||
val errorRef = allocPointerTo<ByteVar>()
|
||||
val verificationResult = LLVMVerifyModule(
|
||||
llvmModule, LLVMVerifierFailureAction.LLVMPrintMessageAction, errorRef.ptr)
|
||||
LLVMDisposeMessage(errorRef.value)
|
||||
if (verificationResult == 1) {
|
||||
// TODO: use LLVMDisposeMessage() on errorRef, once possible in interop.
|
||||
if (LLVMVerifyModule(
|
||||
llvmModule, LLVMVerifierFailureAction.LLVMPrintMessageAction, errorRef.ptr) == 1) {
|
||||
if (current.isNotEmpty())
|
||||
println("Error in $current")
|
||||
LLVMDumpModule(llvmModule)
|
||||
@@ -350,8 +349,8 @@ internal class CodeGeneratorVisitor(val context: Context, val lifetimes: Map<IrE
|
||||
|
||||
//-------------------------------------------------------------------------//
|
||||
|
||||
val kVoidFuncType = functionType(voidType)
|
||||
val kInitFuncType = functionType(voidType, false, int32Type)
|
||||
val kVoidFuncType = LLVMFunctionType(LLVMVoidType(), null, 0, 0)!!
|
||||
val kInitFuncType = LLVMFunctionType(LLVMVoidType(), cValuesOf(LLVMInt32Type()), 1, 0)!!
|
||||
val kNodeInitType = LLVMGetTypeByName(context.llvmModule, "struct.InitNode")!!
|
||||
//-------------------------------------------------------------------------//
|
||||
|
||||
@@ -1574,14 +1573,14 @@ internal class CodeGeneratorVisitor(val context: Context, val lifetimes: Map<IrE
|
||||
true -> return kTrue
|
||||
false -> return kFalse
|
||||
}
|
||||
IrConstKind.Char -> return Char16(value.value as Char).llvm
|
||||
IrConstKind.Byte -> return Int8(value.value as Byte).llvm
|
||||
IrConstKind.Short -> return Int16(value.value as Short).llvm
|
||||
IrConstKind.Int -> return Int32(value.value as Int).llvm
|
||||
IrConstKind.Long -> return Int64(value.value as Long).llvm
|
||||
IrConstKind.Char -> return LLVMConstInt(LLVMInt16Type(), (value.value as Char).toLong(), 0)!!
|
||||
IrConstKind.Byte -> return LLVMConstInt(LLVMInt8Type(), (value.value as Byte).toLong(), 1)!!
|
||||
IrConstKind.Short -> return LLVMConstInt(LLVMInt16Type(), (value.value as Short).toLong(), 1)!!
|
||||
IrConstKind.Int -> return LLVMConstInt(LLVMInt32Type(), (value.value as Int).toLong(), 1)!!
|
||||
IrConstKind.Long -> return LLVMConstInt(LLVMInt64Type(), value.value as Long, 1)!!
|
||||
IrConstKind.String -> return evaluateStringConst(value as IrConst<String>)
|
||||
IrConstKind.Float -> return LLVMConstRealOfString(floatType, (value.value as Float).toString())!!
|
||||
IrConstKind.Double -> return LLVMConstRealOfString(doubleType, (value.value as Double).toString())!!
|
||||
IrConstKind.Float -> return LLVMConstRealOfString(LLVMFloatType(), (value.value as Float).toString())!!
|
||||
IrConstKind.Double -> return LLVMConstRealOfString(LLVMDoubleType(), (value.value as Double).toString())!!
|
||||
}
|
||||
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 kImmOne = Int32(1).llvm
|
||||
private val kTrue = Int1(1).llvm
|
||||
private val kFalse = Int1(0).llvm
|
||||
private val kImmZero = LLVMConstInt(LLVMInt32Type(), 0, 1)!!
|
||||
private val kImmOne = LLVMConstInt(LLVMInt32Type(), 1, 1)!!
|
||||
private val kTrue = LLVMConstInt(LLVMInt1Type(), 1, 1)!!
|
||||
private val kFalse = LLVMConstInt(LLVMInt1Type(), 0, 1)!!
|
||||
|
||||
// TODO: Intrinsify?
|
||||
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* }
|
||||
|
||||
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 }
|
||||
|
||||
+29
-58
@@ -9,31 +9,6 @@ import kotlinx.cinterop.*
|
||||
import llvm.*
|
||||
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
|
||||
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 {
|
||||
override val llvm = LLVMConstInt(int1Type, value.toLong(), 1)!!
|
||||
override val llvm = LLVMConstInt(LLVMInt1Type(), value.toLong(), 1)!!
|
||||
}
|
||||
|
||||
internal class Int8(val value: Byte) : ConstValue {
|
||||
override val llvm = LLVMConstInt(int8Type, value.toLong(), 1)!!
|
||||
}
|
||||
|
||||
internal class Int16(val value: Short) : ConstValue {
|
||||
override val llvm = LLVMConstInt(int16Type, value.toLong(), 1)!!
|
||||
override val llvm = LLVMConstInt(LLVMInt8Type(), value.toLong(), 1)!!
|
||||
}
|
||||
|
||||
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 {
|
||||
override val llvm = LLVMConstInt(int32Type, value.toLong(), 1)!!
|
||||
override val llvm = LLVMConstInt(LLVMInt32Type(), value.toLong(), 1)!!
|
||||
}
|
||||
|
||||
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 {
|
||||
override val llvm = LLVMConstReal(floatType, value.toDouble())!!
|
||||
override val llvm = LLVMConstReal(LLVMFloatType(), value.toDouble())!!
|
||||
}
|
||||
|
||||
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 {
|
||||
@@ -161,6 +121,17 @@ internal fun constValue(value: LLVMValueRef) = object : ConstValue {
|
||||
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
|
||||
get() = runtime.typeInfoType
|
||||
internal val RuntimeAware.kObjHeader: LLVMTypeRef
|
||||
@@ -175,13 +146,13 @@ internal val RuntimeAware.kArrayHeaderPtr: LLVMTypeRef
|
||||
get() = pointerType(kArrayHeader)
|
||||
internal val RuntimeAware.kTypeInfoPtr: LLVMTypeRef
|
||||
get() = pointerType(kTypeInfo)
|
||||
internal val kInt1 get() = int1Type
|
||||
internal val kBoolean get() = kInt1
|
||||
internal val kInt8Ptr get() = pointerType(int8Type)
|
||||
internal val kInt8PtrPtr get() = pointerType(kInt8Ptr)
|
||||
internal val kNullInt8Ptr get() = LLVMConstNull(kInt8Ptr)!!
|
||||
internal val kImmInt32Zero get() = Int32(0).llvm
|
||||
internal val kImmInt32One get() = Int32(1).llvm
|
||||
internal val kInt1 = LLVMInt1Type()!!
|
||||
internal val kBoolean = kInt1
|
||||
internal val kInt8Ptr = pointerType(int8Type)
|
||||
internal val kInt8PtrPtr = pointerType(kInt8Ptr)
|
||||
internal val kNullInt8Ptr = LLVMConstNull(kInt8Ptr)!!
|
||||
internal val kImmInt32Zero = Int32(0).llvm
|
||||
internal val kImmInt32One = Int32(1).llvm
|
||||
internal val ContextUtils.kNullObjHeaderPtr: LLVMValueRef
|
||||
get() = LLVMConstNull(this.kObjHeaderPtr)!!
|
||||
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(types: List<LLVMTypeRef>): LLVMTypeRef =
|
||||
LLVMStructTypeInContext(llvmContext, types.toCValues(), types.size, 0)!!
|
||||
LLVMStructType(types.toCValues(), types.size, 0)!!
|
||||
|
||||
internal fun ContextUtils.numParameters(functionType: LLVMTypeRef) : Int {
|
||||
// Note that type is usually function pointer, so we have to dereference it.
|
||||
@@ -302,7 +273,7 @@ fun parseBitcodeFile(path: String): LLVMModuleRef = memScoped {
|
||||
try {
|
||||
|
||||
val moduleRef = alloc<LLVMModuleRefVar>()
|
||||
val parseRes = LLVMParseBitcodeInContext2(llvmContext, memoryBuffer, moduleRef.ptr)
|
||||
val parseRes = LLVMParseBitcode2(memoryBuffer, moduleRef.ptr)
|
||||
if (parseRes != 0) {
|
||||
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 node(vararg it:LLVMValueRef) = LLVMMDNodeInContext(llvmContext, it.toList().toCValues(), it.size)
|
||||
internal fun String.mdString() = LLVMMDString(this, this.length)!!
|
||||
internal fun node(vararg it:LLVMValueRef) = LLVMMDNode(it.toList().toCValues(), it.size)
|
||||
|
||||
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(
|
||||
"kotlin.Array" to kObjHeaderPtr,
|
||||
"kotlin.ByteArray" to int8Type,
|
||||
"kotlin.CharArray" to int16Type,
|
||||
"kotlin.ShortArray" to int16Type,
|
||||
"kotlin.IntArray" to int32Type,
|
||||
"kotlin.LongArray" to int64Type,
|
||||
"kotlin.FloatArray" to floatType,
|
||||
"kotlin.DoubleArray" to doubleType,
|
||||
"kotlin.BooleanArray" to int8Type,
|
||||
"kotlin.String" to int16Type,
|
||||
"kotlin.native.ImmutableBlob" to int8Type,
|
||||
"kotlin.ByteArray" to LLVMInt8Type()!!,
|
||||
"kotlin.CharArray" to LLVMInt16Type()!!,
|
||||
"kotlin.ShortArray" to LLVMInt16Type()!!,
|
||||
"kotlin.IntArray" to LLVMInt32Type()!!,
|
||||
"kotlin.LongArray" to LLVMInt64Type()!!,
|
||||
"kotlin.FloatArray" to LLVMFloatType()!!,
|
||||
"kotlin.DoubleArray" to LLVMDoubleType()!!,
|
||||
"kotlin.BooleanArray" to LLVMInt8Type()!!,
|
||||
"kotlin.String" to LLVMInt16Type()!!,
|
||||
"kotlin.native.ImmutableBlob" to LLVMInt8Type()!!,
|
||||
"kotlin.native.internal.NativePtrArray" to kInt8Ptr
|
||||
)
|
||||
|
||||
// Keep in sync with Konan_RuntimeType.
|
||||
private val runtimeTypeMap = mapOf(
|
||||
kObjHeaderPtr to 1,
|
||||
int8Type to 2,
|
||||
int16Type to 3,
|
||||
int32Type to 4,
|
||||
int64Type to 5,
|
||||
floatType to 6,
|
||||
doubleType to 7,
|
||||
LLVMInt8Type()!! to 2,
|
||||
LLVMInt16Type()!! to 3,
|
||||
LLVMInt32Type()!! to 4,
|
||||
LLVMInt64Type()!! to 5,
|
||||
LLVMFloatType()!! to 6,
|
||||
LLVMDoubleType()!! to 7,
|
||||
kInt8Ptr to 8,
|
||||
int1Type to 9
|
||||
LLVMInt1Type()!! to 9
|
||||
)
|
||||
|
||||
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_INT -> int32Type
|
||||
ObjCValueType.UNSIGNED_LONG_LONG -> int64Type
|
||||
ObjCValueType.FLOAT -> floatType
|
||||
ObjCValueType.DOUBLE -> doubleType
|
||||
ObjCValueType.FLOAT -> LLVMFloatType()!!
|
||||
ObjCValueType.DOUBLE -> LLVMDoubleType()!!
|
||||
ObjCValueType.POINTER -> kInt8Ptr
|
||||
}
|
||||
|
||||
|
||||
@@ -74,15 +74,10 @@ linkerOpts.mingw = -lLLVMX86Disassembler -lLLVMX86AsmParser -lLLVMX86CodeGen -lL
|
||||
# ld: -r and -shared may not be used together
|
||||
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 \
|
||||
LLVMInitializeAllTargetInfos LLVMInitializeAllTargetMCs LLVMInitializeAllTargets LLVMInitializeNativeTarget \
|
||||
LLVMInitializeNativeAsmParser LLVMInitializeNativeAsmPrinter LLVMInitializeNativeDisassembler \
|
||||
LLVMConstInBoundsGEP2 LLVMConstGEP2 LLVMIntPtrType LLVMIntPtrTypeForAS LLVMGetMDKindID LLVMInt1Type LLVMInt8Type \
|
||||
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
|
||||
LLVMConstInBoundsGEP2 LLVMConstGEP2
|
||||
|
||||
strictEnums = LLVMIntPredicate LLVMOpcode LLVMDLLStorageClass LLVMCallConv LLVMThreadLocalMode LLVMAtomicOrdering
|
||||
|
||||
@@ -59,10 +59,6 @@ DIBuilderRef DICreateBuilder(LLVMModuleRef module) {
|
||||
void DIFinalize(DIBuilderRef builder) {
|
||||
auto diBuilder = llvm::unwrap(builder);
|
||||
diBuilder->finalize();
|
||||
}
|
||||
|
||||
void DIDispose(DIBuilderRef builder) {
|
||||
auto diBuilder = llvm::unwrap(builder);
|
||||
delete diBuilder;
|
||||
}
|
||||
|
||||
|
||||
@@ -40,7 +40,6 @@ typedef struct DIExpression *DIExpressionRef;
|
||||
|
||||
DIBuilderRef DICreateBuilder(LLVMModuleRef module);
|
||||
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);
|
||||
|
||||
|
||||
@@ -7,9 +7,8 @@ package org.jetbrains.kotlin.cli.utilities
|
||||
import org.jetbrains.kotlin.native.interop.gen.defFileDependencies
|
||||
import org.jetbrains.kotlin.cli.bc.main as konancMain
|
||||
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 utilityArgs = args.drop(1).toTypedArray()
|
||||
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