diff options
author | Stephen Dolan <mu@netsoc.tcd.ie> | 2013-05-16 00:51:17 +0100 |
---|---|---|
committer | Stephen Dolan <mu@netsoc.tcd.ie> | 2013-05-16 00:51:17 +0100 |
commit | a1e4dfa32412457e03dd0e4e4c2ac17eca02c4f8 (patch) | |
tree | f93f78777d4b54fa8f32630cfccac283572bec55 | |
parent | f8644c31a3e6f4c3d9a95837c22a18fd27155510 (diff) |
Better debug info for struct bytecode.
--debug-dump-disasm produces more comprehensible output now.
-rw-r--r-- | bytecode.c | 51 | ||||
-rw-r--r-- | bytecode.h | 3 | ||||
-rw-r--r-- | compile.c | 11 |
3 files changed, 59 insertions, 6 deletions
@@ -16,12 +16,24 @@ static int bytecode_operation_length(uint16_t* codeptr) { void dump_disassembly(int indent, struct bytecode* bc) { if (bc->nclosures > 0) { - printf("%*s[params: %d]\n", indent, "", bc->nclosures); + printf("%*s[params: ", indent, ""); + jv params = jv_object_get(jv_copy(bc->debuginfo), jv_string("params")); + for (int i=0; i<bc->nclosures; i++) { + if (i) printf(", "); + jv name = jv_array_get(jv_copy(params), i); + printf("%s", jv_string_value(name)); + jv_free(name); + } + jv_free(params); + printf("]\n"); } dump_code(indent, bc); for (int i=0; i<bc->nsubfunctions; i++) { - printf("%*ssubfn[%d]:\n", indent, "", i); - dump_disassembly(indent+2, bc->subfunctions[i]); + struct bytecode* subfn = bc->subfunctions[i]; + jv name = jv_object_get(jv_copy(subfn->debuginfo), jv_string("name")); + printf("%*s%s:%d:\n", indent, "", jv_string_value(name), i); + jv_free(name); + dump_disassembly(indent+2, subfn); } } @@ -35,6 +47,14 @@ void dump_code(int indent, struct bytecode* bc) { } } +static struct bytecode* getlevel(struct bytecode* bc, int level) { + while (level > 0) { + bc = bc->parent; + level--; + } + return bc; +} + void dump_operation(struct bytecode* bc, uint16_t* codeptr) { int pc = codeptr - bc->code; printf("%04d ", pc); @@ -46,15 +66,28 @@ void dump_operation(struct bytecode* bc, uint16_t* codeptr) { for (int i=0; i<imm+1; i++) { uint16_t level = bc->code[pc++]; uint16_t idx = bc->code[pc++]; + jv name; if (idx & ARG_NEWCLOSURE) { - printf(" subfn[%d]", idx & ~ARG_NEWCLOSURE); + idx &= ~ARG_NEWCLOSURE; + name = jv_object_get(jv_copy(getlevel(bc,level)->subfunctions[idx]->debuginfo), + jv_string("name")); } else { - printf(" param[%d]", idx); + name = jv_array_get(jv_object_get(jv_copy(getlevel(bc,level)->debuginfo), + jv_string("params")), idx); } + printf(" %s:%d", + jv_string_value(name), + idx); + jv_free(name); if (level) { printf("^%d", level); } } + } else if (op->op == CALL_BUILTIN) { + int func = bc->code[pc++]; + jv name = jv_array_get(jv_copy(bc->globals->cfunc_names), func); + printf(" %s", jv_string_value(name)); + jv_free(name); } else if (op->flags & OP_HAS_BRANCH) { printf(" %04d", pc + imm); } else if (op->flags & OP_HAS_CONSTANT) { @@ -62,7 +95,11 @@ void dump_operation(struct bytecode* bc, uint16_t* codeptr) { jv_dump(jv_array_get(jv_copy(bc->constants), imm), 0); } else if (op->flags & OP_HAS_VARIABLE) { uint16_t v = bc->code[pc++]; - printf(" v%d", v); + jv name = jv_array_get(jv_object_get(jv_copy(getlevel(bc,imm)->debuginfo), jv_string("locals")), v); + printf(" $%s:%d", + jv_string_value(name), + v); + jv_free(name); if (imm) { printf("^%d", imm); } @@ -74,6 +111,7 @@ void dump_operation(struct bytecode* bc, uint16_t* codeptr) { void symbol_table_free(struct symbol_table* syms) { jv_mem_free(syms->cfunctions); + jv_free(syms->cfunc_names); jv_mem_free(syms); } @@ -85,5 +123,6 @@ void bytecode_free(struct bytecode* bc) { if (!bc->parent) symbol_table_free(bc->globals); jv_mem_free(bc->subfunctions); + jv_free(bc->debuginfo); jv_mem_free(bc); } @@ -10,6 +10,7 @@ struct symbol_table { struct cfunction* cfunctions; int ncfunctions; + jv cfunc_names; }; // The bytecode format matters in: @@ -33,6 +34,8 @@ struct bytecode { int nsubfunctions; struct bytecode* parent; + + jv debuginfo; }; void dump_disassembly(int, struct bytecode* code); @@ -526,6 +526,7 @@ static int compile(struct locfile* locations, struct bytecode* bc, block b) { bc->nsubfunctions = 0; errors += expand_call_arglist(locations, &b); b = BLOCK(b, gen_op_simple(RET)); + jv localnames = jv_array(); for (inst* curr = b.first; curr; curr = curr->next) { if (!curr->next) assert(curr == b.last); int length = opcode_describe(curr->op)->length; @@ -543,6 +544,7 @@ static int compile(struct locfile* locations, struct bytecode* bc, block b) { if ((opcode_describe(curr->op)->flags & OP_HAS_VARIABLE) && curr->bound_by == curr) { curr->imm.intval = var_frame_idx++; + localnames = jv_array_append(localnames, jv_string(curr->symbol)); } if (curr->op == CLOSURE_CREATE) { @@ -552,10 +554,13 @@ static int compile(struct locfile* locations, struct bytecode* bc, block b) { if (curr->op == CLOSURE_CREATE_C) { assert(curr->bound_by == curr); int idx = bc->globals->ncfunctions++; + bc->globals->cfunc_names = jv_array_append(bc->globals->cfunc_names, + jv_string(curr->symbol)); bc->globals->cfunctions[idx] = *curr->imm.cfunc; curr->imm.intval = idx; } } + bc->debuginfo = jv_object_set(bc->debuginfo, jv_string("locals"), localnames); if (bc->nsubfunctions) { bc->subfunctions = jv_mem_alloc(sizeof(struct bytecode*) * bc->nsubfunctions); for (inst* curr = b.first; curr; curr = curr->next) { @@ -565,12 +570,16 @@ static int compile(struct locfile* locations, struct bytecode* bc, block b) { subfn->globals = bc->globals; subfn->parent = bc; subfn->nclosures = 0; + subfn->debuginfo = jv_object_set(jv_object(), jv_string("name"), jv_string(curr->symbol)); + jv params = jv_array(); for (inst* param = curr->arglist.first; param; param = param->next) { assert(param->op == CLOSURE_PARAM); assert(param->bound_by == param); param->imm.intval = subfn->nclosures++; param->compiled = subfn; + params = jv_array_append(params, jv_string(param->symbol)); } + subfn->debuginfo = jv_object_set(subfn->debuginfo, jv_string("params"), params); errors += compile(locations, subfn, curr->subfn); curr->subfn = gen_noop(); } @@ -638,6 +647,8 @@ int block_compile(block b, struct locfile* locations, struct bytecode** out) { int ncfunc = count_cfunctions(b); bc->globals->ncfunctions = 0; bc->globals->cfunctions = jv_mem_alloc(sizeof(struct cfunction) * ncfunc); + bc->globals->cfunc_names = jv_array(); + bc->debuginfo = jv_object_set(jv_object(), jv_string("name"), jv_null()); int nerrors = compile(locations, bc, b); assert(bc->globals->ncfunctions == ncfunc); if (nerrors > 0) { |