Fix the subr-arity returned by native compiled functions with lots of args
This fixes bug #58739. Make subr-arity return, e.g., (12 . 12) rather than (12 . many) for a function with a fixed number of arguments more than 8. * lisp/emacs-lisp/comp.el (comp-prepare-args-for-top-level): Only return a cdr of 'many when there are &rest arguments. * src/eval.c (eval_sub): Also check for a fixed number of args over 8 when using the nargs + *args calling convention. (funcall_subr): Also check numargs <= 8 before using the fixed args calling convention. Include the case numargs > 8 in the aMany calling convention. * src/lisp.h (DEFUN): Amend the comment about MANY.
This commit is contained in:
parent
174dd06464
commit
31e7b9c073
3 changed files with 17 additions and 14 deletions
|
@ -2057,9 +2057,10 @@ and the annotation emission."
|
||||||
"Lexically-scoped FUNCTION."
|
"Lexically-scoped FUNCTION."
|
||||||
(let ((args (comp-func-l-args function)))
|
(let ((args (comp-func-l-args function)))
|
||||||
(cons (make-comp-mvar :constant (comp-args-base-min args))
|
(cons (make-comp-mvar :constant (comp-args-base-min args))
|
||||||
(make-comp-mvar :constant (if (comp-args-p args)
|
(make-comp-mvar :constant (cond
|
||||||
(comp-args-max args)
|
((comp-args-p args) (comp-args-max args))
|
||||||
'many)))))
|
((comp-nargs-rest args) 'many)
|
||||||
|
(t (comp-nargs-nonrest args)))))))
|
||||||
|
|
||||||
(cl-defmethod comp-prepare-args-for-top-level ((function comp-func-d))
|
(cl-defmethod comp-prepare-args-for-top-level ((function comp-func-d))
|
||||||
"Dynamically scoped FUNCTION."
|
"Dynamically scoped FUNCTION."
|
||||||
|
|
15
src/eval.c
15
src/eval.c
|
@ -2435,7 +2435,9 @@ eval_sub (Lisp_Object form)
|
||||||
|
|
||||||
else if (XSUBR (fun)->max_args == UNEVALLED)
|
else if (XSUBR (fun)->max_args == UNEVALLED)
|
||||||
val = (XSUBR (fun)->function.aUNEVALLED) (args_left);
|
val = (XSUBR (fun)->function.aUNEVALLED) (args_left);
|
||||||
else if (XSUBR (fun)->max_args == MANY)
|
else if (XSUBR (fun)->max_args == MANY
|
||||||
|
|| XSUBR (fun)->max_args > 8)
|
||||||
|
|
||||||
{
|
{
|
||||||
/* Pass a vector of evaluated arguments. */
|
/* Pass a vector of evaluated arguments. */
|
||||||
Lisp_Object *vals;
|
Lisp_Object *vals;
|
||||||
|
@ -2998,7 +3000,8 @@ funcall_subr (struct Lisp_Subr *subr, ptrdiff_t numargs, Lisp_Object *args)
|
||||||
if (numargs >= subr->min_args)
|
if (numargs >= subr->min_args)
|
||||||
{
|
{
|
||||||
/* Conforming call to finite-arity subr. */
|
/* Conforming call to finite-arity subr. */
|
||||||
if (numargs <= subr->max_args)
|
if (numargs <= subr->max_args
|
||||||
|
&& subr->max_args <= 8)
|
||||||
{
|
{
|
||||||
Lisp_Object argbuf[8];
|
Lisp_Object argbuf[8];
|
||||||
Lisp_Object *a;
|
Lisp_Object *a;
|
||||||
|
@ -3034,15 +3037,13 @@ funcall_subr (struct Lisp_Subr *subr, ptrdiff_t numargs, Lisp_Object *args)
|
||||||
return subr->function.a8 (a[0], a[1], a[2], a[3], a[4], a[5],
|
return subr->function.a8 (a[0], a[1], a[2], a[3], a[4], a[5],
|
||||||
a[6], a[7]);
|
a[6], a[7]);
|
||||||
default:
|
default:
|
||||||
/* If a subr takes more than 8 arguments without using MANY
|
emacs_abort (); /* Can't happen. */
|
||||||
or UNEVALLED, we need to extend this function to support it.
|
|
||||||
Until this is done, there is no way to call the function. */
|
|
||||||
emacs_abort ();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Call to n-adic subr. */
|
/* Call to n-adic subr. */
|
||||||
if (subr->max_args == MANY)
|
if (subr->max_args == MANY
|
||||||
|
|| subr->max_args > 8)
|
||||||
return subr->function.aMANY (numargs, args);
|
return subr->function.aMANY (numargs, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3183,10 +3183,11 @@ CHECK_SUBR (Lisp_Object x)
|
||||||
`minargs' should be a number, the minimum number of arguments allowed.
|
`minargs' should be a number, the minimum number of arguments allowed.
|
||||||
`maxargs' should be a number, the maximum number of arguments allowed,
|
`maxargs' should be a number, the maximum number of arguments allowed,
|
||||||
or else MANY or UNEVALLED.
|
or else MANY or UNEVALLED.
|
||||||
MANY means pass a vector of evaluated arguments,
|
MANY means there are &rest arguments. Here we pass a vector
|
||||||
in the form of an integer number-of-arguments
|
of evaluated arguments in the form of an integer
|
||||||
followed by the address of a vector of Lisp_Objects
|
number-of-arguments followed by the address of a vector of
|
||||||
which contains the argument values.
|
Lisp_Objects which contains the argument values. (We also use
|
||||||
|
this convention when calling a subr with more than 8 parameters.)
|
||||||
UNEVALLED means pass the list of unevaluated arguments
|
UNEVALLED means pass the list of unevaluated arguments
|
||||||
`intspec' says how interactive arguments are to be fetched.
|
`intspec' says how interactive arguments are to be fetched.
|
||||||
If the string starts with a `(', `intspec' is evaluated and the resulting
|
If the string starts with a `(', `intspec' is evaluated and the resulting
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue