From 414a481fe36adb55ed0ffb04c6c93d9f6e884e84 Mon Sep 17 00:00:00 2001 From: Konstantin Anisimov Date: Thu, 23 Mar 2017 12:00:25 +0700 Subject: [PATCH] If property initializer is inlined, we do not have proper outer scope to evaluate it --- .../kotlin/backend/konan/llvm/IrToBitcode.kt | 8 +++--- .../backend/konan/lower/FunctionInlining.kt | 25 +++++++++++++------ 2 files changed, 23 insertions(+), 10 deletions(-) diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/IrToBitcode.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/IrToBitcode.kt index 691b1d4ef42..59b685d810c 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/IrToBitcode.kt +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/IrToBitcode.kt @@ -386,7 +386,7 @@ internal class CodeGeneratorVisitor(val context: Context) : IrElementVisitorVoid /** * The scope of variable visibility. */ - private inner class VariableScope : InnerScopeImpl() { + open private inner class VariableScope : InnerScopeImpl() { override fun genDeclareVariable(descriptor: VariableDescriptor, value: LLVMValueRef?): Int { return codegen.vars.createVariable(descriptor to this, value) @@ -1423,8 +1423,10 @@ internal class CodeGeneratorVisitor(val context: Context) : IrElementVisitorVoid val inlinedFunctionScope = InlinedFunctionScope(value) using(inlinedFunctionScope) { - value.statements.forEach { - generateStatement(it) + using(VariableScope()) { + value.statements.forEach { + generateStatement(it) + } } } diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/FunctionInlining.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/FunctionInlining.kt index 83cf44bf5fd..047c89204c0 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/FunctionInlining.kt +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/FunctionInlining.kt @@ -9,6 +9,7 @@ import org.jetbrains.kotlin.ir.IrStatement import org.jetbrains.kotlin.ir.builders.Scope import org.jetbrains.kotlin.ir.declarations.IrFile import org.jetbrains.kotlin.ir.declarations.IrFunction +import org.jetbrains.kotlin.ir.declarations.IrProperty import org.jetbrains.kotlin.ir.declarations.IrVariable import org.jetbrains.kotlin.ir.expressions.* import org.jetbrains.kotlin.ir.expressions.impl.* @@ -25,7 +26,7 @@ internal class FunctionInlining(val context: Context): IrElementTransformerVoid( var currentFile : IrFile? = null var currentFunction : IrFunction? = null - var functionScope : Scope? = null + var currentScope : Scope? = null //-------------------------------------------------------------------------// @@ -44,9 +45,16 @@ internal class FunctionInlining(val context: Context): IrElementTransformerVoid( //-------------------------------------------------------------------------// + override fun visitProperty(declaration: IrProperty): IrStatement { + currentScope = Scope(declaration.descriptor) + return super.visitProperty(declaration) + } + + //-------------------------------------------------------------------------// + override fun visitFunction(declaration: IrFunction): IrStatement { currentFunction = declaration - functionScope = Scope(declaration.descriptor) + currentScope = Scope(declaration.descriptor) return super.visitFunction(declaration) } @@ -78,9 +86,10 @@ internal class FunctionInlining(val context: Context): IrElementTransformerVoid( //---------------------------------------------------------------------// fun needsEvaluation(expression: IrExpression): Boolean { - if (expression is IrGetValue) return false // Parameter is already GetValue - nothing to evaluate. - if (expression is IrConst<*>) return false // Parameter is constant - nothing to evaluate. - if (isLambdaExpression(expression)) return false // Parameter is lambda - will be inlined. + if (expression is IrGetValue) return false // Parameter is already GetValue - nothing to evaluate. + if (expression is IrConst<*>) return false // Parameter is constant - nothing to evaluate. + if (expression is IrCallableReference) return false // Parameter is nothing to evaluate. + if (isLambdaExpression(expression)) return false // Parameter is lambda - will be inlined. return true } @@ -123,7 +132,8 @@ internal class FunctionInlining(val context: Context): IrElementTransformerVoid( return@forEach } - val newVar = functionScope!!.createTemporaryVariable(argument, "inline", false) // Create new variable and init it with the parameter expression. + val varName = currentScope!!.scopeOwner.name.toString() + "_inline" + val newVar = currentScope!!.createTemporaryVariable(argument, varName, false) // Create new variable and init it with the parameter expression. statements.add(0, newVar) // Add initialization of the new variable in statement list. val getVal = IrGetValueImpl(0, 0, newVar.descriptor) // Create new IR element representing access the new variable. @@ -231,7 +241,8 @@ internal class FunctionInlining(val context: Context): IrElementTransformerVoid( fun newVariable(oldVariable: IrVariable): IrVariable { val initializer = oldVariable.initializer!! val isMutable = oldVariable.descriptor.isVar - return functionScope!!.createTemporaryVariable(initializer, "inline", isMutable) // Create new variable and init it with the parameter expression. + val varName = currentScope!!.scopeOwner.name.toString() + "_inline" + return currentScope!!.createTemporaryVariable(initializer, varName, isMutable) // Create new variable and init it with the parameter expression. } //---------------------------------------------------------------------//