Fix and simplify debug location management
!120 (merged) introduces a new way of storing debug locations, inspired by Python. Instead of storing a location for every instruction, we map instruction offsets to locations, and store the locations in a compact manner.
Unfortunately, the approach results to incorrect stack traces at times. It's also quite clunky to generate code for. Instead I'd like to change this to a much simpler representation: instead of tracking offsets, we just map instruction indexes to locations in a dense array. We only care about a subset of instructions anyway (e.g. calls), so this array is likely to be quite small.
Finding the location is quite simple: each frame has its instruction index set to the instruction after a call (since we increment this first). In the current frame we may point to beyond a non-call instruction, such as IntegerAdd
when it overflows. Thus the logic is basically as follows: for the current frame we keep the index as-is, but for all parent frames we subtract 1 from the index (unless the index is already zero). We then scan our dense array until we find an entry for each index.
Memory efficiency isn't that important here: my long term goal is to compile to native code (see #248), at which point we'd probably just use DWARF debugging information, removing the need for this custom system entirely.