CODEGEN: support for labeled break-continue implemented

This commit is contained in:
Konstantin Anisimov
2016-12-02 15:56:27 +03:00
committed by KonstantinAnisimov
parent 9afdfc316b
commit b193ade131
@@ -103,9 +103,9 @@ internal class CodeGeneratorVisitor(val context: Context) : IrElementVisitorVoid
fun genReturn(target: CallableDescriptor, value: LLVMValueRef?) fun genReturn(target: CallableDescriptor, value: LLVMValueRef?)
fun genBreak() fun genBreak(destination: IrBreak)
fun genContinue() fun genContinue(destination: IrContinue)
fun genCall(function: LLVMValueRef, args: List<LLVMValueRef>, result: String?): LLVMValueRef fun genCall(function: LLVMValueRef, args: List<LLVMValueRef>, result: String?): LLVMValueRef
@@ -141,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() = unsupported() override fun genBreak(destination: IrBreak) = unsupported()
override fun genContinue() = unsupported() override fun genContinue(destination: IrContinue) = 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)
@@ -216,70 +216,44 @@ internal class CodeGeneratorVisitor(val context: Context) : IrElementVisitorVoid
val loopCheck = codegen.basicBlock() val loopCheck = codegen.basicBlock()
val loopExit = codegen.basicBlock() val loopExit = codegen.basicBlock()
override fun genBreak() { override fun genBreak(destination: IrBreak) {
codegen.br(loopExit) if (destination.label == loop.label)
codegen.br(loopExit)
else
super.genBreak(destination)
} }
override fun genContinue() { override fun genContinue(destination: IrContinue) {
codegen.br(loopCheck) if (destination.label == loop.label)
codegen.br(loopCheck)
else
super.genContinue(destination)
} }
} }
//-------------------------------------------------------------------------// //-------------------------------------------------------------------------//
override fun visitWhileLoop(loop: IrWhileLoop) { override fun visitWhileLoop(loop: IrWhileLoop) {
evaluateWhileLoop(loop)
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) {
evaluateDoWhileLoop(loop)
using(LoopScope(loop)) {
val loopScope = currentCodeContext as LoopScope
val loopBody = codegen.basicBlock()
codegen.br(loopBody)
codegen.positionAtEnd(loopBody)
evaluateExpression(codegen.newVar(), loop.body)
codegen.br(loopScope.loopCheck)
codegen.positionAtEnd(loopScope.loopCheck)
val condition = evaluateExpression(codegen.newVar(), loop.condition)
codegen.condBr(condition, loopBody, loopScope.loopExit)
codegen.positionAtEnd(loopScope.loopExit)
}
} }
//-------------------------------------------------------------------------// //-------------------------------------------------------------------------//
fun evaluateBreak(): LLVMValueRef? { fun evaluateBreak(destination: IrBreak): LLVMValueRef? {
(currentCodeContext as LoopScope).genBreak() currentCodeContext.genBreak(destination)
return null return null
} }
//-------------------------------------------------------------------------// //-------------------------------------------------------------------------//
fun evaluateContinue(): LLVMValueRef? { fun evaluateContinue(destination: IrContinue): LLVMValueRef? {
(currentCodeContext as LoopScope).genContinue() currentCodeContext.genContinue(destination)
return null return null
} }
@@ -630,9 +604,10 @@ internal class CodeGeneratorVisitor(val context: Context) : IrElementVisitorVoid
is IrStringConcatenation -> return evaluateStringConcatenation(tmpVariableName, value) is IrStringConcatenation -> return evaluateStringConcatenation(tmpVariableName, value)
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 IrDoWhileLoop -> return evaluateDoWhileLoop ( value)
is IrVararg -> return evaluateVararg (tmpVariableName, value) is IrVararg -> return evaluateVararg (tmpVariableName, value)
is IrBreak -> return evaluateBreak ( ) is IrBreak -> return evaluateBreak ( value)
is IrContinue -> return evaluateContinue ( ) is IrContinue -> return evaluateContinue ( value)
null -> return null null -> return null
else -> { else -> {
TODO("${ir2string(value)}") TODO("${ir2string(value)}")
@@ -914,9 +889,6 @@ internal class CodeGeneratorVisitor(val context: Context) : IrElementVisitorVoid
jump(block, value) jump(block, value)
} }
override fun genBreak() = 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) {
genFinalize() genFinalize()
@@ -1019,9 +991,45 @@ internal class CodeGeneratorVisitor(val context: Context) : IrElementVisitorVoid
return null return null
} }
//-------------------------------------------------------------------------//
private fun evaluateWhileLoop(loop: IrWhileLoop): LLVMValueRef? { private fun evaluateWhileLoop(loop: IrWhileLoop): LLVMValueRef? {
visitWhileLoop(loop) val loopScope = LoopScope(loop)
// TODO: incorrect! using(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)
}
return null
}
//-------------------------------------------------------------------------//
private fun evaluateDoWhileLoop(loop: IrDoWhileLoop): LLVMValueRef? {
val loopScope = LoopScope(loop)
using(loopScope) {
val loopBody = codegen.basicBlock()
codegen.br(loopBody)
codegen.positionAtEnd(loopBody)
evaluateExpression(codegen.newVar(), loop.body)
codegen.br(loopScope.loopCheck)
codegen.positionAtEnd(loopScope.loopCheck)
val condition = evaluateExpression(codegen.newVar(), loop.condition)
codegen.condBr(condition, loopBody, loopScope.loopExit)
codegen.positionAtEnd(loopScope.loopExit)
}
return null return null
} }