[Wasm] Add comments to .wat files
This commit is contained in:
committed by
Space Team
parent
41dbbd1fc8
commit
62ac77ca39
+18
@@ -181,6 +181,7 @@ class BodyGenerator(
|
||||
}
|
||||
} else {
|
||||
body.buildGetGlobal(context.referenceGlobalField(field.symbol))
|
||||
body.commentPreviousInstr { "type: ${field.type.render()}" }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -202,6 +203,7 @@ class BodyGenerator(
|
||||
WasmImmediate.GcType(context.referenceGcType(field.parentAsClass.symbol)),
|
||||
WasmImmediate.StructFieldIdx(context.getStructFieldRef(field))
|
||||
)
|
||||
body.commentPreviousInstr { "name: ${field.name.asString()}, type: ${field.type.render()}" }
|
||||
}
|
||||
|
||||
override fun visitSetField(expression: IrSetField) {
|
||||
@@ -215,9 +217,11 @@ class BodyGenerator(
|
||||
struct = context.referenceGcType(field.parentAsClass.symbol),
|
||||
fieldId = context.getStructFieldRef(field),
|
||||
)
|
||||
body.commentPreviousInstr { "name: ${field.name}, type: ${field.type.render()}" }
|
||||
} else {
|
||||
generateExpression(expression.value)
|
||||
body.buildSetGlobal(context.referenceGlobalField(expression.symbol))
|
||||
body.commentPreviousInstr { "type: ${field.type.render()}" }
|
||||
}
|
||||
|
||||
body.buildGetUnit()
|
||||
@@ -234,11 +238,13 @@ class BodyGenerator(
|
||||
else
|
||||
functionContext.referenceLocal(valueSymbol)
|
||||
)
|
||||
body.commentPreviousInstr { "type: ${valueDeclaration.type.render()}" }
|
||||
}
|
||||
|
||||
override fun visitSetValue(expression: IrSetValue) {
|
||||
generateExpression(expression.value)
|
||||
body.buildSetLocal(functionContext.referenceLocal(expression.symbol))
|
||||
body.commentPreviousInstr { "type: ${expression.symbol.owner.type.render()}" }
|
||||
body.buildGetUnit()
|
||||
}
|
||||
|
||||
@@ -263,6 +269,7 @@ class BodyGenerator(
|
||||
WasmOp.ARRAY_NEW_DEFAULT,
|
||||
WasmImmediate.GcType(wasmGcType)
|
||||
)
|
||||
body.commentPreviousInstr { "@WasmArrayOf ctor call: ${klass.fqNameWhenAvailable}" }
|
||||
return
|
||||
}
|
||||
|
||||
@@ -272,6 +279,7 @@ class BodyGenerator(
|
||||
generateExpression(expression.getValueArgument(i)!!)
|
||||
}
|
||||
body.buildStructNew(wasmGcType)
|
||||
body.commentPreviousInstr { "@WasmPrimitiveConstructor ctor call: ${klass.fqNameWhenAvailable}" }
|
||||
return
|
||||
}
|
||||
|
||||
@@ -281,6 +289,7 @@ class BodyGenerator(
|
||||
|
||||
private fun generateAnyParameters(klassSymbol: IrClassSymbol) {
|
||||
//ClassITable and VTable load
|
||||
body.commentGroupStart { "Any parameters" }
|
||||
body.buildGetGlobal(context.referenceGlobalVTable(klassSymbol))
|
||||
if (klassSymbol.owner.hasInterfaceSuperClass()) {
|
||||
body.buildGetGlobal(context.referenceGlobalClassITable(klassSymbol))
|
||||
@@ -290,6 +299,7 @@ class BodyGenerator(
|
||||
|
||||
body.buildConstI32Symbol(context.referenceClassId(klassSymbol))
|
||||
body.buildConstI32(0) // Any::_hashCode
|
||||
body.commentGroupEnd()
|
||||
}
|
||||
|
||||
fun generateObjectCreationPrefixIfNeeded(constructor: IrConstructor) {
|
||||
@@ -297,6 +307,7 @@ class BodyGenerator(
|
||||
if (constructor.origin == PrimaryConstructorLowering.SYNTHETIC_PRIMARY_CONSTRUCTOR) return
|
||||
if (parentClass.isAbstractOrSealed) return
|
||||
val thisParameter = functionContext.referenceLocal(parentClass.thisReceiver!!.symbol)
|
||||
body.commentGroupStart { "Object creation prefix" }
|
||||
body.buildGetLocal(thisParameter)
|
||||
body.buildInstr(WasmOp.REF_IS_NULL)
|
||||
body.buildIf("this_init")
|
||||
@@ -310,6 +321,7 @@ class BodyGenerator(
|
||||
body.buildStructNew(context.referenceGcType(parentClass.symbol))
|
||||
body.buildSetLocal(thisParameter)
|
||||
body.buildEnd()
|
||||
body.commentGroupEnd()
|
||||
}
|
||||
|
||||
override fun visitDelegatingConstructorCall(expression: IrDelegatingConstructorCall) {
|
||||
@@ -330,6 +342,7 @@ class BodyGenerator(
|
||||
generateAnyParameters(klassSymbol)
|
||||
generateExpression(expression)
|
||||
body.buildStructNew(context.referenceGcType(klassSymbol))
|
||||
body.commentPreviousInstr { "box" }
|
||||
}
|
||||
|
||||
private fun generateCall(call: IrFunctionAccessExpression) {
|
||||
@@ -394,17 +407,21 @@ class BodyGenerator(
|
||||
val receiver = call.dispatchReceiver!!
|
||||
generateExpression(receiver)
|
||||
|
||||
body.commentGroupStart { "virtual call: ${function.fqNameWhenAvailable}" }
|
||||
|
||||
//TODO: check why it could be needed
|
||||
generateRefNullCast(receiver.type, klass.defaultType)
|
||||
|
||||
body.buildStructGet(context.referenceGcType(klass.symbol), WasmSymbol(0))
|
||||
body.buildStructGet(context.referenceVTableGcType(klass.symbol), WasmSymbol(vfSlot))
|
||||
body.buildInstr(WasmOp.CALL_REF, WasmImmediate.TypeIdx(context.referenceFunctionType(function.symbol)))
|
||||
body.commentGroupEnd()
|
||||
} else {
|
||||
val symbol = klass.symbol
|
||||
if (symbol in hierarchyDisjointUnions) {
|
||||
generateExpression(call.dispatchReceiver!!)
|
||||
|
||||
body.commentGroupStart { "interface call: ${function.fqNameWhenAvailable}" }
|
||||
body.buildStructGet(context.referenceGcType(irBuiltIns.anyClass), WasmSymbol(1))
|
||||
|
||||
val classITableReference = context.referenceClassITableGcType(symbol)
|
||||
@@ -416,6 +433,7 @@ class BodyGenerator(
|
||||
|
||||
body.buildStructGet(context.referenceVTableGcType(symbol), WasmSymbol(vfSlot))
|
||||
body.buildInstr(WasmOp.CALL_REF, WasmImmediate.TypeIdx(context.referenceFunctionType(function.symbol)))
|
||||
body.commentGroupEnd()
|
||||
} else {
|
||||
body.buildUnreachable()
|
||||
}
|
||||
|
||||
+2
@@ -494,10 +494,12 @@ fun generateConstExpression(expression: IrConst<*>, body: WasmExpressionBuilder,
|
||||
is IrConstKind.String -> {
|
||||
val stringValue = kind.valueOf(expression)
|
||||
val (literalAddress, literalPoolId) = context.referenceStringLiteralAddressAndId(stringValue)
|
||||
body.commentGroupStart { "const string: \"$stringValue\"" }
|
||||
body.buildConstI32Symbol(literalPoolId)
|
||||
body.buildConstI32Symbol(literalAddress)
|
||||
body.buildConstI32(stringValue.length)
|
||||
body.buildCall(context.referenceFunction(context.backendContext.wasmSymbols.stringGetLiteral))
|
||||
body.commentGroupEnd()
|
||||
}
|
||||
else -> error("Unknown constant kind")
|
||||
}
|
||||
|
||||
@@ -95,6 +95,9 @@ sealed class WasmImmediate {
|
||||
class HeapType(val value: WasmHeapType) : WasmImmediate() {
|
||||
constructor(type: WasmType) : this(type.getHeapType())
|
||||
}
|
||||
|
||||
// Pseudo-immediates
|
||||
class ConstString(val value: String) : WasmImmediate()
|
||||
}
|
||||
|
||||
|
||||
@@ -403,11 +406,17 @@ enum class WasmOp(
|
||||
|
||||
// ============================================================
|
||||
// Pseudo-instruction, just alias for a normal call. It's used to easily spot get_unit on the wasm level.
|
||||
GET_UNIT("call", 0x10, FUNC_IDX)
|
||||
GET_UNIT("call", 0x10, FUNC_IDX),
|
||||
|
||||
PSEUDO_COMMENT_PREVIOUS_INSTR("<comment-single>", WASM_OP_PSEUDO_OPCODE),
|
||||
PSEUDO_COMMENT_GROUP_START("<comment-group-start>", WASM_OP_PSEUDO_OPCODE),
|
||||
PSEUDO_COMMENT_GROUP_END("<comment-group-end>", WASM_OP_PSEUDO_OPCODE),
|
||||
;
|
||||
|
||||
constructor(mnemonic: String, opcode: Int, vararg immediates: WasmImmediateKind) : this(mnemonic, opcode, immediates.toList())
|
||||
}
|
||||
|
||||
const val WASM_OP_PSEUDO_OPCODE = 0xFFFF
|
||||
|
||||
val opcodesToOp: Map<Int, WasmOp> =
|
||||
enumValues<WasmOp>().associateBy { it.opcode }
|
||||
|
||||
@@ -178,4 +178,16 @@ abstract class WasmExpressionBuilder {
|
||||
fun buildDrop() {
|
||||
buildInstr(WasmOp.DROP)
|
||||
}
|
||||
|
||||
inline fun commentPreviousInstr(text: () -> String) {
|
||||
buildInstr(WasmOp.PSEUDO_COMMENT_PREVIOUS_INSTR, WasmImmediate.ConstString(text()))
|
||||
}
|
||||
|
||||
inline fun commentGroupStart(text: () -> String) {
|
||||
buildInstr(WasmOp.PSEUDO_COMMENT_GROUP_START, WasmImmediate.ConstString(text()))
|
||||
}
|
||||
|
||||
fun commentGroupEnd() {
|
||||
buildInstr(WasmOp.PSEUDO_COMMENT_GROUP_END)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -210,6 +210,10 @@ class WasmIrToBinary(
|
||||
}
|
||||
|
||||
val opcode = instr.operator.opcode
|
||||
|
||||
if (opcode == WASM_OP_PSEUDO_OPCODE)
|
||||
return
|
||||
|
||||
if (opcode > 0xFF) {
|
||||
b.writeByte((opcode ushr 8).toByte())
|
||||
b.writeByte((opcode and 0xFF).toByte())
|
||||
@@ -259,6 +263,8 @@ class WasmIrToBinary(
|
||||
is WasmImmediate.GcType -> appendModuleFieldReference(x.value.owner)
|
||||
is WasmImmediate.StructFieldIdx -> b.writeVarUInt32(x.value.owner)
|
||||
is WasmImmediate.HeapType -> appendHeapType(x.value)
|
||||
is WasmImmediate.ConstString ->
|
||||
error("Instructions with pseudo immediates should be skipped")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -60,6 +60,34 @@ class WasmIrToText : SExpressionBuilder() {
|
||||
|
||||
private fun appendInstr(wasmInstr: WasmInstr) {
|
||||
val op = wasmInstr.operator
|
||||
|
||||
if (op.opcode == WASM_OP_PSEUDO_OPCODE) {
|
||||
fun commentText() =
|
||||
(wasmInstr.immediates.single() as WasmImmediate.ConstString).value
|
||||
|
||||
when (op) {
|
||||
WasmOp.PSEUDO_COMMENT_PREVIOUS_INSTR -> {
|
||||
val text = commentText()
|
||||
require(text.lineSequence().count() < 2) { "Comments for single instruction should be in one line" }
|
||||
stringBuilder.append(" ;; ")
|
||||
stringBuilder.append(text)
|
||||
}
|
||||
WasmOp.PSEUDO_COMMENT_GROUP_START -> {
|
||||
newLine()
|
||||
commentText().lines().forEach { line ->
|
||||
newLine()
|
||||
stringBuilder.append(";; ")
|
||||
stringBuilder.append(line)
|
||||
}
|
||||
}
|
||||
WasmOp.PSEUDO_COMMENT_GROUP_END -> {
|
||||
newLine()
|
||||
}
|
||||
else -> error("Unknown pseudo op $op")
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
if (op == WasmOp.END || op == WasmOp.ELSE || op == WasmOp.CATCH)
|
||||
indent--
|
||||
|
||||
@@ -113,6 +141,8 @@ class WasmIrToText : SExpressionBuilder() {
|
||||
is WasmImmediate.HeapType -> {
|
||||
appendHeapType(x.value)
|
||||
}
|
||||
|
||||
is WasmImmediate.ConstString -> error("Pseudo immediate")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user