Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
160 changes: 134 additions & 26 deletions src/Debug/debugger.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -398,6 +398,22 @@ void Debugger::printValue(const StackValue *v, const uint32_t idx,
snprintf(buff, 255, R"("type":"F64","value":")" FMT(PRIx64) "\"",
v->value.uint64);
break;
case FUNCREF:
if (is_null_ref(v)) {
snprintf(buff, 255, R"("type":"funcref","value":null)");
} else {
uint32_t fidx = (uint32_t)(uintptr_t)v->value.ref;
snprintf(buff, 255, R"("type":"funcref","value":%u)", fidx);
}
break;
case EXTERNREF:
if (is_null_ref(v)) {
snprintf(buff, 255, R"("type":"externref","value":null)");
} else {
snprintf(buff, 255, R"("type":"externref","value":"%p")",
v->value.ref);
}
break;
default:
snprintf(buff, 255, R"("type":"%02x","value":")" FMT(PRIx64) "\"",
v->value_type, v->value.uint64);
Expand Down Expand Up @@ -610,6 +626,26 @@ void Debugger::dumpLocals(const Module *m) const {
snprintf(_value_str, 255, R"("type":"F64","value":%.7f)",
v->value.f64);
break;
case FUNCREF:
if (is_null_ref(v)) {
snprintf(_value_str, 255,
R"("type":"funcref","value":null)");
} else {
uint32_t fidx = (uint32_t)(uintptr_t)v->value.ref;
snprintf(_value_str, 255, R"("type":"funcref","value":%u)",
fidx);
}
break;
case EXTERNREF:
if (is_null_ref(v)) {
snprintf(_value_str, 255,
R"("type":"externref","value":null)");
} else {
snprintf(_value_str, 255,
R"("type":"externref","value":"%p")",
v->value.ref);
}
break;
default:
snprintf(_value_str, 255,
R"("type":"%02x","value":")" FMT(PRIx64) "\"",
Expand Down Expand Up @@ -850,26 +886,68 @@ void Debugger::inspect(Module *m, const uint16_t sizeStateArray,
break;
}
case tableState: {
this->channel->write(
R"(%s"table":{"max":%d, "init":%d, "elements":[)",
addComma ? "," : "", m->table.maximum, m->table.initial);
this->channel->write("%s\"tables\":[", addComma ? "," : "");
addComma = true;
for (uint32_t j = 0; j < m->table.size; j++) {
this->channel->write("%" PRIu32 "%s", m->table.entries[j],
(j + 1) == m->table.size ? "" : ",");
for (uint32_t tidx = 0; tidx < m->table_count; tidx++) {
ASSERT(tidx < m->table_count, "table index out of bounds");
Table *table = &m->tables[tidx];

this->channel->write(
R"({"index":%d,"max":%d,"init":%d,"elements":[)", tidx,
table->maximum, table->initial);

for (uint32_t j = 0; j < table->size; j++) {
this->channel->write("%" PRIu32 "%s", table->entries[j],
(j + 1) == table->size ? "" : ",");
}
this->channel->write("]}");
if (tidx + 1 < m->table_count) {
this->channel->write(",");
}
}
this->channel->write("]}"); // closing table
this->channel->write("]");
break;
}
case branchingTableState: {
this->channel->write(
R"(%s"br_table":{"size":"0x%x","labels":[)",
addComma ? "," : "", BR_TABLE_SIZE);
for (uint32_t j = 0; j < BR_TABLE_SIZE; j++) {
this->channel->write("%" PRIu32 "%s", m->br_table[j],
(j + 1) == BR_TABLE_SIZE ? "" : ",");
this->channel->write("%s\"br_tables\":[", addComma ? "," : "");
addComma = true;

for (uint32_t tidx = 0; tidx < m->table_count; tidx++) {
Table *table = &m->tables[tidx];

this->channel->write(
R"({"index":%u,"size":"0x%x","labels":[)", tidx,
table->size);

for (uint32_t j = 0; j < table->size; j++) {
StackValue *entry = &table->entries[j];

if (is_null_ref(entry)) {
this->channel->write("null");
} else if (entry->value_type == FUNCREF) {
uint32_t fidx =
(uint32_t)(uintptr_t)entry->value.ref;
this->channel->write("%u", fidx);
} else if (entry->value_type == EXTERNREF) {
this->channel->write("\"%p\"", entry->value.ref);
} else {
this->channel->write("\"0x%" PRIx64 "\"",
entry->value.uint64);
}

if (j + 1 < table->size) {
this->channel->write(",");
}
}

this->channel->write("]}");

if (tidx + 1 < m->table_count) {
this->channel->write(",");
}
}
this->channel->write("]}");

this->channel->write("]");
break;
}
case memoryState: {
Expand Down Expand Up @@ -1079,18 +1157,22 @@ void Debugger::freeState(Module *m, uint8_t *interruptData) {
}
case tableState: {
debug("receiving table info\n");
m->table.initial = read_B32(&first_msg);
m->table.maximum = read_B32(&first_msg);
uint32_t table_index = read_B32(&first_msg);
Table *table = &m->tables[table_index];
table->initial = read_B32(&first_msg);
table->maximum = read_B32(&first_msg);
uint32_t size = read_B32(&first_msg);
debug("init %d max %d size %d\n", m->table.initial,
m->table.maximum, size);
if (m->table.size != size) {
debug("old table size %d\n", m->table.size);
if (m->table.size != 0) free(m->table.entries);
m->table.entries = static_cast<uint32_t *>(acalloc(
size, sizeof(uint32_t), "Module->table.entries"));
debug("table[%u] init %d max %d size %d\n", table_index,
table->initial, table->maximum, size);
if (table->size != size) {
debug("old table[%u] size %d\n", table_index, table->size);
if (table->entries != nullptr) {
free(table->entries);
}
table->entries = static_cast<StackValue *>(
acalloc(size, sizeof(StackValue), "Table.entries"));
}
m->table.size = 0; // allows to accumulatively add entries
table->size = 0;
break;
}
case memoryState: {
Expand Down Expand Up @@ -1234,10 +1316,36 @@ bool Debugger::saveState(Module *m, uint8_t *interruptData) {
break;
}
case tableState: {
uint32_t table_index = read_B32(&program_state);
Table *table = &m->tables[table_index];

uint32_t quantity = read_B32(&program_state);

for (size_t i = 0; i < quantity; i++) {
uint32_t ne = read_B32(&program_state);
m->table.entries[m->table.size++] = ne;
if (table->size >= table->maximum) {
FATAL("table overflow during restoration\n");
}

uint8_t entry_type = *program_state++;

if (entry_type != table->elem_type) {
debug("warning: entry type mismatch at index %u\n", i);
}

StackValue *entry = &table->entries[table->size];
entry->value_type = entry_type;

if (entry_type == FUNCREF) {
uint32_t fidx = read_B32(&program_state);
entry->value.ref = (void *)(uintptr_t)fidx;
} else if (entry_type == EXTERNREF) {
set_null_ref(entry, EXTERNREF);
program_state += sizeof(void *);
} else {
FATAL("unknown table entry type 0x%02x\n", entry_type);
}

table->size++;
}
break;
}
Expand Down
Loading