]> code.delx.au - gnu-emacs/blobdiff - src/eval.c
In ‘adjust-window-trailing-edge’ fix bug with size-preserved windows.
[gnu-emacs] / src / eval.c
index 8194468a650d33c756d9f03fe4da2f19b12abc78..9bdcf4bed1747c27ab6239881ec88bc4cb81421c 100644 (file)
@@ -1,6 +1,6 @@
 /* Evaluator for GNU Emacs Lisp interpreter.
 
-Copyright (C) 1985-1987, 1993-1995, 1999-2014 Free Software Foundation,
+Copyright (C) 1985-1987, 1993-1995, 1999-2015 Free Software Foundation,
 Inc.
 
 This file is part of GNU Emacs.
@@ -38,22 +38,6 @@ struct handler *handlerlist;
 int gcpro_level;
 #endif
 
-Lisp_Object Qautoload, Qmacro, Qexit, Qinteractive, Qcommandp;
-Lisp_Object Qinhibit_quit;
-Lisp_Object Qand_rest;
-static Lisp_Object Qand_optional;
-static Lisp_Object Qinhibit_debugger;
-static Lisp_Object Qdeclare;
-Lisp_Object Qinternal_interpreter_environment, Qclosure;
-
-static Lisp_Object Qdebug;
-
-/* 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;
-
 /* 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:
@@ -61,6 +45,11 @@ Lisp_Object Vrun_hooks;
 
 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;
+
 /* Current number of specbindings allocated in specpdl, not counting
    the dummy entry specpdl[-1].  */
 
@@ -211,6 +200,12 @@ backtrace_next (union specbinding *pdl)
   return pdl;
 }
 
+/* Return a pointer to somewhere near the top of the C stack.  */
+void *
+near_C_stack_top (void)
+{
+  return backtrace_args (backtrace_top ());
+}
 
 void
 init_eval_once (void)
@@ -221,7 +216,7 @@ init_eval_once (void)
   specpdl = specpdl_ptr = pdlvec + 1;
   /* 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 = 600;
+  max_lisp_eval_depth = 800;
 
   Vrun_hooks = Qnil;
 }
@@ -231,6 +226,8 @@ static struct handler handlerlist_sentinel;
 void
 init_eval (void)
 {
+  gcprolist = 0;
+  byte_stack_list = 0;
   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
@@ -586,10 +583,23 @@ usage: (function ARG)  */)
   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.  */
-    return Fcons (Qclosure, Fcons (Vinternal_interpreter_environment,
-                                  XCDR (quoted)));
+    { /* 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 <form>) to build the docstring
+            dynamically.  */
+         Lisp_Object docstring = eval_sub (Fcar (XCDR (tmp)));
+         CHECK_STRING (docstring);
+         cdr = Fcons (XCAR (cdr), Fcons (docstring, XCDR (XCDR (cdr))));
+       }
+      return Fcons (Qclosure, Fcons (Vinternal_interpreter_environment,
+                                    cdr));
+    }
   else
     /* Simply quote the argument.  */
     return quoted;
@@ -1173,7 +1183,8 @@ unwind_to_catch (struct handler *catch, Lisp_Object value)
 
 DEFUN ("throw", Fthrow, Sthrow, 2, 2, 0,
        doc: /* Throw to the catch for TAG and return VALUE from it.
-Both TAG and VALUE are evalled.  */)
+Both TAG and VALUE are evalled.  */
+       attributes: noreturn)
   (register Lisp_Object tag, Lisp_Object value)
 {
   struct handler *c;
@@ -2309,8 +2320,8 @@ usage: (apply FUNCTION &rest ARGUMENTS)  */)
       /* Avoid making funcall cons up a yet another new vector of arguments
         by explicitly supplying nil's for optional values.  */
       SAFE_ALLOCA_LISP (funcall_args, 1 + XSUBR (fun)->max_args);
-      for (i = numargs; i < XSUBR (fun)->max_args; /* nothing */)
-       funcall_args[++i] = Qnil;
+      memclear (funcall_args + numargs + 1,
+               (XSUBR (fun)->max_args - numargs) * word_size);
       funcall_nargs = 1 + XSUBR (fun)->max_args;
     }
   else
