Subject: bug#21683: 25.0.50; `advice-add` doesn't work for compiled primitive functions

From: Daniel Colascione <[email-masked]>
Date: Sun, 18 Oct 2015 14:25:42 -0700

On 10/18/2015 02:16 PM, Philipp Stephani wrote:
> This is documented behavior:
> https://www.gnu.org/software/emacs/manual/html_node/elisp/Advising-Named-Functions.html
> It is possible to advise a primitive (see What Is a Function
> <https://www.gnu.org/software/emacs/manual/html_node/elisp/What-Is-a-Function.html#What-Is-a-Function>),
> but one should typically /not/ do so, for two reasons. Firstly, some
> primitives are used by the advice mechanism, and advising them could
> cause an infinite recursion. Secondly, many primitives are called
> directly from C, and such calls ignore advice; hence, one ends up in a
> confusing situation where some calls (occurring from Lisp code) obey the
> advice and other calls (from C code) do not.

If we wanted to allow advising of primitives such that we also redirect
direct calls from C, it wouldn't be that hard: the idea is to either 1)
insert enough NOPs at the start of every function to encode an absolute
jump[1], or 2) associate with every function a Lisp variable and rest it
for nil-ness (which would be a very cheap and very predictable test
against zero with Qnil being all zero bits) on entry.

Option #1 is more clever and thus more fun to write, but option #2
probably suffices.

I just haven't had a good reason to want to advise a primitive, but if
someone wants to do this work, I wouldn't object to it.

[1] You don't actually have to encode enough bytes for an absolute jump.
You just need to be able to encode enough bytes for a backward jump to
the region before the function; this region can then encode your
absolute jump. If we align functions properly, we get this space for
free half the time. See
http://blogs.msdn.com/b/oldnewthing/archive/2011/09/21/10214405.aspx