CODEGEN: Support for "break" and "continue" implemented

This commit is contained in:
Konstantin Anisimov
2016-12-01 17:46:32 +03:00
committed by KonstantinAnisimov
parent 03e94c6877
commit bafa7e7c3c
@@ -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() {
codegen.br(loopCheck)
}
}
//-------------------------------------------------------------------------//
override fun visitWhileLoop(loop: IrWhileLoop) {
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) val condition = evaluateExpression(codegen.newVar(), loop.condition)
codegen.condBr(condition, loopBody, loopExit) codegen.condBr(condition, loopBody, loopScope.loopExit)
codegen.positionAtEnd(loopBody) codegen.positionAtEnd(loopBody)
evaluateExpression(codegen.newVar(), loop.body) evaluateExpression(codegen.newVar(), loop.body)
codegen.br(loopEnter) codegen.br(loopScope.loopCheck)
codegen.positionAtEnd(loopExit) codegen.positionAtEnd(loopScope.loopExit)
}
} }
//-------------------------------------------------------------------------// //-------------------------------------------------------------------------//
override fun visitDoWhileLoop(loop: IrDoWhileLoop) { override fun visitDoWhileLoop(loop: IrDoWhileLoop) {
using(LoopScope(loop)) {
val loopScope = currentCodeContext as LoopScope
val loopBody = codegen.basicBlock() val loopBody = codegen.basicBlock()
val loopCheck = codegen.basicBlock()
val loopExit = codegen.basicBlock()
codegen.br(loopBody) codegen.br(loopBody)
codegen.positionAtEnd(loopBody) codegen.positionAtEnd(loopBody)
evaluateExpression(codegen.newVar(), loop.body) evaluateExpression(codegen.newVar(), loop.body)
codegen.br(loopCheck) codegen.br(loopScope.loopCheck)
codegen.positionAtEnd(loopCheck) codegen.positionAtEnd(loopScope.loopCheck)
val condition = evaluateExpression(codegen.newVar(), loop.condition) val condition = evaluateExpression(codegen.newVar(), loop.condition)
codegen.condBr(condition, loopBody, loopExit) codegen.condBr(condition, loopBody, loopScope.loopExit)
codegen.positionAtEnd(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) {