📄 debug.c
字号:
/* * Support for debugging the implementation. * Copyright (C) 2001-2002 Darius Bacon */#include "idel_private.h"static const char *op_name[] = {#include "names.inc"};static const int op_operand_count[] = {#include "args.inc"};/* Return the number of operands that Idel opcode `op' takes, or -1 if there's no such opcode. */intoperand_count (int op){ if (NELEMS (op_operand_count) <= (unsigned) op) return -1; return op_operand_count[op];}/* Return the Idel opcode corresponding to internal code `s', or -1 if none. */intlookup_op (i32 s){ cplabel cpl = (cplabel) s; int i, limit = NELEMS (op_name); for (i = 0; i < limit; ++i) if (opcode_labels[i] == cpl) return i; return -1;}/* Return a human-readable string describing the compiled instruction starting at `pc'. The result is statically allocated: non-reentrant, etc. */char *format_op (const i32 *pc){ /* The scratch buffer has to be big enough to fit all the sprintfs, or we have a potential exploit. The format strings have limits on all the field sizes (like %15.15s) to ensure this. (Actually it's safe anyway because all the instruction names are short, and this note is just here for defense in depth.) */ static char scratch[80]; int op = lookup_op (pc[0]); if (NELEMS (op_name) <= (unsigned) op) sprintf (scratch, "%p: Bad opcode: %d", pc, op); else if (op == JUMP) sprintf (scratch, "%p: %-15.15s %p", pc, op_name[op], pc + 2 + pc[1]); else if (operand_count (op) == 1) sprintf (scratch, "%p: %-15.15s %x", pc, op_name[op], pc[1]); else sprintf (scratch, "%p: %-15.15s", pc, op_name[op]); return scratch;}/* Return a human-readable string describing the opcode of the compiled instruction starting at `pc'. The result is statically allocated: non-reentrant, etc. */char *format_opcode (const i32 opcode){ static char scratch[80]; if (NELEMS (op_name) <= (unsigned) opcode) sprintf (scratch, "Bad_opcode"); else sprintf (scratch, "%s", op_name[opcode]); return scratch;}/* Return vm's Entry for the defn starting at `p', or NULL if none. */static const Entry *find_entry (const VM *vm, const i32 *p){ int i; for (i = 0; i < vm->defn_number; ++i) if (vm->entries[i].address == p) return vm->entries + i; return NULL;}/* Display all vm's code on stdout. */voidvm_dump_code (const VM *vm){ int i; for (i = 0; i < vm->num_chunks; ++i) { const i32 *end = vm->chunks[i] + chunk_size; const i32 *p = (i == vm->num_chunks - 1 ? vm->there : vm->chunks[i]); while (p < end) { const Entry *e = find_entry (vm, p); if (e) { printf ("%p:\t\t%d %d (%d)\n", p, e->popping, e->pushing, *p); ++p; } printf ("%s\n", format_op (p)); p += 1 + operand_count (lookup_op (*p)); } }}/* Display vm's stacks on stdout. */voidvm_dump_stacks (const VM *vm){ i32 *sp = vm->sp, *rp = vm->rp, *stack = vm->stack; printf ("Data stack:\n"); for (--sp; stack <= sp; --sp) printf ("%p: %x\n", sp, *sp); printf ("Return stack:\n"); for (; rp < stack + vm->stack_size; rp++) printf ("%p: %x\n", sp, *rp); printf ("\n");}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -