From 5e14ccbccca4a3d1afa94f08308a47972d63f160 Mon Sep 17 00:00:00 2001 From: Igor Yakovlev Date: Mon, 31 Jul 2023 15:43:48 +0200 Subject: [PATCH] [Wasm] Backend support for wasi mode --- .../kotlin/backend/wasm/WasmSymbols.kt | 53 ++++++++++++------- .../backend/wasm/lower/BuiltInsLowering.kt | 10 +++- ...DeclarationsToTopLevelFunctionsLowering.kt | 2 +- .../backend/wasm/lower/JsCodeCallsLowering.kt | 9 +++- .../wasm/lower/JsInteropFunctionsLowering.kt | 52 ++++++++++-------- .../wasm/lower/UnhandledExceptionLowering.kt | 5 +- .../wasm/lower/WasmTypeOperatorLowering.kt | 18 +++++-- .../markAdditionalExportedDeclarations.kt | 9 +++- 8 files changed, 107 insertions(+), 51 deletions(-) diff --git a/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/WasmSymbols.kt b/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/WasmSymbols.kt index 7265512ea4b..9c925196a9d 100644 --- a/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/WasmSymbols.kt +++ b/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/WasmSymbols.kt @@ -23,6 +23,8 @@ import org.jetbrains.kotlin.ir.types.* import org.jetbrains.kotlin.ir.util.SymbolTable import org.jetbrains.kotlin.ir.util.constructors import org.jetbrains.kotlin.ir.util.render +import org.jetbrains.kotlin.js.config.JSConfigurationKeys +import org.jetbrains.kotlin.js.config.WasmTarget import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.resolve.scopes.MemberScope @@ -78,8 +80,6 @@ class WasmSymbols( internal val initAssociatedObjects = getInternalFunction("initAssociatedObjects") internal val addAssociatedObject = getInternalFunction("addAssociatedObject") - internal val throwAsJsException: IrSimpleFunctionSymbol = getInternalFunction("throwAsJsException") - override val throwNullPointerException = getInternalFunction("THROW_NPE") override val throwISE = getInternalFunction("THROW_ISE") override val throwTypeCastException = getInternalFunction("THROW_CCE") @@ -189,7 +189,6 @@ class WasmSymbols( val booleanAnd = getInternalFunction("wasm_i32_and") val refEq = getInternalFunction("wasm_ref_eq") val refIsNull = getInternalFunction("wasm_ref_is_null") - val externRefIsNull = getInternalFunction("wasm_externref_is_null") val refTest = getInternalFunction("wasm_ref_test") val refCastNull = getInternalFunction("wasm_ref_cast_null") val wasmArrayCopy = getInternalFunction("wasm_array_copy") @@ -237,9 +236,6 @@ class WasmSymbols( val unsafeGetScratchRawMemory = getInternalFunction("unsafeGetScratchRawMemory") val returnArgumentIfItIsKotlinAny = getInternalFunction("returnArgumentIfItIsKotlinAny") - val newJsArray = getInternalFunction("newJsArray") - val jsArrayPush = getInternalFunction("jsArrayPush") - val startCoroutineUninterceptedOrReturnIntrinsics = (0..2).map { getInternalFunction("startCoroutineUninterceptedOrReturnIntrinsic$it") } @@ -309,9 +305,6 @@ class WasmSymbols( val wasmAnyRefClass = getIrClass(FqName("kotlin.wasm.internal.reftypes.anyref")) - private val jsAnyClass = getIrClass(FqName("kotlin.js.JsAny")) - val jsAnyType by lazy { jsAnyClass.defaultType } - inner class JsInteropAdapters { val kotlinToJsStringAdapter = getInternalFunction("kotlinToJsStringAdapter") val kotlinToJsAnyAdapter = getInternalFunction("kotlinToJsAnyAdapter") @@ -342,18 +335,42 @@ class WasmSymbols( val kotlinCharToExternRefAdapter = getInternalFunction("kotlinCharToExternRefAdapter") } - val jsInteropAdapters = JsInteropAdapters() + inner class JsRelatedSymbols { + val jsInteropAdapters = JsInteropAdapters() - private val jsExportClass = getIrClass(FqName("kotlin.js.JsExport")) - val jsExportConstructor by lazy { jsExportClass.constructors.single() } + private val jsExportClass = getIrClass(FqName("kotlin.js.JsExport")) + val jsExportConstructor by lazy { jsExportClass.constructors.single() } - private val jsNameClass = getIrClass(FqName("kotlin.js.JsName")) - val jsNameConstructor by lazy { jsNameClass.constructors.single() } + private val jsNameClass = getIrClass(FqName("kotlin.js.JsName")) + val jsNameConstructor by lazy { jsNameClass.constructors.single() } - private val jsFunClass = getIrClass(FqName("kotlin.JsFun")) - val jsFunConstructor by lazy { jsFunClass.constructors.single() } + private val jsFunClass = getIrClass(FqName("kotlin.JsFun")) + val jsFunConstructor by lazy { jsFunClass.constructors.single() } - val jsCode = getFunction("js", kotlinJsPackage) + val jsCode = getFunction("js", kotlinJsPackage) + + val jsAnyType: IrType by lazy { getIrClass(FqName("kotlin.js.JsAny")).defaultType } + + val newJsArray = getInternalFunction("newJsArray") + + val jsArrayPush = getInternalFunction("jsArrayPush") + + val externRefIsNull = getInternalFunction("wasm_externref_is_null") + + internal val throwAsJsException: IrSimpleFunctionSymbol = + getInternalFunction("throwAsJsException") + } + + private val wasmExportClass = getIrClass(FqName("kotlin.wasm.WasmExport")) + val wasmExportConstructor by lazy { wasmExportClass.constructors.single() } + + private val jsRelatedSymbolsIfNonWasi = + when (context.configuration.get(JSConfigurationKeys.WASM_TARGET, WasmTarget.JS) == WasmTarget.JS) { + true -> JsRelatedSymbols() + else -> null + } + + val jsRelatedSymbols get() = jsRelatedSymbolsIfNonWasi ?: error("Cannot access to js related std in wasi mode") private fun findClass(memberScope: MemberScope, name: Name): ClassDescriptor = memberScope.getContributedClassifier(name, NoLookupLocation.FROM_BACKEND) as ClassDescriptor @@ -381,7 +398,7 @@ class WasmSymbols( return symbolTable.descriptorExtension.referenceSimpleFunction(tmp.single()) } - private fun getInternalFunction(name: String) = getFunction(name, wasmInternalPackage) + private fun getInternalFunction(name: String): IrSimpleFunctionSymbol = getFunction(name, wasmInternalPackage) private fun getEnumsFunction(name: String) = getFunction(name, enumsInternalPackage) diff --git a/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/lower/BuiltInsLowering.kt b/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/lower/BuiltInsLowering.kt index 25bd2b36114..558a09ac5f5 100644 --- a/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/lower/BuiltInsLowering.kt +++ b/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/lower/BuiltInsLowering.kt @@ -25,6 +25,8 @@ import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol import org.jetbrains.kotlin.ir.types.* import org.jetbrains.kotlin.ir.util.* import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid +import org.jetbrains.kotlin.js.config.JSConfigurationKeys +import org.jetbrains.kotlin.js.config.WasmTarget import org.jetbrains.kotlin.name.parentOrNull class BuiltInsLowering(val context: WasmBackendContext) : FileLoweringPass { @@ -56,7 +58,13 @@ class BuiltInsLowering(val context: WasmBackendContext) : FileLoweringPass { irBuiltins.eqeqSymbol, irBuiltins.eqeqeqSymbol -> { fun callRefIsNull(expr: IrExpression): IrCall { - val refIsNull = if (expr.type.erasedUpperBound?.isExternal == true) symbols.externRefIsNull else symbols.refIsNull + if ( + context.configuration.get(JSConfigurationKeys.WASM_TARGET, WasmTarget.JS) == WasmTarget.WASI && + expr.type.erasedUpperBound?.isExternal == true + ) { + error("Unexpected external refs in wasi mode") + } + val refIsNull = if (expr.type.erasedUpperBound?.isExternal == true) symbols.jsRelatedSymbols.externRefIsNull else symbols.refIsNull return builder.irCall(refIsNull).apply { putValueArgument(0, expr) } } diff --git a/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/lower/ComplexExternalDeclarationsToTopLevelFunctionsLowering.kt b/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/lower/ComplexExternalDeclarationsToTopLevelFunctionsLowering.kt index b88ee01d09a..8d4b9539b06 100644 --- a/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/lower/ComplexExternalDeclarationsToTopLevelFunctionsLowering.kt +++ b/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/lower/ComplexExternalDeclarationsToTopLevelFunctionsLowering.kt @@ -418,7 +418,7 @@ fun createExternalJsFunction( isExternal = true } val builder = context.createIrBuilder(res.symbol) - res.annotations += builder.irCallConstructor(context.wasmSymbols.jsFunConstructor, typeArguments = emptyList()).also { + res.annotations += builder.irCallConstructor(context.wasmSymbols.jsRelatedSymbols.jsFunConstructor, typeArguments = emptyList()).also { it.putValueArgument(0, builder.irString(jsCode)) } return res diff --git a/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/lower/JsCodeCallsLowering.kt b/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/lower/JsCodeCallsLowering.kt index a473feabf83..5e940f1a849 100644 --- a/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/lower/JsCodeCallsLowering.kt +++ b/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/lower/JsCodeCallsLowering.kt @@ -13,12 +13,17 @@ import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.expressions.* import org.jetbrains.kotlin.ir.types.defaultType import org.jetbrains.kotlin.ir.util.* +import org.jetbrains.kotlin.js.config.JSConfigurationKeys +import org.jetbrains.kotlin.js.config.WasmTarget /** * Lower calls to `js(code)` into `@JsFun(code) external` functions. */ class JsCodeCallsLowering(val context: WasmBackendContext) : FileLoweringPass { + private val jsRelatedSymbols get() = context.wasmSymbols.jsRelatedSymbols + override fun lower(irFile: IrFile) { + if (context.configuration.get(JSConfigurationKeys.WASM_TARGET, WasmTarget.JS) == WasmTarget.WASI) return irFile.transformDeclarationsFlat { declaration -> when (declaration) { is IrSimpleFunction -> transformFunction(declaration) @@ -81,7 +86,7 @@ class JsCodeCallsLowering(val context: WasmBackendContext) : FileLoweringPass { } val builder = context.createIrBuilder(function.symbol) - function.annotations += builder.irCallConstructor(context.wasmSymbols.jsFunConstructor, typeArguments = emptyList()).also { + function.annotations += builder.irCallConstructor(jsRelatedSymbols.jsFunConstructor, typeArguments = emptyList()).also { it.putValueArgument(0, builder.irString(jsFunCode)) } function.body = null @@ -106,7 +111,7 @@ class JsCodeCallsLowering(val context: WasmBackendContext) : FileLoweringPass { private fun IrExpression.getJsCode(): String? { val call = this as? IrCall ?: return null - if (call.symbol != context.wasmSymbols.jsCode) return null + if (call.symbol != jsRelatedSymbols.jsCode) return null @Suppress("UNCHECKED_CAST") return (call.getValueArgument(0) as IrConst).value } 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 a8cf74a8f6a..a3fcd3ce7c4 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 @@ -31,6 +31,8 @@ import org.jetbrains.kotlin.ir.types.* import org.jetbrains.kotlin.ir.util.* import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid +import org.jetbrains.kotlin.js.config.JSConfigurationKeys +import org.jetbrains.kotlin.js.config.WasmTarget import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.util.OperatorNameConventions @@ -41,12 +43,15 @@ import org.jetbrains.kotlin.util.OperatorNameConventions class JsInteropFunctionsLowering(val context: WasmBackendContext) : DeclarationTransformer { val builtIns = context.irBuiltIns val symbols = context.wasmSymbols - val adapters = symbols.jsInteropAdapters + val jsRelatedSymbols get() = context.wasmSymbols.jsRelatedSymbols + val adapters get() = jsRelatedSymbols.jsInteropAdapters val additionalDeclarations = mutableListOf() lateinit var currentParent: IrDeclarationParent override fun transformFlat(declaration: IrDeclaration): List? { + if (context.configuration.get(JSConfigurationKeys.WASM_TARGET, WasmTarget.JS) == WasmTarget.WASI) return null + if (declaration.isFakeOverride) return null if (declaration !is IrSimpleFunction) return null val isExported = declaration.isJsExport() @@ -176,10 +181,10 @@ class JsInteropFunctionsLowering(val context: WasmBackendContext) : DeclarationT val builder: DeclarationIrBuilder = context.createIrBuilder(newFun.symbol) newFun.body = createAdapterFunctionBody(builder, newFun, function, valueParametersAdapters, resultAdapter) - newFun.annotations += builder.irCallConstructor(context.wasmSymbols.jsNameConstructor, typeArguments = emptyList()).also { + newFun.annotations += builder.irCallConstructor(jsRelatedSymbols.jsNameConstructor, typeArguments = emptyList()).also { it.putValueArgument(0, builder.irString(function.getJsNameOrKotlinName().identifier)) } - function.annotations = function.annotations.filter { it.symbol != context.wasmSymbols.jsExportConstructor } + function.annotations = function.annotations.filter { it.symbol != jsRelatedSymbols.jsExportConstructor } return listOf(function, newFun) } @@ -202,15 +207,17 @@ class JsInteropFunctionsLowering(val context: WasmBackendContext) : DeclarationT ) } - val primitivesToExternRefAdapters: Map = mapOf( - builtIns.byteType to adapters.kotlinByteToExternRefAdapter, - builtIns.shortType to adapters.kotlinShortToExternRefAdapter, - builtIns.charType to adapters.kotlinCharToExternRefAdapter, - builtIns.intType to adapters.kotlinIntToExternRefAdapter, - builtIns.longType to adapters.kotlinLongToExternRefAdapter, - builtIns.floatType to adapters.kotlinFloatToExternRefAdapter, - builtIns.doubleType to adapters.kotlinDoubleToExternRefAdapter, - ).mapValues { FunctionBasedAdapter(it.value.owner) } + val primitivesToExternRefAdapters: Map by lazy { + mapOf( + builtIns.byteType to adapters.kotlinByteToExternRefAdapter, + builtIns.shortType to adapters.kotlinShortToExternRefAdapter, + builtIns.charType to adapters.kotlinCharToExternRefAdapter, + builtIns.intType to adapters.kotlinIntToExternRefAdapter, + builtIns.longType to adapters.kotlinLongToExternRefAdapter, + builtIns.floatType to adapters.kotlinFloatToExternRefAdapter, + builtIns.doubleType to adapters.kotlinDoubleToExternRefAdapter, + ).mapValues { FunctionBasedAdapter(it.value.owner) } + } private fun IrType.kotlinToJsAdapterIfNeeded(isReturn: Boolean): InteropTypeAdapter? { if (isReturn && this == builtIns.unitType) @@ -458,7 +465,7 @@ class JsInteropFunctionsLowering(val context: WasmBackendContext) : DeclarationT } // 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()) + result.annotations += builder.irCallConstructor(jsRelatedSymbols.jsExportConstructor, typeArguments = emptyList()) additionalDeclarations += result return result } @@ -466,7 +473,7 @@ class JsInteropFunctionsLowering(val context: WasmBackendContext) : DeclarationT private fun createKotlinToJsClosureConvertor(info: FunctionTypeInfo): IrSimpleFunction { val result = context.irFactory.buildFun { name = Name.identifier("__convertKotlinClosureToJsClosure_${info.signatureString}") - returnType = context.wasmSymbols.jsAnyType + returnType = jsRelatedSymbols.jsAnyType isExternal = true } result.parent = currentParent @@ -487,7 +494,7 @@ class JsInteropFunctionsLowering(val context: WasmBackendContext) : DeclarationT append(")") } - result.annotations += builder.irCallConstructor(context.wasmSymbols.jsFunConstructor, typeArguments = emptyList()).also { + result.annotations += builder.irCallConstructor(jsRelatedSymbols.jsFunConstructor, typeArguments = emptyList()).also { it.putValueArgument(0, builder.irString(jsCode)) } @@ -507,7 +514,7 @@ class JsInteropFunctionsLowering(val context: WasmBackendContext) : DeclarationT result.parent = currentParent result.addValueParameter { name = Name.identifier("f") - type = context.wasmSymbols.jsAnyType + type = jsRelatedSymbols.jsAnyType } val closureClass = context.irFactory.buildClass { @@ -520,7 +527,7 @@ class JsInteropFunctionsLowering(val context: WasmBackendContext) : DeclarationT val closureClassField = closureClass.addField { name = Name.identifier("jsClosure") - type = context.wasmSymbols.jsAnyType + type = jsRelatedSymbols.jsAnyType visibility = DescriptorVisibilities.PRIVATE isFinal = true } @@ -589,7 +596,7 @@ class JsInteropFunctionsLowering(val context: WasmBackendContext) : DeclarationT result.parent = currentParent result.addValueParameter { name = Name.identifier("f") - type = symbols.jsAnyType + type = jsRelatedSymbols.jsAnyType } val arity = info.adaptedParameterTypes.size repeat(arity) { paramIndex -> @@ -607,7 +614,7 @@ class JsInteropFunctionsLowering(val context: WasmBackendContext) : DeclarationT append(")") } - result.annotations += builder.irCallConstructor(context.wasmSymbols.jsFunConstructor, typeArguments = emptyList()).also { + result.annotations += builder.irCallConstructor(jsRelatedSymbols.jsFunConstructor, typeArguments = emptyList()).also { it.putValueArgument(0, builder.irString(jsFun)) } @@ -817,7 +824,7 @@ class JsInteropFunctionsLowering(val context: WasmBackendContext) : DeclarationT private val fromElementType: IrType, ) : InteropTypeAdapter { override val toType: IrType = - context.wasmSymbols.jsAnyType + jsRelatedSymbols.jsAnyType private val elementAdapter = primitivesToExternRefAdapters[fromElementType] @@ -837,7 +844,7 @@ class JsInteropFunctionsLowering(val context: WasmBackendContext) : DeclarationT // newJsArray.push(adapt(originalArray[index])); // index++ // } - val newJsArrayVar = irTemporary(irCall(symbols.newJsArray)) + val newJsArrayVar = irTemporary(irCall(jsRelatedSymbols.newJsArray)) val indexVar = irTemporary(irInt(0), isMutable = true) val arraySizeVar = irTemporary(irCall(sizeMethod).apply { dispatchReceiver = irGet(originalArrayVar) }) @@ -854,7 +861,7 @@ class JsInteropFunctionsLowering(val context: WasmBackendContext) : DeclarationT ), this@irBlock ) - +irCall(symbols.jsArrayPush).apply { + +irCall(jsRelatedSymbols.jsArrayPush).apply { putValueArgument(0, irGet(newJsArrayVar)) putValueArgument(1, adaptedValue) } @@ -885,6 +892,7 @@ internal fun StringBuilder.appendParameterList(size: Int, name: String = "p", is */ class JsInteropFunctionCallsLowering(val context: WasmBackendContext) : BodyLoweringPass { override fun lower(irBody: IrBody, container: IrDeclaration) { + if (context.configuration.get(JSConfigurationKeys.WASM_TARGET, WasmTarget.JS) == WasmTarget.WASI) return irBody.transformChildrenVoid(object : IrElementTransformerVoid() { override fun visitCall(expression: IrCall): IrExpression { expression.transformChildrenVoid() diff --git a/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/lower/UnhandledExceptionLowering.kt b/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/lower/UnhandledExceptionLowering.kt index a581b0a89cc..f1dcdb8a05a 100644 --- a/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/lower/UnhandledExceptionLowering.kt +++ b/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/lower/UnhandledExceptionLowering.kt @@ -20,6 +20,8 @@ import org.jetbrains.kotlin.ir.declarations.IrFunction import org.jetbrains.kotlin.ir.expressions.IrBlockBody import org.jetbrains.kotlin.ir.expressions.IrExpressionBody import org.jetbrains.kotlin.ir.util.toIrConst +import org.jetbrains.kotlin.js.config.JSConfigurationKeys +import org.jetbrains.kotlin.js.config.WasmTarget import org.jetbrains.kotlin.name.Name // This pass needed to wrap around unhandled exceptions from JsExport functions and throw JS exception for call from JS site @@ -47,7 +49,7 @@ import org.jetbrains.kotlin.name.Name internal class UnhandledExceptionLowering(val context: WasmBackendContext) : FileLoweringPass { private val throwableType = context.irBuiltIns.throwableType private val irBooleanType = context.wasmSymbols.irBuiltIns.booleanType - private val throwAsJsException = context.wasmSymbols.throwAsJsException + private val throwAsJsException get() = context.wasmSymbols.jsRelatedSymbols.throwAsJsException private val isNotFirstWasmExportCallGetter = context.wasmSymbols.isNotFirstWasmExportCall.owner.getter!!.symbol private val isNotFirstWasmExportCallSetter = context.wasmSymbols.isNotFirstWasmExportCall.owner.setter!!.symbol @@ -131,6 +133,7 @@ internal class UnhandledExceptionLowering(val context: WasmBackendContext) : Fil } override fun lower(irFile: IrFile) { + if (context.configuration.get(JSConfigurationKeys.WASM_TARGET, WasmTarget.JS) == WasmTarget.WASI) return for (declaration in irFile.declarations) { if (declaration is IrFunction && declaration.isExported()) { processExportFunction(declaration) diff --git a/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/lower/WasmTypeOperatorLowering.kt b/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/lower/WasmTypeOperatorLowering.kt index b6f874d036e..52d50be268e 100644 --- a/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/lower/WasmTypeOperatorLowering.kt +++ b/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/lower/WasmTypeOperatorLowering.kt @@ -23,6 +23,8 @@ import org.jetbrains.kotlin.ir.expressions.* import org.jetbrains.kotlin.ir.types.* import org.jetbrains.kotlin.ir.util.* import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid +import org.jetbrains.kotlin.js.config.JSConfigurationKeys +import org.jetbrains.kotlin.js.config.WasmTarget class WasmTypeOperatorLowering(val context: WasmBackendContext) : FileLoweringPass { @@ -34,11 +36,11 @@ class WasmTypeOperatorLowering(val context: WasmBackendContext) : FileLoweringPa class WasmBaseTypeOperatorTransformer(val context: WasmBackendContext) : IrElementTransformerVoidWithContext() { private val symbols = context.wasmSymbols private val builtIns = context.irBuiltIns + private val jsToKotlinAnyAdapter get() = symbols.jsRelatedSymbols.jsInteropAdapters.jsToKotlinAnyAdapter + private val kotlinToJsAnyAdapter get() = symbols.jsRelatedSymbols.jsInteropAdapters.kotlinToJsAnyAdapter private lateinit var builder: DeclarationIrBuilder - override fun visitSimpleFunction(declaration: IrSimpleFunction): IrStatement { - return super.visitSimpleFunction(declaration) - } + override fun visitTypeOperator(expression: IrTypeOperatorCall): IrExpression { super.visitTypeOperator(expression) builder = context.createIrBuilder(currentScope!!.scope.scopeOwnerSymbol).at(expression) @@ -213,7 +215,10 @@ class WasmBaseTypeOperatorTransformer(val context: WasmBackendContext) : IrEleme } if (fromClass.isExternal && !toClass.isExternal) { - val narrowingToAny = builder.irCall(symbols.jsInteropAdapters.jsToKotlinAnyAdapter).also { + if (context.configuration.get(JSConfigurationKeys.WASM_TARGET, WasmTarget.JS) == WasmTarget.WASI) { + TODO("Implement externalize adapter for wasi mode") + } + val narrowingToAny = builder.irCall(jsToKotlinAnyAdapter).also { it.putValueArgument(0, value) } // Continue narrowing from Any to expected type @@ -221,7 +226,10 @@ class WasmBaseTypeOperatorTransformer(val context: WasmBackendContext) : IrEleme } if (toClass.isExternal && !fromClass.isExternal) { - return builder.irCall(symbols.jsInteropAdapters.kotlinToJsAnyAdapter).also { + if (context.configuration.get(JSConfigurationKeys.WASM_TARGET, WasmTarget.JS) == WasmTarget.WASI) { + TODO("Implement internalize adapter for wasi mode") + } + return builder.irCall(kotlinToJsAnyAdapter).also { it.putValueArgument(0, value) } } diff --git a/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/lower/markAdditionalExportedDeclarations.kt b/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/lower/markAdditionalExportedDeclarations.kt index 689123c95a3..71b17dd7f87 100644 --- a/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/lower/markAdditionalExportedDeclarations.kt +++ b/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/lower/markAdditionalExportedDeclarations.kt @@ -11,17 +11,24 @@ import org.jetbrains.kotlin.ir.builders.irCallConstructor import org.jetbrains.kotlin.ir.declarations.IrFile import org.jetbrains.kotlin.ir.declarations.IrFunction import org.jetbrains.kotlin.ir.util.fqNameWhenAvailable +import org.jetbrains.kotlin.js.config.JSConfigurationKeys +import org.jetbrains.kotlin.js.config.WasmTarget import org.jetbrains.kotlin.name.FqName /** * Mark declarations from [exportedFqNames] with @JsExport annotation */ fun markExportedDeclarations(context: WasmBackendContext, irFile: IrFile, exportedFqNames: Set) { + val exportConstructor = when (context.configuration.get(JSConfigurationKeys.WASM_TARGET, WasmTarget.JS)) { + WasmTarget.WASI -> context.wasmSymbols.wasmExportConstructor + else -> context.wasmSymbols.jsRelatedSymbols.jsExportConstructor + } + for (declaration in irFile.declarations) { if (declaration is IrFunction && declaration.fqNameWhenAvailable in exportedFqNames) { val builder = context.createIrBuilder(irFile.symbol) declaration.annotations += - builder.irCallConstructor(context.wasmSymbols.jsExportConstructor, typeArguments = emptyList()) + builder.irCallConstructor(exportConstructor, typeArguments = emptyList()) } } } \ No newline at end of file