[codegen] switch scopes for local variable initializers according to their locations provided by inliner.
This commit is contained in:
+46
-2
@@ -9,6 +9,7 @@ import kotlinx.cinterop.*
|
|||||||
import llvm.*
|
import llvm.*
|
||||||
import org.jetbrains.kotlin.backend.common.descriptors.allParameters
|
import org.jetbrains.kotlin.backend.common.descriptors.allParameters
|
||||||
import org.jetbrains.kotlin.backend.common.ir.ir2string
|
import org.jetbrains.kotlin.backend.common.ir.ir2string
|
||||||
|
import org.jetbrains.kotlin.backend.common.lower.inline.InlinerExpressionLocationHint
|
||||||
import org.jetbrains.kotlin.backend.konan.*
|
import org.jetbrains.kotlin.backend.konan.*
|
||||||
import org.jetbrains.kotlin.backend.konan.descriptors.*
|
import org.jetbrains.kotlin.backend.konan.descriptors.*
|
||||||
import org.jetbrains.kotlin.backend.konan.ir.*
|
import org.jetbrains.kotlin.backend.konan.ir.*
|
||||||
@@ -22,6 +23,7 @@ import org.jetbrains.kotlin.ir.IrStatement
|
|||||||
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
|
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
|
||||||
import org.jetbrains.kotlin.ir.declarations.*
|
import org.jetbrains.kotlin.ir.declarations.*
|
||||||
import org.jetbrains.kotlin.ir.expressions.*
|
import org.jetbrains.kotlin.ir.expressions.*
|
||||||
|
import org.jetbrains.kotlin.ir.symbols.IrFunctionSymbol
|
||||||
import org.jetbrains.kotlin.ir.types.*
|
import org.jetbrains.kotlin.ir.types.*
|
||||||
import org.jetbrains.kotlin.ir.util.*
|
import org.jetbrains.kotlin.ir.util.*
|
||||||
import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid
|
import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid
|
||||||
@@ -277,6 +279,40 @@ internal class CodeGeneratorVisitor(val context: Context, val lifetimes: Map<IrE
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun <T:IrElement> findCodeContext(entry: T, context:CodeContext?, predicate: CodeContext.(T) -> Boolean): CodeContext? {
|
||||||
|
if(context == null)
|
||||||
|
//TODO: replace `return null` with `throw NoContextFound()` ASAP.
|
||||||
|
return null
|
||||||
|
if (context.predicate(entry))
|
||||||
|
return context
|
||||||
|
return findCodeContext(entry, (context as? InnerScope)?.outerContext, predicate)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private inline fun <R> switchSymbolizationContextTo(symbol: IrFunctionSymbol, block: () -> R): R? {
|
||||||
|
val functionContext = findCodeContext(symbol.owner, currentCodeContext) {
|
||||||
|
val declaration = (this as? FunctionScope)?.declaration
|
||||||
|
val returnableBlock = (this as? ReturnableBlockScope)?.returnableBlock
|
||||||
|
val inlinedFunction = returnableBlock?.inlineFunctionSymbol?.owner
|
||||||
|
declaration == it || inlinedFunction == it
|
||||||
|
} ?: return null
|
||||||
|
|
||||||
|
/**
|
||||||
|
* We can't switch context safely, only for symbolzation needs: location, scope detection.
|
||||||
|
*/
|
||||||
|
using(object: InnerScopeImpl() {
|
||||||
|
override fun location(line: Int, column: Int): LocationInfo? {
|
||||||
|
return functionContext.location(line, column)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun scope(): DIScopeOpaqueRef? {
|
||||||
|
return functionContext.scope()
|
||||||
|
}
|
||||||
|
|
||||||
|
}) {
|
||||||
|
return block()
|
||||||
|
}
|
||||||
|
}
|
||||||
private fun appendCAdapters() {
|
private fun appendCAdapters() {
|
||||||
context.cAdapterGenerator.generateBindings(codegen)
|
context.cAdapterGenerator.generateBindings(codegen)
|
||||||
}
|
}
|
||||||
@@ -1198,7 +1234,15 @@ internal class CodeGeneratorVisitor(val context: Context, val lifetimes: Map<IrE
|
|||||||
|
|
||||||
private fun generateVariable(variable: IrVariable) {
|
private fun generateVariable(variable: IrVariable) {
|
||||||
context.log{"generateVariable : ${ir2string(variable)}"}
|
context.log{"generateVariable : ${ir2string(variable)}"}
|
||||||
val value = variable.initializer?.let { evaluateExpression(it) }
|
val value = variable.initializer?.let {
|
||||||
|
val callSiteOrigin = (it as? IrBlock)?.origin as? InlinerExpressionLocationHint
|
||||||
|
val inlineAtFunctionSymbol = callSiteOrigin?.inlineAtSymbol as? IrFunctionSymbol
|
||||||
|
inlineAtFunctionSymbol?.run {
|
||||||
|
switchSymbolizationContextTo(inlineAtFunctionSymbol) {
|
||||||
|
evaluateExpression(it)
|
||||||
|
}
|
||||||
|
} ?: evaluateExpression(it)
|
||||||
|
}
|
||||||
currentCodeContext.genDeclareVariable(
|
currentCodeContext.genDeclareVariable(
|
||||||
variable, value, debugInfoIfNeeded(
|
variable, value, debugInfoIfNeeded(
|
||||||
(currentCodeContext.functionScope() as FunctionScope).declaration, variable))
|
(currentCodeContext.functionScope() as FunctionScope).declaration, variable))
|
||||||
@@ -2383,7 +2427,7 @@ internal class CodeGeneratorVisitor(val context: Context, val lifetimes: Map<IrE
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class NoContextFound : Throwable()
|
||||||
|
|
||||||
internal class LocationInfo(val scope: DIScopeOpaqueRef,
|
internal class LocationInfo(val scope: DIScopeOpaqueRef,
|
||||||
val line: Int,
|
val line: Int,
|
||||||
|
|||||||
Reference in New Issue
Block a user