Skip to content

Commit 39e353a

Browse files
committed
Support different argument counts when mocking
1 parent d67b5f3 commit 39e353a

8 files changed

Lines changed: 202 additions & 67 deletions

File tree

src/main/kotlin/be/ugent/topl/mio/debugger/Debugger.kt

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -464,16 +464,18 @@ open class Debugger(private val connection: Connection, start: Boolean = true, p
464464
}
465465
}
466466

467-
open fun addPrimitiveOverride(primName: String, arg: Int, returnValue: Int) {
467+
open fun addPrimitiveOverride(primName: String, args: List<Int>, returnValue: Int): Boolean {
468468
val primNameSerialised = primName.chars().toList().joinToString("") { c: Int -> String.format("%02x", c) } + "00"
469-
val payload = primNameSerialised + String.format("%08x", arg) + String.format("%08x", returnValue)
469+
val payload = primNameSerialised + args.joinToString { String.format("%08x", it) } + String.format("%08x", returnValue)
470470
send(80, payload)
471+
return messageQueue.waitForAck("80")[0] == "1"
471472
}
472473

473-
open fun removePrimitiveOverride(primName: String, arg: Int) {
474+
open fun removePrimitiveOverride(primName: String, args: List<Int>): Boolean {
474475
val primNameSerialised = primName.chars().toList().joinToString("") { c: Int -> String.format("%02x", c) } + "00"
475-
val payload = primNameSerialised + String.format("%08x", arg)
476+
val payload = primNameSerialised + args.joinToString { String.format("%08x", it) }
476477
send(81, payload)
478+
return messageQueue.waitForAck("81")[0] == "1"
477479
}
478480

479481
fun updateModule(wasmFilename: String) {

src/main/kotlin/be/ugent/topl/mio/debugger/MessageQueue.kt

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,4 +110,12 @@ class MessageQueue(private val notifyAdded: (List<String>) -> Unit = {}) {
110110
if (it.trimEnd('\r') != str) throw Exception()
111111
}
112112
}
113+
114+
fun waitForAck(str: String): List<String> {
115+
val ackMsg = waitForResponse {
116+
if (!it.trimEnd('\r').startsWith("ack$str")) throw Exception()
117+
}.first
118+
val splitMsg = ackMsg.split(";")
119+
return splitMsg.subList(1, splitMsg.size)
120+
}
113121
}

src/main/kotlin/be/ugent/topl/mio/debugger/MultiverseDebugger.kt

Lines changed: 11 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -110,18 +110,6 @@ open class MultiverseNode(val children: MutableList<MultiverseNode> = mutableLis
110110
values.clear()
111111
}
112112

113-
open fun nextNode(overrides: Map<String,Map<Int, Int>>): MultiverseNode {
114-
return children[0]
115-
}
116-
117-
fun nextNode(overrides: Map<String, Map<Int, Int>>, n: Int): MultiverseNode {
118-
var dest = this
119-
for (i in 0 ..< n) {
120-
dest = dest.nextNode(overrides)
121-
}
122-
return dest
123-
}
124-
125113
open fun nextNode(stackValue: WasmStackValue): MultiverseNode {
126114
return children[0]
127115
}
@@ -142,14 +130,6 @@ class PrimitiveNode(val primitive: String, val arg: List<Int>, children: Mutable
142130
override val edgeLength: Int
143131
get() = 135
144132

145-
override fun nextNode(overrides: Map<String,Map<Int, Int>>): MultiverseNode {
146-
val returnValue = overrides[primitive]?.get(arg.first())
147-
if (returnValue != null) {
148-
return children[values.indexOf(returnValue)]
149-
}
150-
throw Exception("Unknown destination!")
151-
}
152-
153133
override fun nextNode(stackValue: WasmStackValue): MultiverseNode {
154134
return children[values.indexOf(stackValue.value.toInt())]
155135
}
@@ -166,7 +146,7 @@ class MultiverseDebugger(
166146
) : Debugger(connection, start, onHitBreakpoint) {
167147
val graph = MultiverseGraph()
168148
private var len = 0
169-
val overrides = mutableMapOf<String, MutableMap<Int, Int>>()
149+
val overrides = mutableMapOf<String, MutableMap<List<Int>, Int>>()
170150

171151
// TODO: Remove, just for testing
172152
init {
@@ -239,18 +219,20 @@ class MultiverseDebugger(
239219
graphUpdated()
240220
}
241221

242-
override fun addPrimitiveOverride(primName: String, arg: Int, returnValue: Int) {
243-
super.addPrimitiveOverride(primName, arg, returnValue)
222+
override fun addPrimitiveOverride(primName: String, args: List<Int>, returnValue: Int): Boolean {
223+
val result = super.addPrimitiveOverride(primName, args, returnValue)
244224
if (!overrides.containsKey(primName))
245225
overrides[primName] = mutableMapOf()
246-
overrides[primName]!![arg] = returnValue
226+
overrides[primName]!![args] = returnValue
247227
mockingUpdated()
228+
return result
248229
}
249230

250-
override fun removePrimitiveOverride(primName: String, arg: Int) {
251-
super.removePrimitiveOverride(primName, arg)
252-
overrides[primName]?.remove(arg)
231+
override fun removePrimitiveOverride(primName: String, args: List<Int>): Boolean {
232+
val result = super.removePrimitiveOverride(primName, args)
233+
overrides[primName]?.remove(args)
253234
mockingUpdated()
235+
return result
254236
}
255237

256238
fun createNewPath(returnValue: Int, override: Boolean = true) {
@@ -260,7 +242,7 @@ class MultiverseDebugger(
260242
currentNode.addChild(MultiverseNode())
261243
graphUpdated()
262244
if (override) {
263-
addPrimitiveOverride(currentNode.primitive, currentNode.arg.first(), returnValue)
245+
addPrimitiveOverride(currentNode.primitive, currentNode.arg, returnValue)
264246
}
265247
}
266248
}
@@ -282,7 +264,7 @@ class MultiverseDebugger(
282264
if (!overrides.containsKey(primitiveName)) {
283265
overrides[primitiveName] = mutableMapOf()
284266
}
285-
overrides[primitiveName]?.set(snapshotOverrides.arg, snapshotOverrides.return_value)
267+
overrides[primitiveName]?.set(snapshotOverrides.args, snapshotOverrides.return_value)
286268
}
287269
mockingUpdated()
288270
}

src/main/kotlin/be/ugent/topl/mio/ui/InteractiveDebugger.kt

Lines changed: 57 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ import be.ugent.topl.mio.debugger.ConstraintParser
77
import be.ugent.topl.mio.debugger.Debugger
88
import be.ugent.topl.mio.debugger.ExecutionState
99
import be.ugent.topl.mio.debugger.MultiverseDebugger
10-
import be.ugent.topl.mio.debugger.MultiverseNode
1110
import be.ugent.topl.mio.debugger.PrimitiveNode
1211
import be.ugent.topl.mio.sourcemap.SourceMap
1312
import be.ugent.topl.mio.woodstate.Checkpoint
@@ -479,7 +478,7 @@ interface MultiverseAction {
479478

480479
class OverrideAction(val debugger: Debugger, val node: PrimitiveNode, val index: Int) : MultiverseAction {
481480
override fun doAction() {
482-
debugger.addPrimitiveOverride(node.primitive, node.arg.first(), node.values[index])
481+
debugger.addPrimitiveOverride(node.primitive, node.arg, node.values[index])
483482
}
484483

485484
}
@@ -638,32 +637,55 @@ class MultiversePanel(private val multiverseDebugger: MultiverseDebugger, config
638637
customButton.addActionListener {
639638
val currentNode = multiverseDebugger.graph.currentNode
640639
val mainPanel = JPanel()
641-
val primitiveNameTextField = JComboBox<String>()
640+
val primitiveSelector = JComboBox<String>()
642641
multiverseDebugger.wasmBinary.metadata.primitive_fidx_mapping.forEach {
643-
primitiveNameTextField.addItem(it)
642+
primitiveSelector.addItem(it)
644643
}
645-
mainPanel.add(primitiveNameTextField)
644+
mainPanel.add(primitiveSelector)
646645
mainPanel.add(JLabel("("))
647-
val argTextField = JTextField()
648-
mainPanel.add(argTextField)
646+
val argBox = Box.createHorizontalBox()
647+
mainPanel.add(argBox)
648+
649+
val argTextFields = mutableListOf<JTextField>()
650+
fun updateArgFields() {
651+
argTextFields.clear()
652+
// TODO: Determine the count based on binary info from WARDuino
653+
val argCount = if (
654+
primitiveSelector.selectedItem.toString() == "display_width" ||
655+
primitiveSelector.selectedItem.toString() == "display_height" ||
656+
primitiveSelector.selectedItem.toString() == "random_int") 0 else 1
657+
repeat(argCount) {
658+
argTextFields.add(JTextField())
659+
}
660+
argBox.removeAll()
661+
for (textField in argTextFields) {
662+
argBox.add(textField)
663+
}
664+
argBox.revalidate()
665+
argBox.repaint()
666+
}
667+
updateArgFields()
668+
649669
mainPanel.add(JLabel(") = "))
650670
val returnValueTextField = JTextField()
651671
mainPanel.add(returnValueTextField)
652672

653673
if (currentNode is PrimitiveNode) {
654-
argTextField.isEnabled = false
655-
argTextField.text = currentNode.arg.toString()
656-
primitiveNameTextField.isEnabled = false
657-
primitiveNameTextField.selectedItem = currentNode.primitive
674+
for (i in currentNode.arg.indices) {
675+
argTextFields[i].isEnabled = false
676+
argTextFields[i].text = currentNode.arg[i].toString()
677+
}
678+
primitiveSelector.isEnabled = false
679+
primitiveSelector.selectedItem = currentNode.primitive
658680
}
659681

660682
val relations = if (File(DebuggerConfig.configDir + "/program.constraints").exists()) ConstraintParser.parseFile("test.constraints") else listOf()
661683

662684
fun handleRelations() {
663685
returnValueTextField.isEnabled = true
664686
for (relation in relations) {
665-
if (primitiveNameTextField.selectedItem == relation.override.primName &&
666-
argTextField.text == relation.override.arg.toString()
687+
if (primitiveSelector.selectedItem == relation.override.primName &&
688+
argTextFields[0].text == relation.override.arg.toString()
667689
) {
668690
val state = multiverseDebugger.getCurrentState()
669691
val realValue = state.io!!.find { it.key == relation.io.key }?.value
@@ -676,22 +698,25 @@ class MultiversePanel(private val multiverseDebugger: MultiverseDebugger, config
676698
}
677699

678700
// Re-check relations when changing primitive or argument.
679-
primitiveNameTextField.addActionListener {
701+
primitiveSelector.addActionListener {
680702
handleRelations()
703+
updateArgFields()
681704
}
682-
argTextField.document.addDocumentListener(object : DocumentListener {
683-
override fun insertUpdate(e: DocumentEvent?) {
684-
handleRelations()
685-
}
705+
for (textField in argTextFields) {
706+
textField.document.addDocumentListener(object : DocumentListener {
707+
override fun insertUpdate(e: DocumentEvent?) {
708+
handleRelations()
709+
}
686710

687-
override fun removeUpdate(e: DocumentEvent?) {
688-
handleRelations()
689-
}
711+
override fun removeUpdate(e: DocumentEvent?) {
712+
handleRelations()
713+
}
690714

691-
override fun changedUpdate(e: DocumentEvent?) {
692-
handleRelations()
693-
}
694-
})
715+
override fun changedUpdate(e: DocumentEvent?) {
716+
handleRelations()
717+
}
718+
})
719+
}
695720

696721
val pauseIcon = ImageIcon(javaClass.getResource("/logo-small.png"))
697722

@@ -720,10 +745,13 @@ class MultiversePanel(private val multiverseDebugger: MultiverseDebugger, config
720745
dialog.isVisible = true
721746
val x = optionPane.value
722747
if (x == allOptions[1]) {
723-
val primitiveName = primitiveNameTextField.selectedItem as String
724-
val arg = argTextField.text.toInt()
748+
val primitiveName = primitiveSelector.selectedItem as String
749+
val args = mutableListOf<Int>()
750+
for (textField in argTextFields) {
751+
args.add(textField.text.toInt())
752+
}
725753
val returnValue = (returnValueTextField.text as String).toInt()
726-
multiverseDebugger.addPrimitiveOverride(primitiveName, arg, returnValue)
754+
multiverseDebugger.addPrimitiveOverride(primitiveName, args, returnValue)
727755
} else if (x == allOptions[0]) {
728756
showPathRangeWindow()
729757
}
@@ -772,7 +800,7 @@ class MultiversePanel(private val multiverseDebugger: MultiverseDebugger, config
772800
mockPanel.clear()
773801
for (primMocks in multiverseDebugger.overrides) {
774802
for (argResultPair in primMocks.value) {
775-
mockPanel.addItem(primMocks.key, listOf(argResultPair.key), argResultPair.value) {
803+
mockPanel.addItem(primMocks.key, argResultPair.key, argResultPair.value) {
776804
multiverseDebugger.removePrimitiveOverride(primMocks.key, argResultPair.key)
777805
}
778806
}

src/main/kotlin/be/ugent/topl/mio/woodstate/WOODState.kt

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -123,15 +123,15 @@ data class BRTable(
123123

124124
data class PrimitiveOverride(
125125
val fidx: Int,
126-
val arg: Int,
126+
val args: List<Int>,
127127
val return_value: Int,
128128
) {
129129
constructor(
130130
metadata: WasmInfo,
131131
primitiveName: String,
132-
arg: Int,
132+
args: List<Int>,
133133
returnValue: Int
134-
) : this(metadata.primitive_fidx_mapping.indexOf(primitiveName), arg, returnValue)
134+
) : this(metadata.primitive_fidx_mapping.indexOf(primitiveName), args, returnValue)
135135

136136
fun getPrimitiveName(metadata: WasmInfo): String = metadata.primitive_fidx_mapping[fidx]
137137
}
@@ -617,7 +617,7 @@ class WOODState(woodResponse: WOODDumpResponse) {
617617
logger.trace("--------------")
618618
logger.trace("Found ${woodResponse.overrides.size} active overrides.")
619619
serializeList(stateMsgs, ExecutionStateType.overridesState, woodResponse.overrides) {
620-
HexaEncoder.serializeUInt32BE(it.fidx) + HexaEncoder.serializeUInt32BE(it.arg) + HexaEncoder.serializeUInt32BE(it.return_value)
620+
HexaEncoder.serializeUInt32BE(it.fidx) + it.args.joinToString { HexaEncoder.serializeUInt32BE(it) } + HexaEncoder.serializeUInt32BE(it.return_value)
621621
}
622622
}
623623

src/test/kotlin/DebuggerTests.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -331,7 +331,7 @@ class DebuggerTests : DebuggerTestBase() {
331331
println("Running $wdcliPath")
332332
debugger.pause()
333333
//debugger.addPrimitiveOverride("chip_digital_read", 0, 5)
334-
debugger.addPrimitiveOverride("chip_digital_write", 0, 5)
334+
debugger.addPrimitiveOverride("chip_digital_write", listOf(0), 5)
335335
debugger.snapshot()
336336
Thread.sleep(1000)
337337
debugger.close()

0 commit comments

Comments
 (0)