Proper fix for interop enum and struct generation
Current approach to generate interop enum and structs during linkage stage turned out to be fragile. We might get unbound wrapper descriptors which are useless for function body generation. The solution is to postpone body generation until linkage step is complete.
This commit is contained in:
committed by
Stanislav Erokhin
parent
77899446cb
commit
b68a934d88
+5
@@ -133,6 +133,11 @@ internal fun Context.psiToIr(
|
|||||||
modulesWithoutDCE
|
modulesWithoutDCE
|
||||||
.filter(ModuleDescriptor::isFromInteropLibrary)
|
.filter(ModuleDescriptor::isFromInteropLibrary)
|
||||||
.forEach(irProviderForCEnumsAndCStructs::referenceAllEnumsAndStructsFrom)
|
.forEach(irProviderForCEnumsAndCStructs::referenceAllEnumsAndStructsFrom)
|
||||||
|
|
||||||
|
|
||||||
|
translator.addPostprocessingStep {
|
||||||
|
irProviderForCEnumsAndCStructs.generateBodies()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+6
@@ -41,6 +41,12 @@ internal interface DescriptorToIrTranslationMixin {
|
|||||||
|
|
||||||
val typeTranslator: TypeTranslator
|
val typeTranslator: TypeTranslator
|
||||||
|
|
||||||
|
val postLinkageSteps: MutableList<() -> Unit>
|
||||||
|
|
||||||
|
fun invokePostLinkageSteps() {
|
||||||
|
postLinkageSteps.forEach { it() }
|
||||||
|
}
|
||||||
|
|
||||||
fun KotlinType.toIrType() = typeTranslator.translateType(this)
|
fun KotlinType.toIrType() = typeTranslator.translateType(this)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
+17
-1
@@ -13,6 +13,7 @@ import org.jetbrains.kotlin.backend.konan.ir.interop.cenum.CEnumClassGenerator
|
|||||||
import org.jetbrains.kotlin.backend.konan.ir.interop.cenum.CEnumCompanionGenerator
|
import org.jetbrains.kotlin.backend.konan.ir.interop.cenum.CEnumCompanionGenerator
|
||||||
import org.jetbrains.kotlin.backend.konan.ir.interop.cenum.CEnumVarClassGenerator
|
import org.jetbrains.kotlin.backend.konan.ir.interop.cenum.CEnumVarClassGenerator
|
||||||
import org.jetbrains.kotlin.backend.konan.ir.interop.cstruct.CStructVarClassGenerator
|
import org.jetbrains.kotlin.backend.konan.ir.interop.cstruct.CStructVarClassGenerator
|
||||||
|
import org.jetbrains.kotlin.backend.konan.ir.interop.cstruct.CStructVarCompanionGenerator
|
||||||
import org.jetbrains.kotlin.descriptors.*
|
import org.jetbrains.kotlin.descriptors.*
|
||||||
import org.jetbrains.kotlin.ir.declarations.*
|
import org.jetbrains.kotlin.ir.declarations.*
|
||||||
import org.jetbrains.kotlin.ir.symbols.*
|
import org.jetbrains.kotlin.ir.symbols.*
|
||||||
@@ -50,8 +51,10 @@ internal class IrProviderForCEnumAndCStructStubs(
|
|||||||
CEnumVarClassGenerator(context, interopBuiltIns)
|
CEnumVarClassGenerator(context, interopBuiltIns)
|
||||||
private val cEnumClassGenerator =
|
private val cEnumClassGenerator =
|
||||||
CEnumClassGenerator(context, cEnumCompanionGenerator, cEnumVarClassGenerator)
|
CEnumClassGenerator(context, cEnumCompanionGenerator, cEnumVarClassGenerator)
|
||||||
|
private val cStructCompanionGenerator =
|
||||||
|
CStructVarCompanionGenerator(context, interopBuiltIns)
|
||||||
private val cStructClassGenerator =
|
private val cStructClassGenerator =
|
||||||
CStructVarClassGenerator(context, interopBuiltIns)
|
CStructVarClassGenerator(context, interopBuiltIns, cStructCompanionGenerator)
|
||||||
|
|
||||||
fun isCEnumOrCStruct(declarationDescriptor: DeclarationDescriptor): Boolean =
|
fun isCEnumOrCStruct(declarationDescriptor: DeclarationDescriptor): Boolean =
|
||||||
declarationDescriptor.run { findCEnumDescriptor(interopBuiltIns) ?: findCStructDescriptor(interopBuiltIns) } != null
|
declarationDescriptor.run { findCEnumDescriptor(interopBuiltIns) ?: findCStructDescriptor(interopBuiltIns) } != null
|
||||||
@@ -73,6 +76,19 @@ internal class IrProviderForCEnumAndCStructStubs(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* We postpone generation of bodies until IR linkage is complete.
|
||||||
|
* This way we ensure that all used symbols are resolved.
|
||||||
|
*/
|
||||||
|
fun generateBodies() {
|
||||||
|
cEnumCompanionGenerator.invokePostLinkageSteps()
|
||||||
|
cEnumByValueFunctionGenerator.invokePostLinkageSteps()
|
||||||
|
cEnumClassGenerator.invokePostLinkageSteps()
|
||||||
|
cEnumVarClassGenerator.invokePostLinkageSteps()
|
||||||
|
cStructClassGenerator.invokePostLinkageSteps()
|
||||||
|
cStructCompanionGenerator.invokePostLinkageSteps()
|
||||||
|
}
|
||||||
|
|
||||||
fun getDeclaration(descriptor: DeclarationDescriptor, idSignature: IdSignature, file: IrFile, symbolKind: BinarySymbolData.SymbolKind): IrSymbolOwner {
|
fun getDeclaration(descriptor: DeclarationDescriptor, idSignature: IdSignature, file: IrFile, symbolKind: BinarySymbolData.SymbolKind): IrSymbolOwner {
|
||||||
return symbolTable.run {
|
return symbolTable.run {
|
||||||
when (symbolKind) {
|
when (symbolKind) {
|
||||||
|
|||||||
+40
-37
@@ -32,6 +32,7 @@ internal class CEnumByValueFunctionGenerator(
|
|||||||
override val irBuiltIns: IrBuiltIns = context.irBuiltIns
|
override val irBuiltIns: IrBuiltIns = context.irBuiltIns
|
||||||
override val symbolTable: SymbolTable = context.symbolTable
|
override val symbolTable: SymbolTable = context.symbolTable
|
||||||
override val typeTranslator: TypeTranslator = context.typeTranslator
|
override val typeTranslator: TypeTranslator = context.typeTranslator
|
||||||
|
override val postLinkageSteps: MutableList<() -> Unit> = mutableListOf()
|
||||||
|
|
||||||
fun generateByValueFunction(
|
fun generateByValueFunction(
|
||||||
companionIrClass: IrClass,
|
companionIrClass: IrClass,
|
||||||
@@ -51,46 +52,48 @@ internal class CEnumByValueFunctionGenerator(
|
|||||||
// i++
|
// i++
|
||||||
// }
|
// }
|
||||||
// throw NPE
|
// throw NPE
|
||||||
byValueIrFunction.body = irBuilder(irBuiltIns, byValueIrFunction.symbol, SYNTHETIC_OFFSET, SYNTHETIC_OFFSET).irBlockBody {
|
postLinkageSteps.add {
|
||||||
+irReturn(irBlock {
|
byValueIrFunction.body = irBuilder(irBuiltIns, byValueIrFunction.symbol, SYNTHETIC_OFFSET, SYNTHETIC_OFFSET).irBlockBody {
|
||||||
val values = irTemporary(irCall(valuesIrFunctionSymbol), isMutable = true)
|
+irReturn(irBlock {
|
||||||
val inductionVariable = irTemporary(irInt(0), isMutable = true)
|
val values = irTemporary(irCall(valuesIrFunctionSymbol), isMutable = true)
|
||||||
val arrayClass = values.type.classOrNull!!
|
val inductionVariable = irTemporary(irInt(0), isMutable = true)
|
||||||
val valuesSize = irCall(symbols.arraySize.getValue(arrayClass), irBuiltIns.intType).also { irCall ->
|
val arrayClass = values.type.classOrNull!!
|
||||||
irCall.dispatchReceiver = irGet(values)
|
val valuesSize = irCall(symbols.arraySize.getValue(arrayClass), irBuiltIns.intType).also { irCall ->
|
||||||
}
|
irCall.dispatchReceiver = irGet(values)
|
||||||
val getElementFn = symbols.arrayGet.getValue(arrayClass)
|
|
||||||
val plusFun = symbols.getBinaryOperator(OperatorNameConventions.PLUS, irBuiltIns.intType, irBuiltIns.intType)
|
|
||||||
val lessFunctionSymbol = irBuiltIns.lessFunByOperandType.getValue(irBuiltIns.intClass)
|
|
||||||
+irWhile().also { loop ->
|
|
||||||
loop.condition = irCall(lessFunctionSymbol, irBuiltIns.booleanType).also { irCall ->
|
|
||||||
irCall.putValueArgument(0, irGet(inductionVariable))
|
|
||||||
irCall.putValueArgument(1, valuesSize)
|
|
||||||
}
|
}
|
||||||
loop.body = irBlock {
|
val getElementFn = symbols.arrayGet.getValue(arrayClass)
|
||||||
val entry = irTemporary(irCall(getElementFn, byValueIrFunction.returnType).also { irCall ->
|
val plusFun = symbols.getBinaryOperator(OperatorNameConventions.PLUS, irBuiltIns.intType, irBuiltIns.intType)
|
||||||
irCall.dispatchReceiver = irGet(values)
|
val lessFunctionSymbol = irBuiltIns.lessFunByOperandType.getValue(irBuiltIns.intClass)
|
||||||
|
+irWhile().also { loop ->
|
||||||
|
loop.condition = irCall(lessFunctionSymbol, irBuiltIns.booleanType).also { irCall ->
|
||||||
irCall.putValueArgument(0, irGet(inductionVariable))
|
irCall.putValueArgument(0, irGet(inductionVariable))
|
||||||
}, isMutable = true)
|
irCall.putValueArgument(1, valuesSize)
|
||||||
val valueGetter = entry.type.getClass()!!.getPropertyGetter("value")!!
|
}
|
||||||
val entryValue = irGet(irValueParameter.type, irGet(entry), valueGetter)
|
loop.body = irBlock {
|
||||||
+irIfThenElse(
|
val entry = irTemporary(irCall(getElementFn, byValueIrFunction.returnType).also { irCall ->
|
||||||
type = irBuiltIns.unitType,
|
irCall.dispatchReceiver = irGet(values)
|
||||||
condition = irEquals(entryValue, irGet(irValueParameter)),
|
irCall.putValueArgument(0, irGet(inductionVariable))
|
||||||
thenPart = irReturn(irGet(entry)),
|
}, isMutable = true)
|
||||||
elsePart = irSetVar(
|
val valueGetter = entry.type.getClass()!!.getPropertyGetter("value")!!
|
||||||
inductionVariable,
|
val entryValue = irGet(irValueParameter.type, irGet(entry), valueGetter)
|
||||||
irCallOp(plusFun, irBuiltIns.intType,
|
+irIfThenElse(
|
||||||
irGet(inductionVariable),
|
type = irBuiltIns.unitType,
|
||||||
irInt(1)
|
condition = irEquals(entryValue, irGet(irValueParameter)),
|
||||||
)
|
thenPart = irReturn(irGet(entry)),
|
||||||
)
|
elsePart = irSetVar(
|
||||||
)
|
inductionVariable,
|
||||||
|
irCallOp(plusFun, irBuiltIns.intType,
|
||||||
|
irGet(inductionVariable),
|
||||||
|
irInt(1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
+IrCallImpl.fromSymbolOwner(startOffset, endOffset, irBuiltIns.nothingType,
|
||||||
+IrCallImpl.fromSymbolDescriptor(startOffset, endOffset, irBuiltIns.nothingType,
|
symbols.throwNullPointerException)
|
||||||
symbols.throwNullPointerException)
|
})
|
||||||
})
|
}
|
||||||
}
|
}
|
||||||
return byValueIrFunction
|
return byValueIrFunction
|
||||||
}
|
}
|
||||||
|
|||||||
+40
-24
@@ -49,6 +49,7 @@ internal class CEnumClassGenerator(
|
|||||||
override val irBuiltIns: IrBuiltIns = context.irBuiltIns
|
override val irBuiltIns: IrBuiltIns = context.irBuiltIns
|
||||||
override val symbolTable: SymbolTable = context.symbolTable
|
override val symbolTable: SymbolTable = context.symbolTable
|
||||||
override val typeTranslator: TypeTranslator = context.typeTranslator
|
override val typeTranslator: TypeTranslator = context.typeTranslator
|
||||||
|
override val postLinkageSteps: MutableList<() -> Unit> = mutableListOf()
|
||||||
|
|
||||||
private val enumClassMembersGenerator = EnumClassMembersGenerator(DeclarationGenerator(context))
|
private val enumClassMembersGenerator = EnumClassMembersGenerator(DeclarationGenerator(context))
|
||||||
|
|
||||||
@@ -97,38 +98,46 @@ internal class CEnumClassGenerator(
|
|||||||
SYNTHETIC_OFFSET, SYNTHETIC_OFFSET, IrDeclarationOrigin.PROPERTY_BACKING_FIELD,
|
SYNTHETIC_OFFSET, SYNTHETIC_OFFSET, IrDeclarationOrigin.PROPERTY_BACKING_FIELD,
|
||||||
propertyDescriptor, propertyDescriptor.type.toIrType(), DescriptorVisibilities.PRIVATE
|
propertyDescriptor, propertyDescriptor.type.toIrType(), DescriptorVisibilities.PRIVATE
|
||||||
).also {
|
).also {
|
||||||
it.initializer = irBuilder(irBuiltIns, it.symbol, SYNTHETIC_OFFSET, SYNTHETIC_OFFSET).run {
|
postLinkageSteps.add {
|
||||||
irExprBody(irGet(irClass.primaryConstructor!!.valueParameters[0]))
|
it.initializer = irBuilder(irBuiltIns, it.symbol, SYNTHETIC_OFFSET, SYNTHETIC_OFFSET).run {
|
||||||
|
irExprBody(irGet(irClass.primaryConstructor!!.valueParameters[0]))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
val getter = irProperty.getter!!
|
val getter = irProperty.getter!!
|
||||||
getter.correspondingPropertySymbol = irProperty.symbol
|
getter.correspondingPropertySymbol = irProperty.symbol
|
||||||
getter.body = irBuilder(irBuiltIns, getter.symbol, SYNTHETIC_OFFSET, SYNTHETIC_OFFSET).irBlockBody {
|
postLinkageSteps.add {
|
||||||
+irReturn(
|
getter.body = irBuilder(irBuiltIns, getter.symbol, SYNTHETIC_OFFSET, SYNTHETIC_OFFSET).irBlockBody {
|
||||||
irGetField(
|
+irReturn(
|
||||||
irGet(getter.dispatchReceiverParameter!!),
|
irGetField(
|
||||||
irProperty.backingField!!
|
irGet(getter.dispatchReceiverParameter!!),
|
||||||
)
|
irProperty.backingField!!
|
||||||
)
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return irProperty
|
return irProperty
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun createEnumEntry(enumDescriptor: ClassDescriptor, entryDescriptor: ClassDescriptor): IrEnumEntry {
|
private fun createEnumEntry(enumDescriptor: ClassDescriptor, entryDescriptor: ClassDescriptor): IrEnumEntry {
|
||||||
return symbolTable.declareEnumEntry(
|
val enumEntry = symbolTable.declareEnumEntry(
|
||||||
SYNTHETIC_OFFSET, SYNTHETIC_OFFSET,
|
SYNTHETIC_OFFSET, SYNTHETIC_OFFSET,
|
||||||
IrDeclarationOrigin.IR_EXTERNAL_DECLARATION_STUB, entryDescriptor
|
IrDeclarationOrigin.IR_EXTERNAL_DECLARATION_STUB, entryDescriptor
|
||||||
).also { enumEntry ->
|
)
|
||||||
enumEntry.initializerExpression = IrExpressionBodyImpl(IrEnumConstructorCallImpl.fromSymbolDescriptor(
|
val constructorSymbol = symbolTable.referenceConstructor(enumDescriptor.unsubstitutedPrimaryConstructor!!)
|
||||||
|
postLinkageSteps.add {
|
||||||
|
enumEntry.initializerExpression = IrExpressionBodyImpl(IrEnumConstructorCallImpl(
|
||||||
SYNTHETIC_OFFSET, SYNTHETIC_OFFSET,
|
SYNTHETIC_OFFSET, SYNTHETIC_OFFSET,
|
||||||
type = irBuiltIns.unitType,
|
type = irBuiltIns.unitType,
|
||||||
symbol = symbolTable.referenceConstructor(enumDescriptor.unsubstitutedPrimaryConstructor!!),
|
symbol = constructorSymbol,
|
||||||
typeArgumentsCount = 0 // enums can't be generic
|
typeArgumentsCount = 0,
|
||||||
|
valueArgumentsCount = constructorSymbol.owner.valueParameters.size
|
||||||
).also {
|
).also {
|
||||||
it.putValueArgument(0, extractEnumEntryValue(entryDescriptor))
|
it.putValueArgument(0, extractEnumEntryValue(entryDescriptor))
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
return enumEntry
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -146,16 +155,23 @@ internal class CEnumClassGenerator(
|
|||||||
private fun createEnumPrimaryConstructor(descriptor: ClassDescriptor): IrConstructor {
|
private fun createEnumPrimaryConstructor(descriptor: ClassDescriptor): IrConstructor {
|
||||||
val irConstructor = createConstructor(descriptor.unsubstitutedPrimaryConstructor!!)
|
val irConstructor = createConstructor(descriptor.unsubstitutedPrimaryConstructor!!)
|
||||||
val enumConstructor = context.builtIns.enum.constructors.single()
|
val enumConstructor = context.builtIns.enum.constructors.single()
|
||||||
irConstructor.body = irBuilder(irBuiltIns, irConstructor.symbol, SYNTHETIC_OFFSET, SYNTHETIC_OFFSET).irBlockBody {
|
val constructorSymbol = symbolTable.referenceConstructor(enumConstructor)
|
||||||
+IrEnumConstructorCallImpl.fromSymbolDescriptor(
|
val classSymbol = symbolTable.referenceClass(descriptor)
|
||||||
startOffset, endOffset,
|
val type = descriptor.defaultType.toIrType()
|
||||||
context.irBuiltIns.unitType,
|
postLinkageSteps.add {
|
||||||
symbolTable.referenceConstructor(enumConstructor),
|
irConstructor.body = irBuilder(irBuiltIns, irConstructor.symbol, SYNTHETIC_OFFSET, SYNTHETIC_OFFSET)
|
||||||
typeArgumentsCount = 1 // kotlin.Enum<T> has a single type parameter.
|
.irBlockBody {
|
||||||
).apply {
|
+IrEnumConstructorCallImpl(
|
||||||
putTypeArgument(0, descriptor.defaultType.toIrType())
|
startOffset, endOffset,
|
||||||
}
|
context.irBuiltIns.unitType,
|
||||||
+irInstanceInitializer(symbolTable.referenceClass(descriptor))
|
constructorSymbol,
|
||||||
|
typeArgumentsCount = 1, // kotlin.Enum<T> has a single type parameter.
|
||||||
|
valueArgumentsCount = constructorSymbol.owner.valueParameters.size
|
||||||
|
).apply {
|
||||||
|
putTypeArgument(0, type)
|
||||||
|
}
|
||||||
|
+irInstanceInitializer(classSymbol)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return irConstructor
|
return irConstructor
|
||||||
}
|
}
|
||||||
|
|||||||
+13
-7
@@ -32,6 +32,7 @@ internal class CEnumCompanionGenerator(
|
|||||||
override val irBuiltIns: IrBuiltIns = context.irBuiltIns
|
override val irBuiltIns: IrBuiltIns = context.irBuiltIns
|
||||||
override val symbolTable: SymbolTable = context.symbolTable
|
override val symbolTable: SymbolTable = context.symbolTable
|
||||||
override val typeTranslator: TypeTranslator = context.typeTranslator
|
override val typeTranslator: TypeTranslator = context.typeTranslator
|
||||||
|
override val postLinkageSteps: MutableList<() -> Unit> = mutableListOf()
|
||||||
|
|
||||||
// Depends on already generated `.values()` irFunction.
|
// Depends on already generated `.values()` irFunction.
|
||||||
fun generate(enumClass: IrClass): IrClass =
|
fun generate(enumClass: IrClass): IrClass =
|
||||||
@@ -50,13 +51,16 @@ internal class CEnumCompanionGenerator(
|
|||||||
private fun createCompanionConstructor(companionObjectDescriptor: ClassDescriptor): IrConstructor {
|
private fun createCompanionConstructor(companionObjectDescriptor: ClassDescriptor): IrConstructor {
|
||||||
val anyPrimaryConstructor = companionObjectDescriptor.builtIns.any.unsubstitutedPrimaryConstructor!!
|
val anyPrimaryConstructor = companionObjectDescriptor.builtIns.any.unsubstitutedPrimaryConstructor!!
|
||||||
val superConstructorSymbol = symbolTable.referenceConstructor(anyPrimaryConstructor)
|
val superConstructorSymbol = symbolTable.referenceConstructor(anyPrimaryConstructor)
|
||||||
|
val classSymbol = symbolTable.referenceClass(companionObjectDescriptor)
|
||||||
return createConstructor(companionObjectDescriptor.unsubstitutedPrimaryConstructor!!).also {
|
return createConstructor(companionObjectDescriptor.unsubstitutedPrimaryConstructor!!).also {
|
||||||
it.body = irBuilder(irBuiltIns, it.symbol, SYNTHETIC_OFFSET, SYNTHETIC_OFFSET).irBlockBody {
|
postLinkageSteps.add {
|
||||||
+IrDelegatingConstructorCallImpl.fromSymbolDescriptor(
|
it.body = irBuilder(irBuiltIns, it.symbol, SYNTHETIC_OFFSET, SYNTHETIC_OFFSET).irBlockBody {
|
||||||
startOffset, endOffset, context.irBuiltIns.unitType,
|
+IrDelegatingConstructorCallImpl.fromSymbolOwner(
|
||||||
superConstructorSymbol
|
startOffset, endOffset, context.irBuiltIns.unitType,
|
||||||
)
|
superConstructorSymbol
|
||||||
+irInstanceInitializer(symbolTable.referenceClass(companionObjectDescriptor))
|
)
|
||||||
|
+irInstanceInitializer(classSymbol)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -88,7 +92,9 @@ internal class CEnumCompanionGenerator(
|
|||||||
private fun declareEntryAliasProperty(propertyDescriptor: PropertyDescriptor, enumClass: IrClass): IrProperty {
|
private fun declareEntryAliasProperty(propertyDescriptor: PropertyDescriptor, enumClass: IrClass): IrProperty {
|
||||||
val entrySymbol = fundCorrespondingEnumEntrySymbol(propertyDescriptor, enumClass)
|
val entrySymbol = fundCorrespondingEnumEntrySymbol(propertyDescriptor, enumClass)
|
||||||
return createProperty(propertyDescriptor).also {
|
return createProperty(propertyDescriptor).also {
|
||||||
it.getter!!.body = generateAliasGetterBody(it.getter!!, entrySymbol, enumClass)
|
postLinkageSteps.add {
|
||||||
|
it.getter!!.body = generateAliasGetterBody(it.getter!!, entrySymbol, enumClass)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+20
-13
@@ -34,6 +34,7 @@ internal class CEnumVarClassGenerator(
|
|||||||
override val irBuiltIns: IrBuiltIns = context.irBuiltIns
|
override val irBuiltIns: IrBuiltIns = context.irBuiltIns
|
||||||
override val symbolTable: SymbolTable = context.symbolTable
|
override val symbolTable: SymbolTable = context.symbolTable
|
||||||
override val typeTranslator: TypeTranslator = context.typeTranslator
|
override val typeTranslator: TypeTranslator = context.typeTranslator
|
||||||
|
override val postLinkageSteps: MutableList<() -> Unit> = mutableListOf()
|
||||||
|
|
||||||
fun generate(enumIrClass: IrClass): IrClass {
|
fun generate(enumIrClass: IrClass): IrClass {
|
||||||
val enumVarClassDescriptor = enumIrClass.descriptor.unsubstitutedMemberScope
|
val enumVarClassDescriptor = enumIrClass.descriptor.unsubstitutedMemberScope
|
||||||
@@ -56,13 +57,16 @@ internal class CEnumVarClassGenerator(
|
|||||||
val enumVarConstructorSymbol = symbolTable.referenceConstructor(
|
val enumVarConstructorSymbol = symbolTable.referenceConstructor(
|
||||||
interopBuiltIns.cEnumVar.unsubstitutedPrimaryConstructor!!
|
interopBuiltIns.cEnumVar.unsubstitutedPrimaryConstructor!!
|
||||||
)
|
)
|
||||||
irConstructor.body = irBuilder(irBuiltIns, irConstructor.symbol, SYNTHETIC_OFFSET, SYNTHETIC_OFFSET).irBlockBody {
|
val classSymbol = symbolTable.referenceClass(enumVarClass.descriptor)
|
||||||
+IrDelegatingConstructorCallImpl.fromSymbolDescriptor(
|
postLinkageSteps.add {
|
||||||
startOffset, endOffset, context.irBuiltIns.unitType, enumVarConstructorSymbol
|
irConstructor.body = irBuilder(irBuiltIns, irConstructor.symbol, SYNTHETIC_OFFSET, SYNTHETIC_OFFSET).irBlockBody {
|
||||||
).also {
|
+IrDelegatingConstructorCallImpl.fromSymbolOwner(
|
||||||
it.putValueArgument(0, irGet(irConstructor.valueParameters[0]))
|
startOffset, endOffset, context.irBuiltIns.unitType, enumVarConstructorSymbol
|
||||||
|
).also {
|
||||||
|
it.putValueArgument(0, irGet(irConstructor.valueParameters[0]))
|
||||||
|
}
|
||||||
|
+irInstanceInitializer(classSymbol)
|
||||||
}
|
}
|
||||||
+irInstanceInitializer(symbolTable.referenceClass(enumVarClass.descriptor))
|
|
||||||
}
|
}
|
||||||
return irConstructor
|
return irConstructor
|
||||||
}
|
}
|
||||||
@@ -77,15 +81,18 @@ internal class CEnumVarClassGenerator(
|
|||||||
|
|
||||||
private fun createCompanionConstructor(companionObjectDescriptor: ClassDescriptor, typeSize: Int): IrConstructor {
|
private fun createCompanionConstructor(companionObjectDescriptor: ClassDescriptor, typeSize: Int): IrConstructor {
|
||||||
val superConstructorSymbol = symbolTable.referenceConstructor(interopBuiltIns.cPrimitiveVarType.unsubstitutedPrimaryConstructor!!)
|
val superConstructorSymbol = symbolTable.referenceConstructor(interopBuiltIns.cPrimitiveVarType.unsubstitutedPrimaryConstructor!!)
|
||||||
|
val classSymbol = symbolTable.referenceClass(companionObjectDescriptor)
|
||||||
return createConstructor(companionObjectDescriptor.unsubstitutedPrimaryConstructor!!).also {
|
return createConstructor(companionObjectDescriptor.unsubstitutedPrimaryConstructor!!).also {
|
||||||
it.body = irBuilder(irBuiltIns, it.symbol, SYNTHETIC_OFFSET, SYNTHETIC_OFFSET).irBlockBody {
|
postLinkageSteps.add {
|
||||||
+IrDelegatingConstructorCallImpl.fromSymbolDescriptor(
|
it.body = irBuilder(irBuiltIns, it.symbol, SYNTHETIC_OFFSET, SYNTHETIC_OFFSET).irBlockBody {
|
||||||
startOffset, endOffset, context.irBuiltIns.unitType,
|
+IrDelegatingConstructorCallImpl.fromSymbolOwner(
|
||||||
superConstructorSymbol
|
startOffset, endOffset, context.irBuiltIns.unitType,
|
||||||
).also {
|
superConstructorSymbol
|
||||||
it.putValueArgument(0, irInt(typeSize))
|
).also {
|
||||||
|
it.putValueArgument(0, irInt(typeSize))
|
||||||
|
}
|
||||||
|
+irInstanceInitializer(classSymbol)
|
||||||
}
|
}
|
||||||
+irInstanceInitializer(symbolTable.referenceClass(companionObjectDescriptor))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+12
-10
@@ -23,14 +23,14 @@ import org.jetbrains.kotlin.psi2ir.generators.GeneratorContext
|
|||||||
|
|
||||||
internal class CStructVarClassGenerator(
|
internal class CStructVarClassGenerator(
|
||||||
context: GeneratorContext,
|
context: GeneratorContext,
|
||||||
private val interopBuiltIns: InteropBuiltIns
|
private val interopBuiltIns: InteropBuiltIns,
|
||||||
|
private val companionGenerator: CStructVarCompanionGenerator
|
||||||
) : DescriptorToIrTranslationMixin {
|
) : DescriptorToIrTranslationMixin {
|
||||||
|
|
||||||
override val irBuiltIns: IrBuiltIns = context.irBuiltIns
|
override val irBuiltIns: IrBuiltIns = context.irBuiltIns
|
||||||
override val symbolTable: SymbolTable = context.symbolTable
|
override val symbolTable: SymbolTable = context.symbolTable
|
||||||
override val typeTranslator: TypeTranslator = context.typeTranslator
|
override val typeTranslator: TypeTranslator = context.typeTranslator
|
||||||
|
override val postLinkageSteps: MutableList<() -> Unit> = mutableListOf()
|
||||||
private val companionGenerator = CStructVarCompanionGenerator(context, interopBuiltIns)
|
|
||||||
|
|
||||||
fun findOrGenerateCStruct(classDescriptor: ClassDescriptor, parent: IrDeclarationContainer): IrClass {
|
fun findOrGenerateCStruct(classDescriptor: ClassDescriptor, parent: IrDeclarationContainer): IrClass {
|
||||||
val irClassSymbol = symbolTable.referenceClass(classDescriptor)
|
val irClassSymbol = symbolTable.referenceClass(classDescriptor)
|
||||||
@@ -61,14 +61,16 @@ internal class CStructVarClassGenerator(
|
|||||||
interopBuiltIns.cStructVar.unsubstitutedPrimaryConstructor!!
|
interopBuiltIns.cStructVar.unsubstitutedPrimaryConstructor!!
|
||||||
)
|
)
|
||||||
return createConstructor(irClass.descriptor.unsubstitutedPrimaryConstructor!!).also { irConstructor ->
|
return createConstructor(irClass.descriptor.unsubstitutedPrimaryConstructor!!).also { irConstructor ->
|
||||||
irConstructor.body = irBuilder(irBuiltIns, irConstructor.symbol, SYNTHETIC_OFFSET, SYNTHETIC_OFFSET).irBlockBody {
|
postLinkageSteps.add {
|
||||||
+IrDelegatingConstructorCallImpl.fromSymbolDescriptor(
|
irConstructor.body = irBuilder(irBuiltIns, irConstructor.symbol, SYNTHETIC_OFFSET, SYNTHETIC_OFFSET).irBlockBody {
|
||||||
startOffset, endOffset,
|
+IrDelegatingConstructorCallImpl.fromSymbolOwner(
|
||||||
context.irBuiltIns.unitType, enumVarConstructorSymbol
|
startOffset, endOffset,
|
||||||
).also {
|
context.irBuiltIns.unitType, enumVarConstructorSymbol
|
||||||
it.putValueArgument(0, irGet(irConstructor.valueParameters[0]))
|
).also {
|
||||||
|
it.putValueArgument(0, irGet(irConstructor.valueParameters[0]))
|
||||||
|
}
|
||||||
|
+irInstanceInitializer(symbolTable.referenceClass(irClass.descriptor))
|
||||||
}
|
}
|
||||||
+irInstanceInitializer(symbolTable.referenceClass(irClass.descriptor))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+11
-8
@@ -32,6 +32,7 @@ internal class CStructVarCompanionGenerator(
|
|||||||
override val irBuiltIns: IrBuiltIns = context.irBuiltIns
|
override val irBuiltIns: IrBuiltIns = context.irBuiltIns
|
||||||
override val symbolTable: SymbolTable = context.symbolTable
|
override val symbolTable: SymbolTable = context.symbolTable
|
||||||
override val typeTranslator: TypeTranslator = context.typeTranslator
|
override val typeTranslator: TypeTranslator = context.typeTranslator
|
||||||
|
override val postLinkageSteps: MutableList<() -> Unit> = mutableListOf()
|
||||||
|
|
||||||
fun generate(structDescriptor: ClassDescriptor): IrClass =
|
fun generate(structDescriptor: ClassDescriptor): IrClass =
|
||||||
createClass(structDescriptor.companionObjectDescriptor!!) { companionIrClass ->
|
createClass(structDescriptor.companionObjectDescriptor!!) { companionIrClass ->
|
||||||
@@ -45,15 +46,17 @@ internal class CStructVarCompanionGenerator(
|
|||||||
private fun createCompanionConstructor(companionObjectDescriptor: ClassDescriptor, size: Long, align: Int): IrConstructor {
|
private fun createCompanionConstructor(companionObjectDescriptor: ClassDescriptor, size: Long, align: Int): IrConstructor {
|
||||||
val superConstructorSymbol = symbolTable.referenceConstructor(interopBuiltIns.cStructVarType.unsubstitutedPrimaryConstructor!!)
|
val superConstructorSymbol = symbolTable.referenceConstructor(interopBuiltIns.cStructVarType.unsubstitutedPrimaryConstructor!!)
|
||||||
return createConstructor(companionObjectDescriptor.unsubstitutedPrimaryConstructor!!).also { irConstructor ->
|
return createConstructor(companionObjectDescriptor.unsubstitutedPrimaryConstructor!!).also { irConstructor ->
|
||||||
irConstructor.body = irBuilder(irBuiltIns, irConstructor.symbol, SYNTHETIC_OFFSET, SYNTHETIC_OFFSET).irBlockBody {
|
postLinkageSteps.add {
|
||||||
+IrDelegatingConstructorCallImpl.fromSymbolDescriptor(
|
irConstructor.body = irBuilder(irBuiltIns, irConstructor.symbol, SYNTHETIC_OFFSET, SYNTHETIC_OFFSET).irBlockBody {
|
||||||
startOffset, endOffset, context.irBuiltIns.unitType,
|
+IrDelegatingConstructorCallImpl.fromSymbolOwner(
|
||||||
superConstructorSymbol
|
startOffset, endOffset, context.irBuiltIns.unitType,
|
||||||
).also {
|
superConstructorSymbol
|
||||||
it.putValueArgument(0, irLong(size))
|
).also {
|
||||||
it.putValueArgument(1, irInt(align))
|
it.putValueArgument(0, irLong(size))
|
||||||
|
it.putValueArgument(1, irInt(align))
|
||||||
|
}
|
||||||
|
+irInstanceInitializer(symbolTable.referenceClass(companionObjectDescriptor))
|
||||||
}
|
}
|
||||||
+irInstanceInitializer(symbolTable.referenceClass(companionObjectDescriptor))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user