summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStephen Dolan <mu@netsoc.tcd.ie>2013-05-16 00:51:17 +0100
committerStephen Dolan <mu@netsoc.tcd.ie>2013-05-16 00:51:17 +0100
commita1e4dfa32412457e03dd0e4e4c2ac17eca02c4f8 (patch)
treef93f78777d4b54fa8f32630cfccac283572bec55
parentf8644c31a3e6f4c3d9a95837c22a18fd27155510 (diff)
Better debug info for struct bytecode.
--debug-dump-disasm produces more comprehensible output now.
-rw-r--r--bytecode.c51
-rw-r--r--bytecode.h3
-rw-r--r--compile.c11
3 files changed, 59 insertions, 6 deletions
diff --git a/bytecode.c b/bytecode.c
index 39381204..b5703a9a 100644
--- a/bytecode.c
+++ b/bytecode.c
@@ -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);
}
diff --git a/bytecode.h b/bytecode.h
index e84f1387..c742cdd9 100644
--- a/bytecode.h
+++ b/bytecode.h
@@ -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);
diff --git a/compile.c b/compile.c
index 6c1e8f87..1f8be905 100644
--- a/compile.c
+++ b/compile.c
@@ -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) {