Anton Ertl - 2019-01-04

I have not looked at FICL, so I don't know how it uses
setjmp/longjump. In Gforth we use setjump/longjump to get back from
the signal handler (for stuff like invalid memory access, Ctrl-C,
stack underflow, division by zero) to the engine. All these
conditions produce a Forth-level exception, which helps getting around
the problem for gforth-fast (the benchmarking engine): All stack
pointers and the instruction pointer are reset to the value stored in
the exception frame, so if we lose the values they had when the signal
was raised, this is not a problem.

For gforth (the debugging engine), we also want to produce a
backtrace, so we need to preserve the values of the instruction
pointer and the return stack pointer when the signal was raised. For
the return stack pointer, we make sure it is stored in memory (like
the volatile solution above); the instruction pointer is updated more
often, so to reduce the performance impact we keep it in a register,
but explicitly store its value to memory at the start of every
primitive (VM instruction).

We also considered restoring the values of the registers we are
interested in from sigcontext, but did not take this route for
portability reasons.