if (!NILP (notsogood))
return notsogood;
else
- return safe_call (1, Qget_scratch_buffer_create);
+ return safe_calln (Qget_scratch_buffer_create);
}
/* The following function is a safe variant of Fother_buffer: It doesn't
becoming dead under our feet. safe_call below could return nil
if recreating *scratch* in Lisp, which does some fancy stuff,
signals an error in some weird use case. */
- buf = safe_call (1, Qget_scratch_buffer_create);
+ buf = safe_calln (Qget_scratch_buffer_create);
if (NILP (buf))
{
AUTO_STRING (scratch, "*scratch*");
Fcons (undo_list, Fcurrent_buffer ()));
bset_undo_list (current_buffer, Qt);
TEMP_SET_PT_BOTH (coding->dst_pos, coding->dst_pos_byte);
- val = safe_call1 (CODING_ATTR_POST_READ (attrs),
+ val = safe_calln (CODING_ATTR_POST_READ (attrs),
make_fixnum (coding->produced_char));
CHECK_FIXNAT (val);
coding->produced_char += Z - prev_Z;
set_buffer_internal (XBUFFER (coding->src_object));
}
- safe_call2 (CODING_ATTR_PRE_WRITE (attrs),
+ safe_calln (CODING_ATTR_PRE_WRITE (attrs),
make_fixnum (BEG), make_fixnum (Z));
if (XBUFFER (coding->src_object) != current_buffer)
kill_src_buffer = 1;
if (NILP (string))
record_unwind_protect (restore_point_unwind,
build_marker (current_buffer, pt, pt_byte));
- lgstring = safe_call (7, Vauto_composition_function, AREF (rule, 2),
+ lgstring = safe_calln (Vauto_composition_function, AREF (rule, 2),
pos, make_fixnum (to), font_object, string,
direction);
}
}
\f
+static Lisp_Object
+safe_eval_handler (Lisp_Object arg, ptrdiff_t nargs, Lisp_Object *args)
+{
+ add_to_log ("Error muted by safe_call: %S signaled %S",
+ Flist (nargs, args), arg);
+ return Qnil;
+}
+
+Lisp_Object
+safe_funcall (ptrdiff_t nargs, Lisp_Object *args)
+{
+ specpdl_ref count = SPECPDL_INDEX ();
+ /* FIXME: This function started its life in 'xdisp.c' for use internally
+ by the redisplay. So it was important to inhibit redisplay.
+ Not clear if we still need this 'specbind' now that 'xdisp.c' has its
+ own version of this code. */
+ specbind (Qinhibit_redisplay, Qt);
+ /* Use Qt to ensure debugger does not run. */
+ Lisp_Object val = internal_condition_case_n (Ffuncall, nargs, args, Qt,
+ safe_eval_handler);
+ return unbind_to (count, val);
+}
+
+Lisp_Object
+safe_eval (Lisp_Object sexp)
+{
+ return safe_calln (Qeval, sexp, Qt);
+}
+
/* Apply a C subroutine SUBR to the NUMARGS evaluated arguments in ARG_VECTOR
and return the result of evaluation. */
x_clipboard_manager_save_frame (frame);
#endif
- safe_call2 (Qrun_hook_with_args, Qdelete_frame_functions, frame);
+ safe_calln (Qrun_hook_with_args, Qdelete_frame_functions, frame);
}
/* delete_frame_functions may have deleted any frame, including this
= Fcons (list3 (Qrun_hook_with_args, Qafter_delete_frame_functions, frame),
pending_funcalls);
else
- safe_call2 (Qrun_hook_with_args, Qafter_delete_frame_functions, frame);
+ safe_calln (Qrun_hook_with_args, Qafter_delete_frame_functions, frame);
if (!NILP (minibuffer_child_frame))
/* If minibuffer_child_frame is non-nil, it was FRAME's minibuffer
if (!NILP (Vhaiku_drag_wheel_function)
&& (haiku_dnd_allow_same_frame
|| XFRAME (ie->frame_or_window) != haiku_dnd_frame))
- safe_call (7, Vhaiku_drag_wheel_function, ie->frame_or_window,
+ safe_calln (Vhaiku_drag_wheel_function, ie->frame_or_window,
ie->x, ie->y, horizontal ? Qt : Qnil, up ? Qt : Qnil,
make_int (ie->modifiers));
if (!NILP (help) && !STRINGP (help))
{
if (FUNCTIONP (help))
- help = safe_call (4, help, window, object, pos);
+ help = safe_calln (help, window, object, pos);
else
help = safe_eval (help);
{
Lisp_Object funcall = XCAR (pending_funcalls);
pending_funcalls = XCDR (pending_funcalls);
- safe_call2 (Qapply, XCAR (funcall), XCDR (funcall));
+ safe_calln (Qapply, XCAR (funcall), XCDR (funcall));
}
if (CONSP (timers) || CONSP (idle_timers))
{
/* map_keymap_canonical may be used from redisplay (e.g. when building menus)
so be careful to ignore errors and to inhibit redisplay. */
- map = safe_call1 (Qkeymap_canonicalize, map);
+ map = safe_calln (Qkeymap_canonicalize, map);
/* No need to use `map_keymap' here because canonical map has no parent. */
map_keymap_internal (map, fun, args, data);
}
empty initializers), and is overkill for simple usages like
'Finsert (1, &text);'. */
#define CALLN(f, ...) CALLMANY (f, ((Lisp_Object []) {__VA_ARGS__}))
-
-/* Call function fn on no arguments. */
+#define calln(...) CALLN (Ffuncall, __VA_ARGS__)
+/* Compatibility aliases. */
+#define call1 calln
+#define call2 calln
+#define call3 calln
+#define call4 calln
+#define call5 calln
+#define call6 calln
+#define call7 calln
+#define call8 calln
+
+/* Define 'call0' as a function rather than a CPP macro because we
+ sometimes want to pass it as a first class function. */
INLINE Lisp_Object
call0 (Lisp_Object fn)
{
return Ffuncall (1, &fn);
}
-/* Call function fn with 1 argument arg1. */
-INLINE Lisp_Object
-call1 (Lisp_Object fn, Lisp_Object arg1)
-{
- return CALLN (Ffuncall, fn, arg1);
-}
-
-/* Call function fn with 2 arguments arg1, arg2. */
-INLINE Lisp_Object
-call2 (Lisp_Object fn, Lisp_Object arg1, Lisp_Object arg2)
-{
- return CALLN (Ffuncall, fn, arg1, arg2);
-}
-
-/* Call function fn with 3 arguments arg1, arg2, arg3. */
-INLINE Lisp_Object
-call3 (Lisp_Object fn, Lisp_Object arg1, Lisp_Object arg2, Lisp_Object arg3)
-{
- return CALLN (Ffuncall, fn, arg1, arg2, arg3);
-}
-
-/* Call function fn with 4 arguments arg1, arg2, arg3, arg4. */
-INLINE Lisp_Object
-call4 (Lisp_Object fn, Lisp_Object arg1, Lisp_Object arg2, Lisp_Object arg3,
- Lisp_Object arg4)
-{
- return CALLN (Ffuncall, fn, arg1, arg2, arg3, arg4);
-}
-
-/* Call function fn with 5 arguments arg1, arg2, arg3, arg4, arg5. */
-INLINE Lisp_Object
-call5 (Lisp_Object fn, Lisp_Object arg1, Lisp_Object arg2, Lisp_Object arg3,
- Lisp_Object arg4, Lisp_Object arg5)
-{
- return CALLN (Ffuncall, fn, arg1, arg2, arg3, arg4, arg5);
-}
-
-/* Call function fn with 6 arguments arg1, arg2, arg3, arg4, arg5, arg6. */
-INLINE 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 CALLN (Ffuncall, fn, arg1, arg2, arg3, arg4, arg5, arg6);
-}
-
-/* Call function fn with 7 arguments arg1, arg2, arg3, arg4, arg5, arg6, arg7. */
-INLINE 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 CALLN (Ffuncall, fn, arg1, arg2, arg3, arg4, arg5, arg6, arg7);
-}
-
-/* Call function fn with 8 arguments arg1, arg2, arg3, arg4, arg5,
- arg6, arg7, arg8. */
-INLINE Lisp_Object
-call8 (Lisp_Object fn, Lisp_Object arg1, Lisp_Object arg2, Lisp_Object arg3,
- Lisp_Object arg4, Lisp_Object arg5, Lisp_Object arg6, Lisp_Object arg7,
- Lisp_Object arg8)
-{
- return CALLN (Ffuncall, fn, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8);
-}
-
extern void defvar_lisp (struct Lisp_Objfwd const *, char const *);
extern void defvar_lisp_nopro (struct Lisp_Objfwd const *, char const *);
extern void defvar_bool (struct Lisp_Boolfwd const *, char const *);
Lisp_Object nosuffix, Lisp_Object must_suffix);
extern Lisp_Object call_debugger (Lisp_Object arg);
extern void init_eval_once (void);
-extern Lisp_Object safe_call (ptrdiff_t, Lisp_Object, ...);
-extern Lisp_Object safe_call1 (Lisp_Object, Lisp_Object);
-extern Lisp_Object safe_call2 (Lisp_Object, Lisp_Object, Lisp_Object);
+extern Lisp_Object safe_funcall (ptrdiff_t, Lisp_Object*);
+#define safe_calln(...) \
+ CALLMANY (safe_funcall, ((Lisp_Object []) {__VA_ARGS__}))
+
extern void init_eval (void);
extern void syms_of_eval (void);
extern void prog_ignore (Lisp_Object);
/* `substitute-command-keys' may bug out, which would lead
to infinite recursion when we're called from
skip_debugger, so ignore errors. */
- Lisp_Object subs = safe_call1 (Qsubstitute_command_keys, errmsg);
+ Lisp_Object subs = safe_calln (Qsubstitute_command_keys, errmsg);
if (!NILP (subs))
errmsg = subs;
}
&& syntax_propertize__done < zv)
{
modiff_count modiffs = CHARS_MODIFF;
- safe_call1 (Qinternal__syntax_propertize,
+ safe_calln (Qinternal__syntax_propertize,
make_fixnum (min (zv, 1 + charpos)));
if (modiffs != CHARS_MODIFF)
error ("internal--syntax-propertize modified the buffer!");
tty->previous_color_mode = mode;
tty_setup_colors (tty , mode);
/* This recomputes all the faces given the new color definitions. */
- safe_call (1, intern ("tty-set-up-initial-frame-faces"));
+ safe_calln (intern ("tty-set-up-initial-frame-faces"));
}
}
Qdelete_terminal_functions, terminal),
pending_funcalls);
else
- safe_call2 (Qrun_hook_with_args, Qdelete_terminal_functions, terminal);
+ safe_calln (Qrun_hook_with_args, Qdelete_terminal_functions, terminal);
if (t->delete_terminal_hook)
(*t->delete_terminal_hook) (t);
for each of them. */
Lisp_Object functions = XTS_PARSER (parser)->after_change_functions;
FOR_EACH_TAIL (functions)
- safe_call2 (XCAR (functions), lisp_ranges, parser);
+ safe_calln (XCAR (functions), lisp_ranges, parser);
unbind_to (count, Qnil);
}
frame. Make sure to record changes for each live frame
in window_change_record later. */
window_change_record_frames = true;
- safe_call1 (XCAR (funs), window_or_frame);
+ safe_calln (XCAR (funs), window_or_frame);
}
funs = XCDR (funs);
Lisp form evaluation
***********************************************************************/
-/* Error handler for safe_eval and safe_call. */
+/* Error handler for dsafe_eval and dsafe_call. */
static Lisp_Object
-safe_eval_handler (Lisp_Object arg, ptrdiff_t nargs, Lisp_Object *args)
+dsafe_eval_handler (Lisp_Object arg, ptrdiff_t nargs, Lisp_Object *args)
{
add_to_log ("Error during redisplay: %S signaled %S",
Flist (nargs, args), arg);
following. Return the result, or nil if something went
wrong. Prevent redisplay during the evaluation. */
+/* FIXME: What's the guiding principle behind the choice
+ of which calls should set 'inhibit_quit' and which don't. */
static Lisp_Object
-safe__call (bool inhibit_quit, ptrdiff_t nargs, Lisp_Object func, va_list ap)
+dsafe__call (bool inhibit_quit, Lisp_Object (f) (ptrdiff_t, Lisp_Object *),
+ ptrdiff_t nargs, Lisp_Object *args)
{
Lisp_Object val;
val = Qnil;
else
{
- ptrdiff_t i;
specpdl_ref count = SPECPDL_INDEX ();
- Lisp_Object *args;
- USE_SAFE_ALLOCA;
- SAFE_ALLOCA_LISP (args, nargs);
-
- args[0] = func;
- for (i = 1; i < nargs; i++)
- args[i] = va_arg (ap, Lisp_Object);
specbind (Qinhibit_redisplay, Qt);
if (inhibit_quit)
specbind (Qinhibit_quit, Qt);
/* Use Qt to ensure debugger does not run,
so there is no possibility of wanting to redisplay. */
- val = internal_condition_case_n (Ffuncall, nargs, args, Qt,
- safe_eval_handler);
- val = SAFE_FREE_UNBIND_TO (count, val);
+ val = internal_condition_case_n (f, nargs, args, Qt,
+ dsafe_eval_handler);
+ val = unbind_to (count, val);
}
return val;
}
-Lisp_Object
-safe_call (ptrdiff_t nargs, Lisp_Object func, ...)
-{
- Lisp_Object retval;
- va_list ap;
-
- va_start (ap, func);
- retval = safe__call (false, nargs, func, ap);
- va_end (ap);
- return retval;
-}
-
-/* Call function FN with one argument ARG.
- Return the result, or nil if something went wrong. */
-
-Lisp_Object
-safe_call1 (Lisp_Object fn, Lisp_Object arg)
-{
- return safe_call (2, fn, arg);
-}
+#define SAFE_CALLMANY(inhibit_quit, f, array) \
+ dsafe__call ((inhibit_quit), f, ARRAYELTS (array), array)
+#define dsafe_calln(inhibit_quit, ...) \
+ SAFE_CALLMANY ((inhibit_quit), Ffuncall, ((Lisp_Object []) {__VA_ARGS__}))
static Lisp_Object
-safe__call1 (bool inhibit_quit, Lisp_Object fn, ...)
-{
- Lisp_Object retval;
- va_list ap;
-
- va_start (ap, fn);
- retval = safe__call (inhibit_quit, 2, fn, ap);
- va_end (ap);
- return retval;
-}
-
-Lisp_Object
-safe_eval (Lisp_Object sexpr)
+dsafe_call1 (Lisp_Object f, Lisp_Object arg)
{
- return safe__call1 (false, Qeval, sexpr);
+ return dsafe_calln (false, f, arg);
}
static Lisp_Object
-safe__eval (bool inhibit_quit, Lisp_Object sexpr)
+dsafe_eval (Lisp_Object sexpr)
{
- return safe__call1 (inhibit_quit, Qeval, sexpr);
+ return dsafe_calln (true, Qeval, sexpr, Qt);
}
-/* Call function FN with two arguments ARG1 and ARG2.
- Return the result, or nil if something went wrong. */
-
-Lisp_Object
-safe_call2 (Lisp_Object fn, Lisp_Object arg1, Lisp_Object arg2)
-{
- return safe_call (3, fn, arg1, arg2);
-}
-
-
\f
/***********************************************************************
Debugging
it->f->inhibit_clear_image_cache = true;
if (!CONSP (val) || EQ (XCAR (val), Qlambda))
- safe_call1 (val, pos);
+ dsafe_call1 (val, pos);
else
{
Lisp_Object fns, fn;
{
fn = XCAR (fns);
if (!EQ (fn, Qt))
- safe_call1 (fn, pos);
+ dsafe_call1 (fn, pos);
}
}
else
- safe_call1 (fn, pos);
+ dsafe_call1 (fn, pos);
}
}
/* Save and restore the bidi cache, since FORM could be crazy
enough to re-enter redisplay, e.g., by calling 'message'. */
itdata = bidi_shelve_cache ();
- form = safe_eval (form);
+ form = dsafe_eval (form);
bidi_unshelve_cache (itdata, false);
form = unbind_to (count, form);
}
struct face *face = FACE_FROM_ID (it->f, it->face_id);
Lisp_Object height;
itdata = bidi_shelve_cache ();
- height = safe_call1 (it->font_height,
+ height = dsafe_call1 (it->font_height,
face->lface[LFACE_HEIGHT_INDEX]);
bidi_unshelve_cache (itdata, false);
if (NUMBERP (height))
specbind (Qheight, face->lface[LFACE_HEIGHT_INDEX]);
itdata = bidi_shelve_cache ();
- value = safe_eval (it->font_height);
+ value = dsafe_eval (it->font_height);
bidi_unshelve_cache (itdata, false);
value = unbind_to (count, value);
displaying changes from under them. Such a resizing can happen,
for instance, when which-func prints a long message while
we are running fontification-functions. We're running these
- functions with safe_call which binds inhibit-redisplay to t. */
+ functions with dsafe_call which binds inhibit-redisplay to t. */
if (!NILP (Vinhibit_redisplay))
return false;
if (FRAME_MINIBUF_ONLY_P (f))
{
if (!NILP (resize_mini_frames))
- safe_call1 (Qwindow__resize_mini_frame, WINDOW_FRAME (w));
+ dsafe_call1 (Qwindow__resize_mini_frame, WINDOW_FRAME (w));
}
else
{
{
specpdl_ref count = SPECPDL_INDEX ();
specbind (Qinhibit_quit, Qt);
- message = safe_call1 (Vset_message_function, string);
+ message = dsafe_call1 (Vset_message_function, string);
unbind_to (count, Qnil);
if (STRINGP (message))
{
specpdl_ref count = SPECPDL_INDEX ();
specbind (Qinhibit_quit, Qt);
- preserve = safe_call (1, Vclear_message_function);
+ preserve = dsafe_calln (false, Vclear_message_function);
unbind_to (count, Qnil);
}
windows = Fcons (this, windows);
}
}
- safe__call1 (true, Vpre_redisplay_function, windows);
+ dsafe_calln (true, Vpre_redisplay_function, windows);
}
/* Update all frame titles based on their buffer names, etc. We do
if (!NILP (Vwindow_scroll_functions))
{
- specpdl_ref count = SPECPDL_INDEX ();
- specbind (Qinhibit_quit, Qt);
safe_run_hooks_2
(Qwindow_scroll_functions, window, make_fixnum (CHARPOS (startp)));
- unbind_to (count, Qnil);
SET_TEXT_POS_FROM_MARKER (startp, w->start);
/* In case the hook functions switch buffers. */
set_buffer_internal (XBUFFER (w->contents));
XSETWINDOW (window, w);
/* Implementation note: if the function we call here signals an
error, we will NOT scroll when the cursor is partially-visible. */
- Lisp_Object val = safe_call1 (mclfv_p, window);
+ Lisp_Object val = dsafe_call1 (mclfv_p, window);
if (NILP (val))
return true;
else if (just_test_user_preference_p)
propagated its info to `w' anyway. */
w->redisplay = false;
XBUFFER (w->contents)->text->redisplay = false;
- safe__call1 (true, Vpre_redisplay_function, Fcons (window, Qnil));
+ dsafe_calln (true, Vpre_redisplay_function, Fcons (window, Qnil));
if (w->redisplay || XBUFFER (w->contents)->text->redisplay
|| ((EQ (Vdisplay_line_numbers, Qrelative)
can reasonably tell whether a mouse click will select w. */
XSETWINDOW (window, w);
if (FUNCTIONP (default_help))
- wset_mode_line_help_echo (w, safe_call1 (default_help, window));
+ wset_mode_line_help_echo (w, dsafe_call1 (default_help, window));
else if (STRINGP (default_help))
wset_mode_line_help_echo (w, default_help);
else
/* PROPS might cause set-text-properties to signal
an error, so we call it via internal_condition_case_n,
to avoid an infloop in redisplay due to the error. */
+ /* FIXME: Use 'SAFE_CALLMANY'? */
internal_condition_case_n (safe_set_text_properties,
4,
((Lisp_Object [])
Flength (elt),
props,
elt}),
- Qt, safe_eval_handler);
+ Qt, dsafe_eval_handler);
/* Add this item to mode_line_proptrans_alist. */
mode_line_proptrans_alist
= Fcons (Fcons (elt, props),
if (CONSP (XCDR (elt)))
{
Lisp_Object spec;
- spec = safe__eval (true, XCAR (XCDR (elt)));
+ spec = dsafe_eval (XCAR (XCDR (elt)));
/* The :eval form could delete the frame stored in the
iterator, which will cause a crash if we try to
access faces and other fields (e.g., FRAME_KBOARD)
Lisp_Object val = Qnil;
if (STRINGP (curdir))
- val = safe_call1 (intern ("file-remote-p"), curdir);
+ val = dsafe_call1 (intern ("file-remote-p"), curdir);
val = unbind_to (count, val);
{
/* Call function with current height as argument.
From is the new height. */
- result = safe_call1 (from, to);
+ result = safe_calln (from, to);
/* Ensure that if TO was absolute, so is the result. */
if (FIXNUMP (to) && !FIXNUMP (result))
XSETFRAME (lval, f);
x_dnd_action = None;
x_dnd_action_symbol
- = safe_call2 (Vx_dnd_native_test_function,
+ = safe_calln (Vx_dnd_native_test_function,
Fposn_at_x_y (make_fixnum (win_x),
make_fixnum (win_y),
lval, Qnil),
/* Now try to determine the coding system that should be
used. locale is in Host Portable Character Encoding, and
as such can be passed to build_string as is. */
- dpyinfo->xim_coding = safe_call1 (Vx_input_coding_function,
+ dpyinfo->xim_coding = safe_calln (Vx_input_coding_function,
build_string (locale));
}
}
terminal_list = terminal->next_terminal;
unblock_input ();
kset_system_key_alist (terminal->kboard,
- safe_call1 (Qvendor_specific_keysyms,
+ safe_calln (Qvendor_specific_keysyms,
(vendor
? build_string (vendor)
: empty_unibyte_string)));