backend: implement KonanSharedVariablesManager
This commit is contained in:
committed by
SvyatoslavScherbina
parent
7d5890e354
commit
8dce1884fd
+16
@@ -1,6 +1,10 @@
|
|||||||
package org.jetbrains.kotlin.backend.konan
|
package org.jetbrains.kotlin.backend.konan
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.backend.konan.llvm.KonanBuiltIns
|
||||||
import org.jetbrains.kotlin.descriptors.*
|
import org.jetbrains.kotlin.descriptors.*
|
||||||
|
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
|
||||||
|
import org.jetbrains.kotlin.name.FqName
|
||||||
|
import org.jetbrains.kotlin.name.Name
|
||||||
import org.jetbrains.kotlin.resolve.OverridingUtil
|
import org.jetbrains.kotlin.resolve.OverridingUtil
|
||||||
import org.jetbrains.kotlin.resolve.descriptorUtil.*
|
import org.jetbrains.kotlin.resolve.descriptorUtil.*
|
||||||
|
|
||||||
@@ -66,6 +70,18 @@ internal val ClassDescriptor.isArray: Boolean
|
|||||||
internal val ClassDescriptor.isInterface: Boolean
|
internal val ClassDescriptor.isInterface: Boolean
|
||||||
get() = (this.kind == ClassKind.INTERFACE)
|
get() = (this.kind == ClassKind.INTERFACE)
|
||||||
|
|
||||||
|
private val konanInternal = FqName.fromSegments(listOf("konan", "internal"))
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return built-in class `konan.internal.$name`
|
||||||
|
*/
|
||||||
|
internal fun KonanBuiltIns.getKonanInternalClass(name: String): ClassDescriptor {
|
||||||
|
val classifier = this.builtInsModule
|
||||||
|
.getPackage(konanInternal).memberScope
|
||||||
|
.getContributedClassifier(Name.identifier(name), NoLookupLocation.FROM_BACKEND)
|
||||||
|
|
||||||
|
return classifier as ClassDescriptor
|
||||||
|
}
|
||||||
|
|
||||||
internal val CallableDescriptor.allValueParameters: List<ParameterDescriptor>
|
internal val CallableDescriptor.allValueParameters: List<ParameterDescriptor>
|
||||||
get() {
|
get() {
|
||||||
|
|||||||
+4
-1
@@ -1,12 +1,15 @@
|
|||||||
package org.jetbrains.kotlin.backend.konan
|
package org.jetbrains.kotlin.backend.konan
|
||||||
|
|
||||||
import org.jetbrains.kotlin.backend.common.BackendContext
|
import org.jetbrains.kotlin.backend.common.BackendContext
|
||||||
|
import org.jetbrains.kotlin.backend.konan.descriptors.KonanSharedVariablesManager
|
||||||
import org.jetbrains.kotlin.backend.konan.llvm.KonanPlatform
|
import org.jetbrains.kotlin.backend.konan.llvm.KonanPlatform
|
||||||
|
|
||||||
open internal class KonanBackendContext : BackendContext {
|
open internal class KonanBackendContext : BackendContext {
|
||||||
override val builtIns = KonanPlatform.builtIns
|
override val builtIns = KonanPlatform.builtIns
|
||||||
|
|
||||||
override val sharedVariablesManager by lazy {
|
override val sharedVariablesManager by lazy {
|
||||||
TODO()
|
// Creating lazily because builtIns module seems to be incomplete during `link` test;
|
||||||
|
// TODO: investigate this.
|
||||||
|
KonanSharedVariablesManager(builtIns)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+106
@@ -0,0 +1,106 @@
|
|||||||
|
package org.jetbrains.kotlin.backend.konan.descriptors
|
||||||
|
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.backend.common.descriptors.SharedVariablesManager
|
||||||
|
import org.jetbrains.kotlin.backend.konan.getKonanInternalClass
|
||||||
|
import org.jetbrains.kotlin.backend.konan.llvm.KonanBuiltIns
|
||||||
|
import org.jetbrains.kotlin.descriptors.ClassConstructorDescriptor
|
||||||
|
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
|
||||||
|
import org.jetbrains.kotlin.descriptors.VariableDescriptor
|
||||||
|
import org.jetbrains.kotlin.descriptors.impl.LocalVariableDescriptor
|
||||||
|
import org.jetbrains.kotlin.ir.IrStatement
|
||||||
|
import org.jetbrains.kotlin.ir.declarations.IrVariable
|
||||||
|
import org.jetbrains.kotlin.ir.declarations.impl.IrVariableImpl
|
||||||
|
import org.jetbrains.kotlin.ir.expressions.IrExpression
|
||||||
|
import org.jetbrains.kotlin.ir.expressions.IrGetValue
|
||||||
|
import org.jetbrains.kotlin.ir.expressions.IrSetVariable
|
||||||
|
import org.jetbrains.kotlin.ir.expressions.impl.IrCallImpl
|
||||||
|
import org.jetbrains.kotlin.ir.expressions.impl.IrCompositeImpl
|
||||||
|
import org.jetbrains.kotlin.ir.expressions.impl.IrGetValueImpl
|
||||||
|
import org.jetbrains.kotlin.types.*
|
||||||
|
|
||||||
|
internal class KonanSharedVariablesManager(val builtIns: KonanBuiltIns) : SharedVariablesManager {
|
||||||
|
|
||||||
|
private val refClass = builtIns.getKonanInternalClass("Ref")
|
||||||
|
|
||||||
|
private val refClassConstructor = refClass.unsubstitutedPrimaryConstructor!!
|
||||||
|
|
||||||
|
private fun refConstructor(elementType: KotlinType): ClassConstructorDescriptor {
|
||||||
|
val typeParameter = refClassConstructor.typeParameters[0]
|
||||||
|
|
||||||
|
return refClassConstructor.substitute(TypeSubstitutor.create(
|
||||||
|
mapOf(typeParameter.typeConstructor to TypeProjectionImpl(Variance.INVARIANT, elementType))
|
||||||
|
))!!
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun refType(elementType: KotlinType): KotlinType {
|
||||||
|
return refClass.defaultType.replace(listOf(TypeProjectionImpl(elementType)))
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun createSharedVariableDescriptor(variableDescriptor: VariableDescriptor): VariableDescriptor {
|
||||||
|
return LocalVariableDescriptor(
|
||||||
|
variableDescriptor.containingDeclaration, variableDescriptor.annotations, variableDescriptor.name,
|
||||||
|
refType(variableDescriptor.type),
|
||||||
|
false, false, variableDescriptor.source
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getElementProperty(sharedVariableDescriptor: VariableDescriptor): PropertyDescriptor {
|
||||||
|
return sharedVariableDescriptor.type.memberScope.getContributedDescriptors()
|
||||||
|
.filterIsInstance<PropertyDescriptor>()
|
||||||
|
.single {
|
||||||
|
it.name.asString() == "element"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun defineSharedValue(sharedVariableDescriptor: VariableDescriptor,
|
||||||
|
originalDeclaration: IrVariable): IrStatement {
|
||||||
|
|
||||||
|
val valueType = originalDeclaration.descriptor.type
|
||||||
|
|
||||||
|
val refConstructorTypeArguments = mapOf(refClassConstructor.typeParameters[0] to valueType)
|
||||||
|
|
||||||
|
val refConstructorCall = IrCallImpl(
|
||||||
|
originalDeclaration.startOffset, originalDeclaration.endOffset,
|
||||||
|
refConstructor(valueType), refConstructorTypeArguments
|
||||||
|
)
|
||||||
|
val sharedVariableDeclaration = IrVariableImpl(
|
||||||
|
originalDeclaration.startOffset, originalDeclaration.endOffset, originalDeclaration.origin,
|
||||||
|
sharedVariableDescriptor, refConstructorCall
|
||||||
|
)
|
||||||
|
|
||||||
|
val initializer = originalDeclaration.initializer ?:
|
||||||
|
return sharedVariableDeclaration
|
||||||
|
|
||||||
|
val elementProperty = getElementProperty(sharedVariableDescriptor)
|
||||||
|
|
||||||
|
val sharedVariableInitialization =
|
||||||
|
IrCallImpl(initializer.startOffset, initializer.endOffset, elementProperty.setter!!)
|
||||||
|
|
||||||
|
sharedVariableInitialization.dispatchReceiver =
|
||||||
|
IrGetValueImpl(initializer.startOffset, initializer.endOffset, sharedVariableDescriptor)
|
||||||
|
|
||||||
|
sharedVariableInitialization.putValueArgument(0, initializer)
|
||||||
|
|
||||||
|
return IrCompositeImpl(
|
||||||
|
originalDeclaration.startOffset, originalDeclaration.endOffset, builtIns.unitType, null,
|
||||||
|
listOf(sharedVariableDeclaration, sharedVariableInitialization)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getSharedValue(sharedVariableDescriptor: VariableDescriptor, originalGet: IrGetValue): IrExpression {
|
||||||
|
val elementProperty = getElementProperty(sharedVariableDescriptor)
|
||||||
|
return IrCallImpl(originalGet.startOffset, originalGet.endOffset, elementProperty.getter!!).apply {
|
||||||
|
dispatchReceiver = IrGetValueImpl(originalGet.startOffset, originalGet.endOffset, sharedVariableDescriptor)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun setSharedValue(sharedVariableDescriptor: VariableDescriptor, originalSet: IrSetVariable): IrExpression {
|
||||||
|
val elementProperty = getElementProperty(sharedVariableDescriptor)
|
||||||
|
return IrCallImpl(originalSet.startOffset, originalSet.endOffset, elementProperty.setter!!).apply {
|
||||||
|
dispatchReceiver = IrGetValueImpl(originalSet.startOffset, originalSet.endOffset, sharedVariableDescriptor)
|
||||||
|
putValueArgument(0, originalSet.value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -184,4 +184,9 @@ KConstRef Kotlin_getCurrentStackTrace() {
|
|||||||
return GetCurrentStackTrace();
|
return GetCurrentStackTrace();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: consider handling it with compiler magic instead.
|
||||||
|
KRef Kotlin_internal_undefined() {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
} // extern "C"
|
} // extern "C"
|
||||||
|
|||||||
@@ -100,6 +100,8 @@ KString Kotlin_String_subSequence(KString thiz, KInt startIndex, KInt endIndex);
|
|||||||
|
|
||||||
KConstRef Kotlin_getCurrentStackTrace();
|
KConstRef Kotlin_getCurrentStackTrace();
|
||||||
|
|
||||||
|
KRef Kotlin_internal_undefined();
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -0,0 +1,8 @@
|
|||||||
|
package konan.internal
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class is used to allocate closure-captured variables in the heap.
|
||||||
|
*/
|
||||||
|
class Ref<T> {
|
||||||
|
var element: T = undefined()
|
||||||
|
}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
package konan.internal
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns undefined value of type `T`.
|
||||||
|
* This method is unsafe and should be used with care.
|
||||||
|
*/
|
||||||
|
@SymbolName("Kotlin_internal_undefined")
|
||||||
|
internal external fun <T> undefined(): T
|
||||||
Reference in New Issue
Block a user