@@ -2363,14 +2374,10 @@ Instead, use `add-hook' and specify t for the LOCAL argument.
 usage: (run-hooks &rest HOOKS)  */)
   (ptrdiff_t nargs, Lisp_Object *args)
 {
-  Lisp_Object hook[1];
   ptrdiff_t i;
 
   for (i = 0; i < nargs; i++)
-    {
-      hook[0] = args[i];
-      run_hook_with_args (1, hook, funcall_nil);
-    }
+    run_hook (args[i]);
 
   return Qnil;
 }
@@ -2536,20 +2543,27 @@ run_hook_with_args (ptrdiff_t nargs, Lisp_Object *args,
     }
 }
 
+/* Run the hook HOOK, giving each function no args.  */
+
+void
+run_hook (Lisp_Object hook)
+{
+  Frun_hook_with_args (1, &hook);
+}
+
 /* Run the hook HOOK, giving each function the two args ARG1 and ARG2.  */
 
 void
 run_hook_with_args_2 (Lisp_Object hook, Lisp_Object arg1, Lisp_Object arg2)
 {
-  Frun_hook_with_args (3, ((Lisp_Object []) { hook, arg1, arg2 }));
+  CALLN (Frun_hook_with_args, hook, arg1, arg2);
 }
 
 /* Apply fn to arg.  */
 Lisp_Object
 apply1 (Lisp_Object fn, Lisp_Object arg)
 {
-  return (NILP (arg) ? Ffuncall (1, &fn)
-         : Fapply (2, ((Lisp_Object []) { fn, arg })));
+  return NILP (arg) ? Ffuncall (1, &fn) : CALLN (Fapply, fn, arg);
 }
 
 /* Call function fn on no arguments.  */
@@ -2564,7 +2578,7 @@ call0 (Lisp_Object fn)
 Lisp_Object
 call1 (Lisp_Object fn, Lisp_Object arg1)
 {
-  return Ffuncall (2, ((Lisp_Object []) { fn, arg1 }));
+  return CALLN (Ffuncall, fn, arg1);
 }
 
 /* Call function fn with 2 arguments arg1, arg2.  */
@@ -2572,7 +2586,7 @@ call1 (Lisp_Object fn, Lisp_Object arg1)
 Lisp_Object
 call2 (Lisp_Object fn, Lisp_Object arg1, Lisp_Object arg2)
 {
-  return Ffuncall (3, ((Lisp_Object []) { fn, arg1, arg2 }));
+  return CALLN (Ffuncall, fn, arg1, arg2);
 }
 
 /* Call function fn with 3 arguments arg1, arg2, arg3.  */
@@ -2580,7 +2594,7 @@ call2 (Lisp_Object fn, Lisp_Object arg1, Lisp_Object arg2)
 Lisp_Object
 call3 (Lisp_Object fn, Lisp_Object arg1, Lisp_Object arg2, Lisp_Object arg3)
 {
-  return Ffuncall (4, ((Lisp_Object []) { fn, arg1, arg2, arg3 }));
+  return CALLN (Ffuncall, fn, arg1, arg2, arg3);
 }
 
 /* Call function fn with 4 arguments arg1, arg2, arg3, arg4.  */
@@ -2589,7 +2603,7 @@ Lisp_Object
 call4 (Lisp_Object fn, Lisp_Object arg1, Lisp_Object arg2, Lisp_Object arg3,
        Lisp_Object arg4)
 {
-  return Ffuncall (5, ((Lisp_Object []) { fn, arg1, arg2, arg3, arg4 }));
+  return CALLN (Ffuncall, fn, arg1, arg2, arg3, arg4);
 }
 
 /* Call function fn with 5 arguments arg1, arg2, arg3, arg4, arg5.  */
@@ -2598,7 +2612,7 @@ Lisp_Object
 call5 (Lisp_Object fn, Lisp_Object arg1, Lisp_Object arg2, Lisp_Object arg3,
        Lisp_Object arg4, Lisp_Object arg5)
 {
-  return Ffuncall (6, ((Lisp_Object []) { fn, arg1, arg2, arg3, arg4, arg5 }));
+  return CALLN (Ffuncall, fn, arg1, arg2, arg3, arg4, arg5);
 }
 
 /* Call function fn with 6 arguments arg1, arg2, arg3, arg4, arg5, arg6.  */
@@ -2607,8 +2621,7 @@ Lisp_Object
 call6 (Lisp_Object fn, Lisp_Object arg1, Lisp_Object arg2, Lisp_Object arg3,
        Lisp_Object arg4, Lisp_Object arg5, Lisp_Object arg6)
 {
-  return Ffuncall (7, ((Lisp_Object [])
-    { fn, arg1, arg2, arg3, arg4, arg5, arg6 }));
+  return CALLN (Ffuncall, fn, arg1, arg2, arg3, arg4, arg5, arg6);
 }
 
 /* Call function fn with 7 arguments arg1, arg2, arg3, arg4, arg5, arg6, arg7.  */
@@ -2617,8 +2630,7 @@ Lisp_Object
 call7 (Lisp_Object fn, Lisp_Object arg1, Lisp_Object arg2, Lisp_Object arg3,
        Lisp_Object arg4, Lisp_Object arg5, Lisp_Object arg6, Lisp_Object arg7)
 {
-  return Ffuncall (8, ((Lisp_Object [])
-    { fn, arg1, arg2, arg3, arg4, arg5, arg6, arg7 }));
+  return CALLN (Ffuncall, fn, arg1, arg2, arg3, arg4, arg5, arg6, arg7);
 }
 
 /* The caller should GCPRO all the elements of ARGS.  */
@@ -2644,8 +2656,8 @@ usage: (funcall FUNCTION &rest ARGUMENTS)  */)
   ptrdiff_t numargs = nargs - 1;
   Lisp_Object lisp_numargs;
   Lisp_Object val;
-  register Lisp_Object *internal_args;
-  ptrdiff_t i, count;
+  Lisp_Object *internal_args;
+  ptrdiff_t count;
 
   QUIT;
 
@@ -2700,8 +2712,8 @@ usage: (funcall FUNCTION &rest ARGUMENTS)  */)
              eassert (XSUBR (fun)->max_args <= ARRAYELTS (internal_argbuf));
              internal_args = internal_argbuf;
              memcpy (internal_args, args + 1, numargs * word_size);
-             for (i = numargs; i < XSUBR (fun)->max_args; i++)
-               internal_args[i] = Qnil;
+             memclear (internal_args + numargs,
+                       (XSUBR (fun)->max_args - numargs) * word_size);
            }
          else
            internal_args = args + 1;
@@ -3301,27 +3313,27 @@ Output stream used is value of `standard-output'.  */)
 
   while (backtrace_p (pdl))
     {
-      write_string (backtrace_debug_on_exit (pdl) ? "* " : "  ", 2);
+      write_string (backtrace_debug_on_exit (pdl) ? "* " : "  ");
       if (backtrace_nargs (pdl) == UNEVALLED)
        {
          Fprin1 (Fcons (backtrace_function (pdl), *backtrace_args (pdl)),
                  Qnil);
-         write_string ("\n", -1);
+         write_string ("\n");
        }
       else
        {
          tem = backtrace_function (pdl);
          Fprin1 (tem, Qnil);   /* This can QUIT.  */
-         write_string ("(", -1);
+         write_string ("(");
          {
            ptrdiff_t i;
            for (i = 0; i < backtrace_nargs (pdl); i++)
              {
-               if (i) write_string (" ", -1);
+               if (i) write_string (" ");
                Fprin1 (backtrace_args (pdl)[i], Qnil);
              }
          }
-         write_string (")\n", -1);
+         write_string (")\n");
        }
       pdl = backtrace_next (pdl);
     }
