diff options
| author | Miles Bader | 2005-06-30 00:31:46 +0000 |
|---|---|---|
| committer | Miles Bader | 2005-06-30 00:31:46 +0000 |
| commit | eeb88b27e1dbd3f412aa684d44e4a784f6e536a2 (patch) | |
| tree | 23ea1eda87f588e060b6c00e9c7ffac6a89a7e42 /src/eval.c | |
| parent | 16e1457021e3f6e3b83fc9b5262fde38b7140c96 (diff) | |
| parent | 84861437f914ac45c1eea7b6477ffc4783bb3bdd (diff) | |
| download | emacs-eeb88b27e1dbd3f412aa684d44e4a784f6e536a2.tar.gz emacs-eeb88b27e1dbd3f412aa684d44e4a784f6e536a2.zip | |
Revision: miles@gnu.org--gnu-2005/emacs--unicode--0--patch-67
Merge from emacs--cvs-trunk--0
Patches applied:
* emacs--cvs-trunk--0 (patch 447-458)
- Update from CVS
- Update from CVS: lisp/subr.el (add-to-ordered-list): Doc fix.
- Merge from gnus--rel--5.10
* gnus--rel--5.10 (patch 83-85)
- Merge from emacs--cvs-trunk--0
- Update from CVS
Diffstat (limited to 'src/eval.c')
| -rw-r--r-- | src/eval.c | 143 |
1 files changed, 99 insertions, 44 deletions
diff --git a/src/eval.c b/src/eval.c index 8ad289fd51f..17e9f7f4360 100644 --- a/src/eval.c +++ b/src/eval.c | |||
| @@ -227,6 +227,18 @@ init_eval () | |||
| 227 | when_entered_debugger = -1; | 227 | when_entered_debugger = -1; |
| 228 | } | 228 | } |
| 229 | 229 | ||
| 230 | /* unwind-protect function used by call_debugger. */ | ||
| 231 | |||
| 232 | static Lisp_Object | ||
| 233 | restore_stack_limits (data) | ||
| 234 | Lisp_Object data; | ||
| 235 | { | ||
| 236 | max_specpdl_size = XINT (XCAR (data)); | ||
| 237 | max_lisp_eval_depth = XINT (XCDR (data)); | ||
| 238 | } | ||
| 239 | |||
| 240 | /* Call the Lisp debugger, giving it argument ARG. */ | ||
| 241 | |||
| 230 | Lisp_Object | 242 | Lisp_Object |
| 231 | call_debugger (arg) | 243 | call_debugger (arg) |
| 232 | Lisp_Object arg; | 244 | Lisp_Object arg; |
| @@ -234,12 +246,22 @@ call_debugger (arg) | |||
| 234 | int debug_while_redisplaying; | 246 | int debug_while_redisplaying; |
| 235 | int count = SPECPDL_INDEX (); | 247 | int count = SPECPDL_INDEX (); |
| 236 | Lisp_Object val; | 248 | Lisp_Object val; |
| 249 | int old_max = max_specpdl_size; | ||
| 250 | |||
| 251 | /* Temporarily bump up the stack limits, | ||
| 252 | so the debugger won't run out of stack. */ | ||
| 253 | |||
| 254 | max_specpdl_size += 1; | ||
| 255 | record_unwind_protect (restore_stack_limits, | ||
| 256 | Fcons (make_number (old_max), | ||
| 257 | make_number (max_lisp_eval_depth))); | ||
| 258 | max_specpdl_size = old_max; | ||
| 237 | 259 | ||
| 238 | if (lisp_eval_depth + 20 > max_lisp_eval_depth) | 260 | if (lisp_eval_depth + 40 > max_lisp_eval_depth) |
| 239 | max_lisp_eval_depth = lisp_eval_depth + 20; | 261 | max_lisp_eval_depth = lisp_eval_depth + 40; |
| 240 | 262 | ||
| 241 | if (specpdl_size + 40 > max_specpdl_size) | 263 | if (SPECPDL_INDEX () + 100 > max_specpdl_size) |
| 242 | max_specpdl_size = specpdl_size + 40; | 264 | max_specpdl_size = SPECPDL_INDEX () + 100; |
| 243 | 265 | ||
| 244 | #ifdef HAVE_X_WINDOWS | 266 | #ifdef HAVE_X_WINDOWS |
| 245 | if (display_hourglass_p) | 267 | if (display_hourglass_p) |
| @@ -256,6 +278,7 @@ call_debugger (arg) | |||
| 256 | specbind (intern ("debugger-may-continue"), | 278 | specbind (intern ("debugger-may-continue"), |
| 257 | debug_while_redisplaying ? Qnil : Qt); | 279 | debug_while_redisplaying ? Qnil : Qt); |
| 258 | specbind (Qinhibit_redisplay, Qnil); | 280 | specbind (Qinhibit_redisplay, Qnil); |
| 281 | specbind (Qdebug_on_error, Qnil); | ||
| 259 | 282 | ||
| 260 | #if 0 /* Binding this prevents execution of Lisp code during | 283 | #if 0 /* Binding this prevents execution of Lisp code during |
| 261 | redisplay, which necessarily leads to display problems. */ | 284 | redisplay, which necessarily leads to display problems. */ |
| @@ -783,6 +806,10 @@ usage: (defvar SYMBOL &optional INITVALUE DOCSTRING) */) | |||
| 783 | register Lisp_Object sym, tem, tail; | 806 | register Lisp_Object sym, tem, tail; |
| 784 | 807 | ||
| 785 | sym = Fcar (args); | 808 | sym = Fcar (args); |
| 809 | if (SYMBOL_CONSTANT_P (sym)) | ||
| 810 | error ("Constant symbol `%s' specified in defvar", | ||
| 811 | SDATA (SYMBOL_NAME (sym))); | ||
| 812 | |||
| 786 | tail = Fcdr (args); | 813 | tail = Fcdr (args); |
| 787 | if (!NILP (Fcdr (Fcdr (tail)))) | 814 | if (!NILP (Fcdr (Fcdr (tail)))) |
| 788 | error ("Too many arguments"); | 815 | error ("Too many arguments"); |
| @@ -862,12 +889,24 @@ usage: (defconst SYMBOL INITVALUE [DOCSTRING]) */) | |||
| 862 | return sym; | 889 | return sym; |
| 863 | } | 890 | } |
| 864 | 891 | ||
| 892 | /* Error handler used in Fuser_variable_p. */ | ||
| 893 | static Lisp_Object | ||
| 894 | user_variable_p_eh (ignore) | ||
| 895 | Lisp_Object ignore; | ||
| 896 | { | ||
| 897 | return Qnil; | ||
| 898 | } | ||
| 899 | |||
| 865 | DEFUN ("user-variable-p", Fuser_variable_p, Suser_variable_p, 1, 1, 0, | 900 | DEFUN ("user-variable-p", Fuser_variable_p, Suser_variable_p, 1, 1, 0, |
| 866 | doc: /* Returns t if VARIABLE is intended to be set and modified by users. | 901 | doc: /* Return t if VARIABLE is intended to be set and modified by users. |
| 867 | \(The alternative is a variable used internally in a Lisp program.) | 902 | \(The alternative is a variable used internally in a Lisp program.) |
| 868 | Determined by whether the first character of the documentation | 903 | A variable is a user variable if |
| 869 | for the variable is `*' or if the variable is customizable (has a non-nil | 904 | \(1) the first character of its documentation is `*', or |
| 870 | value of `standard-value' or of `custom-autoload' on its property list). */) | 905 | \(2) it is customizable (its property list contains a non-nil value |
| 906 | of `standard-value' or `custom-autoload'), or | ||
| 907 | \(3) it is an alias for another user variable. | ||
| 908 | Return nil if VARIABLE is an alias and there is a loop in the | ||
| 909 | chain of symbols. */) | ||
| 871 | (variable) | 910 | (variable) |
| 872 | Lisp_Object variable; | 911 | Lisp_Object variable; |
| 873 | { | 912 | { |
| @@ -876,23 +915,37 @@ value of `standard-value' or of `custom-autoload' on its property list). */) | |||
| 876 | if (!SYMBOLP (variable)) | 915 | if (!SYMBOLP (variable)) |
| 877 | return Qnil; | 916 | return Qnil; |
| 878 | 917 | ||
| 879 | documentation = Fget (variable, Qvariable_documentation); | 918 | /* If indirect and there's an alias loop, don't check anything else. */ |
| 880 | if (INTEGERP (documentation) && XINT (documentation) < 0) | 919 | if (XSYMBOL (variable)->indirect_variable |
| 881 | return Qt; | 920 | && NILP (internal_condition_case_1 (indirect_variable, variable, |
| 882 | if (STRINGP (documentation) | 921 | Qt, user_variable_p_eh))) |
| 883 | && ((unsigned char) SREF (documentation, 0) == '*')) | 922 | return Qnil; |
| 884 | return Qt; | 923 | |
| 885 | /* If it is (STRING . INTEGER), a negative integer means a user variable. */ | 924 | while (1) |
| 886 | if (CONSP (documentation) | 925 | { |
| 887 | && STRINGP (XCAR (documentation)) | 926 | documentation = Fget (variable, Qvariable_documentation); |
| 888 | && INTEGERP (XCDR (documentation)) | 927 | if (INTEGERP (documentation) && XINT (documentation) < 0) |
| 889 | && XINT (XCDR (documentation)) < 0) | 928 | return Qt; |
| 890 | return Qt; | 929 | if (STRINGP (documentation) |
| 891 | /* Customizable? See `custom-variable-p'. */ | 930 | && ((unsigned char) SREF (documentation, 0) == '*')) |
| 892 | if ((!NILP (Fget (variable, intern ("standard-value")))) | 931 | return Qt; |
| 893 | || (!NILP (Fget (variable, intern ("custom-autoload"))))) | 932 | /* If it is (STRING . INTEGER), a negative integer means a user variable. */ |
| 894 | return Qt; | 933 | if (CONSP (documentation) |
| 895 | return Qnil; | 934 | && STRINGP (XCAR (documentation)) |
| 935 | && INTEGERP (XCDR (documentation)) | ||
| 936 | && XINT (XCDR (documentation)) < 0) | ||
| 937 | return Qt; | ||
| 938 | /* Customizable? See `custom-variable-p'. */ | ||
| 939 | if ((!NILP (Fget (variable, intern ("standard-value")))) | ||
| 940 | || (!NILP (Fget (variable, intern ("custom-autoload"))))) | ||
| 941 | return Qt; | ||
| 942 | |||
| 943 | if (!XSYMBOL (variable)->indirect_variable) | ||
| 944 | return Qnil; | ||
| 945 | |||
| 946 | /* An indirect variable? Let's follow the chain. */ | ||
| 947 | variable = XSYMBOL (variable)->value; | ||
| 948 | } | ||
| 896 | } | 949 | } |
| 897 | 950 | ||
| 898 | DEFUN ("let*", FletX, SletX, 1, UNEVALLED, 0, | 951 | DEFUN ("let*", FletX, SletX, 1, UNEVALLED, 0, |
| @@ -1533,7 +1586,16 @@ See also the function `condition-case'. */) | |||
| 1533 | /* This hook is used by edebug. */ | 1586 | /* This hook is used by edebug. */ |
| 1534 | if (! NILP (Vsignal_hook_function) | 1587 | if (! NILP (Vsignal_hook_function) |
| 1535 | && ! NILP (error_symbol)) | 1588 | && ! NILP (error_symbol)) |
| 1536 | call2 (Vsignal_hook_function, error_symbol, data); | 1589 | { |
| 1590 | /* Edebug takes care of restoring these variables when it exits. */ | ||
| 1591 | if (lisp_eval_depth + 20 > max_lisp_eval_depth) | ||
| 1592 | max_lisp_eval_depth = lisp_eval_depth + 20; | ||
| 1593 | |||
| 1594 | if (SPECPDL_INDEX () + 40 > max_specpdl_size) | ||
| 1595 | max_specpdl_size = SPECPDL_INDEX () + 40; | ||
| 1596 | |||
| 1597 | call2 (Vsignal_hook_function, error_symbol, data); | ||
| 1598 | } | ||
| 1537 | 1599 | ||
| 1538 | conditions = Fget (real_error_symbol, Qerror_conditions); | 1600 | conditions = Fget (real_error_symbol, Qerror_conditions); |
| 1539 | 1601 | ||
| @@ -1555,12 +1617,6 @@ See also the function `condition-case'. */) | |||
| 1555 | { | 1617 | { |
| 1556 | register Lisp_Object clause; | 1618 | register Lisp_Object clause; |
| 1557 | 1619 | ||
| 1558 | if (lisp_eval_depth + 20 > max_lisp_eval_depth) | ||
| 1559 | max_lisp_eval_depth = lisp_eval_depth + 20; | ||
| 1560 | |||
| 1561 | if (specpdl_size + 40 > max_specpdl_size) | ||
| 1562 | max_specpdl_size = specpdl_size + 40; | ||
| 1563 | |||
| 1564 | clause = find_handler_clause (handlerlist->handler, conditions, | 1620 | clause = find_handler_clause (handlerlist->handler, conditions, |
| 1565 | error_symbol, data, &debugger_value); | 1621 | error_symbol, data, &debugger_value); |
| 1566 | 1622 | ||
| @@ -1673,7 +1729,11 @@ skip_debugger (conditions, data) | |||
| 1673 | = SIG is nil, and DATA is (SYMBOL . REST-OF-DATA). | 1729 | = SIG is nil, and DATA is (SYMBOL . REST-OF-DATA). |
| 1674 | This is for memory-full errors only. | 1730 | This is for memory-full errors only. |
| 1675 | 1731 | ||
| 1676 | Store value returned from debugger into *DEBUGGER_VALUE_PTR. */ | 1732 | Store value returned from debugger into *DEBUGGER_VALUE_PTR. |
| 1733 | |||
| 1734 | We need to increase max_specpdl_size temporarily around | ||
| 1735 | anything we do that can push on the specpdl, so as not to get | ||
| 1736 | a second error here in case we're handling specpdl overflow. */ | ||
| 1677 | 1737 | ||
| 1678 | static Lisp_Object | 1738 | static Lisp_Object |
| 1679 | find_handler_clause (handlers, conditions, sig, data, debugger_value_ptr) | 1739 | find_handler_clause (handlers, conditions, sig, data, debugger_value_ptr) |
| @@ -1691,7 +1751,6 @@ find_handler_clause (handlers, conditions, sig, data, debugger_value_ptr) | |||
| 1691 | || !NILP (Vdebug_on_signal)) /* This says call debugger even if | 1751 | || !NILP (Vdebug_on_signal)) /* This says call debugger even if |
| 1692 | there is a handler. */ | 1752 | there is a handler. */ |
| 1693 | { | 1753 | { |
| 1694 | int count = SPECPDL_INDEX (); | ||
| 1695 | int debugger_called = 0; | 1754 | int debugger_called = 0; |
| 1696 | Lisp_Object sig_symbol, combined_data; | 1755 | Lisp_Object sig_symbol, combined_data; |
| 1697 | /* This is set to 1 if we are handling a memory-full error, | 1756 | /* This is set to 1 if we are handling a memory-full error, |
| @@ -1713,6 +1772,7 @@ find_handler_clause (handlers, conditions, sig, data, debugger_value_ptr) | |||
| 1713 | 1772 | ||
| 1714 | if (wants_debugger (Vstack_trace_on_error, conditions)) | 1773 | if (wants_debugger (Vstack_trace_on_error, conditions)) |
| 1715 | { | 1774 | { |
| 1775 | max_specpdl_size++; | ||
| 1716 | #ifdef PROTOTYPES | 1776 | #ifdef PROTOTYPES |
| 1717 | internal_with_output_to_temp_buffer ("*Backtrace*", | 1777 | internal_with_output_to_temp_buffer ("*Backtrace*", |
| 1718 | (Lisp_Object (*) (Lisp_Object)) Fbacktrace, | 1778 | (Lisp_Object (*) (Lisp_Object)) Fbacktrace, |
| @@ -1721,6 +1781,7 @@ find_handler_clause (handlers, conditions, sig, data, debugger_value_ptr) | |||
| 1721 | internal_with_output_to_temp_buffer ("*Backtrace*", | 1781 | internal_with_output_to_temp_buffer ("*Backtrace*", |
| 1722 | Fbacktrace, Qnil); | 1782 | Fbacktrace, Qnil); |
| 1723 | #endif | 1783 | #endif |
| 1784 | max_specpdl_size--; | ||
| 1724 | } | 1785 | } |
| 1725 | if (! no_debugger | 1786 | if (! no_debugger |
| 1726 | && (EQ (sig_symbol, Qquit) | 1787 | && (EQ (sig_symbol, Qquit) |
| @@ -1729,7 +1790,6 @@ find_handler_clause (handlers, conditions, sig, data, debugger_value_ptr) | |||
| 1729 | && ! skip_debugger (conditions, combined_data) | 1790 | && ! skip_debugger (conditions, combined_data) |
| 1730 | && when_entered_debugger < num_nonmacro_input_events) | 1791 | && when_entered_debugger < num_nonmacro_input_events) |
| 1731 | { | 1792 | { |
| 1732 | specbind (Qdebug_on_error, Qnil); | ||
| 1733 | *debugger_value_ptr | 1793 | *debugger_value_ptr |
| 1734 | = call_debugger (Fcons (Qerror, | 1794 | = call_debugger (Fcons (Qerror, |
| 1735 | Fcons (combined_data, Qnil))); | 1795 | Fcons (combined_data, Qnil))); |
| @@ -1739,7 +1799,7 @@ find_handler_clause (handlers, conditions, sig, data, debugger_value_ptr) | |||
| 1739 | if (EQ (handlers, Qerror)) | 1799 | if (EQ (handlers, Qerror)) |
| 1740 | { | 1800 | { |
| 1741 | if (debugger_called) | 1801 | if (debugger_called) |
| 1742 | return unbind_to (count, Qlambda); | 1802 | return Qlambda; |
| 1743 | return Qt; | 1803 | return Qt; |
| 1744 | } | 1804 | } |
| 1745 | } | 1805 | } |
| @@ -3019,13 +3079,8 @@ grow_specpdl () | |||
| 3019 | if (max_specpdl_size < 400) | 3079 | if (max_specpdl_size < 400) |
| 3020 | max_specpdl_size = 400; | 3080 | max_specpdl_size = 400; |
| 3021 | if (specpdl_size >= max_specpdl_size) | 3081 | if (specpdl_size >= max_specpdl_size) |
| 3022 | { | 3082 | Fsignal (Qerror, |
| 3023 | if (!NILP (Vdebug_on_error)) | 3083 | Fcons (build_string ("Variable binding depth exceeds max-specpdl-size"), Qnil)); |
| 3024 | /* Leave room for some specpdl in the debugger. */ | ||
| 3025 | max_specpdl_size = specpdl_size + 100; | ||
| 3026 | Fsignal (Qerror, | ||
| 3027 | Fcons (build_string ("Variable binding depth exceeds max-specpdl-size"), Qnil)); | ||
| 3028 | } | ||
| 3029 | } | 3084 | } |
| 3030 | specpdl_size *= 2; | 3085 | specpdl_size *= 2; |
| 3031 | if (specpdl_size > max_specpdl_size) | 3086 | if (specpdl_size > max_specpdl_size) |
| @@ -3333,7 +3388,7 @@ syms_of_eval () | |||
| 3333 | { | 3388 | { |
| 3334 | DEFVAR_INT ("max-specpdl-size", &max_specpdl_size, | 3389 | DEFVAR_INT ("max-specpdl-size", &max_specpdl_size, |
| 3335 | doc: /* *Limit on number of Lisp variable bindings & unwind-protects. | 3390 | doc: /* *Limit on number of Lisp variable bindings & unwind-protects. |
| 3336 | If Lisp code tries to make more than this many at once, | 3391 | If Lisp code tries to increase the total number past this amount, |
| 3337 | an error is signaled. | 3392 | an error is signaled. |
| 3338 | You can safely use a value considerably larger than the default value, | 3393 | You can safely use a value considerably larger than the default value, |
| 3339 | if that proves inconveniently small. However, if you increase it too far, | 3394 | if that proves inconveniently small. However, if you increase it too far, |