backend: partially port code to new interop
This commit is contained in:
+3
-4
@@ -1,7 +1,7 @@
|
|||||||
package org.jetbrains.kotlin.backend.konan.llvm
|
package org.jetbrains.kotlin.backend.konan.llvm
|
||||||
|
|
||||||
|
|
||||||
import kotlin_native.interop.*
|
import kotlin_.cinterop.*
|
||||||
import llvm.*
|
import llvm.*
|
||||||
import org.jetbrains.kotlin.descriptors.ClassConstructorDescriptor
|
import org.jetbrains.kotlin.descriptors.ClassConstructorDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||||
@@ -118,9 +118,8 @@ internal class CodeGenerator(override val context:Context) : ContextUtils {
|
|||||||
fun call(llvmFunction: LLVMOpaqueValue?, args: List<LLVMOpaqueValue?>, result: String?): LLVMOpaqueValue? {
|
fun call(llvmFunction: LLVMOpaqueValue?, args: List<LLVMOpaqueValue?>, result: String?): LLVMOpaqueValue? {
|
||||||
if (args.size == 0) return LLVMBuildCall(context.llvmBuilder, llvmFunction, null, 0, result)
|
if (args.size == 0) return LLVMBuildCall(context.llvmBuilder, llvmFunction, null, 0, result)
|
||||||
memScoped {
|
memScoped {
|
||||||
val rargs = alloc(array[args.size](Ref to LLVMOpaqueValue))
|
val rargs = allocArrayOf(args)
|
||||||
args.forEachIndexed { i, llvmOpaqueValue -> rargs[i].value = args[i] }
|
return LLVMBuildCall(context.llvmBuilder, llvmFunction, rargs[0].ptr, args.size, result)
|
||||||
return LLVMBuildCall(context.llvmBuilder, llvmFunction, rargs[0], args.size, result)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+2
-2
@@ -4,12 +4,12 @@ import llvm.*
|
|||||||
import org.jetbrains.kotlin.backend.konan.ModuleIndex
|
import org.jetbrains.kotlin.backend.konan.ModuleIndex
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrModuleFragment
|
import org.jetbrains.kotlin.ir.declarations.IrModuleFragment
|
||||||
|
|
||||||
internal class Context(val irModule: IrModuleFragment, val runtime: Runtime, val llvmModule: LLVMOpaqueModule) {
|
internal class Context(val irModule: IrModuleFragment, val runtime: Runtime, val llvmModule: LLVMModuleRef) {
|
||||||
val moduleIndex = ModuleIndex(irModule)
|
val moduleIndex = ModuleIndex(irModule)
|
||||||
|
|
||||||
val llvmBuilder = LLVMCreateBuilder()
|
val llvmBuilder = LLVMCreateBuilder()
|
||||||
|
|
||||||
private fun importFunction(name: String, otherModule: LLVMOpaqueModule): LLVMOpaqueValue {
|
private fun importFunction(name: String, otherModule: LLVMModuleRef): LLVMValueRef {
|
||||||
if (LLVMGetNamedFunction(llvmModule, name) != null) {
|
if (LLVMGetNamedFunction(llvmModule, name) != null) {
|
||||||
throw IllegalArgumentException("function $name already exists")
|
throw IllegalArgumentException("function $name already exists")
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-2
@@ -1,6 +1,6 @@
|
|||||||
package org.jetbrains.kotlin.backend.konan.llvm
|
package org.jetbrains.kotlin.backend.konan.llvm
|
||||||
|
|
||||||
import kotlin_native.interop.*
|
import kotlin_.cinterop.*
|
||||||
import llvm.*
|
import llvm.*
|
||||||
import org.jetbrains.kotlin.backend.konan.hash.GlobalHash
|
import org.jetbrains.kotlin.backend.konan.hash.GlobalHash
|
||||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||||
@@ -22,7 +22,7 @@ internal interface ContextUtils {
|
|||||||
val runtime: Runtime
|
val runtime: Runtime
|
||||||
get() = context.runtime
|
get() = context.runtime
|
||||||
|
|
||||||
val llvmTargetData: LLVMOpaqueTargetData
|
val llvmTargetData: LLVMTargetDataRef
|
||||||
get() = runtime.targetData
|
get() = runtime.targetData
|
||||||
|
|
||||||
val staticData: StaticData
|
val staticData: StaticData
|
||||||
|
|||||||
+1
-1
@@ -4,7 +4,7 @@ import llvm.*
|
|||||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||||
import org.jetbrains.kotlin.types.KotlinType
|
import org.jetbrains.kotlin.types.KotlinType
|
||||||
|
|
||||||
internal fun getLLVMType(type: KotlinType): LLVMOpaqueType {
|
internal fun getLLVMType(type: KotlinType): LLVMTypeRef {
|
||||||
return when {
|
return when {
|
||||||
KotlinBuiltIns.isBoolean(type) -> LLVMInt1Type()
|
KotlinBuiltIns.isBoolean(type) -> LLVMInt1Type()
|
||||||
KotlinBuiltIns.isByte(type) -> LLVMInt8Type()
|
KotlinBuiltIns.isByte(type) -> LLVMInt8Type()
|
||||||
|
|||||||
+11
-11
@@ -1,22 +1,22 @@
|
|||||||
package org.jetbrains.kotlin.backend.konan.llvm
|
package org.jetbrains.kotlin.backend.konan.llvm
|
||||||
|
|
||||||
import kotlin_native.interop.*
|
import kotlin_.cinterop.*
|
||||||
import org.jetbrains.kotlin.backend.konan.hash.*
|
import org.jetbrains.kotlin.backend.konan.hash.*
|
||||||
|
|
||||||
internal fun localHash(data: ByteArray): Long {
|
internal fun localHash(data: ByteArray): Long {
|
||||||
memScoped {
|
memScoped {
|
||||||
val hashBox = alloc(Int64Box)
|
val res = alloc<LocalHashVar>()
|
||||||
val bytes = allocNativeArrayOf(data)
|
val bytes = allocArrayOf(data)
|
||||||
MakeLocalHash(bytes.ptr, data.size, hashBox)
|
MakeLocalHash(bytes[0].ptr, data.size, res.ptr)
|
||||||
return hashBox.value
|
return res.value
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal fun globalHash(data: ByteArray, retValPlacement: Placement): GlobalHash {
|
internal fun globalHash(data: ByteArray, retValPlacement: NativePlacement): GlobalHash {
|
||||||
val res = retValPlacement.alloc(GlobalHash)
|
val res = retValPlacement.alloc<GlobalHash>()
|
||||||
memScoped {
|
memScoped {
|
||||||
val bytes = allocNativeArrayOf(data)
|
val bytes = allocArrayOf(data)
|
||||||
MakeGlobalHash(bytes.ptr, data.size, res)
|
MakeGlobalHash(bytes[0].ptr, data.size, res.ptr)
|
||||||
}
|
}
|
||||||
return res
|
return res
|
||||||
}
|
}
|
||||||
@@ -24,8 +24,8 @@ internal fun globalHash(data: ByteArray, retValPlacement: Placement): GlobalHash
|
|||||||
internal fun base64Encode(data: ByteArray): String {
|
internal fun base64Encode(data: ByteArray): String {
|
||||||
memScoped {
|
memScoped {
|
||||||
val resultSize = 4 * data.size / 3 + 3 + 1
|
val resultSize = 4 * data.size / 3 + 3 + 1
|
||||||
val result = alloc(NativeArray of Int8Box length resultSize)
|
val result = allocArray<CInt8Var>(resultSize)
|
||||||
val bytes = allocNativeArrayOf(data)
|
val bytes = allocArrayOf(data)
|
||||||
Base64Encode(bytes.ptr, data.size, result.ptr, resultSize)
|
Base64Encode(bytes.ptr, data.size, result.ptr, resultSize)
|
||||||
// TODO: any better way to do that without two copies?
|
// TODO: any better way to do that without two copies?
|
||||||
return CString.fromArray(result).toString()
|
return CString.fromArray(result).toString()
|
||||||
|
|||||||
+5
-5
@@ -1,6 +1,6 @@
|
|||||||
package org.jetbrains.kotlin.backend.konan.llvm
|
package org.jetbrains.kotlin.backend.konan.llvm
|
||||||
|
|
||||||
import kotlin_native.interop.*
|
import kotlin_.cinterop.*
|
||||||
import llvm.*
|
import llvm.*
|
||||||
import org.jetbrains.kotlin.backend.konan.*
|
import org.jetbrains.kotlin.backend.konan.*
|
||||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||||
@@ -36,10 +36,10 @@ fun emitLLVM(module: IrModuleFragment, runtimeFile: String, outFile: String) {
|
|||||||
println("\n--- Generate bitcode ------------------------------------------------------\n")
|
println("\n--- Generate bitcode ------------------------------------------------------\n")
|
||||||
module.acceptVoid(CodeGeneratorVisitor(context))
|
module.acceptVoid(CodeGeneratorVisitor(context))
|
||||||
memScoped {
|
memScoped {
|
||||||
val errorRef = alloc(Int8Box.ref)
|
val errorRef = allocPointerTo<CInt8Var>()
|
||||||
// TODO: use LLVMDisposeMessage() on errorRef, once possible in interop.
|
// TODO: use LLVMDisposeMessage() on errorRef, once possible in interop.
|
||||||
if (LLVMVerifyModule(
|
if (LLVMVerifyModule(
|
||||||
llvmModule, LLVMVerifierFailureAction.LLVMPrintMessageAction, errorRef) == 1) {
|
llvmModule, LLVMVerifierFailureAction.LLVMPrintMessageAction, errorRef.ptr) == 1) {
|
||||||
LLVMDumpModule(llvmModule)
|
LLVMDumpModule(llvmModule)
|
||||||
throw Error("Invalid module");
|
throw Error("Invalid module");
|
||||||
}
|
}
|
||||||
@@ -532,8 +532,8 @@ internal class CodeGeneratorVisitor(val context: Context) : IrElementVisitorVoid
|
|||||||
val objHeaderPtr = codegen.bitcast(kObjHeaderPtr, thisPtr, codegen.newVar())
|
val objHeaderPtr = codegen.bitcast(kObjHeaderPtr, thisPtr, codegen.newVar())
|
||||||
val typePtr = pointerType(codegen.classType(value.containingDeclaration as ClassDescriptor))
|
val typePtr = pointerType(codegen.classType(value.containingDeclaration as ClassDescriptor))
|
||||||
memScoped {
|
memScoped {
|
||||||
val args = allocNativeArrayOf(LLVMOpaqueValue, kImmOne)
|
val args = allocArrayOf(kImmOne)
|
||||||
val objectPtr = LLVMBuildGEP(codegen.context.llvmBuilder, objHeaderPtr, args[0], 1, codegen.newVar())
|
val objectPtr = LLVMBuildGEP(codegen.context.llvmBuilder, objHeaderPtr, args[0].ptr, 1, codegen.newVar())
|
||||||
val typedObjPtr = codegen.bitcast(typePtr, objectPtr!!, codegen.newVar())
|
val typedObjPtr = codegen.bitcast(typePtr, objectPtr!!, codegen.newVar())
|
||||||
val fieldPtr = LLVMBuildStructGEP(codegen.context.llvmBuilder, typedObjPtr, codegen.indexInClass(value), codegen.newVar())
|
val fieldPtr = LLVMBuildStructGEP(codegen.context.llvmBuilder, typedObjPtr, codegen.indexInClass(value), codegen.newVar())
|
||||||
return fieldPtr
|
return fieldPtr
|
||||||
|
|||||||
+27
-27
@@ -1,6 +1,6 @@
|
|||||||
package org.jetbrains.kotlin.backend.konan.llvm
|
package org.jetbrains.kotlin.backend.konan.llvm
|
||||||
|
|
||||||
import kotlin_native.interop.*
|
import kotlin_.cinterop.*
|
||||||
import llvm.*
|
import llvm.*
|
||||||
import org.jetbrains.kotlin.descriptors.ClassConstructorDescriptor
|
import org.jetbrains.kotlin.descriptors.ClassConstructorDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||||
@@ -11,9 +11,9 @@ import org.jetbrains.kotlin.utils.singletonOrEmptyList
|
|||||||
*/
|
*/
|
||||||
internal interface ConstValue {
|
internal interface ConstValue {
|
||||||
|
|
||||||
fun getLlvmValue(): LLVMOpaqueValue?
|
fun getLlvmValue(): LLVMValueRef?
|
||||||
|
|
||||||
fun getLlvmType(): LLVMOpaqueType {
|
fun getLlvmType(): LLVMTypeRef {
|
||||||
return LLVMTypeOf(getLlvmValue())!!
|
return LLVMTypeOf(getLlvmValue())!!
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -23,45 +23,45 @@ internal interface ConstPointer : ConstValue {
|
|||||||
fun getElementPtr(index: Int): ConstPointer = ConstGetElementPtr(this, index)
|
fun getElementPtr(index: Int): ConstPointer = ConstGetElementPtr(this, index)
|
||||||
}
|
}
|
||||||
|
|
||||||
internal fun constPointer(value: LLVMOpaqueValue?) = object : ConstPointer {
|
internal fun constPointer(value: LLVMValueRef?) = object : ConstPointer {
|
||||||
override fun getLlvmValue() = value
|
override fun getLlvmValue() = value
|
||||||
}
|
}
|
||||||
|
|
||||||
private class ConstGetElementPtr(val pointer: ConstPointer, val index: Int) : ConstPointer {
|
private class ConstGetElementPtr(val pointer: ConstPointer, val index: Int) : ConstPointer {
|
||||||
override fun getLlvmValue(): LLVMOpaqueValue? {
|
override fun getLlvmValue(): LLVMValueRef? {
|
||||||
// TODO: probably it should be computed once when initialized?
|
// TODO: probably it should be computed once when initialized?
|
||||||
// TODO: squash multiple GEPs
|
// TODO: squash multiple GEPs
|
||||||
val indices = intArrayOf(0, index).map { Int32(it).getLlvmValue() }
|
val indices = intArrayOf(0, index).map { Int32(it).getLlvmValue() }
|
||||||
memScoped {
|
memScoped {
|
||||||
val indicesArray = allocNativeArrayOf(LLVMOpaqueValue, indices)
|
val indicesArray = allocArrayOf(indices)
|
||||||
return LLVMConstInBoundsGEP(pointer.getLlvmValue(), indicesArray[0], indices.size)
|
return LLVMConstInBoundsGEP(pointer.getLlvmValue(), indicesArray[0].ptr, indices.size)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal fun ConstPointer.bitcast(toType: LLVMOpaqueType) = constPointer(LLVMConstBitCast(this.getLlvmValue(), toType))
|
internal fun ConstPointer.bitcast(toType: LLVMTypeRef) = constPointer(LLVMConstBitCast(this.getLlvmValue(), toType))
|
||||||
|
|
||||||
internal class ConstArray(val elemType: LLVMOpaqueType?, val elements: List<ConstValue>) : ConstValue {
|
internal class ConstArray(val elemType: LLVMTypeRef?, val elements: List<ConstValue>) : ConstValue {
|
||||||
|
|
||||||
override fun getLlvmValue(): LLVMOpaqueValue? {
|
override fun getLlvmValue(): LLVMValueRef? {
|
||||||
val values = elements.map { it.getLlvmValue() }.toTypedArray()
|
val values = elements.map { it.getLlvmValue() }.toTypedArray()
|
||||||
|
|
||||||
memScoped {
|
memScoped {
|
||||||
val valuesNativeArrayPtr = allocNativeArrayOf(LLVMOpaqueValue, *values)[0]
|
val valuesNativeArrayPtr = allocArrayOf(*values)[0].ptr
|
||||||
|
|
||||||
return LLVMConstArray(elemType, valuesNativeArrayPtr, values.size)
|
return LLVMConstArray(elemType, valuesNativeArrayPtr, values.size)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal open class Struct(val type: LLVMOpaqueType?, val elements: List<ConstValue>) : ConstValue {
|
internal open class Struct(val type: LLVMTypeRef?, val elements: List<ConstValue>) : ConstValue {
|
||||||
|
|
||||||
constructor(type: LLVMOpaqueType?, vararg elements: ConstValue) : this(type, elements.toList())
|
constructor(type: LLVMTypeRef?, vararg elements: ConstValue) : this(type, elements.toList())
|
||||||
|
|
||||||
override fun getLlvmValue(): LLVMOpaqueValue? {
|
override fun getLlvmValue(): LLVMValueRef? {
|
||||||
val values = elements.map { it.getLlvmValue() }.toTypedArray()
|
val values = elements.map { it.getLlvmValue() }.toTypedArray()
|
||||||
memScoped {
|
memScoped {
|
||||||
val valuesNativeArrayPtr = allocNativeArrayOf(LLVMOpaqueValue, *values)[0]
|
val valuesNativeArrayPtr = allocArrayOf(*values)[0].ptr
|
||||||
return LLVMConstNamedStruct(type, valuesNativeArrayPtr, values.size)
|
return LLVMConstNamedStruct(type, valuesNativeArrayPtr, values.size)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -79,43 +79,43 @@ internal class Int64(val value: Long) : ConstValue {
|
|||||||
override fun getLlvmValue() = LLVMConstInt(LLVMInt64Type(), value, 1)
|
override fun getLlvmValue() = LLVMConstInt(LLVMInt64Type(), value, 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
internal class Zero(val type: LLVMOpaqueType?) : ConstValue {
|
internal class Zero(val type: LLVMTypeRef?) : ConstValue {
|
||||||
override fun getLlvmValue() = LLVMConstNull(type)
|
override fun getLlvmValue() = LLVMConstNull(type)
|
||||||
}
|
}
|
||||||
|
|
||||||
internal class NullPointer(val pointeeType: LLVMOpaqueType?): ConstPointer {
|
internal class NullPointer(val pointeeType: LLVMTypeRef?): ConstPointer {
|
||||||
override fun getLlvmValue() = LLVMConstNull(pointerType(pointeeType))
|
override fun getLlvmValue() = LLVMConstNull(pointerType(pointeeType))
|
||||||
}
|
}
|
||||||
|
|
||||||
internal fun constValue(value: LLVMOpaqueValue?) = object : ConstValue {
|
internal fun constValue(value: LLVMValueRef?) = object : ConstValue {
|
||||||
override fun getLlvmValue() = value
|
override fun getLlvmValue() = value
|
||||||
}
|
}
|
||||||
|
|
||||||
internal val int8Type = LLVMInt8Type()
|
internal val int8Type = LLVMInt8Type()
|
||||||
internal val int32Type = LLVMInt32Type()
|
internal val int32Type = LLVMInt32Type()
|
||||||
|
|
||||||
internal fun pointerType(pointeeType: LLVMOpaqueType?) = LLVMPointerType(pointeeType, 0)
|
internal fun pointerType(pointeeType: LLVMTypeRef?) = LLVMPointerType(pointeeType, 0)
|
||||||
|
|
||||||
internal fun structType(vararg types: LLVMOpaqueType?): LLVMOpaqueType = memScoped {
|
internal fun structType(vararg types: LLVMTypeRef?): LLVMTypeRef = memScoped {
|
||||||
LLVMStructType(allocNativeArrayOf(LLVMOpaqueType, *types)[0], types.size, 0)!!
|
LLVMStructType(allocArrayOf(*types)[0].ptr, types.size, 0)!!
|
||||||
}
|
}
|
||||||
|
|
||||||
internal fun getLlvmFunctionType(function: FunctionDescriptor): LLVMOpaqueType? {
|
internal fun getLlvmFunctionType(function: FunctionDescriptor): LLVMTypeRef? {
|
||||||
val returnType = getLLVMType(function.returnType!!)
|
val returnType = getLLVMType(function.returnType!!)
|
||||||
val params = function.dispatchReceiverParameter.singletonOrEmptyList() +
|
val params = function.dispatchReceiverParameter.singletonOrEmptyList() +
|
||||||
function.extensionReceiverParameter.singletonOrEmptyList() +
|
function.extensionReceiverParameter.singletonOrEmptyList() +
|
||||||
function.valueParameters
|
function.valueParameters
|
||||||
|
|
||||||
var extraParam = listOf<LLVMOpaqueType?>()
|
var extraParam = listOf<LLVMTypeRef?>()
|
||||||
if (function is ClassConstructorDescriptor) {
|
if (function is ClassConstructorDescriptor) {
|
||||||
extraParam += pointerType(LLVMInt8Type())
|
extraParam += pointerType(LLVMInt8Type())
|
||||||
}
|
}
|
||||||
val paramTypes:List<LLVMOpaqueType?> = params.map { getLLVMType(it.type) }
|
val paramTypes:List<LLVMTypeRef?> = params.map { getLLVMType(it.type) }
|
||||||
extraParam += paramTypes
|
extraParam += paramTypes
|
||||||
|
|
||||||
if (extraParam.size == 0) return LLVMFunctionType(returnType, null, 0, 0)
|
if (extraParam.size == 0) return LLVMFunctionType(returnType, null, 0, 0)
|
||||||
memScoped {
|
memScoped {
|
||||||
val paramTypesPtr = allocNativeArrayOf(LLVMOpaqueType, *extraParam.toTypedArray())[0] // TODO: dispose
|
val paramTypesPtr = allocArrayOf(extraParam)[0].ptr
|
||||||
return LLVMFunctionType(returnType, paramTypesPtr, extraParam.size, 0)
|
return LLVMFunctionType(returnType, paramTypesPtr, extraParam.size, 0)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -123,10 +123,10 @@ internal fun getLlvmFunctionType(function: FunctionDescriptor): LLVMOpaqueType?
|
|||||||
/**
|
/**
|
||||||
* Reads [size] bytes contained in this array.
|
* Reads [size] bytes contained in this array.
|
||||||
*/
|
*/
|
||||||
internal fun NativeArray<Int8Box>.getBytes(size: Int) =
|
internal fun CArray<CInt8Var>.getBytes(size: Long) =
|
||||||
(0 .. size-1).map { this[it].value }.toByteArray()
|
(0 .. size-1).map { this[it].value }.toByteArray()
|
||||||
|
|
||||||
internal fun getFunctionType(ptrToFunction: LLVMOpaqueValue?): LLVMOpaqueType {
|
internal fun getFunctionType(ptrToFunction: LLVMValueRef?): LLVMTypeRef {
|
||||||
val typeOfPtrToFunction = LLVMTypeOf(ptrToFunction)
|
val typeOfPtrToFunction = LLVMTypeOf(ptrToFunction)
|
||||||
return LLVMGetElementType(typeOfPtrToFunction)!!
|
return LLVMGetElementType(typeOfPtrToFunction)!!
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-6
@@ -1,11 +1,7 @@
|
|||||||
package org.jetbrains.kotlin.backend.konan.llvm
|
package org.jetbrains.kotlin.backend.konan.llvm
|
||||||
|
|
||||||
import kotlin_native.interop.asCString
|
import kotlin_.cinterop.*
|
||||||
import llvm.LLVMPrintModuleToString
|
import llvm.*
|
||||||
import llvm.LLVMPrintValueToString
|
|
||||||
import llvm.LLVMOpaqueValue
|
|
||||||
import org.jetbrains.kotlin.backend.konan.llvm.Context
|
|
||||||
import org.jetbrains.kotlin.backend.konan.llvm.ContextUtils
|
|
||||||
import org.jetbrains.kotlin.ir.IrElement
|
import org.jetbrains.kotlin.ir.IrElement
|
||||||
import org.jetbrains.kotlin.ir.util.DumpIrTreeVisitor
|
import org.jetbrains.kotlin.ir.util.DumpIrTreeVisitor
|
||||||
import java.io.StringWriter
|
import java.io.StringWriter
|
||||||
|
|||||||
+16
-17
@@ -1,7 +1,7 @@
|
|||||||
package org.jetbrains.kotlin.backend.konan.llvm
|
package org.jetbrains.kotlin.backend.konan.llvm
|
||||||
|
|
||||||
|
|
||||||
import kotlin_native.interop.*
|
import kotlin_.cinterop.*
|
||||||
import llvm.*
|
import llvm.*
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrFunction
|
import org.jetbrains.kotlin.ir.declarations.IrFunction
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrModuleFragment
|
import org.jetbrains.kotlin.ir.declarations.IrModuleFragment
|
||||||
@@ -33,21 +33,21 @@ fun readModuleMetadata(file: File): String {
|
|||||||
|
|
||||||
class MetadataReader(file: File) {
|
class MetadataReader(file: File) {
|
||||||
|
|
||||||
lateinit var llvmModule: LLVMOpaqueModule
|
lateinit var llvmModule: LLVMModuleRef
|
||||||
lateinit var llvmContext: LLVMOpaqueContext
|
lateinit var llvmContext: LLVMContextRef
|
||||||
|
|
||||||
init {
|
init {
|
||||||
memScoped {
|
memScoped {
|
||||||
val bufRef = alloc(LLVMOpaqueMemoryBuffer.ref)
|
val bufRef = alloc<LLVMMemoryBufferRefVar>()
|
||||||
val errorRef = alloc(Int8Box.ref)
|
val errorRef = allocPointerTo<CInt8Var>()
|
||||||
val res = LLVMCreateMemoryBufferWithContentsOfFile(file.toString(), bufRef, errorRef)
|
val res = LLVMCreateMemoryBufferWithContentsOfFile(file.toString(), bufRef.ptr, errorRef.ptr)
|
||||||
if (res != 0) {
|
if (res != 0) {
|
||||||
throw Error(errorRef.value?.asCString()?.toString())
|
throw Error(errorRef.value?.asCString()?.toString())
|
||||||
}
|
}
|
||||||
|
|
||||||
llvmContext = LLVMContextCreate()!!
|
llvmContext = LLVMContextCreate()!!
|
||||||
val moduleRef = alloc(LLVMOpaqueModule.ref)
|
val moduleRef = alloc<LLVMModuleRefVar>()
|
||||||
val parseResult = LLVMParseBitcodeInContext2(llvmContext, bufRef.value, moduleRef)
|
val parseResult = LLVMParseBitcodeInContext2(llvmContext, bufRef.value, moduleRef.ptr)
|
||||||
if (parseResult != 0) {
|
if (parseResult != 0) {
|
||||||
throw Error(parseResult.toString())
|
throw Error(parseResult.toString())
|
||||||
}
|
}
|
||||||
@@ -59,8 +59,8 @@ class MetadataReader(file: File) {
|
|||||||
|
|
||||||
fun string(node: LLVMOpaqueValue): String {
|
fun string(node: LLVMOpaqueValue): String {
|
||||||
memScoped {
|
memScoped {
|
||||||
val len = alloc(Int32Box)
|
val len = alloc<CInt32Var>()
|
||||||
val str1 = LLVMGetMDString(node, len)!!
|
val str1 = LLVMGetMDString(node, len.ptr)!!
|
||||||
val str = str1.asCString().toString()
|
val str = str1.asCString().toString()
|
||||||
return str
|
return str
|
||||||
|
|
||||||
@@ -70,9 +70,9 @@ class MetadataReader(file: File) {
|
|||||||
fun namedMetadataNode(name: String, index: Int): LLVMOpaqueValue {
|
fun namedMetadataNode(name: String, index: Int): LLVMOpaqueValue {
|
||||||
memScoped {
|
memScoped {
|
||||||
val nodeCount = LLVMGetNamedMetadataNumOperands(llvmModule, "kmetadata")!!
|
val nodeCount = LLVMGetNamedMetadataNumOperands(llvmModule, "kmetadata")!!
|
||||||
val nodeArray = alloc(array[nodeCount](Ref to LLVMOpaqueValue))
|
val nodeArray = allocArray<LLVMValueRefVar>(nodeCount)
|
||||||
|
|
||||||
LLVMGetNamedMetadataOperands(llvmModule, "kmetadata", nodeArray[0])!!
|
LLVMGetNamedMetadataOperands(llvmModule, "kmetadata", nodeArray[0].ptr)!!
|
||||||
|
|
||||||
return nodeArray[0].value!!
|
return nodeArray[0].value!!
|
||||||
}
|
}
|
||||||
@@ -81,9 +81,9 @@ class MetadataReader(file: File) {
|
|||||||
fun metadataOperand(metadataNode: LLVMOpaqueValue, index: Int): LLVMOpaqueValue {
|
fun metadataOperand(metadataNode: LLVMOpaqueValue, index: Int): LLVMOpaqueValue {
|
||||||
memScoped {
|
memScoped {
|
||||||
val operandCount = LLVMGetMDNodeNumOperands(metadataNode)!!
|
val operandCount = LLVMGetMDNodeNumOperands(metadataNode)!!
|
||||||
val operandArray = alloc(array[operandCount](Ref to LLVMOpaqueValue))
|
val operandArray = allocArray<LLVMValueRefVar>(operandCount)
|
||||||
|
|
||||||
LLVMGetMDNodeOperands(metadataNode, operandArray[0])!!
|
LLVMGetMDNodeOperands(metadataNode, operandArray[0].ptr)!!
|
||||||
|
|
||||||
return operandArray[0].value!!
|
return operandArray[0].value!!
|
||||||
}
|
}
|
||||||
@@ -104,9 +104,8 @@ internal class MetadataGenerator(override val context: Context): ContextUtils {
|
|||||||
|
|
||||||
private fun metadataNode(args: List<LLVMOpaqueValue?>): LLVMOpaqueValue {
|
private fun metadataNode(args: List<LLVMOpaqueValue?>): LLVMOpaqueValue {
|
||||||
memScoped {
|
memScoped {
|
||||||
val references = alloc(array[args.size](Ref to LLVMOpaqueValue))
|
val references = allocArrayOf(args)
|
||||||
args.forEachIndexed { i, llvmOpaqueValue -> references[i].value = args[i]}
|
return LLVMMDNode(references[0].ptr, args.size)!!
|
||||||
return LLVMMDNode(references[0], args.size)!!
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+2
-3
@@ -1,8 +1,7 @@
|
|||||||
package org.jetbrains.kotlin.backend.konan.llvm
|
package org.jetbrains.kotlin.backend.konan.llvm
|
||||||
|
|
||||||
|
|
||||||
import kotlin_native.interop.allocNativeArrayOf
|
import kotlin_.cinterop.*
|
||||||
import kotlin_native.interop.memScoped
|
|
||||||
import llvm.*
|
import llvm.*
|
||||||
import org.jetbrains.kotlin.backend.konan.implementation
|
import org.jetbrains.kotlin.backend.konan.implementation
|
||||||
import org.jetbrains.kotlin.backend.konan.implementedInterfaces
|
import org.jetbrains.kotlin.backend.konan.implementedInterfaces
|
||||||
@@ -66,7 +65,7 @@ internal class RTTIGenerator(override val context: Context) : ContextUtils {
|
|||||||
|
|
||||||
memScoped {
|
memScoped {
|
||||||
val fieldTypesNativeArrayPtr = if (fieldTypes.size > 0) {
|
val fieldTypesNativeArrayPtr = if (fieldTypes.size > 0) {
|
||||||
allocNativeArrayOf(LLVMOpaqueType, *fieldTypes)[0]
|
allocArrayOf(*fieldTypes)[0].ptr
|
||||||
} else {
|
} else {
|
||||||
null
|
null
|
||||||
}
|
}
|
||||||
|
|||||||
+9
-13
@@ -1,32 +1,28 @@
|
|||||||
package org.jetbrains.kotlin.backend.konan.llvm
|
package org.jetbrains.kotlin.backend.konan.llvm
|
||||||
|
|
||||||
import kotlin_native.interop.*
|
import kotlin_.cinterop.*
|
||||||
import llvm.*
|
import llvm.*
|
||||||
|
|
||||||
class Runtime(private val bitcodeFile: String) {
|
class Runtime(private val bitcodeFile: String) {
|
||||||
val llvmModule: LLVMOpaqueModule
|
val llvmModule: LLVMModuleRef
|
||||||
|
|
||||||
init {
|
init {
|
||||||
val arena = Arena()
|
llvmModule = memScoped {
|
||||||
try {
|
|
||||||
|
|
||||||
val bufRef = arena.alloc(LLVMOpaqueMemoryBuffer.ref)
|
val bufRef = allocPointerTo<LLVMOpaqueMemoryBuffer>()
|
||||||
val errorRef = arena.alloc(Int8Box.ref)
|
val errorRef = allocPointerTo<CInt8Var>()
|
||||||
val res = LLVMCreateMemoryBufferWithContentsOfFile(bitcodeFile, bufRef, errorRef)
|
val res = LLVMCreateMemoryBufferWithContentsOfFile(bitcodeFile, bufRef.ptr, errorRef.ptr)
|
||||||
if (res != 0) {
|
if (res != 0) {
|
||||||
throw Error(errorRef.value?.asCString()?.toString())
|
throw Error(errorRef.value?.asCString()?.toString())
|
||||||
}
|
}
|
||||||
|
|
||||||
val moduleRef = arena.alloc(LLVMOpaqueModule.ref)
|
val moduleRef = alloc<LLVMModuleRefVar>()
|
||||||
val parseRes = LLVMParseBitcode2(bufRef.value, moduleRef)
|
val parseRes = LLVMParseBitcode2(bufRef.value, moduleRef.ptr)
|
||||||
if (parseRes != 0) {
|
if (parseRes != 0) {
|
||||||
throw Error(parseRes.toString())
|
throw Error(parseRes.toString())
|
||||||
}
|
}
|
||||||
|
|
||||||
llvmModule = moduleRef.value!!
|
moduleRef.value!!
|
||||||
|
|
||||||
} finally {
|
|
||||||
arena.clear()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+11
@@ -0,0 +1,11 @@
|
|||||||
|
package org.jetbrains.kotlin.backend.konan.llvm
|
||||||
|
|
||||||
|
import kotlin_.cinterop.CPointer
|
||||||
|
import kotlin_.cinterop.CPointerVarWithValueMappedTo
|
||||||
|
|
||||||
|
// TODO: the definitions below are required to perform smooth migration to new interop;
|
||||||
|
// remove after replacing with LLVM*Ref typedefs
|
||||||
|
|
||||||
|
typealias LLVMOpaqueValue = CPointer<llvm.LLVMOpaqueValue>
|
||||||
|
typealias LLVMOpaqueType = CPointer<llvm.LLVMOpaqueType>
|
||||||
|
typealias LLVMOpaqueBasicBlock = CPointer<llvm.LLVMOpaqueBasicBlock>
|
||||||
Reference in New Issue
Block a user