From 504d72011ba51d1e803415a34c8ddf779e4b586c Mon Sep 17 00:00:00 2001 From: Pavel Kunyavskiy Date: Thu, 15 Jul 2021 16:45:23 +0300 Subject: [PATCH] [K/N] Transform FunctionReference without bound values to ConstantValue --- .../konan/lower/FunctionReferenceLowering.kt | 59 +++++++++++-------- .../tests/runtime/exceptions/custom_hook.kt | 3 +- .../tests/runtime/workers/worker9.kt | 6 +- 3 files changed, 42 insertions(+), 26 deletions(-) diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/FunctionReferenceLowering.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/FunctionReferenceLowering.kt index 38aa7c28752..ebdfaabd483 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/FunctionReferenceLowering.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/FunctionReferenceLowering.kt @@ -146,38 +146,33 @@ internal class FunctionReferenceLowering(val context: Context): FileLoweringPass fun transformFunctionReference(expression: IrFunctionReference, samSuperType: IrType? = null): IrExpression { 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, expression.startOffset, expression.endOffset) - return irBuilder.irCall(loweredFunctionReference.functionReferenceConstructor.symbol).apply { - expression.getArguments().forEachIndexed { index, argument -> - putValueArgument(index, argument.second) - } - } + val (clazz, newExpression) = FunctionReferenceBuilder(irFile, parent, expression, context, irBuilder, samSuperType).build() + generatedClasses.add(clazz) + return newExpression } }, data = null) 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 symbols = context.ir.symbols - private val irBuiltIns = context.irBuiltIns - private val getContinuationSymbol = symbols.getContinuation - private val continuationClassSymbol = getContinuationSymbol.owner.returnType.classifierOrFail as IrClassSymbol - - private inner class FunctionReferenceBuilder( + class FunctionReferenceBuilder( val irFile: IrFile, val parent: IrDeclarationParent, 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 endOffset = functionReference.endOffset private val referencedFunction = functionReference.symbol.owner @@ -243,7 +238,7 @@ internal class FunctionReferenceLowering(val context: Context): FileLoweringPass private val kSuspendFunctionImplSymbol = symbols.kSuspendFunctionImpl private val kSuspendFunctionImplConstructorSymbol = kSuspendFunctionImplSymbol.constructors.single() - fun build(): BuiltFunctionReference { + private fun buildClass(): IrClass { val superClass = when { isKSuspendFunction -> kSuspendFunctionImplSymbol.typeWith(referencedFunction.returnType) isLambda -> irBuiltIns.anyType @@ -296,11 +291,11 @@ internal class FunctionReferenceLowering(val context: Context): FileLoweringPass functionReferenceClass.addFakeOverrides(context.typeSystem) - return BuiltFunctionReference(functionReferenceClass, buildConstructor()) + return functionReferenceClass } - private fun buildConstructor(): IrConstructor = - IrConstructorImpl( + private fun buildConstructor(): IrConstructor { + return IrConstructorImpl( startOffset, endOffset, DECLARATION_ORIGIN_FUNCTION_REFERENCE_IMPL, 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() = (if (referencedFunction.isSuspend) 1 else 0) + getAdaptedCallableReferenceFlags() shl 1 @@ -385,8 +397,8 @@ internal class FunctionReferenceLowering(val context: Context): FileLoweringPass return false } - private fun buildInvokeMethod(superFunction: IrSimpleFunction): IrSimpleFunction = - IrFunctionImpl( + private fun buildInvokeMethod(superFunction: IrSimpleFunction): IrSimpleFunction { + return IrFunctionImpl( startOffset, endOffset, DECLARATION_ORIGIN_FUNCTION_REFERENCE_IMPL, IrSimpleFunctionSymbolImpl(), @@ -452,5 +464,6 @@ internal class FunctionReferenceLowering(val context: Context): FileLoweringPass ) } } + } } } diff --git a/kotlin-native/backend.native/tests/runtime/exceptions/custom_hook.kt b/kotlin-native/backend.native/tests/runtime/exceptions/custom_hook.kt index 7cb9a179687..077295073b4 100644 --- a/kotlin-native/backend.native/tests/runtime/exceptions/custom_hook.kt +++ b/kotlin-native/backend.native/tests/runtime/exceptions/custom_hook.kt @@ -8,8 +8,9 @@ import kotlin.native.concurrent.* import kotlin.native.internal.* fun mainLegacyMM() { + val wrong = "wrong" assertFailsWith { - setUnhandledExceptionHook { _ -> println("wrong") } + setUnhandledExceptionHook { _ -> println(wrong) } } val x = 42 diff --git a/kotlin-native/backend.native/tests/runtime/workers/worker9.kt b/kotlin-native/backend.native/tests/runtime/workers/worker9.kt index 930b851d95d..7dbed3563d3 100644 --- a/kotlin-native/backend.native/tests/runtime/workers/worker9.kt +++ b/kotlin-native/backend.native/tests/runtime/workers/worker9.kt @@ -49,14 +49,16 @@ fun withLock(op: () -> Unit) { } } else { assertFailsWith { + val message = "shall not happen" worker.executeAfter { - println("shall not happen") + println(message) } } } assertFailsWith { + val message = "shall not happen" worker.executeAfter(-1, { - println("shall not happen") + println(message) }.freeze()) }