33#include < algorithm>
44#include < cinttypes>
55#include < cstring>
6+ #include < optional>
67#ifndef ARDUINO
78#include < nlohmann/json.hpp>
89#else
@@ -332,6 +333,14 @@ bool Debugger::checkDebugMessages(Module *m, RunningState *program_state) {
332333 this ->dumpCallbackmapping ();
333334 free (interruptData);
334335 break ;
336+ case interruptSetOverridePinValue:
337+ this ->addOverride (m, interruptData + 1 );
338+ free (interruptData);
339+ break ;
340+ case interruptUnsetOverridePinValue:
341+ this ->removeOverride (m, interruptData + 1 );
342+ free (interruptData);
343+ break ;
335344 default :
336345 // handle later
337346 this ->channel ->write (" COULD not parse interrupt data!\n " );
@@ -725,7 +734,7 @@ bool Debugger::handlePushedEvent(char *bytes) const {
725734}
726735
727736void Debugger::snapshot (Module *m) const {
728- uint16_t numberBytes = 11 ;
737+ uint16_t numberBytes = 12 ;
729738 uint8_t state[] = {pcState,
730739 breakpointsState,
731740 callstackState,
@@ -736,7 +745,8 @@ void Debugger::snapshot(Module *m) const {
736745 stackState,
737746 callbacksState,
738747 eventsState,
739- ioState};
748+ ioState,
749+ overridesState};
740750 inspect (m, numberBytes, state);
741751}
742752
@@ -885,6 +895,23 @@ void Debugger::inspect(Module *m, const uint16_t sizeStateArray,
885895 addComma = true ;
886896 break ;
887897 }
898+ case overridesState: {
899+ this ->channel ->write (" %s" , addComma ? " ," : " " );
900+ this ->channel ->write (R"( "overrides": [)" );
901+ bool comma = false ;
902+ for (auto key : overrides) {
903+ for (auto argResult : key.second ) {
904+ this ->channel ->write (" %s" , comma ? " , " : " " );
905+ this ->channel ->write (
906+ R"( {"fidx": %d, "arg": %d, "return_value": %d})" ,
907+ key.first , argResult.first , argResult.second );
908+ comma = true ;
909+ }
910+ }
911+ this ->channel ->write (" ]" );
912+ addComma = true ;
913+ break ;
914+ }
888915 default : {
889916 debug (" dumpExecutionState: Received unknown state request\n " );
890917 break ;
@@ -1240,6 +1267,19 @@ bool Debugger::saveState(Module *m, uint8_t *interruptData) {
12401267 restore_external_state (m, external_state);
12411268 break ;
12421269 }
1270+ case overridesState: {
1271+ debug (" receiving overridesState\n " );
1272+ overrides.clear ();
1273+ uint8_t overrides_count = *program_state++;
1274+ for (uint32_t i = 0 ; i < overrides_count; i++) {
1275+ uint32_t fidx = read_B32 (&program_state);
1276+ uint32_t arg = read_B32 (&program_state);
1277+ uint32_t return_value = read_B32 (&program_state);
1278+ overrides[fidx][arg] = return_value;
1279+ debug (" Override %d %d %d\n " , fidx, arg, return_value);
1280+ }
1281+ break ;
1282+ }
12431283 default : {
12441284 FATAL (" saveState: Received unknown program state\n " );
12451285 }
@@ -1411,6 +1451,66 @@ bool Debugger::reset(Module *m) const {
14111451 return true ;
14121452}
14131453
1454+ std::optional<uint32_t > resolve_imported_function (Module *m,
1455+ std::string function_name) {
1456+ for (uint32_t fidx = 0 ; fidx < m->import_count ; fidx++) {
1457+ if (!strcmp (m->functions [fidx].import_field , function_name.c_str ())) {
1458+ return fidx;
1459+ }
1460+ }
1461+ return {};
1462+ }
1463+
1464+ std::string read_string (uint8_t **pos) {
1465+ std::string str = " " ;
1466+ char c = *(*pos)++;
1467+ while (c != ' \0 ' ) {
1468+ str += c;
1469+ c = *(*pos)++;
1470+ }
1471+ return str;
1472+ }
1473+
1474+ void Debugger::addOverride (Module *m, uint8_t *interruptData) {
1475+ std::string primitive_name = read_string (&interruptData);
1476+ uint32_t arg = read_B32 (&interruptData);
1477+ uint32_t result = read_B32 (&interruptData);
1478+
1479+ std::optional<uint32_t > fidx = resolve_imported_function (m, primitive_name);
1480+ if (!fidx) {
1481+ channel->write (
1482+ " Cannot override the result for unknown function \" %s\" .\n " ,
1483+ primitive_name.c_str ());
1484+ return ;
1485+ }
1486+
1487+ channel->write (" Override %s(%d) = %d.\n " , primitive_name.c_str (), arg,
1488+ result);
1489+ overrides[fidx.value ()][arg] = result;
1490+ }
1491+
1492+ void Debugger::removeOverride (Module *m, uint8_t *interruptData) {
1493+ std::string primitive_name = read_string (&interruptData);
1494+ uint32_t arg = read_B32 (&interruptData);
1495+
1496+ std::optional<uint32_t > fidx = resolve_imported_function (m, primitive_name);
1497+ if (!fidx) {
1498+ channel->write (" Cannot remove override for unknown function \" %s\" .\n " ,
1499+ primitive_name.c_str ());
1500+ return ;
1501+ }
1502+
1503+ if (overrides[fidx.value ()].count (arg) == 0 ) {
1504+ channel->write (" Override for %s(%d) not found.\n " ,
1505+ primitive_name.c_str (), arg);
1506+ return ;
1507+ }
1508+
1509+ channel->write (" Removing override %s(%d) = %d.\n " , primitive_name.c_str (),
1510+ arg, overrides[fidx.value ()][arg]);
1511+ overrides[fidx.value ()].erase (arg);
1512+ }
1513+
14141514Debugger::~Debugger () {
14151515 this ->disconnect_proxy ();
14161516 this ->stop ();
0 commit comments