]> git.eshelyaron.com Git - emacs.git/commitdiff
Fix local_cons etc. to not exhaust the stack when in a loop.
authorPaul Eggert <eggert@cs.ucla.edu>
Thu, 25 Sep 2014 02:01:14 +0000 (19:01 -0700)
committerPaul Eggert <eggert@cs.ucla.edu>
Thu, 25 Sep 2014 02:01:14 +0000 (19:01 -0700)
Problem reported in:
http://lists.gnu.org/archive/html/emacs-devel/2014-09/msg00696.html
* buffer.c (Fother_buffer, other_buffer_safely, init_buffer):
* charset.c (load_charset_map_from_file, Ffind_charset_region)
(Ffind_charset_string):
* chartab.c (uniprop_encode_value_numeric, uniprop_table):
* data.c (wrong_range):
* editfns.c (Fpropertize, format2):
* emacs.c (init_cmdargs, decode_env_path):
* fileio.c (auto_save_error):
* fns.c (Fyes_or_no_p):
* font.c (font_style_to_value, font_parse_xlfd)
(font_parse_family_registry, font_delete_unmatched)
(font_add_log):
* fontset.c (Fset_fontset_font):
* frame.c (x_get_arg):
* keyboard.c (echo_dash, safe_run_hooks_error, parse_menu_item)
(read_char_minibuf_menu_prompt):
* keymap.c (silly_event_symbol_error, describe_vector):
* lread.c (load_warn_old_style_backquotes):
* menu.c (single_menu_item):
* minibuf.c (Fread_buffer):
* process.c (status_message, Fformat_network_address)
(server_accept_connection):
* textprop.c (copy_text_properties):
* xdisp.c (Fcurrent_bidi_paragraph_direction):
* xfns.c (x_default_scroll_bar_color_parameter):
* xfont.c (xfont_open):
* xselect.c (x_clipboard_manager_error_1):
* xterm.c (x_term_init):
Put USE_LOCAL_ALLOCA at the start of the function.
* fns.c (maybe_resize_hash_table): Use build_string instead of
build_local_string, since we'd otherwise need a conditional
USE_LOCAL_ALLOCA here, but this is just debugging output and is
not worth the bother of optimization.
* font.c (font_delete_unmatched): Remove by-hand code that
observed MAX_ALLOCA limit, since it's now done automatically.
* keymap.c (Fsingle_key_description): Put USE_SAFE_ALLOCA at top,
since build_local_string needs its sa_alloc.
* lisp.h (lisp_word_count): New function.
(SAFE_ALLOCA_LISP): Use it.
(USE_LOCAL_ALLOCA): New macro.
(local_cons, make_local_vector, make_local_string):
Observe the MAX_ALLOCA limit.
(LISP_STRING_OVERHEAD): New constant.
(make_local_string): Use it.

25 files changed:
src/ChangeLog
src/buffer.c
src/charset.c
src/chartab.c
src/data.c
src/editfns.c
src/emacs.c
src/fileio.c
src/fns.c
src/font.c
src/fontset.c
src/frame.c
src/keyboard.c
src/keymap.c
src/lisp.h
src/lread.c
src/menu.c
src/minibuf.c
src/process.c
src/textprop.c
src/xdisp.c
src/xfns.c
src/xfont.c
src/xselect.c
src/xterm.c

