/* Evaluator for GNU Emacs Lisp interpreter.
Copyright (C) 1985-1987, 1993-1995, 1999-2019 Free Software Foundation,
Inc.
This file is part of GNU Emacs.
GNU Emacs is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or (at
your option) any later version.
GNU Emacs is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Emacs. If not, see . */
#include
#include
#include
#include
#include "lisp.h"
#include "blockinput.h"
#include "commands.h"
#include "keyboard.h"
#include "dispextern.h"
#include "buffer.h"
#include "pdumper.h"
/* CACHEABLE is ordinarily nothing, except it is 'volatile' if
necessary to cajole GCC into not warning incorrectly that a
variable should be volatile. */
#if defined GCC_LINT || defined lint
# define CACHEABLE volatile
#else
# define CACHEABLE /* empty */
#endif
/* Chain of condition and catch handlers currently in effect. */
/* struct handler *handlerlist; */
/* Non-nil means record all fset's and provide's, to be undone
if the file being autoloaded is not fully loaded.
They are recorded by being consed onto the front of Vautoload_queue:
(FUN . ODEF) for a defun, (0 . OFEATURES) for a provide. */
Lisp_Object Vautoload_queue;
/* This holds either the symbol `run-hooks' or nil.
It is nil at an early stage of startup, and when Emacs
is shutting down. */
Lisp_Object Vrun_hooks;
/* The commented-out variables below are macros defined in thread.h. */
/* Current number of specbindings allocated in specpdl, not counting
the dummy entry specpdl[-1]. */
/* ptrdiff_t specpdl_size; */
/* Pointer to beginning of specpdl. A dummy entry specpdl[-1] exists
only so that its address can be taken. */
/* union specbinding *specpdl; */
/* Pointer to first unused element in specpdl. */
/* union specbinding *specpdl_ptr; */
/* Depth in Lisp evaluations and function calls. */
/* static EMACS_INT lisp_eval_depth; */
/* The value of num_nonmacro_input_events as of the last time we
started to enter the debugger. If we decide to enter the debugger
again when this is still equal to num_nonmacro_input_events, then we
know that the debugger itself has an error, and we should just
signal the error instead of entering an infinite loop of debugger
invocations. */
static EMACS_INT when_entered_debugger;
/* The function from which the last `signal' was called. Set in
Fsignal. */
/* FIXME: We should probably get rid of this! */
Lisp_Object Vsignaling_function;
/* These would ordinarily be static, but they need to be visible to GDB. */
bool backtrace_p (union specbinding *) EXTERNALLY_VISIBLE;
Lisp_Object *backtrace_args (union specbinding *) EXTERNALLY_VISIBLE;
Lisp_Object backtrace_function (union specbinding *) EXTERNALLY_VISIBLE;
union specbinding *backtrace_next (union specbinding *) EXTERNALLY_VISIBLE;
union specbinding *backtrace_top (void) EXTERNALLY_VISIBLE;
static Lisp_Object funcall_lambda (Lisp_Object, ptrdiff_t, Lisp_Object *);
static Lisp_Object apply_lambda (Lisp_Object, Lisp_Object, ptrdiff_t);
static Lisp_Object lambda_arity (Lisp_Object);
static Lisp_Object
specpdl_symbol (union specbinding *pdl)
{
eassert (pdl->kind >= SPECPDL_LET);
return pdl->let.symbol;
}
static enum specbind_tag
specpdl_kind (union specbinding *pdl)
{
eassert (pdl->kind >= SPECPDL_LET);
return pdl->let.kind;
}
static Lisp_Object
specpdl_old_value (union specbinding *pdl)
{
eassert (pdl->kind >= SPECPDL_LET);
return pdl->let.old_value;
}
static void
set_specpdl_old_value (union specbinding *pdl, Lisp_Object val)
{
eassert (pdl->kind >= SPECPDL_LET);
pdl->let.old_value = val;
}
static Lisp_Object
specpdl_where (union specbinding *pdl)
{
eassert (pdl->kind > SPECPDL_LET);
return pdl->let.where;
}
static Lisp_Object
specpdl_saved_value (union specbinding *pdl)
{
eassert (pdl->kind >= SPECPDL_LET);
return pdl->let.saved_value;
}
static Lisp_Object
specpdl_arg (union specbinding *pdl)
{
eassert (pdl->kind == SPECPDL_UNWIND);
return pdl->unwind.arg;
}
Lisp_Object
backtrace_function (union specbinding *pdl)
{
eassert (pdl->kind == SPECPDL_BACKTRACE);
return pdl->bt.function;
}
static ptrdiff_t
backtrace_nargs (union specbinding *pdl)
{
eassert (pdl->kind == SPECPDL_BACKTRACE);
return pdl->bt.nargs;
}
Lisp_Object *
backtrace_args (union specbinding *pdl)
{
eassert (pdl->kind == SPECPDL_BACKTRACE);
return pdl->bt.args;
}
static bool
backtrace_debug_on_exit (union specbinding *pdl)
{
eassert (pdl->kind == SPECPDL_BACKTRACE);
return pdl->bt.debug_on_exit;
}
/* Functions to modify slots of backtrace records. */
static void
set_backtrace_args (union specbinding *pdl, Lisp_Object *args, ptrdiff_t nargs)
{
eassert (pdl->kind == SPECPDL_BACKTRACE);
pdl->bt.args = args;
pdl->bt.nargs = nargs;
}
static void
set_backtrace_debug_on_exit (union specbinding *pdl, bool doe)
{
eassert (pdl->kind == SPECPDL_BACKTRACE);
pdl->bt.debug_on_exit = doe;
}
/* Helper functions to scan the backtrace. */
bool
backtrace_p (union specbinding *pdl)
{ return pdl >= specpdl; }
static bool
backtrace_thread_p (struct thread_state *tstate, union specbinding *pdl)
{ return pdl >= tstate->m_specpdl; }
union specbinding *
backtrace_top (void)
{
union specbinding *pdl = specpdl_ptr - 1;
while (backtrace_p (pdl) && pdl->kind != SPECPDL_BACKTRACE)
pdl--;
return pdl;
}
static union specbinding *
backtrace_thread_top (struct thread_state *tstate)
{
union specbinding *pdl = tstate->m_specpdl_ptr - 1;
while (backtrace_thread_p (tstate, pdl) && pdl->kind != SPECPDL_BACKTRACE)
pdl--;
return pdl;
}
union specbinding *
backtrace_next (union specbinding *pdl)
{
pdl--;
while (backtrace_p (pdl) && pdl->kind != SPECPDL_BACKTRACE)
pdl--;
return pdl;
}
static void init_eval_once_for_pdumper (void);
static union specbinding *
backtrace_thread_next (struct thread_state *tstate, union specbinding *pdl)
{
pdl--;
while (backtrace_thread_p (tstate, pdl) && pdl->kind != SPECPDL_BACKTRACE)
pdl--;
return pdl;
}
void
init_eval_once (void)
{
/* Don't forget to update docs (lispref node "Local Variables"). */
max_specpdl_size = 1300; /* 1000 is not enough for CEDET's c-by.el. */
max_lisp_eval_depth = 800;
Vrun_hooks = Qnil;
pdumper_do_now_and_after_load (init_eval_once_for_pdumper);
}
static void
init_eval_once_for_pdumper (void)
{
enum { size = 50 };
union specbinding *pdlvec = malloc ((size + 1) * sizeof *specpdl);
specpdl_size = size;
specpdl = specpdl_ptr = pdlvec + 1;
}
/* static struct handler handlerlist_sentinel; */
void
init_eval (void)
{
specpdl_ptr = specpdl;
{ /* Put a dummy catcher at top-level so that handlerlist is never NULL.
This is important since handlerlist->nextfree holds the freelist
which would otherwise leak every time we unwind back to top-level. */
handlerlist_sentinel = xzalloc (sizeof (struct handler));
handlerlist = handlerlist_sentinel->nextfree = handlerlist_sentinel;
struct handler *c = push_handler (Qunbound, CATCHER);
eassert (c == handlerlist_sentinel);
handlerlist_sentinel->nextfree = NULL;
handlerlist_sentinel->next = NULL;
}
Vquit_flag = Qnil;
debug_on_next_call = 0;
lisp_eval_depth = 0;
/* This is less than the initial value of num_nonmacro_input_events. */
when_entered_debugger = -1;
}
/* Unwind-protect function used by call_debugger. */
static void
restore_stack_limits (Lisp_Object data)
{
max_specpdl_size = XFIXNUM (XCAR (data));
max_lisp_eval_depth = XFIXNUM (XCDR (data));
}
static void grow_specpdl (void);
/* Call the Lisp debugger, giving it argument ARG. */
Lisp_Object
call_debugger (Lisp_Object arg)
{
bool debug_while_redisplaying;
ptrdiff_t count = SPECPDL_INDEX ();
Lisp_Object val;
EMACS_INT old_depth = max_lisp_eval_depth;
/* Do not allow max_specpdl_size less than actual depth (Bug#16603). */
EMACS_INT old_max = max (max_specpdl_size, count);
/* The previous value of 40 is too small now that the debugger
prints using cl-prin1 instead of prin1. Printing lists nested 8
deep (which is the value of print-level used in the debugger)
currently requires 77 additional frames. See bug#31919. */
if (lisp_eval_depth + 100 > max_lisp_eval_depth)
max_lisp_eval_depth = lisp_eval_depth + 100;
/* While debugging Bug#16603, previous value of 100 was found
too small to avoid specpdl overflow in the debugger itself. */
if (max_specpdl_size - 200 < count)
max_specpdl_size = count + 200;
if (old_max == count)
{
/* We can enter the debugger due to specpdl overflow (Bug#16603). */
specpdl_ptr--;
grow_specpdl ();
}
/* Restore limits after leaving the debugger. */
record_unwind_protect (restore_stack_limits,
Fcons (make_fixnum (old_max),
make_fixnum (old_depth)));
#ifdef HAVE_WINDOW_SYSTEM
if (display_hourglass_p)
cancel_hourglass ();
#endif
debug_on_next_call = 0;
when_entered_debugger = num_nonmacro_input_events;
/* Resetting redisplaying_p to 0 makes sure that debug output is
displayed if the debugger is invoked during redisplay. */
debug_while_redisplaying = redisplaying_p;
redisplaying_p = 0;
specbind (intern ("debugger-may-continue"),
debug_while_redisplaying ? Qnil : Qt);
specbind (Qinhibit_redisplay, Qnil);
specbind (Qinhibit_debugger, Qt);
/* If we are debugging an error while `inhibit-changing-match-data'
is bound to non-nil (e.g., within a call to `string-match-p'),
then make sure debugger code can still use match data. */
specbind (Qinhibit_changing_match_data, Qnil);
#if 0 /* Binding this prevents execution of Lisp code during
redisplay, which necessarily leads to display problems. */
specbind (Qinhibit_eval_during_redisplay, Qt);
#endif
val = apply1 (Vdebugger, arg);
/* Interrupting redisplay and resuming it later is not safe under
all circumstances. So, when the debugger returns, abort the
interrupted redisplay by going back to the top-level. */
if (debug_while_redisplaying)
Ftop_level ();
return unbind_to (count, val);
}
static void
do_debug_on_call (Lisp_Object code, ptrdiff_t count)
{
debug_on_next_call = 0;
set_backtrace_debug_on_exit (specpdl + count, true);
call_debugger (list1 (code));
}
/* NOTE!!! Every function that can call EVAL must protect its args
and temporaries from garbage collection while it needs them.
The definition of `For' shows what you have to do. */
DEFUN ("or", For, Sor, 0, UNEVALLED, 0,
doc: /* Eval args until one of them yields non-nil, then return that value.
The remaining args are not evalled at all.
If all args return nil, return nil.
usage: (or CONDITIONS...) */)
(Lisp_Object args)
{
Lisp_Object val = Qnil;
while (CONSP (args))
{
Lisp_Object arg = XCAR (args);
args = XCDR (args);
val = eval_sub (arg);
if (!NILP (val))
break;
}
return val;
}
DEFUN ("and", Fand, Sand, 0, UNEVALLED, 0,
doc: /* Eval args until one of them yields nil, then return nil.
The remaining args are not evalled at all.
If no arg yields nil, return the last arg's value.
usage: (and CONDITIONS...) */)
(Lisp_Object args)
{
Lisp_Object val = Qt;
while (CONSP (args))
{
Lisp_Object arg = XCAR (args);
args = XCDR (args);
val = eval_sub (arg);
if (NILP (val))
break;
}
return val;
}
DEFUN ("if", Fif, Sif, 2, UNEVALLED, 0,
doc: /* If COND yields non-nil, do THEN, else do ELSE...
Returns the value of THEN or the value of the last of the ELSE's.
THEN must be one expression, but ELSE... can be zero or more expressions.
If COND yields nil, and there are no ELSE's, the value is nil.
usage: (if COND THEN ELSE...) */)
(Lisp_Object args)
{
Lisp_Object cond;
cond = eval_sub (XCAR (args));
if (!NILP (cond))
return eval_sub (Fcar (XCDR (args)));
return Fprogn (Fcdr (XCDR (args)));
}
DEFUN ("cond", Fcond, Scond, 0, UNEVALLED, 0,
doc: /* Try each clause until one succeeds.
Each clause looks like (CONDITION BODY...). CONDITION is evaluated
and, if the value is non-nil, this clause succeeds:
then the expressions in BODY are evaluated and the last one's
value is the value of the cond-form.
If a clause has one element, as in (CONDITION), then the cond-form
returns CONDITION's value, if that is non-nil.
If no clause succeeds, cond returns nil.
usage: (cond CLAUSES...) */)
(Lisp_Object args)
{
Lisp_Object val = args;
while (CONSP (args))
{
Lisp_Object clause = XCAR (args);
val = eval_sub (Fcar (clause));
if (!NILP (val))
{
if (!NILP (XCDR (clause)))
val = Fprogn (XCDR (clause));
break;
}
args = XCDR (args);
}
return val;
}
DEFUN ("progn", Fprogn, Sprogn, 0, UNEVALLED, 0,
doc: /* Eval BODY forms sequentially and return value of last one.
usage: (progn BODY...) */)
(Lisp_Object body)
{
Lisp_Object val = Qnil;
while (CONSP (body))
{
Lisp_Object form = XCAR (body);
body = XCDR (body);
val = eval_sub (form);
}
return val;
}
/* Evaluate BODY sequentially, discarding its value. */
void
prog_ignore (Lisp_Object body)
{
Fprogn (body);
}
DEFUN ("prog1", Fprog1, Sprog1, 1, UNEVALLED, 0,
doc: /* Eval FIRST and BODY sequentially; return value from FIRST.
The value of FIRST is saved during the evaluation of the remaining args,
whose values are discarded.
usage: (prog1 FIRST BODY...) */)
(Lisp_Object args)
{
Lisp_Object val = eval_sub (XCAR (args));
prog_ignore (XCDR (args));
return val;
}
DEFUN ("prog2", Fprog2, Sprog2, 2, UNEVALLED, 0,
doc: /* Eval FORM1, FORM2 and BODY sequentially; return value from FORM2.
The value of FORM2 is saved during the evaluation of the
remaining args, whose values are discarded.
usage: (prog2 FORM1 FORM2 BODY...) */)
(Lisp_Object args)
{
eval_sub (XCAR (args));
return Fprog1 (XCDR (args));
}
DEFUN ("setq", Fsetq, Ssetq, 0, UNEVALLED, 0,
doc: /* Set each SYM to the value of its VAL.
The symbols SYM are variables; they are literal (not evaluated).
The values VAL are expressions; they are evaluated.
Thus, (setq x (1+ y)) sets `x' to the value of `(1+ y)'.
The second VAL is not computed until after the first SYM is set, and so on;
each VAL can use the new value of variables set earlier in the `setq'.
The return value of the `setq' form is the value of the last VAL.
usage: (setq [SYM VAL]...) */)
(Lisp_Object args)
{
Lisp_Object val = args, tail = args;
for (EMACS_INT nargs = 0; CONSP (tail); nargs += 2)
{
Lisp_Object sym = XCAR (tail), lex_binding;
tail = XCDR (tail);
if (!CONSP (tail))
xsignal2 (Qwrong_number_of_arguments, Qsetq, make_fixnum (nargs + 1));
Lisp_Object arg = XCAR (tail);
tail = XCDR (tail);
val = eval_sub (arg);
/* Like for eval_sub, we do not check declared_special here since
it's been done when let-binding. */
if (!NILP (Vinternal_interpreter_environment) /* Mere optimization! */
&& SYMBOLP (sym)
&& !NILP (lex_binding
= Fassq (sym, Vinternal_interpreter_environment)))
XSETCDR (lex_binding, val); /* SYM is lexically bound. */
else
Fset (sym, val); /* SYM is dynamically bound. */
}
return val;
}
DEFUN ("quote", Fquote, Squote, 1, UNEVALLED, 0,
doc: /* Return the argument, without evaluating it. `(quote x)' yields `x'.
Warning: `quote' does not construct its return value, but just returns
the value that was pre-constructed by the Lisp reader (see info node
`(elisp)Printed Representation').
This means that \\='(a . b) is not identical to (cons \\='a \\='b): the former
does not cons. Quoting should be reserved for constants that will
never be modified by side-effects, unless you like self-modifying code.
See the common pitfall in info node `(elisp)Rearrangement' for an example
of unexpected results when a quoted object is modified.
usage: (quote ARG) */)
(Lisp_Object args)
{
if (!NILP (XCDR (args)))
xsignal2 (Qwrong_number_of_arguments, Qquote, Flength (args));
return XCAR (args);
}
DEFUN ("function", Ffunction, Sfunction, 1, UNEVALLED, 0,
doc: /* Like `quote', but preferred for objects which are functions.
In byte compilation, `function' causes its argument to be compiled.
`quote' cannot do that.
usage: (function ARG) */)
(Lisp_Object args)
{
Lisp_Object quoted = XCAR (args);
if (!NILP (XCDR (args)))
xsignal2 (Qwrong_number_of_arguments, Qfunction, Flength (args));
if (!NILP (Vinternal_interpreter_environment)
&& CONSP (quoted)
&& EQ (XCAR (quoted), Qlambda))
{ /* This is a lambda expression within a lexical environment;
return an interpreted closure instead of a simple lambda. */
Lisp_Object cdr = XCDR (quoted);
Lisp_Object tmp = cdr;
if (CONSP (tmp)
&& (tmp = XCDR (tmp), CONSP (tmp))
&& (tmp = XCAR (tmp), CONSP (tmp))
&& (EQ (QCdocumentation, XCAR (tmp))))
{ /* Handle the special (:documentation