[Wasm] Require location for buildConstI32 and fix all usages

This commit is contained in:
Zalim Bashorov
2022-12-06 20:34:47 +01:00
parent cdc1d66b1f
commit f2f4c63720
6 changed files with 147 additions and 127 deletions
@@ -13,6 +13,7 @@ import org.jetbrains.kotlin.backend.wasm.utils.isCanonical
import org.jetbrains.kotlin.ir.IrBuiltIns import org.jetbrains.kotlin.ir.IrBuiltIns
import org.jetbrains.kotlin.ir.IrElement import org.jetbrains.kotlin.ir.IrElement
import org.jetbrains.kotlin.ir.backend.js.lower.PrimaryConstructorLowering import org.jetbrains.kotlin.ir.backend.js.lower.PrimaryConstructorLowering
import org.jetbrains.kotlin.ir.backend.js.transformers.irToJs.getSourceLocation
import org.jetbrains.kotlin.ir.backend.js.utils.erasedUpperBound import org.jetbrains.kotlin.ir.backend.js.utils.erasedUpperBound
import org.jetbrains.kotlin.ir.backend.js.utils.findUnitGetInstanceFunction import org.jetbrains.kotlin.ir.backend.js.utils.findUnitGetInstanceFunction
import org.jetbrains.kotlin.ir.backend.js.utils.isDispatchReceiver import org.jetbrains.kotlin.ir.backend.js.utils.isDispatchReceiver
@@ -97,9 +98,11 @@ class BodyGenerator(
val constantArrayId = context.referenceConstantArray(resource) val constantArrayId = context.referenceConstantArray(resource)
body.buildConstI32(0) withLocation(irVararg.getSourceLocation()) {
body.buildConstI32(irVararg.elements.size) body.buildConstI32(0, location)
body.buildInstr(WasmOp.ARRAY_NEW_DATA, wasmArrayType, WasmImmediate.DataIdx(constantArrayId)) body.buildConstI32(irVararg.elements.size, location)
body.buildInstr(WasmOp.ARRAY_NEW_DATA, wasmArrayType, WasmImmediate.DataIdx(constantArrayId))
}
return true return true
} }
@@ -125,7 +128,7 @@ class BodyGenerator(
check(wasmArrayType != null) check(wasmArrayType != null)
generateAnyParameters(arrayClass.symbol) generateAnyParameters(arrayClass.symbol, expression.getSourceLocation())
if (!tryGenerateConstVarargArray(expression, wasmArrayType)) tryGenerateVarargArray(expression, wasmArrayType) if (!tryGenerateConstVarargArray(expression, wasmArrayType)) tryGenerateVarargArray(expression, wasmArrayType)
body.buildStructNew(context.referenceGcType(expression.type.getRuntimeClass(irBuiltIns).symbol)) body.buildStructNew(context.referenceGcType(expression.type.getRuntimeClass(irBuiltIns).symbol))
} }
@@ -274,7 +277,7 @@ class BodyGenerator(
} }
if (expression.symbol.owner.hasWasmPrimitiveConstructorAnnotation()) { if (expression.symbol.owner.hasWasmPrimitiveConstructorAnnotation()) {
generateAnyParameters(klassSymbol) generateAnyParameters(klassSymbol, expression.getSourceLocation())
for (i in 0 until expression.valueArgumentsCount) { for (i in 0 until expression.valueArgumentsCount) {
generateExpression(expression.getValueArgument(i)!!) generateExpression(expression.getValueArgument(i)!!)
} }
@@ -287,7 +290,7 @@ class BodyGenerator(
generateCall(expression) generateCall(expression)
} }
private fun generateAnyParameters(klassSymbol: IrClassSymbol) { private fun generateAnyParameters(klassSymbol: IrClassSymbol, location: SourceLocation) {
//ClassITable and VTable load //ClassITable and VTable load
body.commentGroupStart { "Any parameters" } body.commentGroupStart { "Any parameters" }
body.buildGetGlobal(context.referenceGlobalVTable(klassSymbol)) body.buildGetGlobal(context.referenceGlobalVTable(klassSymbol))
@@ -298,7 +301,7 @@ class BodyGenerator(
} }
body.buildConstI32Symbol(context.referenceClassId(klassSymbol)) body.buildConstI32Symbol(context.referenceClassId(klassSymbol))
body.buildConstI32(0) // Any::_hashCode body.buildConstI32(0, location) // Any::_hashCode
body.commentGroupEnd() body.commentGroupEnd()
} }
@@ -311,7 +314,7 @@ class BodyGenerator(
body.buildGetLocal(thisParameter) body.buildGetLocal(thisParameter)
body.buildInstr(WasmOp.REF_IS_NULL) body.buildInstr(WasmOp.REF_IS_NULL)
body.buildIf("this_init") body.buildIf("this_init")
generateAnyParameters(parentClass.symbol) generateAnyParameters(parentClass.symbol, SourceLocation.NoLocation("Constructor preamble"))
val irFields: List<IrField> = parentClass.allFields(backendContext.irBuiltIns) val irFields: List<IrField> = parentClass.allFields(backendContext.irBuiltIns)
irFields.forEachIndexed { index, field -> irFields.forEachIndexed { index, field ->
if (index > 1) { if (index > 1) {
@@ -339,7 +342,7 @@ class BodyGenerator(
private fun generateBox(expression: IrExpression, type: IrType) { private fun generateBox(expression: IrExpression, type: IrType) {
val klassSymbol = type.getRuntimeClass(irBuiltIns).symbol val klassSymbol = type.getRuntimeClass(irBuiltIns).symbol
generateAnyParameters(klassSymbol) generateAnyParameters(klassSymbol, expression.getSourceLocation())
generateExpression(expression) generateExpression(expression)
body.buildStructNew(context.referenceGcType(klassSymbol)) body.buildStructNew(context.referenceGcType(klassSymbol))
body.commentPreviousInstr { "box" } body.commentPreviousInstr { "box" }
@@ -459,14 +462,14 @@ class BodyGenerator(
} }
} }
private fun generateRefTest(fromType: IrType, toType: IrType) { private fun generateRefTest(fromType: IrType, toType: IrType, location: SourceLocation) {
if (!isDownCastAlwaysSuccessInRuntime(fromType, toType)) { if (!isDownCastAlwaysSuccessInRuntime(fromType, toType)) {
body.buildRefTestStatic( body.buildRefTestStatic(
toType = context.referenceGcType(toType.getRuntimeClass(irBuiltIns).symbol) toType = context.referenceGcType(toType.getRuntimeClass(irBuiltIns).symbol)
) )
} else { } else {
body.buildDrop() body.buildDrop()
body.buildConstI32(1) body.buildConstI32(1, location)
} }
} }
@@ -488,109 +491,115 @@ class BodyGenerator(
return true return true
} }
when (function.symbol) { withLocation(call.getSourceLocation()) {
wasmSymbols.wasmClassId -> { when (function.symbol) {
val klass = call.getTypeArgument(0)!!.getClass() wasmSymbols.wasmClassId -> {
?: error("No class given for wasmClassId intrinsic") val klass = call.getTypeArgument(0)!!.getClass()
assert(!klass.isInterface) ?: error("No class given for wasmClassId intrinsic")
body.buildConstI32Symbol(context.referenceClassId(klass.symbol)) assert(!klass.isInterface)
} body.buildConstI32Symbol(context.referenceClassId(klass.symbol))
}
wasmSymbols.wasmInterfaceId -> { wasmSymbols.wasmInterfaceId -> {
val irInterface = call.getTypeArgument(0)!!.getClass() val irInterface = call.getTypeArgument(0)!!.getClass()
?: error("No interface given for wasmInterfaceId intrinsic") ?: error("No interface given for wasmInterfaceId intrinsic")
assert(irInterface.isInterface) assert(irInterface.isInterface)
body.buildConstI32Symbol(context.referenceInterfaceId(irInterface.symbol)) body.buildConstI32Symbol(context.referenceInterfaceId(irInterface.symbol))
} }
wasmSymbols.wasmIsInterface -> { wasmSymbols.wasmIsInterface -> {
val irInterface = call.getTypeArgument(0)!!.getClass() val irInterface = call.getTypeArgument(0)!!.getClass()
?: error("No interface given for wasmInterfaceId intrinsic") ?: error("No interface given for wasmInterfaceId intrinsic")
assert(irInterface.isInterface) assert(irInterface.isInterface)
if (irInterface.symbol in hierarchyDisjointUnions) { if (irInterface.symbol in hierarchyDisjointUnions) {
val classITable = context.referenceClassITableGcType(irInterface.symbol) val classITable = context.referenceClassITableGcType(irInterface.symbol)
val parameterLocal = functionContext.referenceLocal(SyntheticLocalType.IS_INTERFACE_PARAMETER) val parameterLocal = functionContext.referenceLocal(SyntheticLocalType.IS_INTERFACE_PARAMETER)
body.buildSetLocal(parameterLocal) body.buildSetLocal(parameterLocal)
body.buildBlock("isInterface", WasmI32) { outerLabel -> body.buildBlock("isInterface", WasmI32) { outerLabel ->
body.buildBlock("isInterface", WasmRefNullType(WasmHeapType.Simple.Data)) { innerLabel -> body.buildBlock("isInterface", WasmRefNullType(WasmHeapType.Simple.Data)) { innerLabel ->
body.buildGetLocal(parameterLocal) body.buildGetLocal(parameterLocal)
body.buildStructGet(context.referenceGcType(irBuiltIns.anyClass), WasmSymbol(1)) body.buildStructGet(context.referenceGcType(irBuiltIns.anyClass), WasmSymbol(1))
body.buildBrInstr(WasmOp.BR_ON_CAST_FAIL_DEPRECATED, innerLabel, classITable) body.buildBrInstr(WasmOp.BR_ON_CAST_FAIL_DEPRECATED, innerLabel, classITable)
body.buildStructGet(classITable, context.referenceClassITableInterfaceSlot(irInterface.symbol)) body.buildStructGet(classITable, context.referenceClassITableInterfaceSlot(irInterface.symbol))
body.buildInstr(WasmOp.REF_IS_NULL) body.buildInstr(WasmOp.REF_IS_NULL)
body.buildInstr(WasmOp.I32_EQZ) body.buildInstr(WasmOp.I32_EQZ)
body.buildBr(outerLabel) body.buildBr(outerLabel)
}
body.buildDrop()
body.buildConstI32(0, location)
} }
} else {
body.buildDrop() body.buildDrop()
body.buildConstI32(0) body.buildConstI32(0, location)
} }
} else {
body.buildDrop()
body.buildConstI32(0)
}
}
wasmSymbols.refCastNull -> {
generateRefNullCast(
fromType = call.getValueArgument(0)!!.type,
toType = call.getTypeArgument(0)!!
)
}
wasmSymbols.refTest -> {
generateRefTest(
fromType = call.getValueArgument(0)!!.type,
toType = call.getTypeArgument(0)!!
)
}
wasmSymbols.unboxIntrinsic -> {
val fromType = call.getTypeArgument(0)!!
if (fromType.isNothing()) {
body.buildUnreachable()
// TODO: Investigate why?
return true
} }
// Workaround test codegen/box/elvis/nullNullOk.kt wasmSymbols.refCastNull -> {
if (fromType.makeNotNull().isNothing()) { generateRefNullCast(
body.buildUnreachable() fromType = call.getValueArgument(0)!!.type,
return true toType = call.getTypeArgument(0)!!
)
} }
val toType = call.getTypeArgument(1)!! wasmSymbols.refTest -> {
val klass: IrClass = backendContext.inlineClassesUtils.getInlinedClass(toType)!! generateRefTest(
val field = getInlineClassBackingField(klass) fromType = call.getValueArgument(0)!!.type,
toType = call.getTypeArgument(0)!!,
location
)
}
generateRefNullCast(fromType, toType) wasmSymbols.unboxIntrinsic -> {
generateInstanceFieldAccess(field) val fromType = call.getTypeArgument(0)!!
}
wasmSymbols.unsafeGetScratchRawMemory -> { if (fromType.isNothing()) {
body.buildConstI32Symbol(context.scratchMemAddr) body.buildUnreachable()
} // TODO: Investigate why?
return true
}
wasmSymbols.wasmArrayCopy -> { // Workaround test codegen/box/elvis/nullNullOk.kt
val immediate = WasmImmediate.GcType( if (fromType.makeNotNull().isNothing()) {
context.referenceGcType(call.getTypeArgument(0)!!.getRuntimeClass(irBuiltIns).symbol) body.buildUnreachable()
) return true
body.buildInstr(WasmOp.ARRAY_COPY, immediate, immediate) }
}
wasmSymbols.stringGetPoolSize -> { val toType = call.getTypeArgument(1)!!
body.buildConstI32Symbol(context.stringPoolSize) val klass: IrClass = backendContext.inlineClassesUtils.getInlinedClass(toType)!!
} val field = getInlineClassBackingField(klass)
wasmSymbols.wasmArrayNewData0 -> { generateRefNullCast(fromType, toType)
val arrayGcType = WasmImmediate.GcType( generateInstanceFieldAccess(field)
context.referenceGcType(call.getTypeArgument(0)!!.getRuntimeClass(irBuiltIns).symbol) }
)
body.buildInstr(WasmOp.ARRAY_NEW_DATA, arrayGcType, WasmImmediate.DataIdx(0))
}
else -> { wasmSymbols.unsafeGetScratchRawMemory -> {
return false
body.buildConstI32Symbol(context.scratchMemAddr)
}
wasmSymbols.wasmArrayCopy -> {
val immediate = WasmImmediate.GcType(
context.referenceGcType(call.getTypeArgument(0)!!.getRuntimeClass(irBuiltIns).symbol)
)
body.buildInstr(WasmOp.ARRAY_COPY, immediate, immediate)
}
wasmSymbols.stringGetPoolSize -> {
body.buildConstI32Symbol(context.stringPoolSize)
}
wasmSymbols.wasmArrayNewData0 -> {
val arrayGcType = WasmImmediate.GcType(
context.referenceGcType(call.getTypeArgument(0)!!.getRuntimeClass(irBuiltIns).symbol)
)
body.buildInstr(WasmOp.ARRAY_NEW_DATA, arrayGcType, WasmImmediate.DataIdx(0))
}
else -> {
return false
}
} }
} }
return true return true
@@ -30,6 +30,7 @@ import org.jetbrains.kotlin.ir.visitors.acceptVoid
import org.jetbrains.kotlin.name.parentOrNull import org.jetbrains.kotlin.name.parentOrNull
import org.jetbrains.kotlin.wasm.ir.* import org.jetbrains.kotlin.wasm.ir.*
import org.jetbrains.kotlin.wasm.ir.source.location.withLocation import org.jetbrains.kotlin.wasm.ir.source.location.withLocation
import org.jetbrains.kotlin.wasm.ir.source.location.withNoLocation
class DeclarationGenerator( class DeclarationGenerator(
val context: WasmModuleCodegenContext, val context: WasmModuleCodegenContext,
@@ -472,19 +473,22 @@ class DeclarationGenerator(
} }
} }
fun generateDefaultInitializerForType(type: WasmType, g: WasmExpressionBuilder) = when (type) { fun generateDefaultInitializerForType(type: WasmType, g: WasmExpressionBuilder) =
WasmI32 -> g.buildConstI32(0) withNoLocation("Default initializer, usually don't require location") {
WasmI64 -> g.buildConstI64(0) when (type) {
WasmF32 -> g.buildConstF32(0f) WasmI32 -> g.buildConstI32(0, location)
WasmF64 -> g.buildConstF64(0.0) WasmI64 -> g.buildConstI64(0)
is WasmRefNullType -> g.buildRefNull(type.heapType) WasmF32 -> g.buildConstF32(0f)
is WasmRefNullNoneType -> g.buildRefNull(WasmHeapType.Simple.NullNone) WasmF64 -> g.buildConstF64(0.0)
is WasmRefNullExternrefType -> g.buildRefNull(WasmHeapType.Simple.NullNoExtern) is WasmRefNullType -> g.buildRefNull(type.heapType)
is WasmAnyRef -> g.buildRefNull(WasmHeapType.Simple.Any) is WasmRefNullNoneType -> g.buildRefNull(WasmHeapType.Simple.NullNone)
is WasmExternRef -> g.buildRefNull(WasmHeapType.Simple.Extern) is WasmRefNullExternrefType -> g.buildRefNull(WasmHeapType.Simple.NullNoExtern)
WasmUnreachableType -> error("Unreachable type can't be initialized") is WasmAnyRef -> g.buildRefNull(WasmHeapType.Simple.Any)
else -> error("Unknown value type ${type.name}") is WasmExternRef -> g.buildRefNull(WasmHeapType.Simple.Extern)
} WasmUnreachableType -> error("Unreachable type can't be initialized")
else -> error("Unknown value type ${type.name}")
}
}
fun IrFunction.getEffectiveValueParameters(): List<IrValueParameter> { fun IrFunction.getEffectiveValueParameters(): List<IrValueParameter> {
val implicitThis = if (this is IrConstructor) parentAsClass.thisReceiver!! else null val implicitThis = if (this is IrConstructor) parentAsClass.thisReceiver!! else null
@@ -502,12 +506,12 @@ fun generateConstExpression(expression: IrConst<*>, body: WasmExpressionBuilder,
val bottomType = if (expression.type.getClass()?.isExternal == true) WasmRefNullExternrefType else WasmRefNullNoneType val bottomType = if (expression.type.getClass()?.isExternal == true) WasmRefNullExternrefType else WasmRefNullNoneType
body.buildInstr(WasmOp.REF_NULL, WasmImmediate.HeapType(bottomType)) body.buildInstr(WasmOp.REF_NULL, WasmImmediate.HeapType(bottomType))
} }
is IrConstKind.Boolean -> body.buildConstI32(if (kind.valueOf(expression)) 1 else 0) is IrConstKind.Boolean -> body.buildConstI32(if (kind.valueOf(expression)) 1 else 0, location)
is IrConstKind.Byte -> body.buildConstI32(kind.valueOf(expression).toInt()) is IrConstKind.Byte -> body.buildConstI32(kind.valueOf(expression).toInt(), location)
is IrConstKind.Short -> body.buildConstI32(kind.valueOf(expression).toInt()) is IrConstKind.Short -> body.buildConstI32(kind.valueOf(expression).toInt(), location)
is IrConstKind.Int -> body.buildConstI32(kind.valueOf(expression)) is IrConstKind.Int -> body.buildConstI32(kind.valueOf(expression), location)
is IrConstKind.Long -> body.buildConstI64(kind.valueOf(expression)) is IrConstKind.Long -> body.buildConstI64(kind.valueOf(expression))
is IrConstKind.Char -> body.buildConstI32(kind.valueOf(expression).code) is IrConstKind.Char -> body.buildConstI32(kind.valueOf(expression).code, location)
is IrConstKind.Float -> body.buildConstF32(kind.valueOf(expression)) is IrConstKind.Float -> body.buildConstF32(kind.valueOf(expression))
is IrConstKind.Double -> body.buildConstF64(kind.valueOf(expression)) is IrConstKind.Double -> body.buildConstF64(kind.valueOf(expression))
is IrConstKind.String -> { is IrConstKind.String -> {
@@ -516,7 +520,7 @@ fun generateConstExpression(expression: IrConst<*>, body: WasmExpressionBuilder,
body.commentGroupStart { "const string: \"$stringValue\"" } body.commentGroupStart { "const string: \"$stringValue\"" }
body.buildConstI32Symbol(literalPoolId) body.buildConstI32Symbol(literalPoolId)
body.buildConstI32Symbol(literalAddress) body.buildConstI32Symbol(literalAddress)
body.buildConstI32(stringValue.length) body.buildConstI32(stringValue.length, location)
body.buildCall(context.referenceFunction(context.backendContext.wasmSymbols.stringGetLiteral), location) body.buildCall(context.referenceFunction(context.backendContext.wasmSymbols.stringGetLiteral), location)
body.commentGroupEnd() body.commentGroupEnd()
} }
@@ -12,6 +12,7 @@ import org.jetbrains.kotlin.ir.types.IrType
import org.jetbrains.kotlin.ir.types.isUnit import org.jetbrains.kotlin.ir.types.isUnit
import org.jetbrains.kotlin.ir.util.isElseBranch import org.jetbrains.kotlin.ir.util.isElseBranch
import org.jetbrains.kotlin.wasm.ir.* import org.jetbrains.kotlin.wasm.ir.*
import org.jetbrains.kotlin.wasm.ir.source.location.SourceLocation
private class ExtractedWhenCondition<T>(val condition: IrCall, val const: IrConst<T>) private class ExtractedWhenCondition<T>(val condition: IrCall, val const: IrConst<T>)
private class ExtractedWhenBranch<T>(val conditions: List<ExtractedWhenCondition<T>>, val expression: IrExpression) private class ExtractedWhenBranch<T>(val conditions: List<ExtractedWhenCondition<T>>, val expression: IrExpression)
@@ -134,11 +135,13 @@ private fun BodyGenerator.createBinaryTable(selectorLocal: WasmLocal, intBranche
intBranches.flatMapIndexedTo(sortedCaseToBranchIndex) { index, branch -> branch.conditions.map { it.const.value to index } } intBranches.flatMapIndexedTo(sortedCaseToBranchIndex) { index, branch -> branch.conditions.map { it.const.value to index } }
sortedCaseToBranchIndex.sortBy { it.first } sortedCaseToBranchIndex.sortBy { it.first }
val location = SourceLocation.NoLocation("When's binary search infra")
val thenBody = { result: Int -> val thenBody = { result: Int ->
body.buildConstI32(result) body.buildConstI32(result, location)
} }
val elseBody: () -> Unit = { val elseBody: () -> Unit = {
body.buildConstI32(intBranches.size) body.buildConstI32(intBranches.size, location)
} }
createBinaryTable(selectorLocal, WasmI32, sortedCaseToBranchIndex, 0, sortedCaseToBranchIndex.size, thenBody, elseBody) createBinaryTable(selectorLocal, WasmI32, sortedCaseToBranchIndex, 0, sortedCaseToBranchIndex.size, thenBody, elseBody)
} }
@@ -240,11 +243,13 @@ private fun <T> BodyGenerator.createBinaryTable(
thenBody: (T) -> Unit, thenBody: (T) -> Unit,
elseBody: () -> Unit elseBody: () -> Unit
) { ) {
val location = SourceLocation.NoLocation("When's binary search infra")
val size = toExcl - fromIncl val size = toExcl - fromIncl
if (size == 1) { if (size == 1) {
val (case, result) = sortedCases[fromIncl] val (case, result) = sortedCases[fromIncl]
body.buildGetLocal(selectorLocal) body.buildGetLocal(selectorLocal)
body.buildConstI32(case) body.buildConstI32(case, location)
body.buildInstr(WasmOp.I32_EQ) body.buildInstr(WasmOp.I32_EQ)
body.buildIf("binary_tree_branch", resultType) body.buildIf("binary_tree_branch", resultType)
thenBody(result) thenBody(result)
@@ -257,7 +262,7 @@ private fun <T> BodyGenerator.createBinaryTable(
val border = fromIncl + size / 2 val border = fromIncl + size / 2
body.buildGetLocal(selectorLocal) body.buildGetLocal(selectorLocal)
body.buildConstI32(sortedCases[border].first) body.buildConstI32(sortedCases[border].first, location)
body.buildInstr(WasmOp.I32_LT_S) body.buildInstr(WasmOp.I32_LT_S)
body.buildIf("binary_tree_node", resultType) body.buildIf("binary_tree_node", resultType)
createBinaryTable(selectorLocal, resultType, sortedCases, fromIncl, border, thenBody, elseBody) createBinaryTable(selectorLocal, resultType, sortedCases, fromIncl, border, thenBody, elseBody)
@@ -299,6 +304,8 @@ private fun BodyGenerator.genTableIntSwitch(
brTable: List<Int>, brTable: List<Int>,
expectedType: IrType, expectedType: IrType,
) { ) {
val location = SourceLocation.NoLocation("When's binary search infra")
val baseBlockIndex = body.numberOfNestedBlocks val baseBlockIndex = body.numberOfNestedBlocks
//expressions + else branch + br_table //expressions + else branch + br_table
repeat(branches.size + 2) { repeat(branches.size + 2) {
@@ -308,7 +315,7 @@ private fun BodyGenerator.genTableIntSwitch(
resultType?.let { generateDefaultInitializerForType(it, body) } //stub value resultType?.let { generateDefaultInitializerForType(it, body) } //stub value
body.buildGetLocal(selectorLocal) body.buildGetLocal(selectorLocal)
if (shift != 0) { if (shift != 0) {
body.buildConstI32(shift) body.buildConstI32(shift, location)
body.buildInstr(WasmOp.I32_SUB) body.buildInstr(WasmOp.I32_SUB)
} }
body.buildInstr( body.buildInstr(
@@ -257,7 +257,7 @@ inline fun WasmCompiledModuleFragment.ReferencableAndDefinable<IrClassSymbol, Co
elements.mapTo(into) { elements.mapTo(into) {
val id = address(wasmToIr.getValue(it)) val id = address(wasmToIr.getValue(it))
val offset = mutableListOf<WasmInstr>() val offset = mutableListOf<WasmInstr>()
WasmIrExpressionBuilder(offset).buildConstI32(id) WasmIrExpressionBuilder(offset).buildConstI32(id, SourceLocation.NoLocation("Compile time data per class"))
WasmData(WasmDataMode.Active(0, offset), it.toBytes()) WasmData(WasmDataMode.Active(0, offset), it.toBytes())
} }
} }
@@ -65,8 +65,8 @@ sealed class WasmDataMode {
val memoryIdx: Int, val memoryIdx: Int,
val offset: MutableList<WasmInstr> val offset: MutableList<WasmInstr>
) : WasmDataMode() { ) : WasmDataMode() {
constructor(memoryIdx: Int, offset: Int) : this(memoryIdx, mutableListOf<WasmInstr>().also<MutableList<WasmInstr>> { constructor(memoryIdx: Int, offset: Int, location: SourceLocation) : this(memoryIdx, mutableListOf<WasmInstr>().also<MutableList<WasmInstr>> {
WasmIrExpressionBuilder(it).buildConstI32(offset) WasmIrExpressionBuilder(it).buildConstI32(offset, location)
}) })
} }
@@ -16,7 +16,7 @@ abstract class WasmExpressionBuilder {
abstract var numberOfNestedBlocks: Int abstract var numberOfNestedBlocks: Int
fun buildConstI32(value: Int, location: SourceLocation = SourceLocation.TBDLocation) { fun buildConstI32(value: Int, location: SourceLocation) {
buildInstr(WasmOp.I32_CONST, location, WasmImmediate.ConstI32(value)) buildInstr(WasmOp.I32_CONST, location, WasmImmediate.ConstI32(value))
} }