index ccd5e1ffa6f0b117f9408a0bb3cfe7d4d72dd011..74576709ffad5982eae3e5daffa0d965fda65836 100644 (file)
@@ -1,3 +1,53 @@
+2014-09-25  Paul Eggert  <eggert@cs.ucla.edu>
+
+       Fix local_cons etc. to not exhaust the stack when in a loop.
+       Problem reported in:
+       http://lists.gnu.org/archive/html/emacs-devel/2014-09/msg00696.html
+       * buffer.c (Fother_buffer, other_buffer_safely, init_buffer):
+       * charset.c (load_charset_map_from_file, Ffind_charset_region)
+       (Ffind_charset_string):
+       * chartab.c (uniprop_encode_value_numeric, uniprop_table):
+       * data.c (wrong_range):
+       * editfns.c (Fpropertize, format2):
+       * emacs.c (init_cmdargs, decode_env_path):
+       * fileio.c (auto_save_error):
+       * fns.c (Fyes_or_no_p):
+       * font.c (font_style_to_value, font_parse_xlfd)
+       (font_parse_family_registry, font_delete_unmatched)
+       (font_add_log):
+       * fontset.c (Fset_fontset_font):
+       * frame.c (x_get_arg):
+       * keyboard.c (echo_dash, safe_run_hooks_error, parse_menu_item)
+       (read_char_minibuf_menu_prompt):
+       * keymap.c (silly_event_symbol_error, describe_vector):
+       * lread.c (load_warn_old_style_backquotes):
+       * menu.c (single_menu_item):
+       * minibuf.c (Fread_buffer):
+       * process.c (status_message, Fformat_network_address)
+       (server_accept_connection):
+       * textprop.c (copy_text_properties):
+       * xdisp.c (Fcurrent_bidi_paragraph_direction):
+       * xfns.c (x_default_scroll_bar_color_parameter):
+       * xfont.c (xfont_open):
+       * xselect.c (x_clipboard_manager_error_1):
+       * xterm.c (x_term_init):
+       Put USE_LOCAL_ALLOCA at the start of the function.
+       * fns.c (maybe_resize_hash_table): Use build_string instead of
+       build_local_string, since we'd otherwise need a conditional
+       USE_LOCAL_ALLOCA here, but this is just debugging output and is
+       not worth the bother of optimization.
+       * font.c (font_delete_unmatched): Remove by-hand code that
+       observed MAX_ALLOCA limit, since it's now done automatically.
+       * keymap.c (Fsingle_key_description): Put USE_SAFE_ALLOCA at top,
+       since build_local_string needs its sa_alloc.
+       * lisp.h (lisp_word_count): New function.
+       (SAFE_ALLOCA_LISP): Use it.
+       (USE_LOCAL_ALLOCA): New macro.
+       (local_cons, make_local_vector, make_local_string):
+       Observe the MAX_ALLOCA limit.
+       (LISP_STRING_OVERHEAD): New constant.
+       (make_local_string): Use it.
+
 2014-09-24  Paul Eggert  <eggert@cs.ucla.edu>
 
        Default to stack objects on non-GNU/Linux, non-DOS_NT platforms.
