SpnSourceLocation spn_dbg_get_raw_source_location(SpnHashMap *debug_info, ptrdiff_t address) { SpnSourceLocation loc = { 0, 0 }; if (debug_info) { SpnValue vinsns = spn_hashmap_get_strkey(debug_info, "insns"); SpnArray *insns = arrayvalue(&vinsns); size_t n = spn_array_count(insns); size_t i; /* this is a 'long', because there's no PTRDIFF_MAX in C89 */ long address_window_width = LONG_MAX; /* search for narrowest bytecode range containing 'address'. * XXX: TODO: this may potentially be slow for large files; * benchmark it and use binary search instead, if necessary. */ for (i = 0; i < n; i++) { SpnValue vexpression = spn_array_get(insns, i); SpnHashMap *expression = hashmapvalue(&vexpression); SpnValue vline = spn_hashmap_get_strkey(expression, "line"); SpnValue vcolumn = spn_hashmap_get_strkey(expression, "column"); SpnValue vbegin = spn_hashmap_get_strkey(expression, "begin"); SpnValue vend = spn_hashmap_get_strkey(expression, "end"); unsigned line = intvalue(&vline); unsigned column = intvalue(&vcolumn); ptrdiff_t begin = intvalue(&vbegin); ptrdiff_t end = intvalue(&vend); if (begin <= address && address < end && end - begin < address_window_width) { /* if the range contains the target address, and it * is narrower than the previous one, then memoize it */ loc.line = line; loc.column = column; address_window_width = end - begin; } } } return loc; }
static void print_array(SpnArray *array, int level) { size_t i; size_t n = spn_array_count(array); printf("[\n"); for (i = 0; i < n; i++) { SpnValue val = spn_array_get(array, i); print_indent(level + 1); inner_aux_print(&val, level + 1); printf("\n"); } print_indent(level); printf("]"); }