Fix for finally block for inline functions
For local return from inline function to outer scope just call super version of genReturn.
This commit is contained in:
+13
-34
@@ -152,16 +152,6 @@ internal interface CodeContext {
|
|||||||
*/
|
*/
|
||||||
fun genGetValue(descriptor: ValueDescriptor): LLVMValueRef
|
fun genGetValue(descriptor: ValueDescriptor): LLVMValueRef
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the exit block for the context owned by specified descriptor.
|
|
||||||
*/
|
|
||||||
fun getExit(descriptor: CallableDescriptor): LLVMBasicBlockRef
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the result value for the context owned by specified descriptor.
|
|
||||||
*/
|
|
||||||
fun getResult(descriptor: CallableDescriptor): LLVMValueRef
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns owning function scope.
|
* Returns owning function scope.
|
||||||
*
|
*
|
||||||
@@ -208,10 +198,6 @@ internal class CodeGeneratorVisitor(val context: Context) : IrElementVisitorVoid
|
|||||||
|
|
||||||
override fun genGetValue(descriptor: ValueDescriptor) = unsupported(descriptor)
|
override fun genGetValue(descriptor: ValueDescriptor) = unsupported(descriptor)
|
||||||
|
|
||||||
override fun getExit(descriptor: CallableDescriptor): LLVMBasicBlockRef = unsupported(descriptor)
|
|
||||||
|
|
||||||
override fun getResult(descriptor: CallableDescriptor): LLVMValueRef = unsupported(descriptor)
|
|
||||||
|
|
||||||
override fun functionScope(): CodeContext = unsupported()
|
override fun functionScope(): CodeContext = unsupported()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1395,19 +1381,15 @@ internal class CodeGeneratorVisitor(val context: Context) : IrElementVisitorVoid
|
|||||||
var bbExit : LLVMBasicBlockRef? = null
|
var bbExit : LLVMBasicBlockRef? = null
|
||||||
var resultPhi : LLVMValueRef? = null
|
var resultPhi : LLVMValueRef? = null
|
||||||
|
|
||||||
override fun getExit(descriptor: CallableDescriptor): LLVMBasicBlockRef {
|
private fun getExit(): LLVMBasicBlockRef {
|
||||||
if (descriptor != inlineBody.descriptor)
|
|
||||||
return super.getExit(descriptor)
|
|
||||||
if (bbExit == null) bbExit = codegen.basicBlock("inline_body_exit")
|
if (bbExit == null) bbExit = codegen.basicBlock("inline_body_exit")
|
||||||
return bbExit!!
|
return bbExit!!
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getResult(descriptor: CallableDescriptor): LLVMValueRef {
|
private fun getResult(): LLVMValueRef {
|
||||||
if (descriptor != inlineBody.descriptor)
|
|
||||||
return super.getResult(descriptor)
|
|
||||||
if (resultPhi == null) {
|
if (resultPhi == null) {
|
||||||
val bbCurrent = codegen.currentBlock
|
val bbCurrent = codegen.currentBlock
|
||||||
codegen.positionAtEnd(getExit(descriptor))
|
codegen.positionAtEnd(getExit())
|
||||||
resultPhi = codegen.phi(codegen.getLLVMType(inlineBody.type))
|
resultPhi = codegen.phi(codegen.getLLVMType(inlineBody.type))
|
||||||
codegen.positionAtEnd(bbCurrent)
|
codegen.positionAtEnd(bbCurrent)
|
||||||
}
|
}
|
||||||
@@ -1415,15 +1397,15 @@ internal class CodeGeneratorVisitor(val context: Context) : IrElementVisitorVoid
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun genReturn(target: CallableDescriptor, value: LLVMValueRef?) {
|
override fun genReturn(target: CallableDescriptor, value: LLVMValueRef?) {
|
||||||
if (target == codegen.functionDescriptor) { // It is "non local return".
|
if (target != inlineBody.descriptor) { // It is not our "local return".
|
||||||
super.genReturn(target, value) // Generate real "return".
|
super.genReturn(target, value)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
// It is local return.
|
// It is local return from current function.
|
||||||
codegen.br(getExit(target)!!) // Generate branch on exit block.
|
codegen.br(getExit()) // Generate branch on exit block.
|
||||||
|
|
||||||
if (!KotlinBuiltIns.isUnit(inlineBody.type)) { // If function returns more then "unit"
|
if (!KotlinBuiltIns.isUnit(inlineBody.type)) { // If function returns more then "unit"
|
||||||
codegen.assignPhis(getResult(target) to value!!) // Assign return value to result PHI node.
|
codegen.assignPhis(getResult() to value!!) // Assign return value to result PHI node.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1442,22 +1424,19 @@ internal class CodeGeneratorVisitor(val context: Context) : IrElementVisitorVoid
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (inlinedFunctionScope.bbExit != null) {
|
val bbExit = inlinedFunctionScope.bbExit
|
||||||
|
if (bbExit != null) {
|
||||||
if (!codegen.isAfterTerminator()) { // TODO should we solve this problem once and for all
|
if (!codegen.isAfterTerminator()) { // TODO should we solve this problem once and for all
|
||||||
if (inlinedFunctionScope.resultPhi != null) {
|
if (inlinedFunctionScope.resultPhi != null) {
|
||||||
codegen.unreachable()
|
codegen.unreachable()
|
||||||
} else {
|
} else {
|
||||||
codegen.br(inlinedFunctionScope.bbExit!!)
|
codegen.br(bbExit)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
codegen.positionAtEnd(inlinedFunctionScope.bbExit!!)
|
codegen.positionAtEnd(bbExit)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (inlinedFunctionScope.resultPhi != null) {
|
return inlinedFunctionScope.resultPhi ?: codegen.theUnitInstanceRef.llvm
|
||||||
return inlinedFunctionScope.resultPhi!!
|
|
||||||
} else {
|
|
||||||
return codegen.theUnitInstanceRef.llvm
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//-------------------------------------------------------------------------//
|
//-------------------------------------------------------------------------//
|
||||||
|
|||||||
Reference in New Issue
Block a user