Dialog Wishlist

This bug is now fixed.

The first time a local variable appears in a routine, the compiler allocates some memory for it. The problem is, when it’s compiling a list literal like [$X $X], the list gets compiled from back to front: the last values are compiled first. (This comes down to how lists are represented as LISP-style cons cells. When compiling [$X $X], it first compiles [$X | [] ], and then compiles [$X | that thing].)

As a result, when the same unbound variable appears twice in a row in a list literal, and it hasn’t been used for anything before that list literal, it gets used before the memory is allocated, and the result is undefined! On the Z-machine, it accesses whatever happens to be sitting around in memory. In the debugger, it fails an assert and crashes.

For now, you can work around this in a few different ways. If you use the variable for anything before that, it works fine:

(do nothing $)
(program entry point)
    (do nothing $X)
    ([$X $X] = $Y)
    $Y

Or if you avoid having the same unbound variable twice in a row, that’s also fine:

(program entry point)
    ([$X 0 $X] = $Y)
    $Y

Or, I’ve just submitted a pull request that should fix this once and for all! It also fixes this bug, which has the same root cause.

5 Likes