Moved box & unbox functions one level up
This commit is contained in:
+7
-4
@@ -14,6 +14,7 @@ import org.jetbrains.kotlin.descriptors.Modality
|
|||||||
import org.jetbrains.kotlin.descriptors.Visibilities
|
import org.jetbrains.kotlin.descriptors.Visibilities
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrClass
|
import org.jetbrains.kotlin.ir.declarations.IrClass
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrDeclarationOrigin
|
import org.jetbrains.kotlin.ir.declarations.IrDeclarationOrigin
|
||||||
|
import org.jetbrains.kotlin.ir.declarations.IrFile
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction
|
import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction
|
||||||
import org.jetbrains.kotlin.ir.declarations.impl.IrFunctionImpl
|
import org.jetbrains.kotlin.ir.declarations.impl.IrFunctionImpl
|
||||||
import org.jetbrains.kotlin.ir.declarations.impl.IrValueParameterImpl
|
import org.jetbrains.kotlin.ir.declarations.impl.IrValueParameterImpl
|
||||||
@@ -45,6 +46,7 @@ private fun KonanSymbols.getTypeConversionImpl(
|
|||||||
|
|
||||||
internal val Context.getBoxFunction: (IrClass) -> IrSimpleFunction by Context.lazyMapMember { inlinedClass ->
|
internal val Context.getBoxFunction: (IrClass) -> IrSimpleFunction by Context.lazyMapMember { inlinedClass ->
|
||||||
assert(inlinedClass.isUsedAsBoxClass())
|
assert(inlinedClass.isUsedAsBoxClass())
|
||||||
|
assert(inlinedClass.parent is IrFile) { "Expected top level inline class" }
|
||||||
|
|
||||||
val symbols = ir.symbols
|
val symbols = ir.symbols
|
||||||
|
|
||||||
@@ -63,7 +65,7 @@ internal val Context.getBoxFunction: (IrClass) -> IrSimpleFunction by Context.la
|
|||||||
startOffset, endOffset,
|
startOffset, endOffset,
|
||||||
IrDeclarationOrigin.DEFINED,
|
IrDeclarationOrigin.DEFINED,
|
||||||
IrSimpleFunctionSymbolImpl(descriptor),
|
IrSimpleFunctionSymbolImpl(descriptor),
|
||||||
Name.special("<box>"),
|
Name.special("<${inlinedClass.name}-box>"),
|
||||||
Visibilities.PUBLIC,
|
Visibilities.PUBLIC,
|
||||||
Modality.FINAL,
|
Modality.FINAL,
|
||||||
returnType,
|
returnType,
|
||||||
@@ -89,12 +91,13 @@ internal val Context.getBoxFunction: (IrClass) -> IrSimpleFunction by Context.la
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
descriptor.bind(function)
|
descriptor.bind(function)
|
||||||
function.parent = inlinedClass
|
function.parent = inlinedClass.getContainingFile()!!
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal val Context.getUnboxFunction: (IrClass) -> IrSimpleFunction by Context.lazyMapMember { inlinedClass ->
|
internal val Context.getUnboxFunction: (IrClass) -> IrSimpleFunction by Context.lazyMapMember { inlinedClass ->
|
||||||
assert(inlinedClass.isUsedAsBoxClass())
|
assert(inlinedClass.isUsedAsBoxClass())
|
||||||
|
assert(inlinedClass.parent is IrFile) { "Expected top level inline class" }
|
||||||
|
|
||||||
val symbols = ir.symbols
|
val symbols = ir.symbols
|
||||||
|
|
||||||
@@ -113,7 +116,7 @@ internal val Context.getUnboxFunction: (IrClass) -> IrSimpleFunction by Context.
|
|||||||
startOffset, endOffset,
|
startOffset, endOffset,
|
||||||
IrDeclarationOrigin.DEFINED,
|
IrDeclarationOrigin.DEFINED,
|
||||||
IrSimpleFunctionSymbolImpl(descriptor),
|
IrSimpleFunctionSymbolImpl(descriptor),
|
||||||
Name.special("<unbox>"),
|
Name.special("<${inlinedClass.name}-unbox>"),
|
||||||
Visibilities.PUBLIC,
|
Visibilities.PUBLIC,
|
||||||
Modality.FINAL,
|
Modality.FINAL,
|
||||||
returnType,
|
returnType,
|
||||||
@@ -139,7 +142,7 @@ internal val Context.getUnboxFunction: (IrClass) -> IrSimpleFunction by Context.
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
descriptor.bind(function)
|
descriptor.bind(function)
|
||||||
function.parent = inlinedClass
|
function.parent = inlinedClass.getContainingFile()!!
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+12
-4
@@ -17,7 +17,6 @@ import org.jetbrains.kotlin.backend.konan.descriptors.target
|
|||||||
import org.jetbrains.kotlin.backend.konan.ir.*
|
import org.jetbrains.kotlin.backend.konan.ir.*
|
||||||
import org.jetbrains.kotlin.descriptors.Modality
|
import org.jetbrains.kotlin.descriptors.Modality
|
||||||
import org.jetbrains.kotlin.descriptors.Visibilities
|
import org.jetbrains.kotlin.descriptors.Visibilities
|
||||||
import org.jetbrains.kotlin.ir.IrElement
|
|
||||||
import org.jetbrains.kotlin.ir.IrStatement
|
import org.jetbrains.kotlin.ir.IrStatement
|
||||||
import org.jetbrains.kotlin.ir.builders.*
|
import org.jetbrains.kotlin.ir.builders.*
|
||||||
import org.jetbrains.kotlin.ir.declarations.*
|
import org.jetbrains.kotlin.ir.declarations.*
|
||||||
@@ -46,7 +45,7 @@ internal class Autoboxing(val context: Context) : FileLoweringPass {
|
|||||||
|
|
||||||
override fun lower(irFile: IrFile) {
|
override fun lower(irFile: IrFile) {
|
||||||
irFile.transformChildrenVoid(transformer)
|
irFile.transformChildrenVoid(transformer)
|
||||||
irFile.transformChildrenVoid(InlineClassTransformer(context))
|
irFile.transform(InlineClassTransformer(context), data = null)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -213,6 +212,15 @@ private class InlineClassTransformer(private val context: Context) : IrBuildingT
|
|||||||
private val symbols = context.ir.symbols
|
private val symbols = context.ir.symbols
|
||||||
private val irBuiltIns = context.irBuiltIns
|
private val irBuiltIns = context.irBuiltIns
|
||||||
|
|
||||||
|
private val builtBoxUnboxFunctions = mutableListOf<IrFunction>()
|
||||||
|
|
||||||
|
override fun visitFile(declaration: IrFile): IrFile {
|
||||||
|
declaration.transformChildrenVoid(this)
|
||||||
|
declaration.declarations.addAll(builtBoxUnboxFunctions)
|
||||||
|
builtBoxUnboxFunctions.clear()
|
||||||
|
return declaration
|
||||||
|
}
|
||||||
|
|
||||||
override fun visitClass(declaration: IrClass): IrStatement {
|
override fun visitClass(declaration: IrClass): IrStatement {
|
||||||
super.visitClass(declaration)
|
super.visitClass(declaration)
|
||||||
|
|
||||||
@@ -341,7 +349,7 @@ private class InlineClassTransformer(private val context: Context) : IrBuildingT
|
|||||||
+irReturn(irGet(box))
|
+irReturn(irGet(box))
|
||||||
}
|
}
|
||||||
|
|
||||||
irClass.declarations += function
|
builtBoxUnboxFunctions += function
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun IrBuilderWithScope.irNullPointerOrReference(type: IrType): IrExpression =
|
private fun IrBuilderWithScope.irNullPointerOrReference(type: IrType): IrExpression =
|
||||||
@@ -367,7 +375,7 @@ private class InlineClassTransformer(private val context: Context) : IrBuildingT
|
|||||||
+irReturn(irGetField(irGet(boxParameter), getInlineClassBackingField(irClass)))
|
+irReturn(irGetField(irGet(boxParameter), getInlineClassBackingField(irClass)))
|
||||||
}
|
}
|
||||||
|
|
||||||
irClass.declarations += function
|
builtBoxUnboxFunctions += function
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun buildBoxField(declaration: IrClass) {
|
private fun buildBoxField(declaration: IrClass) {
|
||||||
|
|||||||
+1
-1
@@ -642,7 +642,7 @@ internal object DataFlowIR {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private val IrFunction.isSpecial get() =
|
private val IrFunction.isSpecial get() =
|
||||||
name.asString().let { it.startsWith("<bridge-") || it == "<box>" || it == "<unbox>" }
|
name.asString().let { it.startsWith("<bridge-") || it.endsWith("-box>") || it.endsWith("-unbox>") }
|
||||||
|
|
||||||
private fun mapPropertyInitializer(irField: IrField): FunctionSymbol {
|
private fun mapPropertyInitializer(irField: IrField): FunctionSymbol {
|
||||||
functionMap[irField]?.let { return it }
|
functionMap[irField]?.let { return it }
|
||||||
|
|||||||
+12
-4
@@ -1033,10 +1033,10 @@ internal object Devirtualization {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private val specialNames = listOf("<box>", "<unbox>")
|
private val specialNames = listOf("-box>", "-unbox>")
|
||||||
|
|
||||||
// TODO: do it more reliably.
|
// TODO: do it more reliably.
|
||||||
private fun IrExpression.isBoxOrUnboxCall() = (this is IrCall && symbol.owner.name.asString().let { specialNames.contains(it) })
|
private fun IrExpression.isBoxOrUnboxCall() = (this is IrCall && symbol.owner.name.asString().let { name -> specialNames.any { name.endsWith(it) } })
|
||||||
|
|
||||||
private fun devirtualize(irModule: IrModuleFragment, context: Context, externalModulesDFG: ExternalModulesDFG,
|
private fun devirtualize(irModule: IrModuleFragment, context: Context, externalModulesDFG: ExternalModulesDFG,
|
||||||
devirtualizedCallSites: Map<IrCall, DevirtualizedCallSite>) {
|
devirtualizedCallSites: Map<IrCall, DevirtualizedCallSite>) {
|
||||||
@@ -1356,6 +1356,14 @@ internal object Devirtualization {
|
|||||||
|
|
||||||
irModule.transformChildrenVoid(object: IrElementTransformerVoid() {
|
irModule.transformChildrenVoid(object: IrElementTransformerVoid() {
|
||||||
|
|
||||||
|
fun IrFunction.getCoercedClass(): IrClassifierSymbol {
|
||||||
|
if (name.asString().endsWith("-box>"))
|
||||||
|
return valueParameters[0].type.classifierOrFail
|
||||||
|
if (name.asString().endsWith("-unbox>"))
|
||||||
|
return returnType.classifierOrFail
|
||||||
|
error("Unexpected coercion: ${this.dump()}")
|
||||||
|
}
|
||||||
|
|
||||||
fun fold(expression: IrExpression, coercion: IrCall, cast: IrTypeOperatorCall?,
|
fun fold(expression: IrExpression, coercion: IrCall, cast: IrTypeOperatorCall?,
|
||||||
transformRecursively: Boolean): PossiblyFoldedExpression {
|
transformRecursively: Boolean): PossiblyFoldedExpression {
|
||||||
|
|
||||||
@@ -1367,11 +1375,11 @@ internal object Devirtualization {
|
|||||||
fun IrElement.transformIfAsked() =
|
fun IrElement.transformIfAsked() =
|
||||||
if (transformRecursively) this.transform(transformer, data = null) else this
|
if (transformRecursively) this.transform(transformer, data = null) else this
|
||||||
|
|
||||||
val coercionDeclaringClass = coercion.symbol.owner.parentAsClass
|
val coercionDeclaringClass = coercion.symbol.owner.getCoercedClass()
|
||||||
if (expression.isBoxOrUnboxCall()) {
|
if (expression.isBoxOrUnboxCall()) {
|
||||||
expression as IrCall
|
expression as IrCall
|
||||||
val result =
|
val result =
|
||||||
if (coercionDeclaringClass == expression.symbol.owner.parentAsClass)
|
if (coercionDeclaringClass == expression.symbol.owner.getCoercedClass())
|
||||||
expression.getArguments().single().second
|
expression.getArguments().single().second
|
||||||
else expression
|
else expression
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user