Many of the recent performance changes included replacing Fsetcar()
and Fsetcdr() with XCAR/XCDR on the left side of an assignment. After
thinking about it, I must conclude that these changes are dangerous
in the general case where we don't know if the cons is writable or
not. Fsetcar() contains a call to CHECK_IMPURE, while XCAR does not.
This means that functions like Fdelq() can well cause a coredump
(instead of a mere error) when called on a pure cons, at least on
architectures where purespace is read-only.
If we plan to deal with this, I think we need an lvalue version of
XCAR and XCDR, e.g.:
#define XSETCAR(conscell, newcar) do {
CHECK_IMPURE (conscell);
XCAR (conscell) = newcar;
} while (0)
/* And ditto for XSETCDR. */
This macro would allow us to deal correctly with read-only conses,
while still avoiding the price of a function call to Fsetcar().
(In fact, on *real* Unixes, we could simply use sigaction() to trap
SIGSEGV and have the handler check whether the SEGV was caused by
modifying a pure cons, and signal an error in that case. Of course,
this would not work on Linux.)