diff --git a/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/ir2wasm/BodyGenerator.kt b/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/ir2wasm/BodyGenerator.kt index 845462b2cfa..24f6a8984fd 100644 --- a/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/ir2wasm/BodyGenerator.kt +++ b/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/ir2wasm/BodyGenerator.kt @@ -105,25 +105,8 @@ class BodyGenerator(val context: WasmFunctionCodegenContext) : IrElementVisitorV } } - override fun visitConst(expression: IrConst<*>) { - when (val kind = expression.kind) { - is IrConstKind.Null -> generateDefaultInitializerForType(context.transformType(expression.type), body) - is IrConstKind.Boolean -> body.buildConstI32(if (kind.valueOf(expression)) 1 else 0) - is IrConstKind.Byte -> body.buildConstI32(kind.valueOf(expression).toInt()) - is IrConstKind.Short -> body.buildConstI32(kind.valueOf(expression).toInt()) - is IrConstKind.Int -> body.buildConstI32(kind.valueOf(expression)) - is IrConstKind.Long -> body.buildConstI64(kind.valueOf(expression)) - is IrConstKind.Char -> body.buildConstI32(kind.valueOf(expression).code) - is IrConstKind.Float -> body.buildConstF32(kind.valueOf(expression)) - is IrConstKind.Double -> body.buildConstF64(kind.valueOf(expression)) - is IrConstKind.String -> { - body.buildConstI32Symbol(context.referenceStringLiteral(kind.valueOf(expression))) - body.buildConstI32(kind.valueOf(expression).length) - body.buildCall(context.referenceFunction(wasmSymbols.stringGetLiteral)) - } - else -> error("Unknown constant kind") - } - } + override fun visitConst(expression: IrConst<*>): Unit = + generateConstExpression(expression, body, context) override fun visitGetField(expression: IrGetField) { val field: IrField = expression.symbol.owner diff --git a/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/ir2wasm/DeclarationGenerator.kt b/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/ir2wasm/DeclarationGenerator.kt index 4ea2711189f..e48a9549772 100644 --- a/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/ir2wasm/DeclarationGenerator.kt +++ b/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/ir2wasm/DeclarationGenerator.kt @@ -20,6 +20,9 @@ import org.jetbrains.kotlin.ir.backend.js.utils.getJsNameOrKotlinName import org.jetbrains.kotlin.ir.backend.js.utils.realOverrideTarget import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.expressions.IrBlockBody +import org.jetbrains.kotlin.ir.expressions.IrConst +import org.jetbrains.kotlin.ir.expressions.IrConstKind +import org.jetbrains.kotlin.ir.expressions.IrExpression import org.jetbrains.kotlin.ir.symbols.IrFunctionSymbol import org.jetbrains.kotlin.ir.util.* import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid @@ -364,13 +367,21 @@ class DeclarationGenerator(val context: WasmModuleCodegenContext) : IrElementVis val initBody = mutableListOf() val wasmExpressionGenerator = WasmIrExpressionBuilder(initBody) - generateDefaultInitializerForType(wasmType, wasmExpressionGenerator) + + val initValue: IrExpression? = declaration.initializer?.expression + if (initValue != null) { + check(initValue is IrConst<*> && initValue.kind !is IrConstKind.String && initValue.kind !is IrConstKind.Null) { + "Static field initializer should be non-string const or null" + } + generateConstExpression(initValue, wasmExpressionGenerator, context) + } else { + generateDefaultInitializerForType(wasmType, wasmExpressionGenerator) + } val global = WasmGlobal( name = declaration.fqNameWhenAvailable.toString(), type = wasmType, isMutable = true, - // All globals are currently initialized in start function init = initBody ) @@ -396,4 +407,25 @@ fun IrFunction.getEffectiveValueParameters(): List { } fun IrFunction.isExported(): Boolean = - isJsExport() \ No newline at end of file + isJsExport() + + +fun generateConstExpression(expression: IrConst<*>, body: WasmExpressionBuilder, context: WasmBaseCodegenContext) { + when (val kind = expression.kind) { + is IrConstKind.Null -> generateDefaultInitializerForType(context.transformType(expression.type), body) + is IrConstKind.Boolean -> body.buildConstI32(if (kind.valueOf(expression)) 1 else 0) + is IrConstKind.Byte -> body.buildConstI32(kind.valueOf(expression).toInt()) + is IrConstKind.Short -> body.buildConstI32(kind.valueOf(expression).toInt()) + is IrConstKind.Int -> body.buildConstI32(kind.valueOf(expression)) + is IrConstKind.Long -> body.buildConstI64(kind.valueOf(expression)) + is IrConstKind.Char -> body.buildConstI32(kind.valueOf(expression).code) + is IrConstKind.Float -> body.buildConstF32(kind.valueOf(expression)) + is IrConstKind.Double -> body.buildConstF64(kind.valueOf(expression)) + is IrConstKind.String -> { + body.buildConstI32Symbol(context.referenceStringLiteral(kind.valueOf(expression))) + body.buildConstI32(kind.valueOf(expression).length) + body.buildCall(context.referenceFunction(context.backendContext.wasmSymbols.stringGetLiteral)) + } + else -> error("Unknown constant kind") + } +} \ No newline at end of file diff --git a/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/lower/FieldInitializersLowering.kt b/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/lower/FieldInitializersLowering.kt index 2045e512f08..b20b965844d 100644 --- a/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/lower/FieldInitializersLowering.kt +++ b/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/lower/FieldInitializersLowering.kt @@ -9,11 +9,14 @@ import org.jetbrains.kotlin.backend.common.FileLoweringPass import org.jetbrains.kotlin.backend.common.lower.at import org.jetbrains.kotlin.backend.common.lower.createIrBuilder import org.jetbrains.kotlin.backend.wasm.WasmBackendContext +import org.jetbrains.kotlin.backend.wasm.ir2wasm.getRuntimeClass import org.jetbrains.kotlin.ir.IrElement import org.jetbrains.kotlin.ir.builders.irSetField import org.jetbrains.kotlin.ir.declarations.IrField import org.jetbrains.kotlin.ir.declarations.IrFile import org.jetbrains.kotlin.ir.expressions.IrBlockBody +import org.jetbrains.kotlin.ir.expressions.IrConst +import org.jetbrains.kotlin.ir.expressions.IrConstKind import org.jetbrains.kotlin.ir.expressions.IrExpression import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid @@ -45,6 +48,8 @@ class FieldInitializersLowering(val context: WasmBackendContext) : FileLoweringP if (!declaration.isStatic) return val initValue: IrExpression = declaration.initializer?.expression ?: return + // Constant primitive initializers without implicit casting can be processed by native wasm initializers + if (initValue.type == declaration.type && initValue is IrConst<*> && initValue.kind !is IrConstKind.String && initValue.kind !is IrConstKind.Null) return startFunctionBody.statements.add( builder.at(initValue).irSetField(null, declaration, initValue)