[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<*>) {
|
override fun visitConst(expression: IrConst<*>): Unit =
|
||||||
when (val kind = expression.kind) {
|
generateConstExpression(expression, body, context)
|
||||||
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 visitGetField(expression: IrGetField) {
|
override fun visitGetField(expression: IrGetField) {
|
||||||
val field: IrField = expression.symbol.owner
|
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.backend.js.utils.realOverrideTarget
|
||||||
import org.jetbrains.kotlin.ir.declarations.*
|
import org.jetbrains.kotlin.ir.declarations.*
|
||||||
import org.jetbrains.kotlin.ir.expressions.IrBlockBody
|
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.symbols.IrFunctionSymbol
|
||||||
import org.jetbrains.kotlin.ir.util.*
|
import org.jetbrains.kotlin.ir.util.*
|
||||||
import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid
|
import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid
|
||||||
@@ -364,13 +367,21 @@ class DeclarationGenerator(val context: WasmModuleCodegenContext) : IrElementVis
|
|||||||
|
|
||||||
val initBody = mutableListOf<WasmInstr>()
|
val initBody = mutableListOf<WasmInstr>()
|
||||||
val wasmExpressionGenerator = WasmIrExpressionBuilder(initBody)
|
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(
|
val global = WasmGlobal(
|
||||||
name = declaration.fqNameWhenAvailable.toString(),
|
name = declaration.fqNameWhenAvailable.toString(),
|
||||||
type = wasmType,
|
type = wasmType,
|
||||||
isMutable = true,
|
isMutable = true,
|
||||||
// All globals are currently initialized in start function
|
|
||||||
init = initBody
|
init = initBody
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -396,4 +407,25 @@ fun IrFunction.getEffectiveValueParameters(): List<IrValueParameter> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun IrFunction.isExported(): Boolean =
|
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.at
|
||||||
import org.jetbrains.kotlin.backend.common.lower.createIrBuilder
|
import org.jetbrains.kotlin.backend.common.lower.createIrBuilder
|
||||||
import org.jetbrains.kotlin.backend.wasm.WasmBackendContext
|
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.IrElement
|
||||||
import org.jetbrains.kotlin.ir.builders.irSetField
|
import org.jetbrains.kotlin.ir.builders.irSetField
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrField
|
import org.jetbrains.kotlin.ir.declarations.IrField
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrFile
|
import org.jetbrains.kotlin.ir.declarations.IrFile
|
||||||
import org.jetbrains.kotlin.ir.expressions.IrBlockBody
|
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.expressions.IrExpression
|
||||||
import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid
|
import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid
|
||||||
import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid
|
import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid
|
||||||
@@ -45,6 +48,8 @@ class FieldInitializersLowering(val context: WasmBackendContext) : FileLoweringP
|
|||||||
|
|
||||||
if (!declaration.isStatic) return
|
if (!declaration.isStatic) return
|
||||||
val initValue: IrExpression = declaration.initializer?.expression ?: 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(
|
startFunctionBody.statements.add(
|
||||||
builder.at(initValue).irSetField(null, declaration, initValue)
|
builder.at(initValue).irSetField(null, declaration, initValue)
|
||||||
|
|||||||
Reference in New Issue
Block a user