[EE-IR] Support Local Functions
This commit introduces support for calling and referencing local functions and objects in evaluate expression on the IR backend. The primary incision is a lowering inserted after Local Declaration Lowering, that uses the intermediate data structures recorded by LDL to rewrite calls to local functions to the appropriate function in the binary, instead of predicting the compilation strategy. The required changes to the rest of the pipeline facilitate piping the required data around. The key to this transformation is that _captures by the local function_ must be introduced as _captures by the fragment function_, such that the evaluator infrastructure can find the appropriate values at run-time. This is necessary due to the strategy of compiling local functions to static functions instead of closures. Additional test coverage of stepping behavior support the corresponding changes in the Evaluator, part of the Kotlin Debugger plug-in.
This commit is contained in:
committed by
Nikita Nazarov
parent
5af9303a16
commit
4f8ef8c315
+16
-5
@@ -11,9 +11,9 @@ import org.jetbrains.kotlin.backend.common.descriptors.synthesizedString
|
||||
import org.jetbrains.kotlin.backend.common.ir.*
|
||||
import org.jetbrains.kotlin.backend.common.lower.inline.isInlineParameter
|
||||
import org.jetbrains.kotlin.backend.common.runOnFilePostfix
|
||||
import org.jetbrains.kotlin.descriptors.Modality
|
||||
import org.jetbrains.kotlin.descriptors.DescriptorVisibilities
|
||||
import org.jetbrains.kotlin.descriptors.DescriptorVisibility
|
||||
import org.jetbrains.kotlin.descriptors.Modality
|
||||
import org.jetbrains.kotlin.ir.*
|
||||
import org.jetbrains.kotlin.ir.builders.declarations.buildConstructor
|
||||
import org.jetbrains.kotlin.ir.builders.declarations.buildFun
|
||||
@@ -71,7 +71,8 @@ class LocalDeclarationsLowering(
|
||||
val localNameSanitizer: (String) -> String = { it },
|
||||
val visibilityPolicy: VisibilityPolicy = VisibilityPolicy.DEFAULT,
|
||||
val suggestUniqueNames: Boolean = true, // When `true` appends a `-#index` suffix to lifted declaration names
|
||||
val forceFieldsForInlineCaptures: Boolean = false // See `LocalClassContext`
|
||||
val forceFieldsForInlineCaptures: Boolean = false, // See `LocalClassContext`
|
||||
private val postLocalDeclarationLoweringCallback: ((IntermediateDatastructures) -> Unit)? = null
|
||||
) :
|
||||
BodyLoweringPass {
|
||||
|
||||
@@ -109,7 +110,7 @@ class LocalDeclarationsLowering(
|
||||
ScopeWithCounter(this)
|
||||
}
|
||||
|
||||
private abstract class LocalContext {
|
||||
abstract class LocalContext {
|
||||
val capturedTypeParameterToTypeParameter: MutableMap<IrTypeParameter, IrTypeParameter> = mutableMapOf()
|
||||
|
||||
// By the time typeRemapper is used, the map will be already filled
|
||||
@@ -121,7 +122,7 @@ class LocalDeclarationsLowering(
|
||||
abstract fun irGet(startOffset: Int, endOffset: Int, valueDeclaration: IrValueDeclaration): IrExpression?
|
||||
}
|
||||
|
||||
private abstract class LocalContextWithClosureAsParameters : LocalContext() {
|
||||
abstract class LocalContextWithClosureAsParameters : LocalContext() {
|
||||
|
||||
abstract val declaration: IrFunction
|
||||
abstract val transformedDeclaration: IrFunction
|
||||
@@ -135,7 +136,7 @@ class LocalDeclarationsLowering(
|
||||
}
|
||||
}
|
||||
|
||||
private class LocalFunctionContext(
|
||||
class LocalFunctionContext(
|
||||
override val declaration: IrSimpleFunction,
|
||||
val index: Int,
|
||||
val ownerForLoweredDeclaration: IrDeclarationContainer
|
||||
@@ -246,6 +247,10 @@ class LocalDeclarationsLowering(
|
||||
rewriteDeclarations()
|
||||
|
||||
insertLoweredDeclarationForLocalFunctions()
|
||||
|
||||
postLocalDeclarationLoweringCallback?.invoke(
|
||||
IntermediateDatastructures(localFunctions, newParameterToOld, newParameterToCaptured)
|
||||
)
|
||||
}
|
||||
|
||||
private fun insertLoweredDeclarationForLocalFunctions() {
|
||||
@@ -967,6 +972,12 @@ class LocalDeclarationsLowering(
|
||||
}, Data(null, false))
|
||||
}
|
||||
}
|
||||
|
||||
data class IntermediateDatastructures(
|
||||
val localFunctions: Map<IrFunction, LocalFunctionContext>,
|
||||
val newParameterToOld: Map<IrValueParameter, IrValueParameter>,
|
||||
val newParameterToCaptured: Map<IrValueParameter, IrValueSymbol>
|
||||
)
|
||||
}
|
||||
|
||||
// Local inner classes capture anything through outer
|
||||
|
||||
Reference in New Issue
Block a user