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
|
||||
|
||||
import org.jetbrains.kotlin.backend.konan.llvm.KonanBuiltIns
|
||||
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.descriptorUtil.*
|
||||
|
||||
@@ -66,6 +70,18 @@ internal val ClassDescriptor.isArray: Boolean
|
||||
internal val ClassDescriptor.isInterface: Boolean
|
||||
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>
|
||||
get() {
|
||||
|
||||
+4
-1
@@ -1,12 +1,15 @@
|
||||
package org.jetbrains.kotlin.backend.konan
|
||||
|
||||
import org.jetbrains.kotlin.backend.common.BackendContext
|
||||
import org.jetbrains.kotlin.backend.konan.descriptors.KonanSharedVariablesManager
|
||||
import org.jetbrains.kotlin.backend.konan.llvm.KonanPlatform
|
||||
|
||||
open internal class KonanBackendContext : BackendContext {
|
||||
override val builtIns = KonanPlatform.builtIns
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
// TODO: consider handling it with compiler magic instead.
|
||||
KRef Kotlin_internal_undefined() {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
} // extern "C"
|
||||
|
||||
@@ -100,6 +100,8 @@ KString Kotlin_String_subSequence(KString thiz, KInt startIndex, KInt endIndex);
|
||||
|
||||
KConstRef Kotlin_getCurrentStackTrace();
|
||||
|
||||
KRef Kotlin_internal_undefined();
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#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