- because autoloading is not an explicit request "load this file",
- but rather a request to "call this function".
-
- The value saved here is to be restored into Vautoload_queue. */
- record_unwind_protect (un_autoload, Vautoload_queue);
- Vautoload_queue = Qt;
- /* If `macro_only', assume this autoload to be a "best-effort",
- so don't signal an error if autoloading fails. */
- Fload (Fcar (Fcdr (fundef)), macro_only, Qt, Qnil, Qt);
-
- /* Once loading finishes, don't undo it. */
- Vautoload_queue = Qt;
- unbind_to (count, Qnil);
-
- UNGCPRO;
-
- if (NILP (funname))
- return Qnil;
- else
- {
- Lisp_Object fun = Findirect_function (funname, Qnil);
-
- if (!NILP (Fequal (fun, fundef)))
- error ("Autoloading failed to define function %s",
- SDATA (SYMBOL_NAME (funname)));
- else
- return fun;
- }
-}
-
-\f
-DEFUN ("eval", Feval, Seval, 1, 2, 0,
- doc: /* Evaluate FORM and return its value.
-If LEXICAL is t, evaluate using lexical scoping. */)
- (Lisp_Object form, Lisp_Object lexical)
-{
- ptrdiff_t count = SPECPDL_INDEX ();
- specbind (Qinternal_interpreter_environment,
- CONSP (lexical) || NILP (lexical) ? lexical : Fcons (Qt, Qnil));
- return unbind_to (count, eval_sub (form));
-}
-
-static void
-grow_specpdl (void)
-{
- ptrdiff_t count = SPECPDL_INDEX ();
- ptrdiff_t max_size = min (max_specpdl_size, PTRDIFF_MAX - 1000);
- union specbinding *pdlvec = specpdl - 1;
- ptrdiff_t pdlvecsize = specpdl_size + 1;
- if (max_size <= specpdl_size)
- {
- if (max_specpdl_size < 400)
- max_size = max_specpdl_size = 400;
- if (max_size <= specpdl_size)
- signal_error ("Variable binding depth exceeds max-specpdl-size", Qnil);
- }
- pdlvec = xpalloc (pdlvec, &pdlvecsize, 1, max_size + 1, sizeof *specpdl);
- specpdl = pdlvec + 1;
- specpdl_size = pdlvecsize - 1;
- specpdl_ptr = specpdl + count;
-}
-
-void
-record_in_backtrace (Lisp_Object function, Lisp_Object *args, ptrdiff_t nargs)
-{
- eassert (nargs >= UNEVALLED);
- if (specpdl_ptr == specpdl + specpdl_size)
- grow_specpdl ();
- specpdl_ptr->bt.kind = SPECPDL_BACKTRACE;
- specpdl_ptr->bt.debug_on_exit = false;
- specpdl_ptr->bt.function = function;
- specpdl_ptr->bt.args = args;
- specpdl_ptr->bt.nargs = nargs;
- specpdl_ptr++;
-}
-
-/* Eval a sub-expression of the current expression (i.e. in the same
- lexical scope). */
-Lisp_Object
-eval_sub (Lisp_Object form)
-{
- Lisp_Object fun, val, original_fun, original_args;
- Lisp_Object funcar;
- struct gcpro gcpro1, gcpro2, gcpro3;
-
- if (SYMBOLP (form))
- {
- /* Look up its binding in the lexical environment.
- We do not pay attention to the declared_special flag here, since we
- already did that when let-binding the variable. */
- Lisp_Object lex_binding
- = !NILP (Vinternal_interpreter_environment) /* Mere optimization! */
- ? Fassq (form, Vinternal_interpreter_environment)
- : Qnil;
- if (CONSP (lex_binding))
- return XCDR (lex_binding);
- else
- return Fsymbol_value (form);
- }
-
- if (!CONSP (form))
- return form;
-
- QUIT;
-
- GCPRO1 (form);
- maybe_gc ();
- UNGCPRO;
-
- if (++lisp_eval_depth > max_lisp_eval_depth)
- {
- if (max_lisp_eval_depth < 100)
- max_lisp_eval_depth = 100;
- if (lisp_eval_depth > max_lisp_eval_depth)
- error ("Lisp nesting exceeds `max-lisp-eval-depth'");
- }
-
- original_fun = XCAR (form);
- original_args = XCDR (form);
-
- /* This also protects them from gc. */
- record_in_backtrace (original_fun, &original_args, UNEVALLED);
-
- if (debug_on_next_call)
- do_debug_on_call (Qt);
-
- /* At this point, only original_fun and original_args
- have values that will be used below. */
- retry:
-
- /* Optimize for no indirection. */
- fun = original_fun;
- if (SYMBOLP (fun) && !NILP (fun)
- && (fun = XSYMBOL (fun)->function, SYMBOLP (fun)))
- fun = indirect_function (fun);
-
- if (SUBRP (fun))
- {
- Lisp_Object numargs;
- Lisp_Object argvals[8];
- Lisp_Object args_left;
- register int i, maxargs;
-
- args_left = original_args;
- numargs = Flength (args_left);
-
- check_cons_list ();
-
- if (XINT (numargs) < XSUBR (fun)->min_args
- || (XSUBR (fun)->max_args >= 0
- && XSUBR (fun)->max_args < XINT (numargs)))
- xsignal2 (Qwrong_number_of_arguments, original_fun, numargs);
-
- else if (XSUBR (fun)->max_args == UNEVALLED)
- val = (XSUBR (fun)->function.aUNEVALLED) (args_left);
- else if (XSUBR (fun)->max_args == MANY)
- {
- /* Pass a vector of evaluated arguments. */
- Lisp_Object *vals;
- ptrdiff_t argnum = 0;
- USE_SAFE_ALLOCA;