Fixed bug: finally blocks are not always inside IrFunction

For instance: package level field initializers.
This commit is contained in:
Igor Chevdar
2017-05-24 17:08:37 +03:00
parent 48f5962645
commit 7eee76f0f5
2 changed files with 194 additions and 198 deletions
@@ -82,7 +82,7 @@ internal class KonanLower(val context: Context) {
TailrecLowering(context).runOnFilePostfix(irFile) TailrecLowering(context).runOnFilePostfix(irFile)
} }
phaser.phase(KonanPhase.LOWER_FINALLY) { phaser.phase(KonanPhase.LOWER_FINALLY) {
FinallyBlocksLowering(context).runOnFilePostfix(irFile) FinallyBlocksLowering(context).lower(irFile)
} }
phaser.phase(KonanPhase.LOWER_DEFAULT_PARAMETER_EXTENT) { phaser.phase(KonanPhase.LOWER_DEFAULT_PARAMETER_EXTENT) {
DefaultArgumentStubGenerator(context).runOnFilePostfix(irFile) DefaultArgumentStubGenerator(context).runOnFilePostfix(irFile)
@@ -1,6 +1,5 @@
package org.jetbrains.kotlin.backend.konan.lower package org.jetbrains.kotlin.backend.konan.lower
import org.jetbrains.kotlin.backend.common.FunctionLoweringPass
import org.jetbrains.kotlin.backend.common.lower.* import org.jetbrains.kotlin.backend.common.lower.*
import org.jetbrains.kotlin.backend.common.* import org.jetbrains.kotlin.backend.common.*
import org.jetbrains.kotlin.backend.konan.Context import org.jetbrains.kotlin.backend.konan.Context
@@ -12,22 +11,23 @@ import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.annotations.Annotations import org.jetbrains.kotlin.descriptors.annotations.Annotations
import org.jetbrains.kotlin.descriptors.impl.SimpleFunctionDescriptorImpl import org.jetbrains.kotlin.descriptors.impl.SimpleFunctionDescriptorImpl
import org.jetbrains.kotlin.ir.IrElement import org.jetbrains.kotlin.ir.IrElement
import org.jetbrains.kotlin.ir.IrStatement
import org.jetbrains.kotlin.ir.builders.* import org.jetbrains.kotlin.ir.builders.*
import org.jetbrains.kotlin.ir.declarations.IrDeclarationOrigin import org.jetbrains.kotlin.ir.declarations.IrDeclarationOrigin
import org.jetbrains.kotlin.ir.declarations.IrFile
import org.jetbrains.kotlin.ir.declarations.IrFunction import org.jetbrains.kotlin.ir.declarations.IrFunction
import org.jetbrains.kotlin.ir.declarations.impl.IrVariableImpl import org.jetbrains.kotlin.ir.declarations.impl.IrVariableImpl
import org.jetbrains.kotlin.ir.descriptors.IrTemporaryVariableDescriptorImpl import org.jetbrains.kotlin.ir.descriptors.IrTemporaryVariableDescriptorImpl
import org.jetbrains.kotlin.ir.expressions.* import org.jetbrains.kotlin.ir.expressions.*
import org.jetbrains.kotlin.ir.expressions.impl.* import org.jetbrains.kotlin.ir.expressions.impl.*
import org.jetbrains.kotlin.ir.symbols.IrFunctionSymbol import org.jetbrains.kotlin.ir.symbols.IrFunctionSymbol
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.types.KotlinType import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.types.typeUtil.isNothing import org.jetbrains.kotlin.types.typeUtil.isNothing
import org.jetbrains.kotlin.types.typeUtil.isUnit import org.jetbrains.kotlin.types.typeUtil.isUnit
internal class FinallyBlocksLowering(val context: Context): FunctionLoweringPass { internal class FinallyBlocksLowering(val context: Context): FileLoweringPass, IrElementTransformerVoidWithContext() {
private interface HighLevelJump { private interface HighLevelJump {
fun toIr(context: Context, startOffset: Int, endOffset: Int, value: IrExpression): IrExpression fun toIr(context: Context, startOffset: Int, endOffset: Int, value: IrExpression): IrExpression
@@ -79,10 +79,15 @@ internal class FinallyBlocksLowering(val context: Context): FunctionLoweringPass
} }
} }
override fun lower(irFunction: IrFunction) { override fun lower(irFile: IrFile) {
val functionDescriptor = irFunction.descriptor irFile.transformChildrenVoid(this)
using(ReturnableScope(functionDescriptor)) { }
irFunction.transformChildrenVoid(object : IrElementTransformerVoid() {
override fun visitFunctionNew(declaration: IrFunction): IrStatement {
using(ReturnableScope(declaration.descriptor)) {
return super.visitFunctionNew(declaration)
}
}
override fun visitContainerExpression(expression: IrContainerExpression): IrExpression { override fun visitContainerExpression(expression: IrContainerExpression): IrExpression {
if (expression !is IrReturnableBlockImpl) if (expression !is IrReturnableBlockImpl)
@@ -102,7 +107,7 @@ internal class FinallyBlocksLowering(val context: Context): FunctionLoweringPass
override fun visitBreak(jump: IrBreak): IrExpression { override fun visitBreak(jump: IrBreak): IrExpression {
val startOffset = jump.startOffset val startOffset = jump.startOffset
val endOffset = jump.endOffset val endOffset = jump.endOffset
val irBuilder = context.createIrBuilder(irFunction.symbol, startOffset, endOffset) val irBuilder = context.createIrBuilder(currentScope!!.scope.scopeOwnerSymbol, startOffset, endOffset)
return performHighLevelJump( return performHighLevelJump(
targetScopePredicate = { it is LoopScope && it.loop == jump.loop }, targetScopePredicate = { it is LoopScope && it.loop == jump.loop },
jump = Break(jump.loop), jump = Break(jump.loop),
@@ -115,7 +120,7 @@ internal class FinallyBlocksLowering(val context: Context): FunctionLoweringPass
override fun visitContinue(jump: IrContinue): IrExpression { override fun visitContinue(jump: IrContinue): IrExpression {
val startOffset = jump.startOffset val startOffset = jump.startOffset
val endOffset = jump.endOffset val endOffset = jump.endOffset
val irBuilder = context.createIrBuilder(irFunction.symbol, startOffset, endOffset) val irBuilder = context.createIrBuilder(currentScope!!.scope.scopeOwnerSymbol, startOffset, endOffset)
return performHighLevelJump( return performHighLevelJump(
targetScopePredicate = { it is LoopScope && it.loop == jump.loop }, targetScopePredicate = { it is LoopScope && it.loop == jump.loop },
jump = Continue(jump.loop), jump = Continue(jump.loop),
@@ -187,12 +192,11 @@ internal class FinallyBlocksLowering(val context: Context): FunctionLoweringPass
override fun visitTry(aTry: IrTry): IrExpression { override fun visitTry(aTry: IrTry): IrExpression {
val finallyExpression = aTry.finallyExpression val finallyExpression = aTry.finallyExpression
if (finallyExpression == null) ?: return super.visitTry(aTry)
return super.visitTry(aTry)
val startOffset = aTry.startOffset val startOffset = aTry.startOffset
val endOffset = aTry.endOffset val endOffset = aTry.endOffset
val irBuilder = context.createIrBuilder(irFunction.symbol, startOffset, endOffset) val irBuilder = context.createIrBuilder(currentScope!!.scope.scopeOwnerSymbol, startOffset, endOffset)
val transformer = this val transformer = this
irBuilder.run { irBuilder.run {
val transformedTry = IrTryImpl( val transformedTry = IrTryImpl(
@@ -202,7 +206,7 @@ internal class FinallyBlocksLowering(val context: Context): FunctionLoweringPass
) )
val transformedFinallyExpression = finallyExpression.transform(transformer, null) val transformedFinallyExpression = finallyExpression.transform(transformer, null)
val parameter = IrTemporaryVariableDescriptorImpl( val parameter = IrTemporaryVariableDescriptorImpl(
containingDeclaration = irFunction.descriptor, containingDeclaration = currentScope!!.scope.scopeOwner,
name = Name.identifier("t"), name = Name.identifier("t"),
outType = context.builtIns.throwable.defaultType outType = context.builtIns.throwable.defaultType
) )
@@ -258,24 +262,16 @@ internal class FinallyBlocksLowering(val context: Context): FunctionLoweringPass
} }
} }
private fun getFakeFunctionDescriptor(name: String, returnType: KotlinType): FunctionDescriptor { private fun getFakeFunctionDescriptor(name: String, returnType: KotlinType) =
return SimpleFunctionDescriptorImpl.create( SimpleFunctionDescriptorImpl.create(currentScope!!.scope.scopeOwner, Annotations.EMPTY, name.synthesizedName,
functionDescriptor, CallableMemberDescriptor.Kind.SYNTHESIZED, SourceElement.NO_SOURCE).apply {
Annotations.EMPTY,
name.synthesizedName,
CallableMemberDescriptor.Kind.SYNTHESIZED,
SourceElement.NO_SOURCE).apply {
initialize(null, null, emptyList(), emptyList(), returnType, Modality.ABSTRACT, Visibilities.PRIVATE) initialize(null, null, emptyList(), emptyList(), returnType, Modality.ABSTRACT, Visibilities.PRIVATE)
} }
}
private fun getIrReturnableBlockSymbol(name: String, returnType: KotlinType): IrReturnableBlockSymbol = private fun getIrReturnableBlockSymbol(name: String, returnType: KotlinType): IrReturnableBlockSymbol =
IrReturnableBlockSymbolImpl(getFakeFunctionDescriptor(name, returnType)) IrReturnableBlockSymbolImpl(getFakeFunctionDescriptor(name, returnType))
private inline fun <reified T : IrElement> T.copy() = this.deepCopyWithVariables() private inline fun <reified T : IrElement> T.copy() = this.deepCopyWithVariables()
})
}
}
fun IrBuilderWithScope.irReturn(target: IrFunctionSymbol, value: IrExpression) = fun IrBuilderWithScope.irReturn(target: IrFunctionSymbol, value: IrExpression) =
IrReturnImpl(startOffset, endOffset, target, value) IrReturnImpl(startOffset, endOffset, target, value)