CODEGEN: get_object implementation
This commit is contained in:
committed by
vvlevchenko
parent
efdb896d2c
commit
bab2b8bc3f
+6
@@ -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 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 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 */
|
/* floating-point comparisons */
|
||||||
fun fcmpEq(arg0: LLVMValueRef, arg1: LLVMValueRef, result: String): LLVMValueRef = LLVMBuildFCmp(builder, LLVMRealPredicate.LLVMRealOEQ, arg0, arg1, result)!!
|
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 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: KotlinType, varName: String): LLVMValueRef = alloca( getLLVMType(type), varName)
|
||||||
fun alloca(type: LLVMTypeRef?, varName: String): LLVMValueRef {
|
fun alloca(type: LLVMTypeRef?, varName: String): LLVMValueRef {
|
||||||
appendingTo(prologueBb!!) {
|
appendingTo(prologueBb!!) {
|
||||||
@@ -256,6 +260,8 @@ internal class CodeGenerator(override val context: Context) : ContextUtils {
|
|||||||
code()
|
code()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun llvmFunction(function: FunctionDescriptor): LLVMValueRef = function.llvmFunction
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+1
@@ -23,6 +23,7 @@ internal class Context(val irModule: IrModuleFragment, val runtime: Runtime, val
|
|||||||
private fun importRtFunction(name: String) = importFunction(name, runtime.llvmModule)
|
private fun importRtFunction(name: String) = importFunction(name, runtime.llvmModule)
|
||||||
|
|
||||||
val allocInstanceFunction = importRtFunction("AllocInstance")
|
val allocInstanceFunction = importRtFunction("AllocInstance")
|
||||||
|
val initInstanceFunction = importRtFunction("InitInstance")
|
||||||
val allocArrayFunction = importRtFunction("AllocArrayInstance")
|
val allocArrayFunction = importRtFunction("AllocArrayInstance")
|
||||||
val setArrayFunction = importRtFunction("Kotlin_Array_set")
|
val setArrayFunction = importRtFunction("Kotlin_Array_set")
|
||||||
val lookupFieldOffset = importRtFunction("LookupFieldOffset")
|
val lookupFieldOffset = importRtFunction("LookupFieldOffset")
|
||||||
|
|||||||
+33
-1
@@ -279,7 +279,7 @@ internal class CodeGeneratorVisitor(val context: Context) : IrElementVisitorVoid
|
|||||||
if (!skipConstructorBodyGeneration(constructorDeclaration))
|
if (!skipConstructorBodyGeneration(constructorDeclaration))
|
||||||
constructorDeclaration.acceptChildrenVoid(this)
|
constructorDeclaration.acceptChildrenVoid(this)
|
||||||
|
|
||||||
if (constructorDescriptor.isPrimary && !DescriptorUtils.isCompanionObject(constructorDescriptor.constructedClass)) {
|
if (constructorDescriptor.isPrimary) {
|
||||||
val irOfCurrentClass = context.moduleIndex.classes[classDescriptor.classId]
|
val irOfCurrentClass = context.moduleIndex.classes[classDescriptor.classId]
|
||||||
irOfCurrentClass!!.acceptChildrenVoid(object : IrElementVisitorVoid {
|
irOfCurrentClass!!.acceptChildrenVoid(object : IrElementVisitorVoid {
|
||||||
override fun visitElement(element: IrElement) {
|
override fun visitElement(element: IrElement) {
|
||||||
@@ -602,6 +602,7 @@ internal class CodeGeneratorVisitor(val context: Context) : IrElementVisitorVoid
|
|||||||
is IrVararg -> return evaluateVararg (tmpVariableName, value)
|
is IrVararg -> return evaluateVararg (tmpVariableName, value)
|
||||||
is IrBreak -> return evaluateBreak ( value)
|
is IrBreak -> return evaluateBreak ( value)
|
||||||
is IrContinue -> return evaluateContinue ( value)
|
is IrContinue -> return evaluateContinue ( value)
|
||||||
|
is IrGetObjectValue -> return evaluateGetObjectValue (tmpVariableName, value)
|
||||||
null -> return null
|
null -> return null
|
||||||
else -> {
|
else -> {
|
||||||
TODO("${ir2string(value)}")
|
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) {
|
private fun evaluateExpressionAndJump(expression: IrExpression, destination: ContinuationBlock) {
|
||||||
val result = evaluateExpression("res", expression)
|
val result = evaluateExpression("res", expression)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user