index dc2d17f9f679d0f6d0a77095619c90633fac6153..591f585a7a99589abed5437ee005b78df80f2dfc 100644 (file)
@@ -1509,8 +1509,9 @@ frame's buffer list.
 The buffer is found by scanning the selected or specified frame's buffer
 list first, followed by the list of all buffers.  If no other buffer
 exists, return the buffer `*scratch*' (creating it if necessary).  */)
-  (register Lisp_Object buffer, Lisp_Object visible_ok, Lisp_Object frame)
+  (Lisp_Object buffer, Lisp_Object visible_ok, Lisp_Object frame)
 {
+  USE_LOCAL_ALLOCA;
   struct frame *f = decode_any_frame (frame);
   Lisp_Object tail = f->buffer_list, pred = f->buffer_predicate;
   Lisp_Object buf, notsogood = Qnil;
@@ -1569,6 +1570,7 @@ exists, return the buffer `*scratch*' (creating it if necessary).  */)
 Lisp_Object
 other_buffer_safely (Lisp_Object buffer)
 {
+  USE_LOCAL_ALLOCA;
   Lisp_Object tail, buf;
 
   FOR_EACH_LIVE_BUFFER (tail, buf)
@@ -5238,6 +5240,7 @@ init_buffer_once (void)
 void
 init_buffer (int initialized)
 {
+  USE_LOCAL_ALLOCA;
   char *pwd;
   Lisp_Object temp;
   ptrdiff_t len;
index 3ccac8684be17371aa350faacdef642d709d3c8f..30bcc054221c2c7e86229019886773a162eddcea 100644 (file)
@@ -481,6 +481,7 @@ static void
 load_charset_map_from_file (struct charset *charset, Lisp_Object mapfile,
                            int control_flag)
 {
+  USE_LOCAL_ALLOCA;
   unsigned min_code = CHARSET_MIN_CODE (charset);
   unsigned max_code = CHARSET_MAX_CODE (charset);
   int fd;
@@ -1550,6 +1551,7 @@ If the current buffer is unibyte, the returned list may contain
 only `ascii', `eight-bit-control', and `eight-bit-graphic'.  */)
   (Lisp_Object beg, Lisp_Object end, Lisp_Object table)
 {
+  USE_LOCAL_ALLOCA;
   Lisp_Object charsets;
   ptrdiff_t from, from_byte, to, stop, stop_byte;
   int i;
@@ -1601,6 +1603,7 @@ If STR is unibyte, the returned list may contain
 only `ascii', `eight-bit-control', and `eight-bit-graphic'. */)
   (Lisp_Object str, Lisp_Object table)
 {
+  USE_LOCAL_ALLOCA;
   Lisp_Object charsets;
   int i;
   Lisp_Object val;
index 0653783d02ae252b355b542bd8b3734db36b308a..d25169b7a5efe5936b0ab9c8d3e2d3b49cdb088a 100644 (file)
@@ -1249,6 +1249,7 @@ uniprop_encode_value_run_length (Lisp_Object table, Lisp_Object value)
 static Lisp_Object
 uniprop_encode_value_numeric (Lisp_Object table, Lisp_Object value)
 {
+  USE_LOCAL_ALLOCA;
   Lisp_Object *value_table = XVECTOR (XCHAR_TABLE (table)->extras[4])->contents;
   int i, size = ASIZE (XCHAR_TABLE (table)->extras[4]);
 
@@ -1292,6 +1293,7 @@ uniprop_get_encoder (Lisp_Object table)
 Lisp_Object
 uniprop_table (Lisp_Object prop)
 {
+  USE_LOCAL_ALLOCA;
   Lisp_Object val, table, result;
 
   val = Fassq (prop, Vchar_code_property_alist);
index 414da4cf6f7dc40ff271209dc2ff5dd7ac588503..f839cc9d6f8c6f18eec03e17a13c60bd991dd02e 100644 (file)
@@ -1004,6 +1004,7 @@ wrong_choice (Lisp_Object choice, Lisp_Object wrong)
 static void
 wrong_range (Lisp_Object min, Lisp_Object max, Lisp_Object wrong)
 {
+  USE_LOCAL_ALLOCA;
   xsignal2 (Qerror, Fconcat (4, ((Lisp_Object [])
     { build_local_string ("Value should be from "),
       Fnumber_to_string (min),
index 37fc169ace187297c06cf8292800488431362820..df5d00702fd1c233d6c13b289b2fd998b5a570a9 100644 (file)
@@ -3531,6 +3531,7 @@ properties to add to the result.
 usage: (propertize STRING &rest PROPERTIES)  */)
   (ptrdiff_t nargs, Lisp_Object *args)
 {
+  USE_LOCAL_ALLOCA;
   Lisp_Object properties, string;
   struct gcpro gcpro1, gcpro2;
   ptrdiff_t i;
@@ -4362,6 +4363,7 @@ usage: (format STRING &rest OBJECTS)  */)
 Lisp_Object
 format2 (const char *string1, Lisp_Object arg0, Lisp_Object arg1)
 {
+  USE_LOCAL_ALLOCA;
   return Fformat (3, ((Lisp_Object [])
     { build_local_string (string1), arg0, arg1 }));
 }
index ed218a7d90ba4fdcb58c10a5a1e696de5d40366f..4ba51d3a7f5dc5a9169257d04d821e3430e5f106 100644 (file)
@@ -396,7 +396,8 @@ terminate_due_to_signal (int sig, int backtrace_limit)
 static void
 init_cmdargs (int argc, char **argv, int skip_args, char *original_pwd)
 {
-  register int i;
+  USE_LOCAL_ALLOCA;
+  int i;
   Lisp_Object name, dir, handler;
   ptrdiff_t count = SPECPDL_INDEX ();
   Lisp_Object raw_name;
@@ -2208,6 +2209,7 @@ synchronize_system_messages_locale (void)
 Lisp_Object
 decode_env_path (const char *evarname, const char *defalt, bool empty)
 {
+  USE_LOCAL_ALLOCA;
   const char *path, *p;
   Lisp_Object lpath, element, tem;
   /* Default is to use "." for empty path elements.
index 13e2c889020144b7ec70c2982bd25e6ab8594bc9..0379f0e91154e9013892d4a04e8bece27b813056 100644 (file)
@@ -5411,6 +5411,7 @@ An argument specifies the modification time value to use
 static Lisp_Object
 auto_save_error (Lisp_Object error_val)
 {
+  USE_LOCAL_ALLOCA;
   Lisp_Object msg;
   int i;
   struct gcpro gcpro1;
index 2ddff0fa8189bd63feb8e4993683fbd981662a62..a4836ace68caaf391b806bbee37b66aef66522a8 100644 (file)
--- a/src/fns.c
+++ b/src/fns.c
@@ -2706,7 +2706,8 @@ If dialog boxes are supported, a dialog box will be used
 if `last-nonmenu-event' is nil, and `use-dialog-box' is non-nil.  */)
   (Lisp_Object prompt)
 {
-  register Lisp_Object ans;
+  USE_LOCAL_ALLOCA;
+  Lisp_Object ans;
   struct gcpro gcpro1;
 
   CHECK_STRING (prompt);
@@ -3996,7 +3997,7 @@ maybe_resize_hash_table (struct Lisp_Hash_Table *h)
       if (HASH_TABLE_P (Vpurify_flag)
          && XHASH_TABLE (Vpurify_flag) == h)
        Fmessage (2, ((Lisp_Object [])
-         { build_local_string ("Growing hash table to: %d"),
+         { build_string ("Growing hash table to: %d"),
            make_number (new_size) }));
 #endif
 
index 496fcd5f1a863a78051b7939f8310999ccf5082b..3614d97d47367b40d87f016ce8733e578549023f 100644 (file)
@@ -357,6 +357,7 @@ int
 font_style_to_value (enum font_property_index prop, Lisp_Object val,
                      bool noerror)
 {
+  USE_LOCAL_ALLOCA;
   Lisp_Object table = AREF (font_style_table, prop - FONT_WEIGHT_INDEX);
   int len;
 
@@ -1049,6 +1050,7 @@ font_expand_wildcards (Lisp_Object *field, int n)
 int
 font_parse_xlfd (char *name, ptrdiff_t len, Lisp_Object font)
 {
+  USE_LOCAL_ALLOCA;
   int i, j, n;
   char *f[XLFD_LAST_INDEX + 1];
   Lisp_Object val;
@@ -1758,6 +1760,7 @@ font_parse_name (char *name, ptrdiff_t namelen, Lisp_Object font)
 void
 font_parse_family_registry (Lisp_Object family, Lisp_Object registry, Lisp_Object font_spec)
 {
+  USE_LOCAL_ALLOCA;
   ptrdiff_t len;
   char *p0, *p1;
 
@@ -2683,11 +2686,10 @@ static Lisp_Object scratch_font_spec, scratch_font_prefer;
 static Lisp_Object
 font_delete_unmatched (Lisp_Object vec, Lisp_Object spec, int size)
 {
+  USE_LOCAL_ALLOCA;
   Lisp_Object entity, val;
   enum font_property_index prop;
-  /* If USE_STACK_LISP_OBJECTS, MAX is used to avoid unbounded alloca.  */
-  ptrdiff_t i, max
-    = (USE_STACK_LISP_OBJECTS ? MAX_ALLOCA / sizeof (struct Lisp_Cons) : 0);
+  ptrdiff_t i;
 
   for (val = Qnil, i = ASIZE (vec) - 1; i >= 0; i--)
     {
@@ -2715,7 +2717,7 @@ font_delete_unmatched (Lisp_Object vec, Lisp_Object spec, int size)
        }
       if (NILP (spec))
        {
-         val = --max > 0 ? local_cons (entity, val) : Fcons (entity, val);
+         val = local_cons (entity, val);
          continue;
        }
       for (prop = FONT_WEIGHT_INDEX; prop < FONT_SIZE_INDEX; prop++)
@@ -2746,7 +2748,7 @@ font_delete_unmatched (Lisp_Object vec, Lisp_Object spec, int size)
                   AREF (entity, FONT_AVGWIDTH_INDEX)))
        prop = FONT_SPEC_MAX;
       if (prop < FONT_SPEC_MAX)
-       val = --max > 0 ? local_cons (entity, val) : Fcons (entity, val);
+       val = local_cons (entity, val);
     }
   return (Fvconcat (1, &val));
 }
@@ -5004,6 +5006,7 @@ static Lisp_Object Vfont_log_deferred;
 void
 font_add_log (const char *action, Lisp_Object arg, Lisp_Object result)
 {
+  USE_LOCAL_ALLOCA;
   Lisp_Object val;
   int i;
 
index 5e18d14bd65c7ef457f34801978be4a5199f2503..ff92f16a266f6f190f0e4987e9fd1fd0a0779300 100644 (file)
@@ -1420,6 +1420,7 @@ to the font specifications for TARGET previously set.  If it is
 appended.  By default, FONT-SPEC overrides the previous settings.  */)
   (Lisp_Object name, Lisp_Object target, Lisp_Object font_spec, Lisp_Object frame, Lisp_Object add)
 {
+  USE_LOCAL_ALLOCA;
   Lisp_Object fontset;
   Lisp_Object font_def, registry, family;
   Lisp_Object range_list;
index 5e2f351d77a8dd1247c9d1ce1274f998f5a1c854..75bb7e45105e7aca87318b219f24c0df9f43b34b 100644 (file)
@@ -4137,7 +4137,8 @@ Lisp_Object
 x_get_arg (Display_Info *dpyinfo, Lisp_Object alist, Lisp_Object param,
           const char *attribute, const char *class, enum resource_types type)
 {
-  register Lisp_Object tem;
+  USE_LOCAL_ALLOCA;
+  Lisp_Object tem;
 
   tem = Fassq (param, alist);
 
index 704109e167110c20457c64c7f722b33fc22ae731..e242a886f05bdcfdd55d92fdc3a84a63b6fca555 100644 (file)
@@ -597,6 +597,8 @@ echo_char (Lisp_Object c)
 static void
 echo_dash (void)
 {
+  USE_LOCAL_ALLOCA;
+
   /* Do nothing if not echoing at all.  */
   if (NILP (KVAR (current_kboard, echo_string)))
     return;
@@ -1894,6 +1896,7 @@ safe_run_hooks_1 (ptrdiff_t nargs, Lisp_Object *args)
 static Lisp_Object
 safe_run_hooks_error (Lisp_Object error, ptrdiff_t nargs, Lisp_Object *args)
 {
+  USE_LOCAL_ALLOCA;
   Lisp_Object hook, fun;
 
   eassert (nargs == 2);
@@ -7700,6 +7703,7 @@ menu_item_eval_property (Lisp_Object sexpr)
 bool
 parse_menu_item (Lisp_Object item, int inmenubar)
 {
+  USE_LOCAL_ALLOCA;
   Lisp_Object def, tem, item_string, start;
   Lisp_Object filter;
   Lisp_Object keyhint;
@@ -8523,7 +8527,8 @@ static Lisp_Object
 read_char_minibuf_menu_prompt (int commandflag,
                               Lisp_Object map)
 {
-  register Lisp_Object name;
+  USE_LOCAL_ALLOCA;
+  Lisp_Object name;
   ptrdiff_t nlength;
   /* FIXME: Use the minibuffer's frame width.  */
   ptrdiff_t width = FRAME_COLS (SELECTED_FRAME ()) - 4;
index 1d85a403554f6c014fc820ed7782e3422a581545..768df56363229cb505f9e25abb6044213b6c656c 100644 (file)
@@ -1308,6 +1308,7 @@ append_key (Lisp_Object key_sequence, Lisp_Object key)
 static void
 silly_event_symbol_error (Lisp_Object c)
 {
+  USE_LOCAL_ALLOCA;
   Lisp_Object parsed, base, name, assoc;
   int modifiers;
 
@@ -2235,6 +2236,8 @@ Optional argument NO-ANGLES non-nil means don't put angle brackets
 around function keys and event symbols.  */)
   (Lisp_Object key, Lisp_Object no_angles)
 {
+  USE_SAFE_ALLOCA;
+
   if (CONSP (key) && lucid_event_type_list_p (key))
     key = Fevent_convert_list (key);
 
@@ -2258,7 +2261,6 @@ around function keys and event symbols.  */)
       if (NILP (no_angles))
        {
          Lisp_Object result;
-         USE_SAFE_ALLOCA;
          char *buffer = SAFE_ALLOCA (sizeof "<>"
                                      + SBYTES (SYMBOL_NAME (key)));
          esprintf (buffer, "<%s>", SDATA (SYMBOL_NAME (key)));
@@ -3416,6 +3418,7 @@ describe_vector (Lisp_Object vector, Lisp_Object prefix, Lisp_Object args,
                 bool partial, Lisp_Object shadow, Lisp_Object entire_map,
                 bool keymap_p, bool mention_shadow)
 {
+  USE_LOCAL_ALLOCA;
   Lisp_Object definition;
   Lisp_Object tem2;
   Lisp_Object elt_prefix = Qnil;
index dae8123de5ce321f3ba3868a88d513e4fc42ea15..4cd2e69dac32422f0cf23ca6949a346d3a91e7a0 100644 (file)
@@ -4562,11 +4562,27 @@ extern void *record_xmalloc (size_t) ATTRIBUTE_ALLOC_SIZE ((1));
   } while (false)
 
 
+/* Return floor (NBYTES / WORD_SIZE).  */
+
+INLINE ptrdiff_t
+lisp_word_count (ptrdiff_t nbytes)
+{
+  if (-1 >> 1 == -1)
+    switch (word_size)
+      {
+      case 2: return nbytes >> 1;
+      case 4: return nbytes >> 2;
+      case 8: return nbytes >> 3;
+      case 16: return nbytes >> 4;
+      }
+  return nbytes / word_size - (nbytes % word_size < 0);
+}
+
 /* SAFE_ALLOCA_LISP allocates an array of Lisp_Objects.  */
 
 #define SAFE_ALLOCA_LISP(buf, nelt)                           \
   do {                                                        \
-    if ((nelt) <= sa_avail / word_size)                               \
+    if ((nelt) <= lisp_word_count (sa_avail))                 \
       (buf) = AVAIL_ALLOCA ((nelt) * word_size);              \
     else if ((nelt) <= min (PTRDIFF_MAX, SIZE_MAX) / word_size) \
       {                                                               \
@@ -4635,17 +4651,27 @@ verify (sizeof (struct Lisp_Cons) == sizeof (union Aligned_Cons));
 # define USE_LOCAL_ALLOCATORS
 #endif
 
+/* Any function that uses a local allocator should start with either
+   'USE_SAFE_ALLOCA; or 'USE_LOCAL_ALLOCA;' (but not both).  */
+#ifdef USE_LOCAL_ALLOCATORS
+# define USE_LOCAL_ALLOCA ptrdiff_t sa_avail = MAX_ALLOCA
+#else
+# define USE_LOCAL_ALLOCA
+#endif
+
 #ifdef USE_LOCAL_ALLOCATORS
 
 /* Return a function-scoped cons whose car is X and cdr is Y.  */
 
 # define local_cons(x, y)                                              \
-    ({                                                                 \
-       struct Lisp_Cons *c_ = alloca (sizeof (struct Lisp_Cons));      \
-       c_->car = (x);                                                  \
-       c_->u.cdr = (y);                                                        \
-       make_lisp_ptr (c_, Lisp_Cons);                                  \
-    })
+    (sizeof (struct Lisp_Cons) <= sa_avail                             \
+     ? ({                                                              \
+         struct Lisp_Cons *c_ = AVAIL_ALLOCA (sizeof (struct Lisp_Cons)); \
+         c_->car = (x);                                                \
+         c_->u.cdr = (y);                                              \
+         make_lisp_ptr (c_, Lisp_Cons);                                \
+       })                                                              \
+     : Fcons (x, y))
 
 # define local_list1(a) local_cons (a, Qnil)
 # define local_list2(a, b) local_cons (a, local_list1 (b))
@@ -4658,33 +4684,33 @@ verify (sizeof (struct Lisp_Cons) == sizeof (union Aligned_Cons));
 # define make_local_vector(size, init)                                 \
     ({                                                                 \
        ptrdiff_t size_ = size;                                         \
-       Lisp_Object init_ = init;                                       \
        Lisp_Object vec_;                                               \
-       if (size_ <= (MAX_ALLOCA - header_size) / word_size)            \
+       if (size_ <= lisp_word_count (sa_avail - header_size))          \
         {                                                              \
-          void *ptr_ = alloca (size_ * word_size + header_size);       \
-          vec_ = local_vector_init (ptr_, size_, init_);               \
+          void *ptr_ = AVAIL_ALLOCA (size_ * word_size + header_size); \
+          vec_ = local_vector_init (ptr_, size_, init);                \
         }                                                              \
        else                                                            \
-        vec_ = Fmake_vector (make_number (size_), init_);              \
+        vec_ = Fmake_vector (make_number (size_), init);               \
        vec_;                                                           \
     })
 
+enum { LISP_STRING_OVERHEAD = sizeof (struct Lisp_String) + 1 };
+
 /* Return a function-scoped string with contents DATA and length NBYTES.  */
 
 # define make_local_string(data, nbytes)                               \
     ({                                                                 \
-       char const *data_ = data;                                       \
        ptrdiff_t nbytes_ = nbytes;                                     \
        Lisp_Object string_;                                            \
-       if (nbytes_ <= MAX_ALLOCA - sizeof (struct Lisp_String) - 1)    \
+       if (nbytes_ <= sa_avail - LISP_STRING_OVERHEAD)                 \
         {                                                              \
-          struct Lisp_String *ptr_                                     \
-            = alloca (sizeof (struct Lisp_String) + 1 + nbytes_);      \
-          string_ = local_string_init (ptr_, data_, nbytes_);          \
+          struct Lisp_String *ptr_ = AVAIL_ALLOCA (LISP_STRING_OVERHEAD \
+                                                   + nbytes_);         \
+          string_ = local_string_init (ptr_, data, nbytes_);           \
         }                                                              \
        else                                                            \
-        string_ = make_string (data_, nbytes_);                        \
+        string_ = make_string (data, nbytes_);                         \
        string_;                                                                \
     })
 
index b6f259f1a957c162da9624977f82d671a43b3985..ad4603299afaab364f8b4438e46322a687b493c9 100644 (file)
@@ -968,6 +968,7 @@ load_error_handler (Lisp_Object data)
 static void
 load_warn_old_style_backquotes (Lisp_Object file)
 {
+  USE_LOCAL_ALLOCA;
   if (!NILP (Vold_style_backquotes))
     Fmessage (2, ((Lisp_Object [])
       { build_local_string ("Loading `%s': old-style backquotes detected!"),
@@ -3638,6 +3639,7 @@ read_vector (Lisp_Object readcharfun, bool bytecodeflag)
 static Lisp_Object
 read_list (bool flag, Lisp_Object readcharfun)
 {
+  USE_LOCAL_ALLOCA;
   Lisp_Object val, tail;
   Lisp_Object elt, tem;
   struct gcpro gcpro1, gcpro2;
index ea8da7a9d629073f615e08c55c4dd77f2e5c2e39..8c77f69d9956b19e00b7f04620c7c787596e4f16 100644 (file)
@@ -324,6 +324,7 @@ single_keymap_panes (Lisp_Object keymap, Lisp_Object pane_name,
 static void
 single_menu_item (Lisp_Object key, Lisp_Object item, Lisp_Object dummy, void *skp_v)
 {
+  USE_LOCAL_ALLOCA;
   Lisp_Object map, item_string, enabled;
   struct gcpro gcpro1, gcpro2;
   bool res;
index b5e7e4cd76eb941aa222b47081edbd18770f16e2..c5f52f81de4a747871d2c3838d2eba93dab0bb26 100644 (file)
@@ -1123,6 +1123,7 @@ If `read-buffer-function' is non-nil, this works by calling it as a
 function, instead of the usual behavior.  */)
   (Lisp_Object prompt, Lisp_Object def, Lisp_Object require_match)
 {
+  USE_LOCAL_ALLOCA;
   Lisp_Object result;
   char *s;
   ptrdiff_t len;
index f6484d0370ecb8bbeedc5616334607303f6e06f2..28b55d36815f41c80e1a22d0a806b292b3d435ec 100644 (file)
@@ -592,6 +592,7 @@ decode_status (Lisp_Object l, Lisp_Object *symbol, int *code, bool *coredump)
 static Lisp_Object
 status_message (struct Lisp_Process *p)
 {
+  USE_LOCAL_ALLOCA;
   Lisp_Object status = p->status;
   Lisp_Object symbol;
   int code;
@@ -1290,6 +1291,8 @@ number in the string, even when present in ADDRESS.
 Returns nil if format of ADDRESS is invalid.  */)
   (Lisp_Object address, Lisp_Object omit_port)
 {
+  USE_LOCAL_ALLOCA;
+
   if (NILP (address))
     return Qnil;
 
@@ -4003,6 +4006,7 @@ static EMACS_INT connect_counter = 0;
 static void
 server_accept_connection (Lisp_Object server, int channel)
 {
+  USE_LOCAL_ALLOCA;
   Lisp_Object proc, caller, name, buffer;
   Lisp_Object contact, host, service;
   struct Lisp_Process *ps= XPROCESS (server);
index b75b19b25cc7fc1a4242f9a5672443b5756a7cf8..c7185f3daef8d4129ceda552d61a12a954f34aa4 100644 (file)
@@ -1913,6 +1913,7 @@ Lisp_Object
 copy_text_properties (Lisp_Object start, Lisp_Object end, Lisp_Object src,
                      Lisp_Object pos, Lisp_Object dest, Lisp_Object prop)
 {
+  USE_LOCAL_ALLOCA;
   INTERVAL i;
   Lisp_Object res;
   Lisp_Object stuff;
index ba513644484f6cb39293bb95c2187878615db5d0..1ddabf34b9eb403e1a3544e7bef97ab36fc4f16b 100644 (file)
@@ -20892,6 +20892,7 @@ paragraphs, text begins at the right margin and is read from right to left.
 See also `bidi-paragraph-direction'.  */)
   (Lisp_Object buffer)
 {
+  USE_LOCAL_ALLOCA;
   struct buffer *buf = current_buffer;
   struct buffer *old = buf;
 
index 63978c27f463d64e13456c8db8231f56cd551e8b..b19e5df5802feaf73e1a70b7d26e5d08de1ff8a0 100644 (file)
@@ -1561,6 +1561,7 @@ x_default_scroll_bar_color_parameter (struct frame *f,
                                      const char *xprop, const char *xclass,
                                      int foreground_p)
 {
+  USE_LOCAL_ALLOCA;
   struct x_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
   Lisp_Object tem;
 
@@ -4272,6 +4273,7 @@ XScreenNumberOfScreen (scr)
 void
 select_visual (struct x_display_info *dpyinfo)
 {
+  USE_LOCAL_ALLOCA;
   Display *dpy = dpyinfo->display;
   Screen *screen = dpyinfo->screen;
 
index 4dc26bb41bfc4071ae53ac0e821192c6c4ab715d..fc2dc195822bd67daa8af31512f7f3d141e66174 100644 (file)
@@ -677,6 +677,7 @@ xfont_list_family (struct frame *f)
 static Lisp_Object
 xfont_open (struct frame *f, Lisp_Object entity, int pixel_size)
 {
+  USE_LOCAL_ALLOCA;
   Display_Info *dpyinfo = FRAME_DISPLAY_INFO (f);
   Display *display = dpyinfo->display;
   char name[512];
index 0bc7fbc204a0c386987a9dbdd8d2fc646672a95c..7e6d699dffa0ad34b5a99b881ac83ce1ad4de2c2 100644 (file)
@@ -2159,6 +2159,7 @@ x_clipboard_manager_save (Lisp_Object frame)
 static Lisp_Object
 x_clipboard_manager_error_1 (Lisp_Object err)
 {
+  USE_LOCAL_ALLOCA;
   Fmessage (2, ((Lisp_Object [])
     { build_local_string ("X clipboard manager error: %s\n\
 If the problem persists, set `x-select-enable-clipboard-manager' to nil."),
@@ -2212,6 +2213,7 @@ void
 x_clipboard_manager_save_all (void)
 {
   /* Loop through all X displays, saving owned clipboards.  */
+  USE_LOCAL_ALLOCA;
   struct x_display_info *dpyinfo;
   Lisp_Object local_selection, local_frame;
 
index 89a7453b9539c061f5f46508d4bd482f237c2a7e..9aea0684927612521941c38bb446ec4a37fc0970 100644 (file)
@@ -10692,6 +10692,7 @@ static unsigned x_display_id;
 struct x_display_info *
 x_term_init (Lisp_Object display_name, char *xrm_option, char *resource_name)
 {
+  USE_LOCAL_ALLOCA;
   Display *dpy;
   struct terminal *terminal;
   struct x_display_info *dpyinfo;