[WASM] Initialize constant fields by wasm-initializers
This commit is contained in:
+2
-19
@@ -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
|
||||
|
||||
+35
-3
@@ -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<WasmInstr>()
|
||||
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<IrValueParameter> {
|
||||
}
|
||||
|
||||
fun IrFunction.isExported(): Boolean =
|
||||
isJsExport()
|
||||
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")
|
||||
}
|
||||
}
|
||||
+5
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user