Moved box & unbox functions one level up

This commit is contained in:
Igor Chevdar
2019-05-14 16:45:47 +03:00
parent 52c12dff82
commit b843c95b52
4 changed files with 32 additions and 13 deletions
@@ -14,6 +14,7 @@ import org.jetbrains.kotlin.descriptors.Modality
import org.jetbrains.kotlin.descriptors.Visibilities
import org.jetbrains.kotlin.ir.declarations.IrClass
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.impl.IrFunctionImpl
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 ->
assert(inlinedClass.isUsedAsBoxClass())
assert(inlinedClass.parent is IrFile) { "Expected top level inline class" }
val symbols = ir.symbols
@@ -63,7 +65,7 @@ internal val Context.getBoxFunction: (IrClass) -> IrSimpleFunction by Context.la
startOffset, endOffset,
IrDeclarationOrigin.DEFINED,
IrSimpleFunctionSymbolImpl(descriptor),
Name.special("<box>"),
Name.special("<${inlinedClass.name}-box>"),
Visibilities.PUBLIC,
Modality.FINAL,
returnType,
@@ -89,12 +91,13 @@ internal val Context.getBoxFunction: (IrClass) -> IrSimpleFunction by Context.la
}
})
descriptor.bind(function)
function.parent = inlinedClass
function.parent = inlinedClass.getContainingFile()!!
}
}
internal val Context.getUnboxFunction: (IrClass) -> IrSimpleFunction by Context.lazyMapMember { inlinedClass ->
assert(inlinedClass.isUsedAsBoxClass())
assert(inlinedClass.parent is IrFile) { "Expected top level inline class" }
val symbols = ir.symbols
@@ -113,7 +116,7 @@ internal val Context.getUnboxFunction: (IrClass) -> IrSimpleFunction by Context.
startOffset, endOffset,
IrDeclarationOrigin.DEFINED,
IrSimpleFunctionSymbolImpl(descriptor),
Name.special("<unbox>"),
Name.special("<${inlinedClass.name}-unbox>"),
Visibilities.PUBLIC,
Modality.FINAL,
returnType,
@@ -139,7 +142,7 @@ internal val Context.getUnboxFunction: (IrClass) -> IrSimpleFunction by Context.
}
})
descriptor.bind(function)
function.parent = inlinedClass
function.parent = inlinedClass.getContainingFile()!!
}
}
@@ -17,7 +17,6 @@ import org.jetbrains.kotlin.backend.konan.descriptors.target
import org.jetbrains.kotlin.backend.konan.ir.*
import org.jetbrains.kotlin.descriptors.Modality
import org.jetbrains.kotlin.descriptors.Visibilities
import org.jetbrains.kotlin.ir.IrElement
import org.jetbrains.kotlin.ir.IrStatement
import org.jetbrains.kotlin.ir.builders.*
import org.jetbrains.kotlin.ir.declarations.*
@@ -46,7 +45,7 @@ internal class Autoboxing(val context: Context) : FileLoweringPass {
override fun lower(irFile: IrFile) {
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 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 {
super.visitClass(declaration)
@@ -341,7 +349,7 @@ private class InlineClassTransformer(private val context: Context) : IrBuildingT
+irReturn(irGet(box))
}
irClass.declarations += function
builtBoxUnboxFunctions += function
}
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)))
}
irClass.declarations += function
builtBoxUnboxFunctions += function
}
private fun buildBoxField(declaration: IrClass) {
@@ -642,7 +642,7 @@ internal object DataFlowIR {
}
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 {
functionMap[irField]?.let { return it }
@@ -1033,10 +1033,10 @@ internal object Devirtualization {
}
}
private val specialNames = listOf("<box>", "<unbox>")
private val specialNames = listOf("-box>", "-unbox>")
// 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,
devirtualizedCallSites: Map<IrCall, DevirtualizedCallSite>) {
@@ -1356,6 +1356,14 @@ internal object Devirtualization {
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?,
transformRecursively: Boolean): PossiblyFoldedExpression {
@@ -1367,11 +1375,11 @@ internal object Devirtualization {
fun IrElement.transformIfAsked() =
if (transformRecursively) this.transform(transformer, data = null) else this
val coercionDeclaringClass = coercion.symbol.owner.parentAsClass
val coercionDeclaringClass = coercion.symbol.owner.getCoercedClass()
if (expression.isBoxOrUnboxCall()) {
expression as IrCall
val result =
if (coercionDeclaringClass == expression.symbol.owner.parentAsClass)
if (coercionDeclaringClass == expression.symbol.owner.getCoercedClass())
expression.getArguments().single().second
else expression