[EE-IR] Support mutations by evaluator fragments
- box captured variables using `Ref`s, the same mechanism that's used for shared variables in closures.
This commit is contained in:
committed by
Alexander Udalov
parent
3ccbd25856
commit
be1c0bb9c1
+3
-2
@@ -10,6 +10,7 @@ import org.jetbrains.kotlin.ir.declarations.IrVariable
|
||||
import org.jetbrains.kotlin.ir.expressions.IrExpression
|
||||
import org.jetbrains.kotlin.ir.expressions.IrGetValue
|
||||
import org.jetbrains.kotlin.ir.expressions.IrSetValue
|
||||
import org.jetbrains.kotlin.ir.symbols.IrValueSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.IrVariableSymbol
|
||||
|
||||
interface SharedVariablesManager {
|
||||
@@ -17,7 +18,7 @@ interface SharedVariablesManager {
|
||||
|
||||
fun defineSharedValue(originalDeclaration: IrVariable, sharedVariableDeclaration: IrVariable): IrStatement
|
||||
|
||||
fun getSharedValue(sharedVariableSymbol: IrVariableSymbol, originalGet: IrGetValue): IrExpression
|
||||
fun getSharedValue(sharedVariableSymbol: IrValueSymbol, originalGet: IrGetValue): IrExpression
|
||||
|
||||
fun setSharedValue(sharedVariableSymbol: IrVariableSymbol, originalSet: IrSetValue): IrExpression
|
||||
fun setSharedValue(sharedVariableSymbol: IrValueSymbol, originalSet: IrSetValue): IrExpression
|
||||
}
|
||||
+3
-2
@@ -16,6 +16,7 @@ import org.jetbrains.kotlin.ir.expressions.impl.IrCallImpl
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.IrConstImpl
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.IrGetValueImpl
|
||||
import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.IrValueSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.IrVariableSymbol
|
||||
|
||||
class JsSharedVariablesManager(context: JsIrBackendContext) : SharedVariablesManager {
|
||||
@@ -59,7 +60,7 @@ class JsSharedVariablesManager(context: JsIrBackendContext) : SharedVariablesMan
|
||||
|
||||
override fun defineSharedValue(originalDeclaration: IrVariable, sharedVariableDeclaration: IrVariable) = sharedVariableDeclaration
|
||||
|
||||
override fun getSharedValue(sharedVariableSymbol: IrVariableSymbol, originalGet: IrGetValue): IrExpression {
|
||||
override fun getSharedValue(sharedVariableSymbol: IrValueSymbol, originalGet: IrGetValue): IrExpression {
|
||||
|
||||
return IrCallImpl(
|
||||
originalGet.startOffset,
|
||||
@@ -83,7 +84,7 @@ class JsSharedVariablesManager(context: JsIrBackendContext) : SharedVariablesMan
|
||||
}
|
||||
}
|
||||
|
||||
override fun setSharedValue(sharedVariableSymbol: IrVariableSymbol, originalSet: IrSetValue): IrExpression {
|
||||
override fun setSharedValue(sharedVariableSymbol: IrValueSymbol, originalSet: IrSetValue): IrExpression {
|
||||
return IrCallImpl(
|
||||
originalSet.startOffset,
|
||||
originalSet.endOffset,
|
||||
|
||||
+2
-5
@@ -8,10 +8,7 @@ package org.jetbrains.kotlin.backend.jvm
|
||||
import org.jetbrains.kotlin.analyzer.hasJdkCapability
|
||||
import org.jetbrains.kotlin.backend.common.extensions.IrGenerationExtension
|
||||
import org.jetbrains.kotlin.backend.common.extensions.IrPluginContextImpl
|
||||
import org.jetbrains.kotlin.backend.common.phaser.NamedCompilerPhase
|
||||
import org.jetbrains.kotlin.backend.common.phaser.PhaseConfig
|
||||
import org.jetbrains.kotlin.backend.common.phaser.invokeToplevel
|
||||
import org.jetbrains.kotlin.backend.common.phaser.then
|
||||
import org.jetbrains.kotlin.backend.common.phaser.*
|
||||
import org.jetbrains.kotlin.backend.jvm.ir.getKtFile
|
||||
import org.jetbrains.kotlin.backend.jvm.serialization.JvmIdSignatureDescriptor
|
||||
import org.jetbrains.kotlin.codegen.CodegenFactory
|
||||
@@ -50,7 +47,7 @@ open class JvmIrCodegenFactory(
|
||||
private val externalMangler: JvmDescriptorMangler? = null,
|
||||
private val externalSymbolTable: SymbolTable? = null,
|
||||
private val jvmGeneratorExtensions: JvmGeneratorExtensionsImpl = JvmGeneratorExtensionsImpl(configuration),
|
||||
private val prefixPhases: NamedCompilerPhase<JvmBackendContext, IrModuleFragment>? = null,
|
||||
private val prefixPhases: CompilerPhase<JvmBackendContext, IrModuleFragment, IrModuleFragment>? = null,
|
||||
private val evaluatorFragmentInfoForPsi2Ir: EvaluatorFragmentInfo? = null,
|
||||
) : CodegenFactory {
|
||||
data class JvmIrBackendInput(
|
||||
|
||||
+119
@@ -0,0 +1,119 @@
|
||||
/*
|
||||
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.backend.jvm.lower
|
||||
|
||||
import org.jetbrains.kotlin.backend.common.FileLoweringPass
|
||||
import org.jetbrains.kotlin.backend.common.IrElementTransformerVoidWithContext
|
||||
import org.jetbrains.kotlin.backend.common.ir.copyTo
|
||||
import org.jetbrains.kotlin.backend.common.phaser.makeIrModulePhase
|
||||
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
|
||||
import org.jetbrains.kotlin.ir.IrStatement
|
||||
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.expressions.IrExpression
|
||||
import org.jetbrains.kotlin.ir.expressions.IrGetValue
|
||||
import org.jetbrains.kotlin.ir.expressions.IrSetValue
|
||||
import org.jetbrains.kotlin.ir.symbols.IrValueParameterSymbol
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
|
||||
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
|
||||
|
||||
// Used from the IntelliJ IDEA Kotlin Debugger Plug-In
|
||||
@Suppress("unused")
|
||||
val fragmentSharedVariablesLowering = makeIrModulePhase(
|
||||
::FragmentSharedVariablesLowering,
|
||||
name = "FragmentSharedVariablesLowering",
|
||||
description = "Promotes captured variables that are modified by the fragment to shared variables"
|
||||
)
|
||||
|
||||
// This lowering is a preprocessor for IR in order to support the compilation
|
||||
// scheme used by the "Evaluate Expression..." mechanism of the IntelliJ plug-in
|
||||
// for Kotlin debugging.
|
||||
//
|
||||
// Fragments are compiled as the body of an enclosing function that close the free
|
||||
// variables of the fragment as parameters. The values of these are then extracted
|
||||
// from the stack at the current breakpoint, and the fragment code is invoked with
|
||||
// these values to evaluate the expression.
|
||||
//
|
||||
// If the parameter is a shared variable, e.g. `IntRef` (the same mechanism used to
|
||||
// implement captures of lambdas) the value extracted from the stack is
|
||||
// automatically boxed in a `Ref` before being passed to the fragment.
|
||||
//
|
||||
// Upon return, all `Ref`s are written back into the stack, thus allowing fragments
|
||||
// to modify the state of the program being debugged.
|
||||
//
|
||||
// This lowering promotes these parameters to `Ref`s, as deemed appropriate by
|
||||
// psi2ir's Fragment generation.
|
||||
//
|
||||
// The reason for this "phasing" is that the JVM specific infrastructure (e.g.
|
||||
// symbols for `Ref`s) have not been loaded when psi2ir runs, as psi2ir is designed
|
||||
// to be backend agnostic. So, we "tag" the appropriate parameters with a new
|
||||
// JvmIrDeclarationOrigin that we can then detect in this lowering.
|
||||
//
|
||||
// See `FragmentDeclarationGenerator.kt:declareParameter` for the front half
|
||||
// of this logic.
|
||||
class FragmentSharedVariablesLowering(
|
||||
val context: JvmBackendContext
|
||||
) : IrElementTransformerVoidWithContext(), FileLoweringPass {
|
||||
|
||||
companion object {
|
||||
// Echo of GENERATED_FUNCTION_NAME in the JVM Debugger plug-in.
|
||||
// TODO: Find a good common dependency of JVM Debugger and IR Compiler and deduplicate this
|
||||
const val GENERATED_FUNCTION_NAME = "generated_for_debugger_fun"
|
||||
}
|
||||
|
||||
override fun lower(irFile: IrFile) {
|
||||
irFile.transformChildrenVoid(this)
|
||||
}
|
||||
|
||||
override fun visitFunctionNew(declaration: IrFunction): IrStatement {
|
||||
if (declaration.name.asString() != GENERATED_FUNCTION_NAME) {
|
||||
return super.visitFunctionNew(declaration)
|
||||
}
|
||||
|
||||
val promotedParameters = promoteParametersForCapturesToRefs(declaration)
|
||||
replaceUseOfPromotedParametersWithRefs(declaration, promotedParameters)
|
||||
return declaration
|
||||
}
|
||||
|
||||
private fun promoteParametersForCapturesToRefs(declaration: IrFunction): Map<IrValueParameterSymbol, IrValueParameterSymbol> {
|
||||
val promotedParameters = mutableMapOf<IrValueParameterSymbol, IrValueParameterSymbol>()
|
||||
declaration.valueParameters = declaration.valueParameters.map {
|
||||
if (it.origin == IrDeclarationOrigin.SHARED_VARIABLE_IN_EVALUATOR_FRAGMENT) {
|
||||
val newParameter =
|
||||
it.copyTo(
|
||||
declaration,
|
||||
type = context.sharedVariablesManager.getIrType(it.type),
|
||||
origin = IrDeclarationOrigin.DEFINED
|
||||
)
|
||||
promotedParameters[it.symbol] = newParameter.symbol
|
||||
newParameter
|
||||
} else {
|
||||
it
|
||||
}
|
||||
}
|
||||
return promotedParameters
|
||||
}
|
||||
|
||||
private fun replaceUseOfPromotedParametersWithRefs(
|
||||
declaration: IrFunction,
|
||||
promotedParameters: Map<IrValueParameterSymbol, IrValueParameterSymbol>
|
||||
) {
|
||||
declaration.body!!.transformChildrenVoid(object : IrElementTransformerVoid() {
|
||||
override fun visitGetValue(expression: IrGetValue): IrExpression {
|
||||
expression.transformChildrenVoid(this)
|
||||
val newDeclaration = promotedParameters[expression.symbol] ?: return expression
|
||||
return context.sharedVariablesManager.getSharedValue(newDeclaration, expression)
|
||||
}
|
||||
|
||||
override fun visitSetValue(expression: IrSetValue): IrExpression {
|
||||
expression.transformChildrenVoid(this)
|
||||
val newDeclaration = promotedParameters[expression.symbol] ?: return expression
|
||||
return context.sharedVariablesManager.setSharedValue(newDeclaration, expression)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
+12
-5
@@ -19,7 +19,7 @@ import org.jetbrains.kotlin.ir.expressions.IrExpression
|
||||
import org.jetbrains.kotlin.ir.expressions.IrGetValue
|
||||
import org.jetbrains.kotlin.ir.expressions.IrSetValue
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.*
|
||||
import org.jetbrains.kotlin.ir.symbols.IrVariableSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.IrValueSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.impl.IrVariableSymbolImpl
|
||||
import org.jetbrains.kotlin.ir.types.*
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
@@ -39,7 +39,7 @@ class JvmSharedVariablesManager(
|
||||
name = Name.identifier("Ref")
|
||||
}
|
||||
|
||||
private class RefProvider(val refClass: IrClass, elementType: IrType) {
|
||||
class RefProvider(val refClass: IrClass, elementType: IrType) {
|
||||
val refConstructor = refClass.addConstructor {
|
||||
origin = IrDeclarationOrigin.IR_BUILTINS_STUB
|
||||
}
|
||||
@@ -75,7 +75,7 @@ class JvmSharedVariablesManager(
|
||||
RefProvider(refClass, refClass.typeParameters[0].defaultType)
|
||||
}
|
||||
|
||||
private fun getProvider(valueType: IrType): RefProvider =
|
||||
fun getProvider(valueType: IrType): RefProvider =
|
||||
if (valueType.isPrimitiveType())
|
||||
primitiveRefProviders.getValue(valueType.classifierOrFail)
|
||||
else
|
||||
@@ -129,7 +129,7 @@ class JvmSharedVariablesManager(
|
||||
putValueArgument(0, value)
|
||||
}
|
||||
|
||||
override fun getSharedValue(sharedVariableSymbol: IrVariableSymbol, originalGet: IrGetValue): IrExpression =
|
||||
override fun getSharedValue(sharedVariableSymbol: IrValueSymbol, originalGet: IrGetValue): IrExpression =
|
||||
with(originalGet) {
|
||||
val unboxedType = InlineClassAbi.unboxType(symbol.owner.type)
|
||||
val provider = getProvider(unboxedType ?: symbol.owner.type)
|
||||
@@ -138,7 +138,7 @@ class JvmSharedVariablesManager(
|
||||
unboxedType?.let { unsafeCoerce(unboxedRead, it, symbol.owner.type) } ?: unboxedRead
|
||||
}
|
||||
|
||||
override fun setSharedValue(sharedVariableSymbol: IrVariableSymbol, originalSet: IrSetValue): IrExpression =
|
||||
override fun setSharedValue(sharedVariableSymbol: IrValueSymbol, originalSet: IrSetValue): IrExpression =
|
||||
with(originalSet) {
|
||||
val unboxedType = InlineClassAbi.unboxType(symbol.owner.type)
|
||||
val unboxedValue = unboxedType?.let { unsafeCoerce(value, symbol.owner.type, it) } ?: value
|
||||
@@ -146,6 +146,13 @@ class JvmSharedVariablesManager(
|
||||
val receiver = IrGetValueImpl(startOffset, endOffset, sharedVariableSymbol)
|
||||
IrSetFieldImpl(startOffset, endOffset, provider.elementField.symbol, receiver, unboxedValue, type, origin)
|
||||
}
|
||||
|
||||
@Suppress("MemberVisibilityCanBePrivate") // Used by FragmentSharedVariablesLowering
|
||||
fun getIrType(originalType: IrType): IrType {
|
||||
val provider = getProvider(InlineClassAbi.unboxType(originalType) ?: originalType)
|
||||
val typeArguments = provider.refClass.typeParameters.map { originalType }
|
||||
return provider.refClass.typeWith(typeArguments)
|
||||
}
|
||||
}
|
||||
|
||||
private inline fun IrFactory.addClass(
|
||||
|
||||
+3
-2
@@ -22,6 +22,7 @@ import org.jetbrains.kotlin.ir.expressions.IrGetValue
|
||||
import org.jetbrains.kotlin.ir.expressions.IrSetValue
|
||||
import org.jetbrains.kotlin.ir.expressions.IrTypeOperator
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.*
|
||||
import org.jetbrains.kotlin.ir.symbols.IrValueSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.IrVariableSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.impl.IrConstructorSymbolImpl
|
||||
import org.jetbrains.kotlin.ir.symbols.impl.IrFieldSymbolImpl
|
||||
@@ -78,7 +79,7 @@ class WasmSharedVariablesManager(val context: JsCommonBackendContext, val builtI
|
||||
|
||||
override fun defineSharedValue(originalDeclaration: IrVariable, sharedVariableDeclaration: IrVariable) = sharedVariableDeclaration
|
||||
|
||||
override fun getSharedValue(sharedVariableSymbol: IrVariableSymbol, originalGet: IrGetValue): IrExpression {
|
||||
override fun getSharedValue(sharedVariableSymbol: IrValueSymbol, originalGet: IrGetValue): IrExpression {
|
||||
val getField = IrGetFieldImpl(
|
||||
originalGet.startOffset, originalGet.endOffset,
|
||||
closureBoxFieldDeclaration.symbol,
|
||||
@@ -103,7 +104,7 @@ class WasmSharedVariablesManager(val context: JsCommonBackendContext, val builtI
|
||||
)
|
||||
}
|
||||
|
||||
override fun setSharedValue(sharedVariableSymbol: IrVariableSymbol, originalSet: IrSetValue): IrExpression =
|
||||
override fun setSharedValue(sharedVariableSymbol: IrValueSymbol, originalSet: IrSetValue): IrExpression =
|
||||
IrSetFieldImpl(
|
||||
originalSet.startOffset,
|
||||
originalSet.endOffset,
|
||||
|
||||
+23
-1
@@ -22,5 +22,27 @@ import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||
class EvaluatorFragmentInfo(
|
||||
val classDescriptor: ClassDescriptor,
|
||||
val methodDescriptor: FunctionDescriptor,
|
||||
val parameters: List<DeclarationDescriptor>
|
||||
parameterDescriptors: List<DeclarationDescriptor>,
|
||||
) {
|
||||
var parameters: List<EvaluatorFragmentParameterInfo> = parameterDescriptors.map { EvaluatorFragmentParameterInfo(it, false) }
|
||||
|
||||
companion object {
|
||||
// Used in the IntelliJ Kotlin JVM Debugger Plug-In (CodeFragmentCompiler)
|
||||
// TODO: Remove once intellij-community#1839 has landed.
|
||||
@Suppress("unused")
|
||||
fun createWithFragmentParameterInfo(
|
||||
classDescriptor: ClassDescriptor,
|
||||
methodDescriptor: FunctionDescriptor,
|
||||
parametersWithInfo: List<EvaluatorFragmentParameterInfo>
|
||||
) =
|
||||
EvaluatorFragmentInfo(classDescriptor, methodDescriptor, listOf()).apply {
|
||||
parameters = parametersWithInfo
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
data class EvaluatorFragmentParameterInfo(
|
||||
val descriptor: DeclarationDescriptor,
|
||||
val isLValue: Boolean,
|
||||
)
|
||||
+3
-3
@@ -31,10 +31,10 @@ class FragmentCompilerSymbolTableDecorator(
|
||||
if (descriptor !is ReceiverParameterDescriptor) return super.referenceValueParameter(descriptor)
|
||||
|
||||
val finderPredicate = when (val receiverValue = descriptor.value) {
|
||||
is ExtensionReceiver -> { targetDescriptor: DeclarationDescriptor ->
|
||||
is ExtensionReceiver -> { (targetDescriptor, _): EvaluatorFragmentParameterInfo ->
|
||||
receiverValue == (targetDescriptor as? ReceiverParameterDescriptor)?.value
|
||||
}
|
||||
is ThisClassReceiver -> { targetDescriptor: DeclarationDescriptor ->
|
||||
is ThisClassReceiver -> { (targetDescriptor, _): EvaluatorFragmentParameterInfo ->
|
||||
receiverValue.classDescriptor == targetDescriptor.original
|
||||
}
|
||||
else -> TODO("Unimplemented")
|
||||
@@ -50,7 +50,7 @@ class FragmentCompilerSymbolTableDecorator(
|
||||
|
||||
override fun referenceValue(value: ValueDescriptor): IrValueSymbol {
|
||||
val parameterPosition =
|
||||
fragmentInfo.parameters.indexOf(value)
|
||||
fragmentInfo.parameters.indexOfFirst { it.descriptor == value }
|
||||
if (parameterPosition > -1) {
|
||||
return super.referenceValueParameter(fragmentInfo.methodDescriptor.valueParameters[parameterPosition])
|
||||
}
|
||||
|
||||
+33
-13
@@ -19,6 +19,7 @@ import org.jetbrains.kotlin.psi.KtBlockCodeFragment
|
||||
import org.jetbrains.kotlin.psi2ir.generators.Generator
|
||||
import org.jetbrains.kotlin.psi2ir.generators.GeneratorContext
|
||||
import org.jetbrains.kotlin.psi2ir.generators.createBodyGenerator
|
||||
import org.jetbrains.kotlin.resolve.BindingContextUtils
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
|
||||
open class FragmentDeclarationGenerator(
|
||||
@@ -91,32 +92,51 @@ open class FragmentDeclarationGenerator(
|
||||
private fun generateFragmentValueParameterDeclarations(irFunction: IrSimpleFunction) {
|
||||
val functionDescriptor = irFunction.descriptor
|
||||
functionDescriptor.valueParameters.forEachIndexed { index, valueParameterDescriptor ->
|
||||
irFunction.valueParameters += declareParameter(valueParameterDescriptor).apply {
|
||||
context.fragmentContext!!.capturedDescriptorToFragmentParameterMap[fragmentInfo.parameters[index]] = this.symbol
|
||||
val parameterInfo = fragmentInfo.parameters[index]
|
||||
irFunction.valueParameters += declareParameter(valueParameterDescriptor, parameterInfo).apply {
|
||||
context.fragmentContext!!.capturedDescriptorToFragmentParameterMap[parameterInfo.descriptor] = this.symbol
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun declareParameter(descriptor: ValueParameterDescriptor): IrValueParameter {
|
||||
// Parameter must be _assignable_:
|
||||
// These parameters model the captured variables of the fragment. The captured
|
||||
// _values_ are extracted from the call stack of the JVM being debugged, and supplied
|
||||
// to the fragment evaluator via these parameters. Any modifications by the fragment
|
||||
// are written directly to the parameter, and then extracted from the stack frame
|
||||
// of the interpreter/JVM evaluating the fragment and written back into the call
|
||||
// stack of the JVM being debugged.
|
||||
private fun declareParameter(descriptor: ValueParameterDescriptor, parameterInfo: EvaluatorFragmentParameterInfo): IrValueParameter {
|
||||
// Parameter must be _assignable_ if written by the fragment:
|
||||
// These parameters model the captured variables of the fragment. The
|
||||
// captured _values_ are extracted from the call stack of the JVM being
|
||||
// debugged, and supplied to the fragment evaluator via these
|
||||
// parameters.
|
||||
//
|
||||
// If the parameter is modified by the fragment, the parameter is boxed
|
||||
// in a `Ref`, and the value extracted from that box upon return from
|
||||
// the fragment, then written back into the stack frame of the JVM
|
||||
// being debugged.
|
||||
//
|
||||
// The promotion to `Ref` and the replacement of loads/stores with the
|
||||
// appropriate getfield/putfield API of the `Ref` is done _after_
|
||||
// psi2ir, so for now we must mark the parameter as assignable for the
|
||||
// of IR generation. The replacement is delayed because the JVM
|
||||
// specific infrastructure (i.e. "SharedVariableContext") is not yet
|
||||
// instantiated: PSI2IR is kept backend agnostic.
|
||||
return context.symbolTable.declareValueParameter(
|
||||
UNDEFINED_OFFSET,
|
||||
UNDEFINED_OFFSET,
|
||||
IrDeclarationOrigin.DEFINED,
|
||||
if (shouldPromoteToSharedVariable(parameterInfo)) IrDeclarationOrigin.SHARED_VARIABLE_IN_EVALUATOR_FRAGMENT else IrDeclarationOrigin.DEFINED,
|
||||
descriptor,
|
||||
descriptor.type.toIrType(),
|
||||
(descriptor as? ValueParameterDescriptor)?.varargElementType?.toIrType(),
|
||||
descriptor.varargElementType?.toIrType(),
|
||||
null,
|
||||
isAssignable = true
|
||||
isAssignable = parameterInfo.isLValue
|
||||
)
|
||||
}
|
||||
|
||||
private fun shouldPromoteToSharedVariable(parameterInfo: EvaluatorFragmentParameterInfo) =
|
||||
parameterInfo.isLValue ||
|
||||
BindingContextUtils.isBoxedLocalCapturedInClosure(
|
||||
context.bindingContext,
|
||||
parameterInfo.descriptor
|
||||
)
|
||||
|
||||
|
||||
private fun KotlinType.toIrType() = context.typeTranslator.translateType(this)
|
||||
|
||||
private inline fun <T : IrDeclaration> T.buildWithScope(builder: (T) -> Unit): T =
|
||||
|
||||
@@ -83,6 +83,8 @@ interface IrDeclarationOrigin {
|
||||
object CONTINUATION : IrDeclarationOriginImpl("CONTINUATION", isSynthetic = true)
|
||||
object LOWERED_SUSPEND_FUNCTION : IrDeclarationOriginImpl("LOWERED_SUSPEND_FUNCTION", isSynthetic = true)
|
||||
|
||||
object SHARED_VARIABLE_IN_EVALUATOR_FRAGMENT : IrDeclarationOriginImpl("SHARED_VARIABLE_IN_EVALUATOR_FRAGMENT", isSynthetic = true)
|
||||
|
||||
val isSynthetic: Boolean get() = false
|
||||
}
|
||||
|
||||
|
||||
+3
-3
@@ -18,7 +18,7 @@ import org.jetbrains.kotlin.ir.expressions.impl.IrCallImpl
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.IrCompositeImpl
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.IrConstructorCallImpl
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.IrGetValueImpl
|
||||
import org.jetbrains.kotlin.ir.symbols.IrVariableSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.IrValueSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.impl.IrVariableSymbolImpl
|
||||
import org.jetbrains.kotlin.ir.types.typeWith
|
||||
import org.jetbrains.kotlin.ir.util.constructors
|
||||
@@ -74,7 +74,7 @@ internal class KonanSharedVariablesManager(val context: KonanBackendContext) : S
|
||||
)
|
||||
}
|
||||
|
||||
override fun getSharedValue(sharedVariableSymbol: IrVariableSymbol, originalGet: IrGetValue) =
|
||||
override fun getSharedValue(sharedVariableSymbol: IrValueSymbol, originalGet: IrGetValue) =
|
||||
IrCallImpl(originalGet.startOffset, originalGet.endOffset,
|
||||
originalGet.type, elementProperty.getter!!.symbol,
|
||||
elementProperty.getter!!.typeParameters.size, elementProperty.getter!!.valueParameters.size).apply {
|
||||
@@ -84,7 +84,7 @@ internal class KonanSharedVariablesManager(val context: KonanBackendContext) : S
|
||||
)
|
||||
}
|
||||
|
||||
override fun setSharedValue(sharedVariableSymbol: IrVariableSymbol, originalSet: IrSetValue) =
|
||||
override fun setSharedValue(sharedVariableSymbol: IrValueSymbol, originalSet: IrSetValue) =
|
||||
IrCallImpl(originalSet.startOffset, originalSet.endOffset, context.irBuiltIns.unitType,
|
||||
elementProperty.setter!!.symbol, elementProperty.setter!!.typeParameters.size,
|
||||
elementProperty.setter!!.valueParameters.size).apply {
|
||||
|
||||
Reference in New Issue
Block a user