/* spl_disasm.c — SIR bytecode disassembler * * Usage: spl_disasm */ #include "spl_ir.h" #include int main(int argc, const char **argv) { if (argc < 2) { fprintf(stderr, "Usage: spl_disasm \n"); return 1; } spl_prog_t prog; if (spl_prog_load_from_file(argv[1], &prog) != 0) { fprintf(stderr, "spl_disasm: cannot load '%s'\n", argv[1]); return 1; } printf(";; SPL bytecode dump: %s\n", argv[1]); printf(";; ninsns=%zu nfuncs=%zu nnatives=%zu nstrs=%zu\n\n", vec_size(prog.insns), vec_size(prog.funcs), vec_size(prog.natives), vec_size(prog.strtab)); if (vec_size(prog.funcs) > 0) { printf(";; --- functions ---\n"); for (usize i = 0; i < vec_size(prog.funcs); i++) { spl_func_t *f = &vec_at(prog.funcs, i); printf(" %s nargs=%zu ninsns=%zu addr=%zu\n", f->name ? f->name : "(anon)", f->nargs, f->ninsns, f->address); } printf("\n"); } if (vec_size(prog.natives) > 0) { printf(";; --- natives ---\n"); for (int i = 0; i < (int)vec_size(prog.natives); i++) { spl_native_t *n = &vec_at(prog.natives, i); printf(" %s\n", n->name ? n->name : "(anon)"); } printf("\n"); } if (vec_size(prog.strtab) > 0) { printf(";; --- string table ---\n"); for (int i = 0; i < (int)vec_size(prog.strtab); i++) { printf(" %d: \"%s\"\n", i, vec_at(prog.strtab, i)); } printf("\n"); } printf(";; --- instructions ---\n"); for (usize i = 0; i < vec_size(prog.insns); i++) { spl_ins_t *ins = &vec_at(prog.insns, i); printf("%4zd: %s", i, spl_opcode_name((spl_opcode_t)ins->opcode)); if (ins->type != SPL_VOID) printf(" %s", spl_type_name((spl_type_t)ins->type)); printf(" %zd", ins->imm); /* annotate jumps / calls */ if (ins->opcode == SPL_JMP || ins->opcode == SPL_BZ || ins->opcode == SPL_BNZ) { long long target = (long long)i + 1 + (long long)ins->imm; printf(" ; -> %zd", target); } else if (ins->opcode == SPL_CALL) { printf(" ; nargs=%zd, from stack", (long long)ins->imm); } else if (ins->opcode == SPL_CALLI) { printf(" ; indirect call"); } else if (ins->opcode == SPL_GADDR) { printf(" ; gdata[%zd]", (long long)ins->imm); } printf("\n"); } spl_prog_drop(&prog); return 0; }