From c114afb55dcb6d3ffb82512875f7c9ea63e56243 Mon Sep 17 00:00:00 2001 From: Zalim Bashorov Date: Thu, 6 Apr 2023 15:03:04 +0200 Subject: [PATCH] [Wasm] export `__callFunction_*` only when a respective closure/lambda converter is used --- .../src/org/jetbrains/kotlin/backend/wasm/dce/Dce.kt | 3 +++ .../backend/wasm/dce/WasmUsefulDeclarationProcessor.kt | 6 ++++++ .../kotlin/backend/wasm/lower/JsInteropFunctionsLowering.kt | 2 ++ compiler/testData/codegen/box/size/add.kt | 4 ++-- compiler/testData/codegen/box/size/helloWorld.kt | 4 ++-- compiler/testData/codegen/box/size/helloWorldDOM.kt | 4 ++-- compiler/testData/codegen/box/size/ok.kt | 4 ++-- 7 files changed, 19 insertions(+), 8 deletions(-) diff --git a/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/dce/Dce.kt b/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/dce/Dce.kt index f8893065d97..c83a2db2aec 100644 --- a/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/dce/Dce.kt +++ b/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/dce/Dce.kt @@ -53,6 +53,9 @@ private fun buildRoots(modules: List, context: WasmBackendCont add(context.irBuiltIns.throwableClass.owner) add(context.mainCallsWrapperFunction) add(context.fieldInitFunction) + + // Remove all functions used to call a kotlin closure from JS side, reachable ones will be added back later. + removeAll(context.closureCallExports.values) } private inline fun List.onAllFiles(body: IrFile.() -> Unit) { diff --git a/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/dce/WasmUsefulDeclarationProcessor.kt b/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/dce/WasmUsefulDeclarationProcessor.kt index 8154e1e2a9c..9665cff507b 100644 --- a/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/dce/WasmUsefulDeclarationProcessor.kt +++ b/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/dce/WasmUsefulDeclarationProcessor.kt @@ -23,6 +23,10 @@ internal class WasmUsefulDeclarationProcessor( private val unitGetInstance: IrSimpleFunction = context.findUnitGetInstanceFunction() + // The mapping from function for wrapping a kotlin closure/lambda with JS closure to function used to call a kotlin closure from JS side. + private val kotlinClosureToJsClosureConvertFunToKotlinClosureCallFun = + context.kotlinClosureToJsConverters.entries.associate { (k, v) -> v to context.closureCallExports[k] } + override val bodyVisitor: BodyVisitorBase = object : BodyVisitorBase() { override fun visitConst(expression: IrConst<*>, data: IrDeclaration) = when (expression.kind) { is IrConstKind.Null -> expression.type.enqueueType(data, "expression type") @@ -160,6 +164,8 @@ internal class WasmUsefulDeclarationProcessor( irFunction.getEffectiveValueParameters().forEach { it.enqueueValueParameterType(irFunction) } irFunction.returnType.enqueueType(irFunction, "function return type") + + kotlinClosureToJsClosureConvertFunToKotlinClosureCallFun[irFunction]?.enqueue(irFunction, "kotlin closure to JS closure conversion", false) } override fun processSimpleFunction(irFunction: IrSimpleFunction) { diff --git a/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/lower/JsInteropFunctionsLowering.kt b/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/lower/JsInteropFunctionsLowering.kt index a28be84d7ae..e174167e940 100644 --- a/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/lower/JsInteropFunctionsLowering.kt +++ b/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/lower/JsInteropFunctionsLowering.kt @@ -458,6 +458,8 @@ class JsInteropFunctionsLowering(val context: WasmBackendContext) : DeclarationT } +irReturn(info.resultAdapter.adaptIfNeeded(callInvoke, builder)) } + + // TODO find out a better way to export the such declarations only when it's required. Also, fix building roots for DCE, then. result.annotations += builder.irCallConstructor(context.wasmSymbols.jsExportConstructor, typeArguments = emptyList()) additionalDeclarations += result return result diff --git a/compiler/testData/codegen/box/size/add.kt b/compiler/testData/codegen/box/size/add.kt index cea3d607ab0..782dcab7754 100644 --- a/compiler/testData/codegen/box/size/add.kt +++ b/compiler/testData/codegen/box/size/add.kt @@ -1,7 +1,7 @@ // TARGET_BACKEND: WASM -// WASM_DCE_EXPECTED_OUTPUT_SIZE: wasm 34_869 -// WASM_DCE_EXPECTED_OUTPUT_SIZE: mjs 6_359 +// WASM_DCE_EXPECTED_OUTPUT_SIZE: wasm 29_800 +// WASM_DCE_EXPECTED_OUTPUT_SIZE: mjs 6_104 // FILE: test.kt diff --git a/compiler/testData/codegen/box/size/helloWorld.kt b/compiler/testData/codegen/box/size/helloWorld.kt index 9ae18e82a64..a78d198c8f9 100644 --- a/compiler/testData/codegen/box/size/helloWorld.kt +++ b/compiler/testData/codegen/box/size/helloWorld.kt @@ -1,7 +1,7 @@ // TARGET_BACKEND: WASM -// WASM_DCE_EXPECTED_OUTPUT_SIZE: wasm 65_687 -// WASM_DCE_EXPECTED_OUTPUT_SIZE: mjs 6_458 +// WASM_DCE_EXPECTED_OUTPUT_SIZE: wasm 60_691 +// WASM_DCE_EXPECTED_OUTPUT_SIZE: mjs 6_130 fun box(): String { println("Hello, World!") diff --git a/compiler/testData/codegen/box/size/helloWorldDOM.kt b/compiler/testData/codegen/box/size/helloWorldDOM.kt index 43f12ccaf83..896ca98cbfc 100644 --- a/compiler/testData/codegen/box/size/helloWorldDOM.kt +++ b/compiler/testData/codegen/box/size/helloWorldDOM.kt @@ -1,7 +1,7 @@ // TARGET_BACKEND: WASM -// WASM_DCE_EXPECTED_OUTPUT_SIZE: wasm 38_128 -// WASM_DCE_EXPECTED_OUTPUT_SIZE: mjs 6_798 +// WASM_DCE_EXPECTED_OUTPUT_SIZE: wasm 31_232 +// WASM_DCE_EXPECTED_OUTPUT_SIZE: mjs 6_659 // FILE: test.kt diff --git a/compiler/testData/codegen/box/size/ok.kt b/compiler/testData/codegen/box/size/ok.kt index bb963f46c66..b41d9d8304a 100644 --- a/compiler/testData/codegen/box/size/ok.kt +++ b/compiler/testData/codegen/box/size/ok.kt @@ -1,6 +1,6 @@ // TARGET_BACKEND: WASM -// WASM_DCE_EXPECTED_OUTPUT_SIZE: wasm 34_917 -// WASM_DCE_EXPECTED_OUTPUT_SIZE: mjs 6_231 +// WASM_DCE_EXPECTED_OUTPUT_SIZE: wasm 29_848 +// WASM_DCE_EXPECTED_OUTPUT_SIZE: mjs 5_976 fun box() = "OK" \ No newline at end of file