Codegen: init all slots at the beginning
This is needed for coroutines: when resuming suspend functions all visible locals must be initialized.
This commit is contained in:
+13
-4
@@ -70,10 +70,11 @@ internal class CodeGenerator(override val context: Context) : ContextUtils {
|
|||||||
this.returnType = returnType
|
this.returnType = returnType
|
||||||
this.constructedClass = null
|
this.constructedClass = null
|
||||||
prologueBb = LLVMAppendBasicBlock(function, "prologue")
|
prologueBb = LLVMAppendBasicBlock(function, "prologue")
|
||||||
|
localsInitBb = LLVMAppendBasicBlock(function, "locals_init")
|
||||||
entryBb = LLVMAppendBasicBlock(function, "entry")
|
entryBb = LLVMAppendBasicBlock(function, "entry")
|
||||||
epilogueBb = LLVMAppendBasicBlock(function, "epilogue")
|
epilogueBb = LLVMAppendBasicBlock(function, "epilogue")
|
||||||
cleanupLandingpad = LLVMAppendBasicBlock(function, "cleanup_landingpad")!!
|
cleanupLandingpad = LLVMAppendBasicBlock(function, "cleanup_landingpad")!!
|
||||||
positionAtEnd(entryBb!!)
|
positionAtEnd(localsInitBb!!)
|
||||||
locationInfo?.let {
|
locationInfo?.let {
|
||||||
debugLocation(it)
|
debugLocation(it)
|
||||||
}
|
}
|
||||||
@@ -84,6 +85,7 @@ internal class CodeGenerator(override val context: Context) : ContextUtils {
|
|||||||
// Is removed by DCE trivially, if not needed.
|
// Is removed by DCE trivially, if not needed.
|
||||||
arenaSlot = intToPtr(
|
arenaSlot = intToPtr(
|
||||||
or(ptrToInt(slotsPhi, intPtrType), immOneIntPtrType), kObjHeaderPtrPtr)
|
or(ptrToInt(slotsPhi, intPtrType), immOneIntPtrType), kObjHeaderPtrPtr)
|
||||||
|
positionAtEnd(entryBb!!)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun epilogue(locationInfo: LocationInfo? = null) {
|
fun epilogue(locationInfo: LocationInfo? = null) {
|
||||||
@@ -106,6 +108,10 @@ internal class CodeGenerator(override val context: Context) : ContextUtils {
|
|||||||
Int1(0).llvm))
|
Int1(0).llvm))
|
||||||
}
|
}
|
||||||
addPhiIncoming(slotsPhi!!, prologueBb!! to slots)
|
addPhiIncoming(slotsPhi!!, prologueBb!! to slots)
|
||||||
|
br(localsInitBb!!)
|
||||||
|
}
|
||||||
|
|
||||||
|
appendingTo(localsInitBb!!) {
|
||||||
br(entryBb!!)
|
br(entryBb!!)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -156,6 +162,7 @@ internal class CodeGenerator(override val context: Context) : ContextUtils {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private var prologueBb: LLVMBasicBlockRef? = null
|
private var prologueBb: LLVMBasicBlockRef? = null
|
||||||
|
private var localsInitBb: LLVMBasicBlockRef? = null
|
||||||
private var entryBb: LLVMBasicBlockRef? = null
|
private var entryBb: LLVMBasicBlockRef? = null
|
||||||
private var epilogueBb: LLVMBasicBlockRef? = null
|
private var epilogueBb: LLVMBasicBlockRef? = null
|
||||||
private var cleanupLandingpad: LLVMBasicBlockRef? = null
|
private var cleanupLandingpad: LLVMBasicBlockRef? = null
|
||||||
@@ -191,7 +198,9 @@ internal class CodeGenerator(override val context: Context) : ContextUtils {
|
|||||||
|
|
||||||
fun alloca(type: LLVMTypeRef?, name: String = ""): LLVMValueRef {
|
fun alloca(type: LLVMTypeRef?, name: String = ""): LLVMValueRef {
|
||||||
if (isObjectType(type!!)) {
|
if (isObjectType(type!!)) {
|
||||||
return gep(slotsPhi!!, Int32(slotCount++).llvm)
|
appendingTo(localsInitBb!!) {
|
||||||
|
return gep(slotsPhi!!, Int32(slotCount++).llvm, name)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
appendingTo(prologueBb!!) {
|
appendingTo(prologueBb!!) {
|
||||||
return LLVMBuildAlloca(builder, type, name)!!
|
return LLVMBuildAlloca(builder, type, name)!!
|
||||||
@@ -241,8 +250,8 @@ internal class CodeGenerator(override val context: Context) : ContextUtils {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun gep(base: LLVMValueRef, index: LLVMValueRef): LLVMValueRef {
|
fun gep(base: LLVMValueRef, index: LLVMValueRef, name: String = ""): LLVMValueRef {
|
||||||
return LLVMBuildGEP(builder, base, cValuesOf(index), 1, "")!!
|
return LLVMBuildGEP(builder, base, cValuesOf(index), 1, name)!!
|
||||||
}
|
}
|
||||||
|
|
||||||
fun updateReturnRef(value: LLVMValueRef, address: LLVMValueRef) {
|
fun updateReturnRef(value: LLVMValueRef, address: LLVMValueRef) {
|
||||||
|
|||||||
Reference in New Issue
Block a user