Subject: Re: bug#58739: Lack of error message about number of args (?native compilation?)

From: Alan Mackenzie <[email-masked]>
Date: Sat, 29 Oct 2022 12:04:36 +0000

Hello, Andrea.

On Tue, Oct 25, 2022 at 20:15:38 +0000, Andrea Corallo wrote:
> Alan Mackenzie <[email-masked]> writes:

> > On Sun, Oct 23, 2022 at 12:12:49 +0000, Alan Mackenzie wrote:

[ .... ]

> >> As a matter of interest, I noticed this bug while byte-compiling
> >> desktop.el inside Emacs.  It gave a warning message about the number of
> >> parameters to desktop-buffer having changed from 12+ to 12.

> >> Here, I suspect there's a bug in the native compilation of
> >> desktop-buffer.

> > The problem here is that (func-arity 'desktop-buffer) returns (12 . 12) on a
> > byte compiled desktop.elc, but (12 . many) on the corresponding .eln file.
> > This (12 . many) must be regarded as a bug, since there are no &rest
> > parameters in desktop-buffer.

> > I propose a minor amendment to the definition of MANY, such that it will
> > mean "there are &rest parameters", rather than "the calling convention
> > is with nargs + *args".  I have implemented this, and my patch is below.

> > What I want to ask you to check is that in the native compiler, when
> > declare_imported_func encounters a function with, say, exactly 12
> > arguments, it will throw an error.  I think this is actually correct,
> > since the compiler cannot know whether this function uses the subr
> > calling convention of nargs + *args, or the byte coded convention of
> > pushing the 12 arguments individually onto the stack.  Is throwing this
> > error a good idea?

> Hi Alan,

> to me this fix looks like a good idea (assuming changing the definition
> of MANY is acceptable).

We'll see what Eli says.

> I think also that throwing the error in 'declare_imported_func' is okay
> at this point.

Apologies at this point.  I should have produced an error from this
before bothering you.  I was unable to produce such an error, and I've
spent the last few days understanding what happens here, with this
result:

A call from a native compiled function is always in the form nargs +
*args, regardless of whether there are more than 8 arguments or not.
More accurately, the call to an unknown type of function (.eln/.elc/.el)
puts the function (in some form, I don't know exactly what) at element 0
of *args, and the arguments themselves starting at element 1 of *args.
It then calls Ffuncall (or something like it).

When the called function is a byte-code function, further down the call
stack exec_byte_code gets called with this (nargs + 1) + *args.
exec_byte_code then pushes the arguments onto the stack before
interpreting the byte code.

So this "problem" with the native compiler not knowing what call sequence
to generate isn't a problem at all.  It's all dealt with at run time.  No
doubt this slows down Emacs quite a bit, but it's safe.

So I'll take that bit out of my patch, and commit the rest of it to
master, and see what happens from there.

> Just two small nits (forgive me please :) :

Thanks for these, I've incorporated them into my amended source code.

[ .... ]

> Thanks for the patch!

>   Andrea

-- 
Alan Mackenzie (Nuremberg, Germany).