diff options
Diffstat (limited to 'uscript/us_debug.c')
| -rw-r--r-- | uscript/us_debug.c | 117 |
1 files changed, 117 insertions, 0 deletions
diff --git a/uscript/us_debug.c b/uscript/us_debug.c new file mode 100644 index 0000000..8d5dfe3 --- /dev/null +++ b/uscript/us_debug.c @@ -0,0 +1,117 @@ +#include "us_debug.h" + +#include <assert.h> + +#include "dyn_arr.h" +#include "vm.h" + +static +char *bc_names[] = { +#define BC(name) "BC_" #name, +#include "xbytecode.h" +#undef BC +}; + +int print_instruction(struct us_proto *proto, int idx) +{ + enum bytecode instruction = proto->bytecode[idx]; + fprintf(stderr, "%04d %-15s ", idx, bc_names[instruction]); + switch (instruction) { + case BC_LOAD: { + int const_idx = proto->bytecode[idx + 1]; + char *const_str = val_to_str(proto->constants[const_idx], NULL); + fprintf( + stderr, + "%d (%s)\n", + const_idx, + const_str + ); + mem_free(const_str); + return idx + 2; + } + case BC_LOAD_FUNC: { + int const_idx = proto->bytecode[idx + 1]; + assert(proto->constants[const_idx].type == VAL_PROTO); + struct us_proto *p = get_proto(proto->constants[const_idx]); + int upvalc = p->upvalc; + fprintf( + stderr, + "%.*s() %d\n", + (int)p->name->len, p->name->chars, + upvalc + ); + return idx + 2 + upvalc * 2; + } + case BC_SET_UPVAL: + case BC_GET_UPVAL: + case BC_SET_LOCAL: + case BC_GET_LOCAL: { + int local_idx = proto->bytecode[idx + 1]; + fprintf( + stderr, + "%d\n", + local_idx + ); + return idx + 2; + } + case BC_CALL: + case BC_SMALL_INT: { + fprintf( + stderr, + "%d\n", + proto->bytecode[idx + 1] + ); + return idx + 2; + } + case BC_JMP: + case BC_LOOP: + case BC_FALSEY_JMP: { + u16 jmp = (u16)(proto->bytecode[idx + 1] << 8) | proto->bytecode[idx + 2]; + int dst = idx + jmp + 3; + if (instruction == BC_LOOP) { + dst = idx + 3 - jmp; + } + fprintf( + stderr, + "-> %04d\n", + dst + ); + return idx + 3; + } + case BC_PRINT: + case BC_TRUE: + case BC_FALSE: + case BC_ZILCH: + case BC_POP: + case BC_POP_UPVAL: + case BC_ADD: + case BC_SUB: + case BC_MULT: + case BC_DIV: + case BC_MOD: + case BC_NEG: + case BC_NOT: + case BC_CONCAT: + case BC_EQL: + case BC_NEQL: + case BC_GT: + case BC_LT: + case BC_GTE: + case BC_LTE: + case BC_RET: + putc('\n', stderr); + return idx + 1; + } + + // unreachable + return idx + 1; +} + +void print_func(struct us_proto *func) +{ + fprintf(stderr, "%s():\n", func->name->chars); + for (int i = 0; i < da_len(func->bytecode);) { + putc('\t', stderr); + i = print_instruction(func, i); + } +} |