@@ -3666,7 +3678,6 @@ before making `inhibit-quit' nil.  */);
   DEFSYM (Qautoload, "autoload");
   DEFSYM (Qinhibit_debugger, "inhibit-debugger");
   DEFSYM (Qmacro, "macro");
-  DEFSYM (Qdeclare, "declare");
 
   /* Note that the process handling also uses Qexit, but we don't want
      to staticpro it twice, so we just do it here.  */
@@ -3677,6 +3688,7 @@ before making `inhibit-quit' nil.  */);
   DEFSYM (Qand_rest, "&rest");
   DEFSYM (Qand_optional, "&optional");
   DEFSYM (Qclosure, "closure");
+  DEFSYM (QCdocumentation, ":documentation");
   DEFSYM (Qdebug, "debug");
 
   DEFVAR_LISP ("inhibit-debugger", Vinhibit_debugger,
@@ -3762,7 +3774,8 @@ alist of active lexical bindings.  */);
      (Just imagine if someone makes it buffer-local).  */
   Funintern (Qinternal_interpreter_environment, Qnil);
 
-  DEFSYM (Vrun_hooks, "run-hooks");
+  Vrun_hooks = intern_c_string ("run-hooks");
+  staticpro (&Vrun_hooks);
 
   staticpro (&Vautoload_queue);
   Vautoload_queue = Qnil;