Some debug fixes. (0.27.1)
This commit is contained in:
parent
1ba950ec15
commit
48f5c3e313
2 changed files with 21 additions and 15 deletions
|
|
@ -1,5 +1,5 @@
|
||||||
cmake_minimum_required(VERSION 3.10)
|
cmake_minimum_required(VERSION 3.10)
|
||||||
project(fun VERSION 0.27.0 LANGUAGES C)
|
project(fun VERSION 0.27.1 LANGUAGES C)
|
||||||
|
|
||||||
set(CMAKE_C_STANDARD 99)
|
set(CMAKE_C_STANDARD 99)
|
||||||
set(CMAKE_C_STANDARD_REQUIRED ON)
|
set(CMAKE_C_STANDARD_REQUIRED ON)
|
||||||
|
|
|
||||||
34
src/vm.c
34
src/vm.c
|
|
@ -39,33 +39,39 @@ static VM *g_active_vm = NULL;
|
||||||
/* fprintf wrapper that appends source line info for stderr messages */
|
/* fprintf wrapper that appends source line info for stderr messages */
|
||||||
static int fun_vm_vfprintf(FILE *stream, const char *fmt, va_list ap) {
|
static int fun_vm_vfprintf(FILE *stream, const char *fmt, va_list ap) {
|
||||||
int written = vfprintf(stream, fmt, ap);
|
int written = vfprintf(stream, fmt, ap);
|
||||||
if (stream == stderr && g_active_vm && g_active_vm->current_line > 0) {
|
if (stream == stderr && g_active_vm) {
|
||||||
/* Append more context: line number, opcode name, and ip */
|
/* Determine current frame and instruction pointer of the faulting op */
|
||||||
const char *opname = "unknown";
|
const char *opname = "unknown";
|
||||||
int ip = -1;
|
|
||||||
if (g_active_vm->fp >= 0) {
|
|
||||||
Frame *f = &g_active_vm->frames[g_active_vm->fp];
|
|
||||||
ip = f->ip - 1;
|
|
||||||
if (f->fn && ip >= 0 && ip < f->fn->instr_count) {
|
|
||||||
int op = f->fn->instructions[ip].op;
|
|
||||||
if (op >= 0 && op < (int)(sizeof(opcode_names)/sizeof(opcode_names[0]))) {
|
|
||||||
opname = opcode_names[op];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
const char *fname = NULL;
|
const char *fname = NULL;
|
||||||
const char *sfile = NULL;
|
const char *sfile = NULL;
|
||||||
|
int ip = -1;
|
||||||
|
int line = -1;
|
||||||
if (g_active_vm->fp >= 0) {
|
if (g_active_vm->fp >= 0) {
|
||||||
Frame *f = &g_active_vm->frames[g_active_vm->fp];
|
Frame *f = &g_active_vm->frames[g_active_vm->fp];
|
||||||
|
ip = f->ip - 1; /* last executed instruction */
|
||||||
if (f->fn) {
|
if (f->fn) {
|
||||||
fname = f->fn->name;
|
fname = f->fn->name;
|
||||||
sfile = f->fn->source_file;
|
sfile = f->fn->source_file;
|
||||||
|
/* derive opcode name */
|
||||||
|
if (ip >= 0 && ip < f->fn->instr_count) {
|
||||||
|
int op = f->fn->instructions[ip].op;
|
||||||
|
if (op >= 0 && op < (int)(sizeof(opcode_names)/sizeof(opcode_names[0]))) {
|
||||||
|
opname = opcode_names[op];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* derive source line by scanning back to the most recent OP_LINE marker */
|
||||||
|
for (int i = ip; i >= 0; --i) {
|
||||||
|
Instruction prev = f->fn->instructions[i];
|
||||||
|
if (prev.op == OP_LINE) { line = prev.operand; break; }
|
||||||
|
}
|
||||||
|
/* fallback to VM's last recorded line if no marker found */
|
||||||
|
if (line <= 0) line = g_active_vm->current_line > 0 ? g_active_vm->current_line : 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fprintf(stream == stderr ? stderr : stream,
|
fprintf(stream == stderr ? stderr : stream,
|
||||||
" (at %s:%d in %s, op %s @ip %d)\n",
|
" (at %s:%d in %s, op %s @ip %d)\n",
|
||||||
sfile ? sfile : "<unknown>",
|
sfile ? sfile : "<unknown>",
|
||||||
g_active_vm->current_line,
|
line > 0 ? line : 1,
|
||||||
fname ? fname : "<entry>",
|
fname ? fname : "<entry>",
|
||||||
opname,
|
opname,
|
||||||
ip);
|
ip);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue