stage0
This commit is contained in:
76
stage0/spl_disasm.c
Normal file
76
stage0/spl_disasm.c
Normal file
@@ -0,0 +1,76 @@
|
||||
/* spl_disasm.c — SIR bytecode disassembler
|
||||
*
|
||||
* Usage: spl_disasm <file.sir>
|
||||
*/
|
||||
|
||||
#include "spl_ir.h"
|
||||
#include <stdio.h>
|
||||
|
||||
int main(int argc, const char **argv) {
|
||||
if (argc < 2) {
|
||||
fprintf(stderr, "Usage: spl_disasm <file.sir>\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;
|
||||
}
|
||||
Reference in New Issue
Block a user