summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorPaul Eggert <eggert@cs.ucla.edu>2014-09-24 19:01:14 -0700
committerPaul Eggert <eggert@cs.ucla.edu>2014-09-24 19:01:14 -0700
commit10381f58949355413c86315c571508afb40f0de6 (patch)
tree06761cfffeb1dcd54a633da833b7f0021f1b71c0 /src
parent59355ea9ce310eb45b33e10f2ffaedbc4e2f47a9 (diff)
downloademacs-10381f58949355413c86315c571508afb40f0de6.tar.gz
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.
Diffstat (limited to 'src')
-rw-r--r--src/ChangeLog50
-rw-r--r--src/buffer.c5
-rw-r--r--src/charset.c3
-rw-r--r--src/chartab.c2
-rw-r--r--src/data.c1
-rw-r--r--src/editfns.c2
-rw-r--r--src/emacs.c4
-rw-r--r--src/fileio.c1
-rw-r--r--src/fns.c5
-rw-r--r--src/font.c13
-rw-r--r--src/fontset.c1
-rw-r--r--src/frame.c3
-rw-r--r--src/keyboard.c7
-rw-r--r--src/keymap.c5
-rw-r--r--src/lisp.h62
-rw-r--r--src/lread.c2
-rw-r--r--src/menu.c1
-rw-r--r--src/minibuf.c1
-rw-r--r--src/process.c4
-rw-r--r--src/textprop.c1
-rw-r--r--src/xdisp.c1
-rw-r--r--src/xfns.c2
-rw-r--r--src/xfont.c1
-rw-r--r--src/xselect.c2
-rw-r--r--src/xterm.c1
25 files changed, 150 insertions, 30 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index ccd5e1ffa6f..74576709ffa 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -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.
diff --git a/src/buffer.c b/src/buffer.c
index dc2d17f9f67..591f585a7a9 100644
--- a/src/buffer.c
+++ b/src/buffer.c
@@ -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;
diff --git a/src/charset.c b/src/charset.c
index 3ccac8684be..30bcc054221 100644
--- a/src/charset.c
+++ b/src/charset.c
@@ -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;
diff --git a/src/chartab.c b/src/chartab.c
index 0653783d02a..d25169b7a5e 100644
--- a/src/chartab.c
+++ b/src/chartab.c
@@ -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);
diff --git a/src/data.c b/src/data.c
index 414da4cf6f7..f839cc9d6f8 100644
--- a/src/data.c
+++ b/src/data.c
@@ -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),
diff --git a/src/editfns.c b/src/editfns.c
index 37fc169ace1..df5d00702fd 100644
--- a/src/editfns.c
+++ b/src/editfns.c
@@ -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 }));
}
diff --git a/src/emacs.c b/src/emacs.c
index ed218a7d90b..4ba51d3a7f5 100644
--- a/src/emacs.c
+++ b/src/emacs.c
@@ -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.
diff --git a/src/fileio.c b/src/fileio.c
index 13e2c889020..0379f0e9115 100644
--- a/src/fileio.c
+++ b/src/fileio.c
@@ -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;
diff --git a/src/fns.c b/src/fns.c
index 2ddff0fa818..a4836ace68c 100644
--- 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
diff --git a/src/font.c b/src/font.c
index 496fcd5f1a8..3614d97d473 100644
--- a/src/font.c
+++ b/src/font.c
@@ -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;
diff --git a/src/fontset.c b/src/fontset.c
index 5e18d14bd65..ff92f16a266 100644
--- a/src/fontset.c
+++ b/src/fontset.c
@@ -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;
diff --git a/src/frame.c b/src/frame.c
index 5e2f351d77a..75bb7e45105 100644
--- a/src/frame.c
+++ b/src/frame.c
@@ -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);
diff --git a/src/keyboard.c b/src/keyboard.c
index 704109e1671..e242a886f05 100644
--- a/src/keyboard.c
+++ b/src/keyboard.c
@@ -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;
diff --git a/src/keymap.c b/src/keymap.c
index 1d85a403554..768df563632 100644
--- a/src/keymap.c
+++ b/src/keymap.c
@@ -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;
diff --git a/src/lisp.h b/src/lisp.h
index dae8123de5c..4cd2e69dac3 100644
--- a/src/lisp.h
+++ b/src/lisp.h
@@ -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_; \
})
diff --git a/src/lread.c b/src/lread.c
index b6f259f1a95..ad4603299af 100644
--- a/src/lread.c
+++ b/src/lread.c
@@ -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;
diff --git a/src/menu.c b/src/menu.c
index ea8da7a9d62..8c77f69d995 100644
--- a/src/menu.c
+++ b/src/menu.c
@@ -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;
diff --git a/src/minibuf.c b/src/minibuf.c
index b5e7e4cd76e..c5f52f81de4 100644
--- a/src/minibuf.c
+++ b/src/minibuf.c
@@ -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;
diff --git a/src/process.c b/src/process.c
index f6484d0370e..28b55d36815 100644
--- a/src/process.c
+++ b/src/process.c
@@ -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);
diff --git a/src/textprop.c b/src/textprop.c
index b75b19b25cc..c7185f3daef 100644
--- a/src/textprop.c
+++ b/src/textprop.c
@@ -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;
diff --git a/src/xdisp.c b/src/xdisp.c
index ba513644484..1ddabf34b9e 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -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;
diff --git a/src/xfns.c b/src/xfns.c
index 63978c27f46..b19e5df5802 100644
--- a/src/xfns.c
+++ b/src/xfns.c
@@ -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;
diff --git a/src/xfont.c b/src/xfont.c
index 4dc26bb41bf..fc2dc195822 100644
--- a/src/xfont.c
+++ b/src/xfont.c
@@ -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];
diff --git a/src/xselect.c b/src/xselect.c
index 0bc7fbc204a..7e6d699dffa 100644
--- a/src/xselect.c
+++ b/src/xselect.c
@@ -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;
diff --git a/src/xterm.c b/src/xterm.c
index 89a7453b953..9aea0684927 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -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;