[Wasm] Backend support for wasi mode
This commit is contained in:
committed by
Space Team
parent
22a3000789
commit
5e14ccbccc
@@ -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)
|
||||
|
||||
|
||||
+9
-1
@@ -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) }
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -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
|
||||
|
||||
+7
-2
@@ -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<String>).value
|
||||
}
|
||||
|
||||
+30
-22
@@ -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<IrDeclaration>()
|
||||
lateinit var currentParent: IrDeclarationParent
|
||||
|
||||
override fun transformFlat(declaration: IrDeclaration): List<IrDeclaration>? {
|
||||
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<IrType, InteropTypeAdapter> = 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<IrType, InteropTypeAdapter> 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()
|
||||
|
||||
+4
-1
@@ -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)
|
||||
|
||||
+13
-5
@@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
+8
-1
@@ -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<FqName>) {
|
||||
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())
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user