From cd840997b1154b3df8f4a11bb75f12a402790c39 Mon Sep 17 00:00:00 2001 From: Artem Kobzar Date: Tue, 1 Aug 2023 11:53:14 +0000 Subject: [PATCH] [K/Wasm] Rework Wasm enumEntriesIntrinsic declaration to fix stdlib compilation --- .../common/lower/inline/FunctionInlining.kt | 9 ++++----- .../SaveInlineFunctionsBeforeInlining.kt | 7 +++++-- .../kotlin/backend/wasm/WasmLoweringPhases.kt | 1 + .../wasm/lower/WasmInlineFunctionResolver.kt | 19 +++++++++++++++++++ .../wasm/src/kotlin/enums/EnumEntriesWasm.kt | 10 +++++++--- 5 files changed, 36 insertions(+), 10 deletions(-) create mode 100644 compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/lower/WasmInlineFunctionResolver.kt diff --git a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/inline/FunctionInlining.kt b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/inline/FunctionInlining.kt index d2f97909952..19609b631e5 100644 --- a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/inline/FunctionInlining.kt +++ b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/inline/FunctionInlining.kt @@ -45,6 +45,9 @@ fun IrExpression.isAdaptedFunctionReference() = interface InlineFunctionResolver { fun getFunctionDeclaration(symbol: IrFunctionSymbol): IrFunction fun getFunctionSymbol(irFunction: IrFunction): IrFunctionSymbol + fun shouldExcludeFunctionFromInlining(symbol: IrFunctionSymbol): Boolean { + return Symbols.isLateinitIsInitializedPropertyGetter(symbol) || Symbols.isTypeOfIntrinsic(symbol) + } } fun IrFunction.isTopLevelInPackage(name: String, packageName: String): Boolean { @@ -112,11 +115,7 @@ class FunctionInlining( is IrConstructorCall -> expression.symbol.owner else -> return expression } - if (!callee.needsInlining) - return expression - if (Symbols.isLateinitIsInitializedPropertyGetter(callee.symbol)) - return expression - if (Symbols.isTypeOfIntrinsic(callee.symbol)) + if (!callee.needsInlining || inlineFunctionResolver.shouldExcludeFunctionFromInlining(callee.symbol)) return expression val actualCallee = inlineFunctionResolver.getFunctionDeclaration(callee.symbol) diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/inline/SaveInlineFunctionsBeforeInlining.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/inline/SaveInlineFunctionsBeforeInlining.kt index c06bddb00e7..ebd3c734947 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/inline/SaveInlineFunctionsBeforeInlining.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/inline/SaveInlineFunctionsBeforeInlining.kt @@ -33,10 +33,13 @@ internal class JsInlineFunctionResolver(context: JsIrBackendContext) : DefaultIn private val inlineFunctionsBeforeInlining = context.mapping.inlineFunctionsBeforeInlining private val inlineFunctionsBeforeInliningSymbols = hashMapOf() + override fun shouldExcludeFunctionFromInlining(symbol: IrFunctionSymbol): Boolean { + // TODO: After the expect fun enumEntriesIntrinsic become non-inline function, the code will be removed + return symbol == enumEntriesIntrinsic || super.shouldExcludeFunctionFromInlining(symbol) + } + override fun getFunctionDeclaration(symbol: IrFunctionSymbol): IrFunction { val function = super.getFunctionDeclaration(symbol) - // TODO: After the expect fun enumEntriesIntrinsic become non-inline function, the code will be removed - if (function.symbol == enumEntriesIntrinsic) return function.apply { body = null } val functionBeforeInlining = inlineFunctionsBeforeInlining[function] ?: return function inlineFunctionsBeforeInliningSymbols[functionBeforeInlining] = function.symbol return functionBeforeInlining diff --git a/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/WasmLoweringPhases.kt b/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/WasmLoweringPhases.kt index 2ee8b641573..7dcc91a3289 100644 --- a/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/WasmLoweringPhases.kt +++ b/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/WasmLoweringPhases.kt @@ -169,6 +169,7 @@ private val functionInliningPhase = makeCustomWasmModulePhase( FunctionInlining( context = context, innerClassesSupport = context.innerClassesSupport, + inlineFunctionResolver = WasmInlineFunctionResolver(context), insertAdditionalImplicitCasts = true, ).inline(module) module.patchDeclarationParents() diff --git a/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/lower/WasmInlineFunctionResolver.kt b/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/lower/WasmInlineFunctionResolver.kt new file mode 100644 index 00000000000..2c00bc68d72 --- /dev/null +++ b/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/lower/WasmInlineFunctionResolver.kt @@ -0,0 +1,19 @@ +/* + * Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.backend.wasm.lower + +import org.jetbrains.kotlin.backend.common.lower.inline.DefaultInlineFunctionResolver +import org.jetbrains.kotlin.backend.wasm.WasmBackendContext +import org.jetbrains.kotlin.ir.symbols.IrFunctionSymbol + +class WasmInlineFunctionResolver(context: WasmBackendContext) : DefaultInlineFunctionResolver(context) { + private val enumEntriesIntrinsic = context.wasmSymbols.enumEntriesIntrinsic + + override fun shouldExcludeFunctionFromInlining(symbol: IrFunctionSymbol): Boolean { + // TODO: After the expect fun enumEntriesIntrinsic become non-inline function, the code will be removed + return symbol == enumEntriesIntrinsic || super.shouldExcludeFunctionFromInlining(symbol) + } +} \ No newline at end of file diff --git a/libraries/stdlib/wasm/src/kotlin/enums/EnumEntriesWasm.kt b/libraries/stdlib/wasm/src/kotlin/enums/EnumEntriesWasm.kt index 63580ed1a3e..5b9ed35e62a 100644 --- a/libraries/stdlib/wasm/src/kotlin/enums/EnumEntriesWasm.kt +++ b/libraries/stdlib/wasm/src/kotlin/enums/EnumEntriesWasm.kt @@ -8,6 +8,10 @@ package kotlin.enums @SinceKotlin("1.9") @ExperimentalStdlibApi @PublishedApi -// TODO: After the expect fun enumEntriesIntrinsic become non-inline function, the suppress and external keyword should be removed -@Suppress("INLINE_EXTERNAL_DECLARATION", "WRONG_JS_INTEROP_TYPE") -internal actual external inline fun > enumEntriesIntrinsic(): EnumEntries \ No newline at end of file +internal actual inline fun > enumEntriesIntrinsic(): EnumEntries { + /* + * Implementation note: this body will be replaced with `throw NotImplementedException()` the moment + * all backends starts intrinsifying this call. + */ + return enumEntries(enumValues()) +} \ No newline at end of file