CODEGEN: get_object implementation

This commit is contained in:
Konstantin Anisimov
2016-12-05 14:13:14 +03:00
committed by vvlevchenko
parent efdb896d2c
commit bab2b8bc3f
3 changed files with 40 additions and 1 deletions
@@ -60,11 +60,15 @@ internal class CodeGenerator(override val context: Context) : ContextUtils {
fun icmpLe(arg0: LLVMValueRef, arg1: LLVMValueRef, result: String): LLVMValueRef = LLVMBuildICmp(builder, LLVMIntPredicate.LLVMIntSLE, arg0, arg1, result)!!
fun icmpNe(arg0: LLVMValueRef, arg1: LLVMValueRef, result: String): LLVMValueRef = LLVMBuildICmp(builder, LLVMIntPredicate.LLVMIntNE, arg0, arg1, result)!!
fun ucmpGt(arg0: LLVMValueRef, arg1: LLVMValueRef, result: String): LLVMValueRef = LLVMBuildICmp(builder, LLVMIntPredicate.LLVMIntUGT, arg0, arg1, result)!!
/* floating-point comparisons */
fun fcmpEq(arg0: LLVMValueRef, arg1: LLVMValueRef, result: String): LLVMValueRef = LLVMBuildFCmp(builder, LLVMRealPredicate.LLVMRealOEQ, arg0, arg1, result)!!
fun bitcast(type: LLVMTypeRef?, value: LLVMValueRef, result: String) = LLVMBuildBitCast(builder, value, type, result)!!
fun intToPtr(imm: LLVMValueRef?, DestTy: LLVMTypeRef, Name: String) = LLVMBuildIntToPtr(builder, imm, DestTy, Name)
fun alloca(type: KotlinType, varName: String): LLVMValueRef = alloca( getLLVMType(type), varName)
fun alloca(type: LLVMTypeRef?, varName: String): LLVMValueRef {
appendingTo(prologueBb!!) {
@@ -256,6 +260,8 @@ internal class CodeGenerator(override val context: Context) : ContextUtils {
code()
}
fun llvmFunction(function: FunctionDescriptor): LLVMValueRef = function.llvmFunction
}
@@ -23,6 +23,7 @@ internal class Context(val irModule: IrModuleFragment, val runtime: Runtime, val
private fun importRtFunction(name: String) = importFunction(name, runtime.llvmModule)
val allocInstanceFunction = importRtFunction("AllocInstance")
val initInstanceFunction = importRtFunction("InitInstance")
val allocArrayFunction = importRtFunction("AllocArrayInstance")
val setArrayFunction = importRtFunction("Kotlin_Array_set")
val lookupFieldOffset = importRtFunction("LookupFieldOffset")
@@ -279,7 +279,7 @@ internal class CodeGeneratorVisitor(val context: Context) : IrElementVisitorVoid
if (!skipConstructorBodyGeneration(constructorDeclaration))
constructorDeclaration.acceptChildrenVoid(this)
if (constructorDescriptor.isPrimary && !DescriptorUtils.isCompanionObject(constructorDescriptor.constructedClass)) {
if (constructorDescriptor.isPrimary) {
val irOfCurrentClass = context.moduleIndex.classes[classDescriptor.classId]
irOfCurrentClass!!.acceptChildrenVoid(object : IrElementVisitorVoid {
override fun visitElement(element: IrElement) {
@@ -602,6 +602,7 @@ internal class CodeGeneratorVisitor(val context: Context) : IrElementVisitorVoid
is IrVararg -> return evaluateVararg (tmpVariableName, value)
is IrBreak -> return evaluateBreak ( value)
is IrContinue -> return evaluateContinue ( value)
is IrGetObjectValue -> return evaluateGetObjectValue (tmpVariableName, value)
null -> return null
else -> {
TODO("${ir2string(value)}")
@@ -609,6 +610,37 @@ internal class CodeGeneratorVisitor(val context: Context) : IrElementVisitorVoid
}
}
//-------------------------------------------------------------------------//
private fun evaluateGetObjectValue(tmpVariableName: String, value: IrGetObjectValue): LLVMValueRef? {
val objName = value.descriptor.fqNameSafe.asString()
var objectPtr = LLVMGetNamedGlobal(context.llvmModule, objName)
if (objectPtr == null) {
objectPtr = LLVMAddGlobal(context.llvmModule, codegen.getLLVMType(value.type), objName)
LLVMSetInitializer(objectPtr, codegen.kNullObjHeaderPtr)
}
val bbInit = codegen.basicBlock("label_init")
val bbExit = codegen.basicBlock("label_continue")
val onePtr = codegen.intToPtr(kImmInt64One, codegen.kObjHeaderPtr, codegen.newVar())
val objectVal = codegen.load(objectPtr!!, codegen.newVar())
val condition = codegen.ucmpGt(objectVal, onePtr!!, codegen.newVar())
codegen.condBr(condition, bbExit, bbInit)
codegen.positionAtEnd(bbInit)
val typeInfo = codegen.typeInfoValue(value.descriptor)
val allocHint = Int32(1).llvm
val initFunction = value.descriptor.constructors.first { it.valueParameters.size == 0 }
val ctor = codegen.llvmFunction(initFunction)
val args = listOf(objectPtr, typeInfo, allocHint, ctor)
currentCodeContext.genCall(context.initInstanceFunction, args, codegen.newVar())
codegen.br(bbExit)
codegen.positionAtEnd(bbExit)
return objectVal
}
//-------------------------------------------------------------------------//
private fun evaluateExpressionAndJump(expression: IrExpression, destination: ContinuationBlock) {
val result = evaluateExpression("res", expression)