Mercurial > hg > xemacs-beta
annotate src/backtrace.h @ 4952:19a72041c5ed
Mule-izing, various fixes related to char * arguments
-------------------- ChangeLog entries follow: --------------------
modules/ChangeLog addition:
2010-01-26 Ben Wing <ben@xemacs.org>
* postgresql/postgresql.c:
* postgresql/postgresql.c (CHECK_LIVE_CONNECTION):
* postgresql/postgresql.c (print_pgresult):
* postgresql/postgresql.c (Fpq_conn_defaults):
* postgresql/postgresql.c (Fpq_connectdb):
* postgresql/postgresql.c (Fpq_connect_start):
* postgresql/postgresql.c (Fpq_result_status):
* postgresql/postgresql.c (Fpq_res_status):
Mule-ize large parts of it.
2010-01-26 Ben Wing <ben@xemacs.org>
* ldap/eldap.c (print_ldap):
* ldap/eldap.c (allocate_ldap):
Use write_ascstring().
src/ChangeLog addition:
2010-01-26 Ben Wing <ben@xemacs.org>
* alloc.c:
* alloc.c (build_ascstring):
* alloc.c (build_msg_cistring):
* alloc.c (staticpro_1):
* alloc.c (staticpro_name):
* alloc.c (staticpro_nodump_1):
* alloc.c (staticpro_nodump_name):
* alloc.c (unstaticpro_nodump_1):
* alloc.c (mcpro_1):
* alloc.c (mcpro_name):
* alloc.c (object_memory_usage_stats):
* alloc.c (common_init_alloc_early):
* alloc.c (init_alloc_once_early):
* buffer.c (print_buffer):
* buffer.c (vars_of_buffer):
* buffer.c (common_init_complex_vars_of_buffer):
* buffer.c (init_initial_directory):
* bytecode.c (invalid_byte_code):
* bytecode.c (print_compiled_function):
* bytecode.c (mark_compiled_function):
* chartab.c (print_table_entry):
* chartab.c (print_char_table):
* config.h.in:
* console-gtk.c:
* console-gtk.c (gtk_device_to_console_connection):
* console-gtk.c (gtk_semi_canonicalize_console_connection):
* console-gtk.c (gtk_canonicalize_console_connection):
* console-gtk.c (gtk_semi_canonicalize_device_connection):
* console-gtk.c (gtk_canonicalize_device_connection):
* console-stream.c (stream_init_frame_1):
* console-stream.c (vars_of_console_stream):
* console-stream.c (init_console_stream):
* console-x.c (x_semi_canonicalize_console_connection):
* console-x.c (x_semi_canonicalize_device_connection):
* console-x.c (x_canonicalize_device_connection):
* console-x.h:
* data.c (eq_with_ebola_notice):
* data.c (Fsubr_interactive):
* data.c (Fnumber_to_string):
* data.c (digit_to_number):
* device-gtk.c (gtk_init_device):
* device-msw.c (print_devmode):
* device-x.c (x_event_name):
* dialog-msw.c (handle_directory_dialog_box):
* dialog-msw.c (handle_file_dialog_box):
* dialog-msw.c (vars_of_dialog_mswindows):
* doc.c (weird_doc):
* doc.c (Fsnarf_documentation):
* doc.c (vars_of_doc):
* dumper.c (pdump):
* dynarr.c:
* dynarr.c (Dynarr_realloc):
* editfns.c (Fuser_real_login_name):
* editfns.c (get_home_directory):
* elhash.c (print_hash_table_data):
* elhash.c (print_hash_table):
* emacs.c (main_1):
* emacs.c (vars_of_emacs):
* emodules.c:
* emodules.c (_emodules_list):
* emodules.c (Fload_module):
* emodules.c (Funload_module):
* emodules.c (Flist_modules):
* emodules.c (find_make_module):
* emodules.c (attempt_module_delete):
* emodules.c (emodules_load):
* emodules.c (emodules_doc_subr):
* emodules.c (emodules_doc_sym):
* emodules.c (syms_of_module):
* emodules.c (vars_of_module):
* emodules.h:
* eval.c (print_subr):
* eval.c (signal_call_debugger):
* eval.c (build_error_data):
* eval.c (signal_error):
* eval.c (maybe_signal_error):
* eval.c (signal_continuable_error):
* eval.c (maybe_signal_continuable_error):
* eval.c (signal_error_2):
* eval.c (maybe_signal_error_2):
* eval.c (signal_continuable_error_2):
* eval.c (maybe_signal_continuable_error_2):
* eval.c (signal_ferror):
* eval.c (maybe_signal_ferror):
* eval.c (signal_continuable_ferror):
* eval.c (maybe_signal_continuable_ferror):
* eval.c (signal_ferror_with_frob):
* eval.c (maybe_signal_ferror_with_frob):
* eval.c (signal_continuable_ferror_with_frob):
* eval.c (maybe_signal_continuable_ferror_with_frob):
* eval.c (syntax_error):
* eval.c (syntax_error_2):
* eval.c (maybe_syntax_error):
* eval.c (sferror):
* eval.c (sferror_2):
* eval.c (maybe_sferror):
* eval.c (invalid_argument):
* eval.c (invalid_argument_2):
* eval.c (maybe_invalid_argument):
* eval.c (invalid_constant):
* eval.c (invalid_constant_2):
* eval.c (maybe_invalid_constant):
* eval.c (invalid_operation):
* eval.c (invalid_operation_2):
* eval.c (maybe_invalid_operation):
* eval.c (invalid_change):
* eval.c (invalid_change_2):
* eval.c (maybe_invalid_change):
* eval.c (invalid_state):
* eval.c (invalid_state_2):
* eval.c (maybe_invalid_state):
* eval.c (wtaerror):
* eval.c (stack_overflow):
* eval.c (out_of_memory):
* eval.c (print_multiple_value):
* eval.c (issue_call_trapping_problems_warning):
* eval.c (backtrace_specials):
* eval.c (backtrace_unevalled_args):
* eval.c (Fbacktrace):
* eval.c (warn_when_safe):
* event-Xt.c (modwarn):
* event-Xt.c (modbarf):
* event-Xt.c (check_modifier):
* event-Xt.c (store_modifier):
* event-Xt.c (emacs_Xt_format_magic_event):
* event-Xt.c (describe_event):
* event-gtk.c (dragndrop_data_received):
* event-gtk.c (store_modifier):
* event-gtk.c (gtk_reset_modifier_mapping):
* event-msw.c (dde_eval_string):
* event-msw.c (Fdde_alloc_advise_item):
* event-msw.c (mswindows_dde_callback):
* event-msw.c (FROB):
* event-msw.c (emacs_mswindows_format_magic_event):
* event-stream.c (external_debugging_print_event):
* event-stream.c (execute_help_form):
* event-stream.c (vars_of_event_stream):
* events.c (print_event_1):
* events.c (print_event):
* events.c (event_equal):
* extents.c (print_extent_1):
* extents.c (print_extent):
* extents.c (vars_of_extents):
* faces.c (print_face):
* faces.c (complex_vars_of_faces):
* file-coding.c:
* file-coding.c (print_coding_system):
* file-coding.c (print_coding_system_in_print_method):
* file-coding.c (default_query_method):
* file-coding.c (find_coding_system):
* file-coding.c (make_coding_system_1):
* file-coding.c (chain_print):
* file-coding.c (undecided_print):
* file-coding.c (gzip_print):
* file-coding.c (vars_of_file_coding):
* file-coding.c (complex_vars_of_file_coding):
* fileio.c:
* fileio.c (report_file_type_error):
* fileio.c (report_error_with_errno):
* fileio.c (report_file_error):
* fileio.c (barf_or_query_if_file_exists):
* fileio.c (vars_of_fileio):
* floatfns.c (matherr):
* fns.c (print_bit_vector):
* fns.c (Fmapconcat):
* fns.c (add_suffix_to_symbol):
* fns.c (add_prefix_to_symbol):
* frame-gtk.c:
* frame-gtk.c (Fgtk_window_id):
* frame-x.c (def):
* frame-x.c (x_cde_transfer_callback):
* frame.c:
* frame.c (Fmake_frame):
* gc.c (show_gc_cursor_and_message):
* gc.c (vars_of_gc):
* glyphs-eimage.c (png_instantiate):
* glyphs-eimage.c (tiff_instantiate):
* glyphs-gtk.c (gtk_print_image_instance):
* glyphs-msw.c (mswindows_print_image_instance):
* glyphs-x.c (x_print_image_instance):
* glyphs-x.c (update_widget_face):
* glyphs.c (make_string_from_file):
* glyphs.c (print_image_instance):
* glyphs.c (signal_image_error):
* glyphs.c (signal_image_error_2):
* glyphs.c (signal_double_image_error):
* glyphs.c (signal_double_image_error_2):
* glyphs.c (xbm_mask_file_munging):
* glyphs.c (pixmap_to_lisp_data):
* glyphs.h:
* gui.c (gui_item_display_flush_left):
* hpplay.c (player_error_internal):
* hpplay.c (myHandler):
* intl-win32.c:
* intl-win32.c (langcode_to_lang):
* intl-win32.c (sublangcode_to_lang):
* intl-win32.c (Fmswindows_get_locale_info):
* intl-win32.c (lcid_to_locale_mule_or_no):
* intl-win32.c (mswindows_multibyte_to_unicode_print):
* intl-win32.c (complex_vars_of_intl_win32):
* keymap.c:
* keymap.c (print_keymap):
* keymap.c (ensure_meta_prefix_char_keymapp):
* keymap.c (Fkey_description):
* keymap.c (Ftext_char_description):
* lisp.h:
* lisp.h (struct):
* lisp.h (DECLARE_INLINE_HEADER):
* lread.c (Fload_internal):
* lread.c (locate_file):
* lread.c (read_escape):
* lread.c (read_raw_string):
* lread.c (read1):
* lread.c (read_list):
* lread.c (read_compiled_function):
* lread.c (init_lread):
* lrecord.h:
* marker.c (print_marker):
* marker.c (marker_equal):
* menubar-msw.c (displayable_menu_item):
* menubar-x.c (command_builder_operate_menu_accelerator):
* menubar.c (vars_of_menubar):
* minibuf.c (reinit_complex_vars_of_minibuf):
* minibuf.c (complex_vars_of_minibuf):
* mule-charset.c (Fmake_charset):
* mule-charset.c (complex_vars_of_mule_charset):
* mule-coding.c (iso2022_print):
* mule-coding.c (fixed_width_query):
* number.c (bignum_print):
* number.c (ratio_print):
* number.c (bigfloat_print):
* number.c (bigfloat_finalize):
* objects-msw.c:
* objects-msw.c (mswindows_color_to_string):
* objects-msw.c (mswindows_color_list):
* objects-tty.c:
* objects-tty.c (tty_font_list):
* objects-tty.c (tty_find_charset_font):
* objects-xlike-inc.c (xft_find_charset_font):
* objects-xlike-inc.c (endif):
* print.c:
* print.c (write_istring):
* print.c (write_ascstring):
* print.c (Fterpri):
* print.c (Fprint):
* print.c (print_error_message):
* print.c (print_vector_internal):
* print.c (print_cons):
* print.c (print_string):
* print.c (printing_unreadable_object):
* print.c (print_internal):
* print.c (print_float):
* print.c (print_symbol):
* process-nt.c (mswindows_report_winsock_error):
* process-nt.c (nt_canonicalize_host_name):
* process-unix.c (unix_canonicalize_host_name):
* process.c (print_process):
* process.c (report_process_error):
* process.c (report_network_error):
* process.c (make_process_internal):
* process.c (Fstart_process_internal):
* process.c (status_message):
* process.c (putenv_internal):
* process.c (vars_of_process):
* process.h:
* profile.c (vars_of_profile):
* rangetab.c (print_range_table):
* realpath.c (vars_of_realpath):
* redisplay.c (vars_of_redisplay):
* search.c (wordify):
* search.c (Freplace_match):
* sheap.c (sheap_adjust_h):
* sound.c (report_sound_error):
* sound.c (Fplay_sound_file):
* specifier.c (print_specifier):
* symbols.c (Fsubr_name):
* symbols.c (do_symval_forwarding):
* symbols.c (set_default_buffer_slot_variable):
* symbols.c (set_default_console_slot_variable):
* symbols.c (store_symval_forwarding):
* symbols.c (default_value):
* symbols.c (defsymbol_massage_name_1):
* symbols.c (defsymbol_massage_name_nodump):
* symbols.c (defsymbol_massage_name):
* symbols.c (defsymbol_massage_multiword_predicate_nodump):
* symbols.c (defsymbol_massage_multiword_predicate):
* symbols.c (defsymbol_nodump):
* symbols.c (defsymbol):
* symbols.c (defkeyword):
* symbols.c (defkeyword_massage_name):
* symbols.c (check_module_subr):
* symbols.c (deferror_1):
* symbols.c (deferror):
* symbols.c (deferror_massage_name):
* symbols.c (deferror_massage_name_and_message):
* symbols.c (defvar_magic):
* symeval.h:
* symeval.h (DEFVAR_SYMVAL_FWD):
* sysdep.c:
* sysdep.c (init_system_name):
* sysdll.c:
* sysdll.c (MAYBE_PREPEND_UNDERSCORE):
* sysdll.c (dll_function):
* sysdll.c (dll_variable):
* sysdll.c (dll_error):
* sysdll.c (dll_open):
* sysdll.c (dll_close):
* sysdll.c (image_for_address):
* sysdll.c (my_find_image):
* sysdll.c (search_linked_libs):
* sysdll.h:
* sysfile.h:
* sysfile.h (DEFAULT_DIRECTORY_FALLBACK):
* syswindows.h:
* tests.c (DFC_CHECK_LENGTH):
* tests.c (DFC_CHECK_CONTENT):
* tests.c (Ftest_hash_tables):
* text.c (vars_of_text):
* text.h:
* tooltalk.c (tt_opnum_string):
* tooltalk.c (tt_message_arg_ival_string):
* tooltalk.c (Ftooltalk_default_procid):
* tooltalk.c (Ftooltalk_default_session):
* tooltalk.c (init_tooltalk):
* tooltalk.c (vars_of_tooltalk):
* ui-gtk.c (Fdll_load):
* ui-gtk.c (type_to_marshaller_type):
* ui-gtk.c (Fgtk_import_function_internal):
* ui-gtk.c (emacs_gtk_object_printer):
* ui-gtk.c (emacs_gtk_boxed_printer):
* unicode.c (unicode_to_ichar):
* unicode.c (unicode_print):
* unicode.c (unicode_query):
* unicode.c (vars_of_unicode):
* unicode.c (complex_vars_of_unicode):
* win32.c:
* win32.c (mswindows_report_process_error):
* window.c (print_window):
* xemacs.def.in.in:
BASIC IDEA: Further fixing up uses of char * and CIbyte *
to reflect their actual semantics; Mule-izing some code;
redoing of the not-yet-working code to handle message translation.
Clean up code to handle message-translation (not yet working).
Create separate versions of build_msg_string() for working with
Ibyte *, CIbyte *, and Ascbyte * arguments. Assert that Ascbyte *
arguments are pure-ASCII. Make build_msg_string() be the same
as build_msg_ascstring(). Create same three versions of GETTEXT()
and DEFER_GETTEXT(). Also create build_defer_string() and
variants for the equivalent of DEFER_GETTEXT() when building a
string. Remove old CGETTEXT(). Clean up code where GETTEXT(),
DEFER_GETTEXT(), build_msg_string(), etc. was being called and
introduce some new calls to build_msg_string(), etc. Remove
GETTEXT() from calls to weird_doc() -- we assume that the
message snarfer knows about weird_doc(). Remove uses of
DEFER_GETTEXT() from error messages in sysdep.c and instead use
special comments /* @@@begin-snarf@@@ */ and /* @@@end-snarf@@@ */
that the message snarfer presumably knows about.
Create build_ascstring() and use it in many instances in place
of build_string(). The purpose of having Ascbyte * variants is
to make the code more self-documenting in terms of what sort of
semantics is expected for char * strings. In fact in the process
of looking for uses of build_string(), much improperly Mule-ized
was discovered.
Mule-ize a lot of code as described in previous paragraph,
e.g. in sysdep.c.
Make the error functions take Ascbyte * strings and fix up a
couple of places where non-pure-ASCII strings were being passed in
(file-coding.c, mule-coding.c, unicode.c). (It's debatable whether
we really need to make the error functions work this way. It
helps catch places where code is written in a way that message
translation won't work, but we may well never implement message
translation.)
Make staticpro() and friends take Ascbyte * strings instead of
raw char * strings. Create a const_Ascbyte_ptr dynarr type
to describe what's held by staticpro_names[] and friends,
create pdump descriptions for const_Ascbyte_ptr dynarrs, and
use them in place of specially-crafted staticpro descriptions.
Mule-ize certain other functions (e.g. x_event_name) by correcting
raw use of char * to Ascbyte *, Rawbyte * or another such type,
and raw use of char[] buffers to another type (usually Ascbyte[]).
Change many uses of write_c_string() to write_msg_string(),
write_ascstring(), etc.
Mule-ize emodules.c, emodules.h, sysdll.h.
Fix some un-Mule-ized code in intl-win32.c.
A comment in event-Xt.c and the limitations of the message
snarfer (make-msgfile or whatever) is presumably incorrect --
it should be smart enough to handle function calls spread over
more than one line. Clean up code in event-Xt.c that was
written awkwardly for this reason.
In config.h.in, instead of NEED_ERROR_CHECK_TYPES_INLINES,
create a more general XEMACS_DEFS_NEEDS_INLINE_DECLS to
indicate when inlined functions need to be declared in
xemacs.defs.in.in, and make use of it in xemacs.defs.in.in.
We need to do this because postgresql.c now calls qxestrdup(),
which is an inline function.
Make nconc2() and other such functions MODULE_API and put
them in xemacs.defs.in.in since postgresql.c now uses them.
Clean up indentation in lread.c and a few other places.
In text.h, document ASSERT_ASCTEXT_ASCII() and
ASSERT_ASCTEXT_ASCII_LEN(), group together the stand-in
encodings and add some more for DLL symbols, function and
variable names, etc.
author | Ben Wing <ben@xemacs.org> |
---|---|
date | Tue, 26 Jan 2010 23:22:30 -0600 |
parents | 989a7680c221 |
children | 308d34e9f07d |
rev | line source |
---|---|
428 | 1 /* The lisp stack. |
2 Copyright (C) 1985, 1986, 1987, 1992, 1993 Free Software Foundation, Inc. | |
1292 | 3 Copyright (C) 2002, 2003 Ben Wing. |
428 | 4 |
5 This file is part of XEmacs. | |
6 | |
7 XEmacs is free software; you can redistribute it and/or modify it | |
8 under the terms of the GNU General Public License as published by the | |
9 Free Software Foundation; either version 2, or (at your option) any | |
10 later version. | |
11 | |
12 XEmacs is distributed in the hope that it will be useful, but WITHOUT | |
13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
15 for more details. | |
16 | |
17 You should have received a copy of the GNU General Public License | |
18 along with XEmacs; see the file COPYING. If not, write to | |
19 the Free Software Foundation, Inc., 59 Temple Place - Suite 330, | |
20 Boston, MA 02111-1307, USA. */ | |
21 | |
22 /* Synched up with: FSF 19.30. Contained redundantly in various C files | |
23 in FSFmacs. */ | |
24 | |
25 /* Authorship: | |
26 | |
27 FSF: Original version; a long time ago. | |
28 XEmacs: split out of some C files. (For some obscure reason, a header | |
29 file couldn't be used in FSF Emacs, but XEmacs doesn't have | |
30 that problem.) | |
31 Mly (probably) or JWZ: Some changes. | |
32 */ | |
33 | |
440 | 34 #ifndef INCLUDED_backtrace_h_ |
35 #define INCLUDED_backtrace_h_ | |
428 | 36 |
37 #include <setjmp.h> | |
38 | |
853 | 39 #ifdef ERROR_CHECK_CATCH |
40 /* you can use this if you are trying to debug corruption in the | |
41 catchlist */ | |
42 void check_catchlist_sanity (void); | |
43 | |
44 /* you can use this if you are trying to debug corruption in the specbind | |
45 stack */ | |
46 void check_specbind_stack_sanity (void); | |
47 #else | |
48 #define check_catchlist_sanity() | |
49 #define check_specbind_stack_sanity() | |
50 #endif | |
51 | |
428 | 52 /* These definitions are used in eval.c and alloc.c */ |
53 | |
54 struct backtrace | |
55 { | |
56 struct backtrace *next; | |
57 Lisp_Object *function; | |
58 Lisp_Object *args; /* Points to vector of args. */ | |
59 int nargs; /* Length of vector. | |
60 If nargs is UNEVALLED, args points to | |
61 slot holding list of unevalled args */ | |
62 int pdlcount; /* specpdl_depth () when invoked */ | |
63 char evalargs; | |
64 /* Nonzero means call value of debugger when done with this operation. */ | |
65 char debug_on_exit; | |
1292 | 66 |
67 /* All the rest is information for the use of the profiler. The only | |
68 thing that eval.c does is set the first value to 0 so that it can | |
69 be relied upon. */ | |
70 | |
71 /* ----------------------------------------------------------------- */ | |
72 | |
73 /* 0 = profiling not turned on when function called. | |
74 Since profiling can be turned on and off dynamically, we can't | |
75 always count on having info recorded when a function was called | |
76 and need to take evasive action if necessary. | |
77 1 = profiling turned on but function not yet actually called. Lots of | |
78 stuff can happen between when a function is pushed onto the | |
79 backtrace list and when it's actually called (e.g. evalling its | |
80 arguments, autoloading, etc.). For greater accuracy we don't | |
81 treat the preamble stuff as part of the function itself. | |
82 2 = profiling turned on, function called. | |
83 */ | |
84 char function_being_called; | |
85 /* The trick here is handling recursive functions and dealing with the | |
86 dynamicity of in-profile/not-in-profile. I used to just use a bunch | |
87 of hash tables for all info but that fails in the presence of | |
88 recursive functions because they can modify values out from under | |
89 you. The algorithm here is that we record the total_ticks and | |
90 total_consing, as well as the current values of `total-timing' and | |
91 `total-gc-usage' for the OBJ -- that's because recursive functions, | |
92 which get called later and exit early, will go ahead and modify the | |
93 `total-timing' and `total-gc-usage' for the fun, even though it's | |
94 not "correct" because the outer function is still running. However, | |
95 if we ask for profiling info at this point, at least we're getting | |
96 SOME info. | |
97 | |
98 So ... On entry, we record these four values. On exit, we compute | |
99 an offset from the recorded value to the current value and then | |
100 store it into the appropriate hash table entry, using the recorded | |
101 value in the entry rather than the actual one. (Inner recursive | |
102 functions may have added their own values to the total-counts, and | |
103 we want to subsume them, not add to them.) | |
104 | |
105 #### Also we need to go through the backtrace list during | |
106 stop-profiling and record values, just like for unwind_to. */ | |
107 EMACS_INT current_total_timing_val; | |
108 EMACS_INT current_total_gc_usage_val; | |
109 EMACS_UINT total_ticks_at_start; | |
110 EMACS_UINT total_consing_at_start; | |
428 | 111 }; |
112 | |
113 /* This structure helps implement the `catch' and `throw' control | |
114 structure. A struct catchtag contains all the information needed | |
115 to restore the state of the interpreter after a non-local jump. | |
853 | 116 (No information is stored concerning how to restore the state of |
117 the condition-handler list; this is handled implicitly through | |
118 an unwind-protect. unwind-protects are on the specbind stack, | |
119 which is reset to its proper value by `throw'. In the process of | |
120 that, any intervening bindings are reset and unwind-protects called, | |
121 which fixes up the condition-handler list. | |
428 | 122 |
123 catchtag structures are chained together in the C calling stack; | |
124 the `next' member points to the next outer catchtag. | |
125 | |
126 A call like (throw TAG VAL) searches for a catchtag whose `tag' | |
853 | 127 member is TAG, and then unbinds to it. A value of Vcatch_everything_tag |
128 for the `tag' member of a catchtag is special and means "catch all throws, | |
129 regardless of the tag". This is used internally by the C code. The `val' | |
130 member is used to hold VAL while the stack is unwound; `val' is returned | |
131 as the value of the catch form. The `actual_tag' member holds the value | |
132 of TAG as passed to throw, so that it can be retrieved when catches with | |
133 Vcatch_everything_tag are set up. | |
428 | 134 |
135 All the other members are concerned with restoring the interpreter | |
136 state. */ | |
137 | |
138 struct catchtag | |
139 { | |
140 Lisp_Object tag; | |
853 | 141 /* Stores the actual tag used in `throw'; the same as TAG, unless |
142 TAG is Vcatch_everything_tag. */ | |
143 Lisp_Object actual_tag; | |
2532 | 144 /* A backtrace prior to the throw, used with Vcatch_everything_tag. */ |
145 Lisp_Object backtrace; | |
428 | 146 Lisp_Object val; |
147 struct catchtag *next; | |
148 struct gcpro *gcpro; | |
149 JMP_BUF jmp; | |
150 struct backtrace *backlist; | |
151 #if 0 /* FSFmacs */ | |
617 | 152 /* FSF uses a separate handler stack to hold condition-cases, |
153 where we use Vcondition_handlers. We should switch to their | |
154 system becaue it avoids the need to mess around with consing | |
155 up stuff and then dangerously freeing it. See comment in | |
156 condition_case_unwind(). */ | |
428 | 157 struct handler *handlerlist; |
158 #endif | |
159 int lisp_eval_depth; | |
160 int pdlcount; | |
161 #if 0 /* FSFmacs */ | |
162 /* This is the equivalent of async_timer_suppress_count. | |
163 We probably don't have to bother with this. */ | |
164 int poll_suppress_count; | |
165 #endif | |
166 }; | |
167 | |
168 /* Dynamic-binding-o-rama */ | |
169 | |
170 /* Structure for recording Lisp call stack for backtrace purposes. */ | |
171 | |
172 /* The special binding stack holds the outer values of variables while | |
173 they are bound by a function application or a let form, stores the | |
174 code to be executed for Lisp unwind-protect forms, and stores the C | |
175 functions to be called for record_unwind_protect. | |
176 | |
177 If func is non-zero, undoing this binding applies func to old_value; | |
178 This implements record_unwind_protect. | |
179 If func is zero and symbol is nil, undoing this binding evaluates | |
180 the list of forms in old_value; this implements Lisp's unwind-protect | |
181 form. | |
182 Otherwise, undoing this binding stores old_value as symbol's value; this | |
183 undoes the bindings made by a let form or function call. */ | |
184 | |
185 struct specbinding | |
186 { | |
187 Lisp_Object symbol; | |
188 Lisp_Object old_value; | |
189 Lisp_Object (*func) (Lisp_Object); /* for unwind-protect */ | |
190 }; | |
191 | |
192 #if 0 /* FSFmacs */ | |
193 /* #### */ | |
194 /* Everything needed to describe an active condition case. */ | |
195 struct handler | |
196 { | |
197 /* The handler clauses and variable from the condition-case form. */ | |
198 Lisp_Object handler; | |
199 Lisp_Object var; | |
200 /* Fsignal stores here the condition-case clause that applies, | |
201 and Fcondition_case thus knows which clause to run. */ | |
202 Lisp_Object chosen_clause; | |
203 | |
204 /* Used to effect the longjmp() out to the handler. */ | |
205 struct catchtag *tag; | |
206 | |
207 /* The next enclosing handler. */ | |
208 struct handler *next; | |
209 }; | |
210 | |
211 extern struct handler *handlerlist; | |
212 | |
213 #endif | |
214 | |
215 /* These are extern because GC needs to mark them */ | |
216 extern struct specbinding *specpdl; | |
217 extern struct specbinding *specpdl_ptr; | |
218 extern struct catchtag *catchlist; | |
219 extern struct backtrace *backtrace_list; | |
220 | |
771 | 221 /* Most callers should simply use specbind() and unbind_to_1(), but if |
428 | 222 speed is REALLY IMPORTANT, you can use the faster macros below */ |
223 void specbind_magic (Lisp_Object, Lisp_Object); | |
647 | 224 void grow_specpdl (EMACS_INT reserved); |
428 | 225 void unbind_to_hairy (int); |
226 extern int specpdl_size; | |
227 | |
228 /* Inline version of specbind(). | |
229 Use this instead of specbind() if speed is sufficiently important | |
230 to save the overhead of even a single function call. */ | |
231 #define SPECBIND(symbol_object, value_object) do { \ | |
232 Lisp_Object SB_symbol = (symbol_object); \ | |
233 Lisp_Object SB_newval = (value_object); \ | |
234 Lisp_Object SB_oldval; \ | |
440 | 235 Lisp_Symbol *SB_sym; \ |
428 | 236 \ |
237 SPECPDL_RESERVE (1); \ | |
238 \ | |
239 CHECK_SYMBOL (SB_symbol); \ | |
240 SB_sym = XSYMBOL (SB_symbol); \ | |
241 SB_oldval = SB_sym->value; \ | |
242 \ | |
243 if (!SYMBOL_VALUE_MAGIC_P (SB_oldval) || UNBOUNDP (SB_oldval)) \ | |
244 { \ | |
440 | 245 /* #### the following test will go away when we have a constant \ |
428 | 246 symbol magic object */ \ |
247 if (EQ (SB_symbol, Qnil) || \ | |
248 EQ (SB_symbol, Qt) || \ | |
249 SYMBOL_IS_KEYWORD (SB_symbol)) \ | |
250 reject_constant_symbols (SB_symbol, SB_newval, 0, \ | |
251 UNBOUNDP (SB_newval) ? \ | |
252 Qmakunbound : Qset); \ | |
253 \ | |
254 specpdl_ptr->symbol = SB_symbol; \ | |
255 specpdl_ptr->old_value = SB_oldval; \ | |
256 specpdl_ptr->func = 0; \ | |
257 specpdl_ptr++; \ | |
258 specpdl_depth_counter++; \ | |
259 \ | |
260 SB_sym->value = (SB_newval); \ | |
261 } \ | |
262 else \ | |
263 specbind_magic (SB_symbol, SB_newval); \ | |
853 | 264 check_specbind_stack_sanity (); \ |
428 | 265 } while (0) |
266 | |
267 /* An even faster, but less safe inline version of specbind(). | |
268 Caller guarantees that: | |
269 - SYMBOL is a non-constant symbol (i.e. not Qnil, Qt, or keyword). | |
270 - specpdl_depth_counter >= specpdl_size. | |
271 Else we crash. */ | |
272 #define SPECBIND_FAST_UNSAFE(symbol_object, value_object) do { \ | |
273 Lisp_Object SFU_symbol = (symbol_object); \ | |
274 Lisp_Object SFU_newval = (value_object); \ | |
440 | 275 Lisp_Symbol *SFU_sym = XSYMBOL (SFU_symbol); \ |
428 | 276 Lisp_Object SFU_oldval = SFU_sym->value; \ |
814 | 277 /* Most of the time, will be previously unbound. #### With a bit of \ |
278 rearranging, this could be reduced to only one check. */ \ | |
279 if (UNBOUNDP (SFU_oldval) || !SYMBOL_VALUE_MAGIC_P (SFU_oldval)) \ | |
428 | 280 { \ |
281 specpdl_ptr->symbol = SFU_symbol; \ | |
282 specpdl_ptr->old_value = SFU_oldval; \ | |
283 specpdl_ptr->func = 0; \ | |
284 specpdl_ptr++; \ | |
285 specpdl_depth_counter++; \ | |
286 \ | |
287 SFU_sym->value = (SFU_newval); \ | |
288 } \ | |
289 else \ | |
290 specbind_magic (SFU_symbol, SFU_newval); \ | |
853 | 291 check_specbind_stack_sanity (); \ |
428 | 292 } while (0) |
293 /* Request enough room for SIZE future entries on special binding stack */ | |
294 #define SPECPDL_RESERVE(size) do { \ | |
647 | 295 EMACS_INT SR_size = (size); \ |
428 | 296 if (specpdl_depth() + SR_size >= specpdl_size) \ |
297 grow_specpdl (SR_size); \ | |
298 } while (0) | |
299 | |
771 | 300 /* Inline version of unbind_to_1(). |
301 [[Use this instead of unbind_to_1() if speed is sufficiently important | |
302 to save the overhead of even a single function call.]] | |
303 This is bogus pseudo-optimization. --ben | |
428 | 304 |
771 | 305 Most of the time, unbind_to_1() is called only on ordinary |
428 | 306 variables, so optimize for that. */ |
307 #define UNBIND_TO_GCPRO(count, value) do { \ | |
308 int UNBIND_TO_count = (count); \ | |
309 while (specpdl_depth_counter != UNBIND_TO_count) \ | |
310 { \ | |
440 | 311 Lisp_Symbol *sym; \ |
428 | 312 --specpdl_ptr; \ |
313 --specpdl_depth_counter; \ | |
314 \ | |
315 if (specpdl_ptr->func != 0 || \ | |
316 ((sym = XSYMBOL (specpdl_ptr->symbol)), \ | |
317 SYMBOL_VALUE_MAGIC_P (sym->value))) \ | |
318 { \ | |
319 struct gcpro gcpro1; \ | |
320 GCPRO1 (value); \ | |
321 unbind_to_hairy (UNBIND_TO_count); \ | |
322 UNGCPRO; \ | |
323 break; \ | |
324 } \ | |
325 \ | |
326 sym->value = specpdl_ptr->old_value; \ | |
327 } \ | |
853 | 328 check_specbind_stack_sanity (); \ |
428 | 329 } while (0) |
330 | |
771 | 331 /* A slightly faster inline version of unbind_to_1, |
428 | 332 that doesn't offer GCPROing services. */ |
333 #define UNBIND_TO(count) do { \ | |
334 int UNBIND_TO_count = (count); \ | |
335 while (specpdl_depth_counter != UNBIND_TO_count) \ | |
336 { \ | |
440 | 337 Lisp_Symbol *sym; \ |
428 | 338 --specpdl_ptr; \ |
339 --specpdl_depth_counter; \ | |
340 \ | |
341 if (specpdl_ptr->func != 0 || \ | |
342 ((sym = XSYMBOL (specpdl_ptr->symbol)), \ | |
343 SYMBOL_VALUE_MAGIC_P (sym->value))) \ | |
344 { \ | |
345 unbind_to_hairy (UNBIND_TO_count); \ | |
346 break; \ | |
347 } \ | |
348 \ | |
349 sym->value = specpdl_ptr->old_value; \ | |
350 } \ | |
853 | 351 check_specbind_stack_sanity (); \ |
428 | 352 } while (0) |
353 | |
354 #if 0 | |
355 /* Unused. It's too hard to guarantee that the current bindings | |
356 contain only variables. */ | |
771 | 357 /* Another inline version of unbind_to_1(). VALUE is GC-protected. |
428 | 358 Caller guarantees that: |
359 - all of the elements on the binding stack are variable bindings. | |
360 Else we crash. */ | |
361 #define UNBIND_TO_GCPRO_VARIABLES_ONLY(count, value) do { \ | |
362 int UNBIND_TO_count = (count); \ | |
363 while (specpdl_depth_counter != UNBIND_TO_count) \ | |
364 { \ | |
440 | 365 Lisp_Symbol *sym; \ |
428 | 366 --specpdl_ptr; \ |
367 --specpdl_depth_counter; \ | |
368 \ | |
369 sym = XSYMBOL (specpdl_ptr->symbol); \ | |
370 if (!SYMBOL_VALUE_MAGIC_P (sym->value)) \ | |
371 sym->value = specpdl_ptr->old_value; \ | |
372 else \ | |
373 { \ | |
374 struct gcpro gcpro1; \ | |
375 GCPRO1 (value); \ | |
376 unbind_to_hairy (UNBIND_TO_count); \ | |
377 UNGCPRO; \ | |
378 break; \ | |
379 } \ | |
380 } \ | |
381 } while (0) | |
382 #endif /* unused */ | |
383 | |
384 /* A faster, but less safe inline version of Fset(). | |
385 Caller guarantees that: | |
386 - SYMBOL is a non-constant symbol (i.e. not Qnil, Qt, or keyword). | |
387 Else we crash. */ | |
388 #define FSET_FAST_UNSAFE(sym, newval) do { \ | |
389 Lisp_Object FFU_sym = (sym); \ | |
390 Lisp_Object FFU_newval = (newval); \ | |
440 | 391 Lisp_Symbol *FFU_symbol = XSYMBOL (FFU_sym); \ |
428 | 392 Lisp_Object FFU_oldval = FFU_symbol->value; \ |
393 if (!SYMBOL_VALUE_MAGIC_P (FFU_oldval) || UNBOUNDP (FFU_oldval)) \ | |
394 FFU_symbol->value = FFU_newval; \ | |
395 else \ | |
396 Fset (FFU_sym, FFU_newval); \ | |
397 } while (0) | |
398 | |
1292 | 399 /* Note: you must always fill in all of the fields in a backtrace structure |
400 before pushing them on the backtrace_list. The profiling code depends | |
401 on this. */ | |
402 | |
403 #define PUSH_BACKTRACE(bt) do { \ | |
404 (bt).next = backtrace_list; \ | |
405 backtrace_list = &(bt); \ | |
406 } while (0) | |
407 | |
408 #define POP_BACKTRACE(bt) do { \ | |
409 backtrace_list = (bt).next; \ | |
410 } while (0) | |
411 | |
440 | 412 #endif /* INCLUDED_backtrace_h_ */ |