CODEGEN: Support for "break" and "continue" implemented
This commit is contained in:
committed by
KonstantinAnisimov
parent
03e94c6877
commit
bafa7e7c3c
+64
-28
@@ -16,6 +16,7 @@ import org.jetbrains.kotlin.ir.descriptors.IrBuiltinOperatorDescriptorBase
|
|||||||
import org.jetbrains.kotlin.ir.descriptors.IrTemporaryVariableDescriptor
|
import org.jetbrains.kotlin.ir.descriptors.IrTemporaryVariableDescriptor
|
||||||
import org.jetbrains.kotlin.ir.expressions.*
|
import org.jetbrains.kotlin.ir.expressions.*
|
||||||
import org.jetbrains.kotlin.ir.expressions.impl.IrBinaryPrimitiveImpl
|
import org.jetbrains.kotlin.ir.expressions.impl.IrBinaryPrimitiveImpl
|
||||||
|
import org.jetbrains.kotlin.ir.expressions.impl.IrBreakImpl
|
||||||
import org.jetbrains.kotlin.ir.expressions.impl.IrSetterCallImpl
|
import org.jetbrains.kotlin.ir.expressions.impl.IrSetterCallImpl
|
||||||
import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid
|
import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid
|
||||||
import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid
|
import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid
|
||||||
@@ -102,9 +103,9 @@ internal class CodeGeneratorVisitor(val context: Context) : IrElementVisitorVoid
|
|||||||
|
|
||||||
fun genReturn(target: CallableDescriptor, value: LLVMValueRef?)
|
fun genReturn(target: CallableDescriptor, value: LLVMValueRef?)
|
||||||
|
|
||||||
fun genBreak(loop: IrLoop)
|
fun genBreak()
|
||||||
|
|
||||||
fun genContinue(loop: IrLoop)
|
fun genContinue()
|
||||||
|
|
||||||
fun genCall(function: LLVMValueRef, args: List<LLVMValueRef>, result: String?): LLVMValueRef
|
fun genCall(function: LLVMValueRef, args: List<LLVMValueRef>, result: String?): LLVMValueRef
|
||||||
|
|
||||||
@@ -140,9 +141,9 @@ internal class CodeGeneratorVisitor(val context: Context) : IrElementVisitorVoid
|
|||||||
|
|
||||||
override fun genReturn(target: CallableDescriptor, value: LLVMValueRef?) = unsupported(target)
|
override fun genReturn(target: CallableDescriptor, value: LLVMValueRef?) = unsupported(target)
|
||||||
|
|
||||||
override fun genBreak(loop: IrLoop) = unsupported(loop)
|
override fun genBreak() = unsupported()
|
||||||
|
|
||||||
override fun genContinue(loop: IrLoop) = unsupported(loop)
|
override fun genContinue() = unsupported()
|
||||||
|
|
||||||
override fun genCall(function: LLVMValueRef, args: List<LLVMValueRef>, result: String?) = unsupported(function)
|
override fun genCall(function: LLVMValueRef, args: List<LLVMValueRef>, result: String?) = unsupported(function)
|
||||||
|
|
||||||
@@ -211,42 +212,75 @@ internal class CodeGeneratorVisitor(val context: Context) : IrElementVisitorVoid
|
|||||||
|
|
||||||
//-------------------------------------------------------------------------//
|
//-------------------------------------------------------------------------//
|
||||||
|
|
||||||
override fun visitWhileLoop(loop: IrWhileLoop) {
|
private inner class LoopScope(val loop: IrLoop) : InnerScopeImpl() {
|
||||||
val loopEnter = codegen.basicBlock()
|
val loopCheck = codegen.basicBlock()
|
||||||
val loopBody = codegen.basicBlock()
|
|
||||||
val loopExit = codegen.basicBlock()
|
val loopExit = codegen.basicBlock()
|
||||||
|
|
||||||
codegen.br(loopEnter)
|
override fun genBreak() {
|
||||||
|
codegen.br(loopExit)
|
||||||
|
}
|
||||||
|
|
||||||
codegen.positionAtEnd(loopEnter)
|
override fun genContinue() {
|
||||||
val condition = evaluateExpression(codegen.newVar(), loop.condition)
|
codegen.br(loopCheck)
|
||||||
codegen.condBr(condition, loopBody, loopExit)
|
}
|
||||||
|
}
|
||||||
|
|
||||||
codegen.positionAtEnd(loopBody)
|
//-------------------------------------------------------------------------//
|
||||||
evaluateExpression(codegen.newVar(), loop.body)
|
|
||||||
|
|
||||||
codegen.br(loopEnter)
|
override fun visitWhileLoop(loop: IrWhileLoop) {
|
||||||
codegen.positionAtEnd(loopExit)
|
|
||||||
|
using(LoopScope(loop)) {
|
||||||
|
val loopScope = currentCodeContext as LoopScope
|
||||||
|
val loopBody = codegen.basicBlock()
|
||||||
|
|
||||||
|
codegen.br(loopScope.loopCheck)
|
||||||
|
|
||||||
|
codegen.positionAtEnd(loopScope.loopCheck)
|
||||||
|
val condition = evaluateExpression(codegen.newVar(), loop.condition)
|
||||||
|
codegen.condBr(condition, loopBody, loopScope.loopExit)
|
||||||
|
|
||||||
|
codegen.positionAtEnd(loopBody)
|
||||||
|
evaluateExpression(codegen.newVar(), loop.body)
|
||||||
|
|
||||||
|
codegen.br(loopScope.loopCheck)
|
||||||
|
codegen.positionAtEnd(loopScope.loopExit)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//-------------------------------------------------------------------------//
|
//-------------------------------------------------------------------------//
|
||||||
|
|
||||||
override fun visitDoWhileLoop(loop: IrDoWhileLoop) {
|
override fun visitDoWhileLoop(loop: IrDoWhileLoop) {
|
||||||
val loopBody = codegen.basicBlock()
|
|
||||||
val loopCheck = codegen.basicBlock()
|
|
||||||
val loopExit = codegen.basicBlock()
|
|
||||||
|
|
||||||
codegen.br(loopBody)
|
using(LoopScope(loop)) {
|
||||||
|
val loopScope = currentCodeContext as LoopScope
|
||||||
|
val loopBody = codegen.basicBlock()
|
||||||
|
|
||||||
codegen.positionAtEnd(loopBody)
|
codegen.br(loopBody)
|
||||||
evaluateExpression(codegen.newVar(), loop.body)
|
|
||||||
codegen.br(loopCheck)
|
|
||||||
|
|
||||||
codegen.positionAtEnd(loopCheck)
|
codegen.positionAtEnd(loopBody)
|
||||||
val condition = evaluateExpression(codegen.newVar(), loop.condition)
|
evaluateExpression(codegen.newVar(), loop.body)
|
||||||
codegen.condBr(condition, loopBody, loopExit)
|
codegen.br(loopScope.loopCheck)
|
||||||
|
|
||||||
codegen.positionAtEnd(loopExit)
|
codegen.positionAtEnd(loopScope.loopCheck)
|
||||||
|
val condition = evaluateExpression(codegen.newVar(), loop.condition)
|
||||||
|
codegen.condBr(condition, loopBody, loopScope.loopExit)
|
||||||
|
|
||||||
|
codegen.positionAtEnd(loopScope.loopExit)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------------//
|
||||||
|
|
||||||
|
fun evaluateBreak(): LLVMValueRef? {
|
||||||
|
(currentCodeContext as LoopScope).genBreak()
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------------//
|
||||||
|
|
||||||
|
fun evaluateContinue(): LLVMValueRef? {
|
||||||
|
(currentCodeContext as LoopScope).genContinue()
|
||||||
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
//-------------------------------------------------------------------------//
|
//-------------------------------------------------------------------------//
|
||||||
@@ -597,6 +631,8 @@ internal class CodeGeneratorVisitor(val context: Context) : IrElementVisitorVoid
|
|||||||
is IrBlockBody -> return evaluateBlock (tmpVariableName, value as IrStatementContainer)
|
is IrBlockBody -> return evaluateBlock (tmpVariableName, value as IrStatementContainer)
|
||||||
is IrWhileLoop -> return evaluateWhileLoop ( value)
|
is IrWhileLoop -> return evaluateWhileLoop ( value)
|
||||||
is IrVararg -> return evaluateVararg (tmpVariableName, value)
|
is IrVararg -> return evaluateVararg (tmpVariableName, value)
|
||||||
|
is IrBreak -> return evaluateBreak ( )
|
||||||
|
is IrContinue -> return evaluateContinue ( )
|
||||||
null -> return null
|
null -> return null
|
||||||
else -> {
|
else -> {
|
||||||
TODO("${ir2string(value)}")
|
TODO("${ir2string(value)}")
|
||||||
@@ -878,8 +914,8 @@ internal class CodeGeneratorVisitor(val context: Context) : IrElementVisitorVoid
|
|||||||
jump(block, value)
|
jump(block, value)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun genBreak(loop: IrLoop) = TODO()
|
override fun genBreak() = TODO()
|
||||||
override fun genContinue(loop: IrLoop) = TODO()
|
override fun genContinue() = TODO()
|
||||||
|
|
||||||
// When an exception is caught, finalize the scope and rethrow the exception.
|
// When an exception is caught, finalize the scope and rethrow the exception.
|
||||||
override fun genHandler(exception: LLVMValueRef) {
|
override fun genHandler(exception: LLVMValueRef) {
|
||||||
|
|||||||
Reference in New Issue
Block a user