backend: properly import functions from runtime

This commit is contained in:
Svyatoslav Scherbina
2016-10-27 17:57:00 +03:00
committed by Nikolay Igotti
parent b6e314f274
commit 1ec7d806fa
4 changed files with 22 additions and 14 deletions
@@ -1,8 +1,6 @@
package org.jetbrains.kotlin.backend.native.llvm
import llvm.LLVMCreateBuilder
import llvm.LLVMDisposeBuilder
import llvm.LLVMOpaqueModule
import llvm.*
import org.jetbrains.kotlin.backend.native.ModuleIndex
import org.jetbrains.kotlin.ir.declarations.IrModuleFragment
@@ -11,6 +9,21 @@ internal class Context(val irModule: IrModuleFragment, val runtime: Runtime, val
val llvmBuilder = LLVMCreateBuilder()
private fun importFunction(name: String, otherModule: LLVMOpaqueModule): LLVMOpaqueValue {
if (LLVMGetNamedFunction(llvmModule, name) != null) {
throw IllegalArgumentException("function $name already exists")
}
val externalFunction = LLVMGetNamedFunction(otherModule, name)!!
val functionType = getFunctionType(externalFunction)
return LLVMAddFunction(llvmModule, name, functionType)!!
}
private fun importRtFunction(name: String) = importFunction(name, runtime.llvmModule)
val allocInstanceFunction = importRtFunction("AllocInstance")
fun dispose() {
LLVMDisposeBuilder(llvmBuilder)
}
@@ -22,7 +22,6 @@ fun emitLLVM(module: IrModuleFragment, runtimeFile: String, outFile: String) {
val context = Context(module, runtime, llvmModule) // TODO: dispose
module.acceptVoid(RTTIGeneratorVisitor(context))
context.runtime.importRuntime(llvmModule)
module.acceptVoid(CodeGeneratorVisitor(context))
memScoped {
val errorRef = alloc(Int8Box.ref)
@@ -180,7 +179,7 @@ internal class CodeGeneratorVisitor(val context: Context) : IrElementVisitorVoid
private fun evaluateConstructorCall(variableName: String, callee: IrCall, args: MutableList<LLVMOpaqueValue?>): LLVMOpaqueValue? {
memScoped {
val params = allocNativeArrayOf(LLVMOpaqueValue, generator.typeInfoValue((callee.descriptor as ClassConstructorDescriptor).containingDeclaration), Int32(1).getLlvmValue())
val thisValue = LLVMBuildCall(context.llvmBuilder, context.runtime.allocInstanceFunction, params[0], 2, variableName)
val thisValue = LLVMBuildCall(context.llvmBuilder, context.allocInstanceFunction, params[0], 2, variableName)
val constructorParams: MutableList<LLVMOpaqueValue?> = mutableListOf()
@@ -97,4 +97,9 @@ internal fun NativeArray<Int8Box>.asCompileTimeValue(size: Int): ConstArray {
return ConstArray(int8Type, (0 .. size-1).map {
Int8(this[it].value)
})
}
internal fun getFunctionType(ptrToFunction: LLVMOpaqueValue?): LLVMOpaqueType {
val typeOfPtrToFunction = LLVMTypeOf(ptrToFunction)
return LLVMGetElementType(typeOfPtrToFunction)!!
}
@@ -34,15 +34,6 @@ class Runtime(private val bitcodeFile: String) {
val fieldTableRecordType = LLVMGetTypeByName(llvmModule, "struct.FieldTableRecord")
val methodTableRecordType = LLVMGetTypeByName(llvmModule, "struct.MethodTableRecord")
val globalhHashType = LLVMGetTypeByName(llvmModule, "struct.GlobalHash")
val allocInstanceFunction = LLVMGetNamedFunction(llvmModule, "AllocInstance")
fun importRuntime(module: LLVMOpaqueModule) {
memScoped {
val params = allocNativeArrayOf(LLVMOpaqueType, pointerType(typeInfoType), LLVMInt32Type())
val functionAllocInstanceType = LLVMFunctionType(pointerType(LLVMInt8Type()),params[0], 2, 0)
LLVMAddFunction(module, "AllocInstance", functionAllocInstanceType)
}
}
val target = LLVMGetTarget(llvmModule)!!.asCString().toString()