[K/N] Transform FunctionReference without bound values to ConstantValue

This commit is contained in:
Pavel Kunyavskiy
2021-07-15 16:45:23 +03:00
committed by Space
parent e4a4cd3e16
commit 504d72011b
3 changed files with 42 additions and 26 deletions
@@ -146,38 +146,33 @@ internal class FunctionReferenceLowering(val context: Context): FileLoweringPass
fun transformFunctionReference(expression: IrFunctionReference, samSuperType: IrType? = null): IrExpression { fun transformFunctionReference(expression: IrFunctionReference, samSuperType: IrType? = null): IrExpression {
val parent: IrDeclarationContainer = (currentClass?.irElement as? IrClass) ?: irFile val parent: IrDeclarationContainer = (currentClass?.irElement as? IrClass) ?: irFile
val loweredFunctionReference = FunctionReferenceBuilder(irFile, parent, expression, samSuperType).build()
generatedClasses.add(loweredFunctionReference.functionReferenceClass)
val irBuilder = context.createIrBuilder(currentScope!!.scope.scopeOwnerSymbol, val irBuilder = context.createIrBuilder(currentScope!!.scope.scopeOwnerSymbol,
expression.startOffset, expression.endOffset) expression.startOffset, expression.endOffset)
return irBuilder.irCall(loweredFunctionReference.functionReferenceConstructor.symbol).apply { val (clazz, newExpression) = FunctionReferenceBuilder(irFile, parent, expression, context, irBuilder, samSuperType).build()
expression.getArguments().forEachIndexed { index, argument -> generatedClasses.add(clazz)
putValueArgument(index, argument.second) return newExpression
}
}
} }
}, data = null) }, data = null)
irFile.declarations += generatedClasses irFile.declarations += generatedClasses
} }
private class BuiltFunctionReference(val functionReferenceClass: IrClass,
val functionReferenceConstructor: IrConstructor)
private val VOLATILE_LAMBDA_FQ_NAME = FqName.fromSegments(listOf("kotlin", "native", "internal", "VolatileLambda")) private val VOLATILE_LAMBDA_FQ_NAME = FqName.fromSegments(listOf("kotlin", "native", "internal", "VolatileLambda"))
private val symbols = context.ir.symbols
private val irBuiltIns = context.irBuiltIns
private val getContinuationSymbol = symbols.getContinuation class FunctionReferenceBuilder(
private val continuationClassSymbol = getContinuationSymbol.owner.returnType.classifierOrFail as IrClassSymbol
private inner class FunctionReferenceBuilder(
val irFile: IrFile, val irFile: IrFile,
val parent: IrDeclarationParent, val parent: IrDeclarationParent,
val functionReference: IrFunctionReference, val functionReference: IrFunctionReference,
val samSuperType: IrType? val context: Context,
val irBuilder: IrBuilderWithScope,
val samSuperType: IrType? = null,
) { ) {
data class BuiltFunctionReference(val functionReferenceClass: IrClass, val functionReferenceExpression: IrExpression)
private val irBuiltIns = context.irBuiltIns
private val symbols = context.ir.symbols
private val getContinuationSymbol = symbols.getContinuation
private val continuationClassSymbol = getContinuationSymbol.owner.returnType.classifierOrFail as IrClassSymbol
private val startOffset = functionReference.startOffset private val startOffset = functionReference.startOffset
private val endOffset = functionReference.endOffset private val endOffset = functionReference.endOffset
private val referencedFunction = functionReference.symbol.owner private val referencedFunction = functionReference.symbol.owner
@@ -243,7 +238,7 @@ internal class FunctionReferenceLowering(val context: Context): FileLoweringPass
private val kSuspendFunctionImplSymbol = symbols.kSuspendFunctionImpl private val kSuspendFunctionImplSymbol = symbols.kSuspendFunctionImpl
private val kSuspendFunctionImplConstructorSymbol = kSuspendFunctionImplSymbol.constructors.single() private val kSuspendFunctionImplConstructorSymbol = kSuspendFunctionImplSymbol.constructors.single()
fun build(): BuiltFunctionReference { private fun buildClass(): IrClass {
val superClass = when { val superClass = when {
isKSuspendFunction -> kSuspendFunctionImplSymbol.typeWith(referencedFunction.returnType) isKSuspendFunction -> kSuspendFunctionImplSymbol.typeWith(referencedFunction.returnType)
isLambda -> irBuiltIns.anyType isLambda -> irBuiltIns.anyType
@@ -296,11 +291,11 @@ internal class FunctionReferenceLowering(val context: Context): FileLoweringPass
functionReferenceClass.addFakeOverrides(context.typeSystem) functionReferenceClass.addFakeOverrides(context.typeSystem)
return BuiltFunctionReference(functionReferenceClass, buildConstructor()) return functionReferenceClass
} }
private fun buildConstructor(): IrConstructor = private fun buildConstructor(): IrConstructor {
IrConstructorImpl( return IrConstructorImpl(
startOffset, endOffset, startOffset, endOffset,
DECLARATION_ORIGIN_FUNCTION_REFERENCE_IMPL, DECLARATION_ORIGIN_FUNCTION_REFERENCE_IMPL,
IrConstructorSymbolImpl(), IrConstructorSymbolImpl(),
@@ -348,6 +343,23 @@ internal class FunctionReferenceLowering(val context: Context): FileLoweringPass
} }
} }
} }
}
fun build(): BuiltFunctionReference {
val clazz = buildClass()
val constructor = buildConstructor()
val arguments = functionReference.getArguments()
val expression = if (arguments.isEmpty()) {
irBuilder.irConstantObject(clazz, emptyMap())
} else {
irBuilder.irCall(constructor).apply {
arguments.forEachIndexed { index, argument ->
putValueArgument(index, argument.second)
}
}
}
return BuiltFunctionReference(clazz, expression)
}
private fun getFlags() = private fun getFlags() =
(if (referencedFunction.isSuspend) 1 else 0) + getAdaptedCallableReferenceFlags() shl 1 (if (referencedFunction.isSuspend) 1 else 0) + getAdaptedCallableReferenceFlags() shl 1
@@ -385,8 +397,8 @@ internal class FunctionReferenceLowering(val context: Context): FileLoweringPass
return false return false
} }
private fun buildInvokeMethod(superFunction: IrSimpleFunction): IrSimpleFunction = private fun buildInvokeMethod(superFunction: IrSimpleFunction): IrSimpleFunction {
IrFunctionImpl( return IrFunctionImpl(
startOffset, endOffset, startOffset, endOffset,
DECLARATION_ORIGIN_FUNCTION_REFERENCE_IMPL, DECLARATION_ORIGIN_FUNCTION_REFERENCE_IMPL,
IrSimpleFunctionSymbolImpl(), IrSimpleFunctionSymbolImpl(),
@@ -452,5 +464,6 @@ internal class FunctionReferenceLowering(val context: Context): FileLoweringPass
) )
} }
} }
}
} }
} }
@@ -8,8 +8,9 @@ import kotlin.native.concurrent.*
import kotlin.native.internal.* import kotlin.native.internal.*
fun mainLegacyMM() { fun mainLegacyMM() {
val wrong = "wrong"
assertFailsWith<InvalidMutabilityException> { assertFailsWith<InvalidMutabilityException> {
setUnhandledExceptionHook { _ -> println("wrong") } setUnhandledExceptionHook { _ -> println(wrong) }
} }
val x = 42 val x = 42
@@ -49,14 +49,16 @@ fun withLock(op: () -> Unit) {
} }
} else { } else {
assertFailsWith<IllegalStateException> { assertFailsWith<IllegalStateException> {
val message = "shall not happen"
worker.executeAfter { worker.executeAfter {
println("shall not happen") println(message)
} }
} }
} }
assertFailsWith<IllegalArgumentException> { assertFailsWith<IllegalArgumentException> {
val message = "shall not happen"
worker.executeAfter(-1, { worker.executeAfter(-1, {
println("shall not happen") println(message)
}.freeze()) }.freeze())
} }