[Wasm] Remove buildInstr without location and fix usages

This commit is contained in:
Zalim Bashorov
2022-12-13 20:35:41 +01:00
parent 42f2edd282
commit 0d203d190e
4 changed files with 45 additions and 37 deletions
@@ -47,7 +47,11 @@ class BodyGenerator(
private val unitGetInstance by lazy { backendContext.findUnitGetInstanceFunction() }
fun WasmExpressionBuilder.buildGetUnit() {
buildInstr(WasmOp.GET_UNIT, WasmImmediate.FuncIdx(context.referenceFunction(unitGetInstance.symbol)))
buildInstr(
WasmOp.GET_UNIT,
SourceLocation.NoLocation("GET_UNIT"),
WasmImmediate.FuncIdx(context.referenceFunction(unitGetInstance.symbol))
)
}
private val anyConstructor by lazy {
@@ -107,7 +111,7 @@ class BodyGenerator(
withLocation(irVararg.getSourceLocation()) {
body.buildConstI32(0, location)
body.buildConstI32(irVararg.elements.size, location)
body.buildInstr(WasmOp.ARRAY_NEW_DATA, wasmArrayType, WasmImmediate.DataIdx(constantArrayId))
body.buildInstr(WasmOp.ARRAY_NEW_DATA, location, wasmArrayType, WasmImmediate.DataIdx(constantArrayId))
}
return true
}
@@ -119,7 +123,7 @@ class BodyGenerator(
}
val length = WasmImmediate.ConstI32(irVararg.elements.size)
body.buildInstr(WasmOp.ARRAY_NEW_FIXED, wasmArrayType, length)
body.buildInstr(WasmOp.ARRAY_NEW_FIXED, irVararg.getSourceLocation(), wasmArrayType, length)
}
override fun visitVararg(expression: IrVararg) {
@@ -181,21 +185,22 @@ class BodyGenerator(
override fun visitGetField(expression: IrGetField) {
val field: IrField = expression.symbol.owner
val receiver: IrExpression? = expression.receiver
val location = expression.getSourceLocation()
if (receiver != null) {
generateExpression(receiver)
if (backendContext.inlineClassesUtils.isClassInlineLike(field.parentAsClass)) {
// Unboxed inline class instance is already represented as backing field.
// Doing nothing.
} else {
generateInstanceFieldAccess(field)
generateInstanceFieldAccess(field, location)
}
} else {
body.buildGetGlobal(context.referenceGlobalField(field.symbol), expression.getSourceLocation())
body.buildGetGlobal(context.referenceGlobalField(field.symbol), location)
body.commentPreviousInstr { "type: ${field.type.render()}" }
}
}
private fun generateInstanceFieldAccess(field: IrField) {
private fun generateInstanceFieldAccess(field: IrField, location: SourceLocation) {
val opcode = when (field.type) {
irBuiltIns.charType ->
WasmOp.STRUCT_GET_U
@@ -210,6 +215,7 @@ class BodyGenerator(
body.buildInstr(
opcode,
location,
WasmImmediate.GcType(context.referenceGcType(field.parentAsClass.symbol)),
WasmImmediate.StructFieldIdx(context.getStructFieldRef(field))
)
@@ -275,20 +281,20 @@ class BodyGenerator(
}
val wasmGcType: WasmSymbol<WasmTypeDeclaration> = context.referenceGcType(klassSymbol)
val location = expression.getSourceLocation()
if (klass.getWasmArrayAnnotation() != null) {
require(expression.valueArgumentsCount == 1) { "@WasmArrayOf constructs must have exactly one argument" }
generateExpression(expression.getValueArgument(0)!!)
body.buildInstr(
WasmOp.ARRAY_NEW_DEFAULT,
location,
WasmImmediate.GcType(wasmGcType)
)
body.commentPreviousInstr { "@WasmArrayOf ctor call: ${klass.fqNameWhenAvailable}" }
return
}
val location = expression.getSourceLocation()
if (expression.symbol.owner.hasWasmPrimitiveConstructorAnnotation()) {
generateAnyParameters(klassSymbol, location)
for (i in 0 until expression.valueArgumentsCount) {
@@ -326,7 +332,7 @@ class BodyGenerator(
body.commentGroupStart { "Object creation prefix" }
withNoLocation("Constructor preamble") {
body.buildGetLocal(thisParameter, location)
body.buildInstr(WasmOp.REF_IS_NULL)
body.buildInstr(WasmOp.REF_IS_NULL, location)
body.buildIf("this_init")
generateAnyParameters(parentClass.symbol, location)
val irFields: List<IrField> = parentClass.allFields(backendContext.irBuiltIns)
@@ -435,7 +441,7 @@ class BodyGenerator(
body.buildStructGet(context.referenceGcType(klass.symbol), WasmSymbol(0), location)
body.buildStructGet(context.referenceVTableGcType(klass.symbol), WasmSymbol(vfSlot), location)
body.buildInstr(WasmOp.CALL_REF, WasmImmediate.TypeIdx(context.referenceFunctionType(function.symbol)))
body.buildInstr(WasmOp.CALL_REF, location, WasmImmediate.TypeIdx(context.referenceFunctionType(function.symbol)))
body.commentGroupEnd()
} else {
val symbol = klass.symbol
@@ -453,7 +459,7 @@ class BodyGenerator(
.indexOfFirst { it.function == function }
body.buildStructGet(context.referenceVTableGcType(symbol), WasmSymbol(vfSlot), location)
body.buildInstr(WasmOp.CALL_REF, WasmImmediate.TypeIdx(context.referenceFunctionType(function.symbol)))
body.buildInstr(WasmOp.CALL_REF, location, WasmImmediate.TypeIdx(context.referenceFunctionType(function.symbol)))
body.commentGroupEnd()
} else {
// We came here for a call to an interface method which interface is not implemented anywhere,
@@ -542,8 +548,8 @@ class BodyGenerator(
body.buildStructGet(context.referenceGcType(irBuiltIns.anyClass), WasmSymbol(1), location)
body.buildBrInstr(WasmOp.BR_ON_CAST_FAIL_DEPRECATED, innerLabel, classITable, location)
body.buildStructGet(classITable, context.referenceClassITableInterfaceSlot(irInterface.symbol), location)
body.buildInstr(WasmOp.REF_IS_NULL)
body.buildInstr(WasmOp.I32_EQZ)
body.buildInstr(WasmOp.REF_IS_NULL, location)
body.buildInstr(WasmOp.I32_EQZ, location)
body.buildBr(outerLabel, location)
}
body.buildDrop(location)
@@ -585,7 +591,7 @@ class BodyGenerator(
val field = getInlineClassBackingField(klass)
generateRefNullCast(fromType, toType, location)
generateInstanceFieldAccess(field)
generateInstanceFieldAccess(field, location)
}
wasmSymbols.unsafeGetScratchRawMemory -> {
@@ -596,7 +602,7 @@ class BodyGenerator(
val immediate = WasmImmediate.GcType(
context.referenceGcType(call.getTypeArgument(0)!!.getRuntimeClass(irBuiltIns).symbol)
)
body.buildInstr(WasmOp.ARRAY_COPY, immediate, immediate)
body.buildInstr(WasmOp.ARRAY_COPY, location, immediate, immediate)
}
wasmSymbols.stringGetPoolSize -> {
@@ -607,7 +613,7 @@ class BodyGenerator(
val arrayGcType = WasmImmediate.GcType(
context.referenceGcType(call.getTypeArgument(0)!!.getRuntimeClass(irBuiltIns).symbol)
)
body.buildInstr(WasmOp.ARRAY_NEW_DATA, arrayGcType, WasmImmediate.DataIdx(0))
body.buildInstr(WasmOp.ARRAY_NEW_DATA, location, arrayGcType, WasmImmediate.DataIdx(0))
}
else -> {
@@ -892,10 +898,11 @@ class BodyGenerator(
val opString = function.getWasmOpAnnotation()
if (opString != null) {
val location = call.getSourceLocation()
val op = WasmOp.valueOf(opString)
when (op.immediates.size) {
0 -> {
body.buildInstr(op)
body.buildInstr(op, location)
}
1 -> {
fun getReferenceGcType(): WasmSymbol<WasmTypeDeclaration> {
@@ -920,7 +927,7 @@ class BodyGenerator(
error("Immediate $imm is unsupported")
}
)
body.buildInstr(op, *immediates)
body.buildInstr(op, location, *immediates)
}
else ->
error("Op $opString is unsupported")
@@ -166,7 +166,7 @@ class DeclarationGenerator(
// TODO: Redesign construction scheme.
if (declaration is IrConstructor) {
exprGen.buildGetLocal(/*implicit this*/ function.locals[0], SourceLocation.NoLocation("Get implicit dispatch receiver"))
exprGen.buildInstr(WasmOp.RETURN)
exprGen.buildInstr(WasmOp.RETURN, SourceLocation.NoLocation("Implicit return from constructor"))
}
// Add unreachable if function returns something but not as a last instruction.
@@ -261,7 +261,7 @@ class DeclarationGenerator(
val location = SourceLocation.NoLocation("Create instance of vtable struct")
metadata.virtualMethods.forEachIndexed { i, method ->
if (method.function.modality != Modality.ABSTRACT) {
buildInstr(WasmOp.REF_FUNC, WasmImmediate.FuncIdx(context.referenceFunction(method.function.symbol)))
buildInstr(WasmOp.REF_FUNC, location, WasmImmediate.FuncIdx(context.referenceFunction(method.function.symbol)))
} else {
check(allowIncompleteImplementations) {
"Cannot find class implementation of method ${method.signature} in class ${klass.fqNameWhenAvailable}"
@@ -309,7 +309,7 @@ class DeclarationGenerator(
if (classMethod != null) {
val functionTypeReference = context.referenceFunction(classMethod.function.symbol)
buildInstr(WasmOp.REF_FUNC, WasmImmediate.FuncIdx(functionTypeReference))
buildInstr(WasmOp.REF_FUNC, location, WasmImmediate.FuncIdx(functionTypeReference))
} else {
//This erased by DCE so abstract version appeared in non-abstract class
buildRefNull(WasmHeapType.Type(context.referenceFunctionType(method.function.symbol)), location)
@@ -507,7 +507,7 @@ fun generateConstExpression(expression: IrConst<*>, body: WasmExpressionBuilder,
when (val kind = expression.kind) {
is IrConstKind.Null -> {
val bottomType = if (expression.type.getClass()?.isExternal == true) WasmRefNullExternrefType else WasmRefNullNoneType
body.buildInstr(WasmOp.REF_NULL, WasmImmediate.HeapType(bottomType))
body.buildInstr(WasmOp.REF_NULL, location, WasmImmediate.HeapType(bottomType))
}
is IrConstKind.Boolean -> body.buildConstI32(if (kind.valueOf(expression)) 1 else 0, location)
is IrConstKind.Byte -> body.buildConstI32(kind.valueOf(expression).toInt(), location)
@@ -256,7 +256,7 @@ private fun <T> BodyGenerator.createBinaryTable(
val (case, result) = sortedCases[fromIncl]
body.buildGetLocal(selectorLocal, location)
body.buildConstI32(case, location)
body.buildInstr(WasmOp.I32_EQ)
body.buildInstr(WasmOp.I32_EQ, location)
body.buildIf("binary_tree_branch", resultType)
thenBody(result)
body.buildElse()
@@ -269,7 +269,7 @@ private fun <T> BodyGenerator.createBinaryTable(
body.buildGetLocal(selectorLocal, location)
body.buildConstI32(sortedCases[border].first, location)
body.buildInstr(WasmOp.I32_LT_S)
body.buildInstr(WasmOp.I32_LT_S, location)
body.buildIf("binary_tree_node", resultType)
createBinaryTable(selectorLocal, resultType, sortedCases, fromIncl, border, thenBody, elseBody)
body.buildElse()
@@ -322,10 +322,11 @@ private fun BodyGenerator.genTableIntSwitch(
body.buildGetLocal(selectorLocal, location)
if (shift != 0) {
body.buildConstI32(shift, location)
body.buildInstr(WasmOp.I32_SUB)
body.buildInstr(WasmOp.I32_SUB, location)
}
body.buildInstr(
WasmOp.BR_TABLE,
location,
WasmImmediate.LabelIdxVector(brTable),
WasmImmediate.LabelIdx(branches.size)
)
@@ -10,10 +10,6 @@ import org.jetbrains.kotlin.wasm.ir.source.location.SourceLocation
abstract class WasmExpressionBuilder {
abstract fun buildInstr(op: WasmOp, location: SourceLocation, vararg immediates: WasmImmediate)
fun buildInstr(op: WasmOp, vararg immediates: WasmImmediate) {
buildInstr(op, SourceLocation.TBDLocation, *immediates)
}
abstract var numberOfNestedBlocks: Int
fun buildConstI32(value: Int, location: SourceLocation) {
@@ -43,7 +39,7 @@ abstract class WasmExpressionBuilder {
@Suppress("UNUSED_PARAMETER")
inline fun buildBlock(label: String?, resultType: WasmType? = null, body: (Int) -> Unit) {
numberOfNestedBlocks++
buildInstr(WasmOp.BLOCK, WasmImmediate.BlockType.Value(resultType))
buildInstr(WasmOp.BLOCK, SourceLocation.NoLocation("BLOCK"), WasmImmediate.BlockType.Value(resultType))
body(numberOfNestedBlocks)
buildEnd()
}
@@ -51,30 +47,34 @@ abstract class WasmExpressionBuilder {
@Suppress("UNUSED_PARAMETER")
inline fun buildLoop(label: String?, resultType: WasmType? = null, body: (Int) -> Unit) {
numberOfNestedBlocks++
buildInstr(WasmOp.LOOP, WasmImmediate.BlockType.Value(resultType))
buildInstr(WasmOp.LOOP, SourceLocation.NoLocation("LOOP"), WasmImmediate.BlockType.Value(resultType))
body(numberOfNestedBlocks)
buildEnd()
}
private fun buildInstrWithNoLocation(op: WasmOp, vararg immediates: WasmImmediate) {
buildInstr(op, SourceLocation.NoLocation(op.mnemonic), *immediates)
}
@Suppress("UNUSED_PARAMETER")
fun buildIf(label: String?, resultType: WasmType? = null) {
numberOfNestedBlocks++
buildInstr(WasmOp.IF, WasmImmediate.BlockType.Value(resultType))
buildInstrWithNoLocation(WasmOp.IF, WasmImmediate.BlockType.Value(resultType))
}
fun buildElse() {
buildInstr(WasmOp.ELSE)
buildInstrWithNoLocation(WasmOp.ELSE)
}
fun buildBlock(resultType: WasmType? = null): Int {
numberOfNestedBlocks++
buildInstr(WasmOp.BLOCK, WasmImmediate.BlockType.Value(resultType))
buildInstrWithNoLocation(WasmOp.BLOCK, WasmImmediate.BlockType.Value(resultType))
return numberOfNestedBlocks
}
fun buildEnd() {
numberOfNestedBlocks--
buildInstr(WasmOp.END)
buildInstrWithNoLocation(WasmOp.END)
}
@@ -101,11 +101,11 @@ abstract class WasmExpressionBuilder {
@Suppress("UNUSED_PARAMETER")
fun buildTry(label: String?, resultType: WasmType? = null) {
numberOfNestedBlocks++
buildInstr(WasmOp.TRY, WasmImmediate.BlockType.Value(resultType))
buildInstrWithNoLocation(WasmOp.TRY, WasmImmediate.BlockType.Value(resultType))
}
fun buildCatch(tagIdx: Int) {
buildInstr(WasmOp.CATCH, WasmImmediate.TagIdx(tagIdx))
buildInstrWithNoLocation(WasmOp.CATCH, WasmImmediate.TagIdx(tagIdx))
}
fun buildBrIf(absoluteBlockLevel: Int, location: SourceLocation) {