diff options
| author | Joakim Verona | 2013-07-02 22:46:17 +0200 |
|---|---|---|
| committer | Joakim Verona | 2013-07-02 22:46:17 +0200 |
| commit | 3718127221fbbc31f8ebd027ab7c95403dbe9118 (patch) | |
| tree | ef422898f3344c8f94f6ecf63eb583122bbf2bd8 /src/eval.c | |
| parent | 1ce45b902c67b8a0dda8d71bd2812de29a9988a6 (diff) | |
| parent | a3b49114c186d84404226af75ae7905bd1cd018f (diff) | |
| download | emacs-3718127221fbbc31f8ebd027ab7c95403dbe9118.tar.gz emacs-3718127221fbbc31f8ebd027ab7c95403dbe9118.zip | |
Merge branch 'trunk' into xwidget
Conflicts:
src/window.c
Diffstat (limited to 'src/eval.c')
| -rw-r--r-- | src/eval.c | 225 |
1 files changed, 153 insertions, 72 deletions
diff --git a/src/eval.c b/src/eval.c index d1d074df777..d3545add21d 100644 --- a/src/eval.c +++ b/src/eval.c | |||
| @@ -76,17 +76,19 @@ Lisp_Object Vrun_hooks; | |||
| 76 | 76 | ||
| 77 | Lisp_Object Vautoload_queue; | 77 | Lisp_Object Vautoload_queue; |
| 78 | 78 | ||
| 79 | /* Current number of specbindings allocated in specpdl. */ | 79 | /* Current number of specbindings allocated in specpdl, not counting |
| 80 | the dummy entry specpdl[-1]. */ | ||
| 80 | 81 | ||
| 81 | ptrdiff_t specpdl_size; | 82 | ptrdiff_t specpdl_size; |
| 82 | 83 | ||
| 83 | /* Pointer to beginning of specpdl. */ | 84 | /* Pointer to beginning of specpdl. A dummy entry specpdl[-1] exists |
| 85 | only so that its address can be taken. */ | ||
| 84 | 86 | ||
| 85 | struct specbinding *specpdl; | 87 | union specbinding *specpdl; |
| 86 | 88 | ||
| 87 | /* Pointer to first unused element in specpdl. */ | 89 | /* Pointer to first unused element in specpdl. */ |
| 88 | 90 | ||
| 89 | struct specbinding *specpdl_ptr; | 91 | union specbinding *specpdl_ptr; |
| 90 | 92 | ||
| 91 | /* Depth in Lisp evaluations and function calls. */ | 93 | /* Depth in Lisp evaluations and function calls. */ |
| 92 | 94 | ||
| @@ -115,40 +117,113 @@ Lisp_Object inhibit_lisp_code; | |||
| 115 | static Lisp_Object funcall_lambda (Lisp_Object, ptrdiff_t, Lisp_Object *); | 117 | static Lisp_Object funcall_lambda (Lisp_Object, ptrdiff_t, Lisp_Object *); |
| 116 | static Lisp_Object apply_lambda (Lisp_Object fun, Lisp_Object args); | 118 | static Lisp_Object apply_lambda (Lisp_Object fun, Lisp_Object args); |
| 117 | 119 | ||
| 120 | static Lisp_Object | ||
| 121 | specpdl_symbol (union specbinding *pdl) | ||
| 122 | { | ||
| 123 | eassert (pdl->kind >= SPECPDL_LET); | ||
| 124 | return pdl->let.symbol; | ||
| 125 | } | ||
| 126 | |||
| 127 | static Lisp_Object | ||
| 128 | specpdl_old_value (union specbinding *pdl) | ||
| 129 | { | ||
| 130 | eassert (pdl->kind >= SPECPDL_LET); | ||
| 131 | return pdl->let.old_value; | ||
| 132 | } | ||
| 133 | |||
| 134 | static Lisp_Object | ||
| 135 | specpdl_where (union specbinding *pdl) | ||
| 136 | { | ||
| 137 | eassert (pdl->kind > SPECPDL_LET); | ||
| 138 | return pdl->let.where; | ||
| 139 | } | ||
| 140 | |||
| 141 | static Lisp_Object | ||
| 142 | specpdl_arg (union specbinding *pdl) | ||
| 143 | { | ||
| 144 | eassert (pdl->kind == SPECPDL_UNWIND); | ||
| 145 | return pdl->unwind.arg; | ||
| 146 | } | ||
| 147 | |||
| 148 | static specbinding_func | ||
| 149 | specpdl_func (union specbinding *pdl) | ||
| 150 | { | ||
| 151 | eassert (pdl->kind == SPECPDL_UNWIND); | ||
| 152 | return pdl->unwind.func; | ||
| 153 | } | ||
| 154 | |||
| 155 | static Lisp_Object | ||
| 156 | backtrace_function (union specbinding *pdl) | ||
| 157 | { | ||
| 158 | eassert (pdl->kind == SPECPDL_BACKTRACE); | ||
| 159 | return pdl->bt.function; | ||
| 160 | } | ||
| 161 | |||
| 162 | static ptrdiff_t | ||
| 163 | backtrace_nargs (union specbinding *pdl) | ||
| 164 | { | ||
| 165 | eassert (pdl->kind == SPECPDL_BACKTRACE); | ||
| 166 | return pdl->bt.nargs; | ||
| 167 | } | ||
| 168 | |||
| 169 | static Lisp_Object * | ||
| 170 | backtrace_args (union specbinding *pdl) | ||
| 171 | { | ||
| 172 | eassert (pdl->kind == SPECPDL_BACKTRACE); | ||
| 173 | return pdl->bt.args; | ||
| 174 | } | ||
| 175 | |||
| 176 | static bool | ||
| 177 | backtrace_debug_on_exit (union specbinding *pdl) | ||
| 178 | { | ||
| 179 | eassert (pdl->kind == SPECPDL_BACKTRACE); | ||
| 180 | return pdl->bt.debug_on_exit; | ||
| 181 | } | ||
| 182 | |||
| 118 | /* Functions to modify slots of backtrace records. */ | 183 | /* Functions to modify slots of backtrace records. */ |
| 119 | 184 | ||
| 120 | static void | 185 | static void |
| 121 | set_backtrace_args (struct specbinding *pdl, Lisp_Object *args) | 186 | set_backtrace_args (union specbinding *pdl, Lisp_Object *args) |
| 122 | { eassert (pdl->kind == SPECPDL_BACKTRACE); pdl->v.bt.args = args; } | 187 | { |
| 188 | eassert (pdl->kind == SPECPDL_BACKTRACE); | ||
| 189 | pdl->bt.args = args; | ||
| 190 | } | ||
| 123 | 191 | ||
| 124 | static void | 192 | static void |
| 125 | set_backtrace_nargs (struct specbinding *pdl, ptrdiff_t n) | 193 | set_backtrace_nargs (union specbinding *pdl, ptrdiff_t n) |
| 126 | { eassert (pdl->kind == SPECPDL_BACKTRACE); pdl->v.bt.nargs = n; } | 194 | { |
| 195 | eassert (pdl->kind == SPECPDL_BACKTRACE); | ||
| 196 | pdl->bt.nargs = n; | ||
| 197 | } | ||
| 127 | 198 | ||
| 128 | static void | 199 | static void |
| 129 | set_backtrace_debug_on_exit (struct specbinding *pdl, bool doe) | 200 | set_backtrace_debug_on_exit (union specbinding *pdl, bool doe) |
| 130 | { eassert (pdl->kind == SPECPDL_BACKTRACE); pdl->v.bt.debug_on_exit = doe; } | 201 | { |
| 202 | eassert (pdl->kind == SPECPDL_BACKTRACE); | ||
| 203 | pdl->bt.debug_on_exit = doe; | ||
| 204 | } | ||
| 131 | 205 | ||
| 132 | /* Helper functions to scan the backtrace. */ | 206 | /* Helper functions to scan the backtrace. */ |
| 133 | 207 | ||
| 134 | bool backtrace_p (struct specbinding *) EXTERNALLY_VISIBLE; | 208 | bool backtrace_p (union specbinding *) EXTERNALLY_VISIBLE; |
| 135 | struct specbinding *backtrace_top (void) EXTERNALLY_VISIBLE; | 209 | union specbinding *backtrace_top (void) EXTERNALLY_VISIBLE; |
| 136 | struct specbinding *backtrace_next (struct specbinding *pdl) EXTERNALLY_VISIBLE; | 210 | union specbinding *backtrace_next (union specbinding *pdl) EXTERNALLY_VISIBLE; |
| 137 | 211 | ||
| 138 | bool backtrace_p (struct specbinding *pdl) | 212 | bool |
| 213 | backtrace_p (union specbinding *pdl) | ||
| 139 | { return pdl >= specpdl; } | 214 | { return pdl >= specpdl; } |
| 140 | 215 | ||
| 141 | struct specbinding * | 216 | union specbinding * |
| 142 | backtrace_top (void) | 217 | backtrace_top (void) |
| 143 | { | 218 | { |
| 144 | struct specbinding *pdl = specpdl_ptr - 1; | 219 | union specbinding *pdl = specpdl_ptr - 1; |
| 145 | while (backtrace_p (pdl) && pdl->kind != SPECPDL_BACKTRACE) | 220 | while (backtrace_p (pdl) && pdl->kind != SPECPDL_BACKTRACE) |
| 146 | pdl--; | 221 | pdl--; |
| 147 | return pdl; | 222 | return pdl; |
| 148 | } | 223 | } |
| 149 | 224 | ||
| 150 | struct specbinding * | 225 | union specbinding * |
| 151 | backtrace_next (struct specbinding *pdl) | 226 | backtrace_next (union specbinding *pdl) |
| 152 | { | 227 | { |
| 153 | pdl--; | 228 | pdl--; |
| 154 | while (backtrace_p (pdl) && pdl->kind != SPECPDL_BACKTRACE) | 229 | while (backtrace_p (pdl) && pdl->kind != SPECPDL_BACKTRACE) |
| @@ -161,9 +236,9 @@ void | |||
| 161 | init_eval_once (void) | 236 | init_eval_once (void) |
| 162 | { | 237 | { |
| 163 | enum { size = 50 }; | 238 | enum { size = 50 }; |
| 164 | specpdl = xmalloc (size * sizeof *specpdl); | 239 | union specbinding *pdlvec = xmalloc ((size + 1) * sizeof *specpdl); |
| 165 | specpdl_size = size; | 240 | specpdl_size = size; |
| 166 | specpdl_ptr = specpdl; | 241 | specpdl = specpdl_ptr = pdlvec + 1; |
| 167 | /* Don't forget to update docs (lispref node "Local Variables"). */ | 242 | /* Don't forget to update docs (lispref node "Local Variables"). */ |
| 168 | max_specpdl_size = 1300; /* 1000 is not enough for CEDET's c-by.el. */ | 243 | max_specpdl_size = 1300; /* 1000 is not enough for CEDET's c-by.el. */ |
| 169 | max_lisp_eval_depth = 600; | 244 | max_lisp_eval_depth = 600; |
| @@ -552,7 +627,7 @@ The return value is BASE-VARIABLE. */) | |||
| 552 | set_internal (base_variable, find_symbol_value (new_alias), Qnil, 1); | 627 | set_internal (base_variable, find_symbol_value (new_alias), Qnil, 1); |
| 553 | 628 | ||
| 554 | { | 629 | { |
| 555 | struct specbinding *p; | 630 | union specbinding *p; |
| 556 | 631 | ||
| 557 | for (p = specpdl_ptr; p > specpdl; ) | 632 | for (p = specpdl_ptr; p > specpdl; ) |
| 558 | if ((--p)->kind >= SPECPDL_LET | 633 | if ((--p)->kind >= SPECPDL_LET |
| @@ -618,7 +693,7 @@ usage: (defvar SYMBOL &optional INITVALUE DOCSTRING) */) | |||
| 618 | else | 693 | else |
| 619 | { /* Check if there is really a global binding rather than just a let | 694 | { /* Check if there is really a global binding rather than just a let |
| 620 | binding that shadows the global unboundness of the var. */ | 695 | binding that shadows the global unboundness of the var. */ |
| 621 | struct specbinding *pdl = specpdl_ptr; | 696 | union specbinding *pdl = specpdl_ptr; |
| 622 | while (pdl > specpdl) | 697 | while (pdl > specpdl) |
| 623 | { | 698 | { |
| 624 | if ((--pdl)->kind >= SPECPDL_LET | 699 | if ((--pdl)->kind >= SPECPDL_LET |
| @@ -1417,7 +1492,7 @@ See also the function `condition-case'. */) | |||
| 1417 | Vsignaling_function = Qnil; | 1492 | Vsignaling_function = Qnil; |
| 1418 | if (!NILP (error_symbol)) | 1493 | if (!NILP (error_symbol)) |
| 1419 | { | 1494 | { |
| 1420 | struct specbinding *pdl = backtrace_next (backtrace_top ()); | 1495 | union specbinding *pdl = backtrace_next (backtrace_top ()); |
| 1421 | if (backtrace_p (pdl) && EQ (backtrace_function (pdl), Qerror)) | 1496 | if (backtrace_p (pdl) && EQ (backtrace_function (pdl), Qerror)) |
| 1422 | pdl = backtrace_next (pdl); | 1497 | pdl = backtrace_next (pdl); |
| 1423 | if (backtrace_p (pdl)) | 1498 | if (backtrace_p (pdl)) |
| @@ -1921,8 +1996,10 @@ If LEXICAL is t, evaluate using lexical scoping. */) | |||
| 1921 | static void | 1996 | static void |
| 1922 | grow_specpdl (void) | 1997 | grow_specpdl (void) |
| 1923 | { | 1998 | { |
| 1924 | register ptrdiff_t count = SPECPDL_INDEX (); | 1999 | ptrdiff_t count = SPECPDL_INDEX (); |
| 1925 | ptrdiff_t max_size = min (max_specpdl_size, PTRDIFF_MAX); | 2000 | ptrdiff_t max_size = min (max_specpdl_size, PTRDIFF_MAX - 1000); |
| 2001 | union specbinding *pdlvec = specpdl - 1; | ||
| 2002 | ptrdiff_t pdlvecsize = specpdl_size + 1; | ||
| 1926 | if (max_size <= specpdl_size) | 2003 | if (max_size <= specpdl_size) |
| 1927 | { | 2004 | { |
| 1928 | if (max_specpdl_size < 400) | 2005 | if (max_specpdl_size < 400) |
| @@ -1930,7 +2007,9 @@ grow_specpdl (void) | |||
| 1930 | if (max_size <= specpdl_size) | 2007 | if (max_size <= specpdl_size) |
| 1931 | signal_error ("Variable binding depth exceeds max-specpdl-size", Qnil); | 2008 | signal_error ("Variable binding depth exceeds max-specpdl-size", Qnil); |
| 1932 | } | 2009 | } |
| 1933 | specpdl = xpalloc (specpdl, &specpdl_size, 1, max_size, sizeof *specpdl); | 2010 | pdlvec = xpalloc (pdlvec, &pdlvecsize, 1, max_size + 1, sizeof *specpdl); |
| 2011 | specpdl = pdlvec + 1; | ||
| 2012 | specpdl_size = pdlvecsize - 1; | ||
| 1934 | specpdl_ptr = specpdl + count; | 2013 | specpdl_ptr = specpdl + count; |
| 1935 | } | 2014 | } |
| 1936 | 2015 | ||
| @@ -1940,11 +2019,11 @@ record_in_backtrace (Lisp_Object function, Lisp_Object *args, ptrdiff_t nargs) | |||
| 1940 | eassert (nargs >= UNEVALLED); | 2019 | eassert (nargs >= UNEVALLED); |
| 1941 | if (specpdl_ptr == specpdl + specpdl_size) | 2020 | if (specpdl_ptr == specpdl + specpdl_size) |
| 1942 | grow_specpdl (); | 2021 | grow_specpdl (); |
| 1943 | specpdl_ptr->kind = SPECPDL_BACKTRACE; | 2022 | specpdl_ptr->bt.kind = SPECPDL_BACKTRACE; |
| 1944 | specpdl_ptr->v.bt.function = function; | 2023 | specpdl_ptr->bt.debug_on_exit = false; |
| 1945 | specpdl_ptr->v.bt.args = args; | 2024 | specpdl_ptr->bt.function = function; |
| 1946 | specpdl_ptr->v.bt.nargs = nargs; | 2025 | specpdl_ptr->bt.args = args; |
| 1947 | specpdl_ptr->v.bt.debug_on_exit = false; | 2026 | specpdl_ptr->bt.nargs = nargs; |
| 1948 | specpdl_ptr++; | 2027 | specpdl_ptr++; |
| 1949 | } | 2028 | } |
| 1950 | 2029 | ||
| @@ -2981,7 +3060,7 @@ DEFUN ("fetch-bytecode", Ffetch_bytecode, Sfetch_bytecode, | |||
| 2981 | bool | 3060 | bool |
| 2982 | let_shadows_buffer_binding_p (struct Lisp_Symbol *symbol) | 3061 | let_shadows_buffer_binding_p (struct Lisp_Symbol *symbol) |
| 2983 | { | 3062 | { |
| 2984 | struct specbinding *p; | 3063 | union specbinding *p; |
| 2985 | Lisp_Object buf = Fcurrent_buffer (); | 3064 | Lisp_Object buf = Fcurrent_buffer (); |
| 2986 | 3065 | ||
| 2987 | for (p = specpdl_ptr; p > specpdl; ) | 3066 | for (p = specpdl_ptr; p > specpdl; ) |
| @@ -3000,7 +3079,7 @@ let_shadows_buffer_binding_p (struct Lisp_Symbol *symbol) | |||
| 3000 | bool | 3079 | bool |
| 3001 | let_shadows_global_binding_p (Lisp_Object symbol) | 3080 | let_shadows_global_binding_p (Lisp_Object symbol) |
| 3002 | { | 3081 | { |
| 3003 | struct specbinding *p; | 3082 | union specbinding *p; |
| 3004 | 3083 | ||
| 3005 | for (p = specpdl_ptr; p > specpdl; ) | 3084 | for (p = specpdl_ptr; p > specpdl; ) |
| 3006 | if ((--p)->kind >= SPECPDL_LET && EQ (specpdl_symbol (p), symbol)) | 3085 | if ((--p)->kind >= SPECPDL_LET && EQ (specpdl_symbol (p), symbol)) |
| @@ -3042,9 +3121,9 @@ specbind (Lisp_Object symbol, Lisp_Object value) | |||
| 3042 | case SYMBOL_PLAINVAL: | 3121 | case SYMBOL_PLAINVAL: |
| 3043 | /* The most common case is that of a non-constant symbol with a | 3122 | /* The most common case is that of a non-constant symbol with a |
| 3044 | trivial value. Make that as fast as we can. */ | 3123 | trivial value. Make that as fast as we can. */ |
| 3045 | specpdl_ptr->kind = SPECPDL_LET; | 3124 | specpdl_ptr->let.kind = SPECPDL_LET; |
| 3046 | specpdl_ptr->v.let.symbol = symbol; | 3125 | specpdl_ptr->let.symbol = symbol; |
| 3047 | specpdl_ptr->v.let.old_value = SYMBOL_VAL (sym); | 3126 | specpdl_ptr->let.old_value = SYMBOL_VAL (sym); |
| 3048 | ++specpdl_ptr; | 3127 | ++specpdl_ptr; |
| 3049 | if (!sym->constant) | 3128 | if (!sym->constant) |
| 3050 | SET_SYMBOL_VAL (sym, value); | 3129 | SET_SYMBOL_VAL (sym, value); |
| @@ -3057,10 +3136,10 @@ specbind (Lisp_Object symbol, Lisp_Object value) | |||
| 3057 | case SYMBOL_FORWARDED: | 3136 | case SYMBOL_FORWARDED: |
| 3058 | { | 3137 | { |
| 3059 | Lisp_Object ovalue = find_symbol_value (symbol); | 3138 | Lisp_Object ovalue = find_symbol_value (symbol); |
| 3060 | specpdl_ptr->kind = SPECPDL_LET_LOCAL; | 3139 | specpdl_ptr->let.kind = SPECPDL_LET_LOCAL; |
| 3061 | specpdl_ptr->v.let.symbol = symbol; | 3140 | specpdl_ptr->let.symbol = symbol; |
| 3062 | specpdl_ptr->v.let.old_value = ovalue; | 3141 | specpdl_ptr->let.old_value = ovalue; |
| 3063 | specpdl_ptr->v.let.where = Fcurrent_buffer (); | 3142 | specpdl_ptr->let.where = Fcurrent_buffer (); |
| 3064 | 3143 | ||
| 3065 | eassert (sym->redirect != SYMBOL_LOCALIZED | 3144 | eassert (sym->redirect != SYMBOL_LOCALIZED |
| 3066 | || (EQ (SYMBOL_BLV (sym)->where, Fcurrent_buffer ()))); | 3145 | || (EQ (SYMBOL_BLV (sym)->where, Fcurrent_buffer ()))); |
| @@ -3068,7 +3147,7 @@ specbind (Lisp_Object symbol, Lisp_Object value) | |||
| 3068 | if (sym->redirect == SYMBOL_LOCALIZED) | 3147 | if (sym->redirect == SYMBOL_LOCALIZED) |
| 3069 | { | 3148 | { |
| 3070 | if (!blv_found (SYMBOL_BLV (sym))) | 3149 | if (!blv_found (SYMBOL_BLV (sym))) |
| 3071 | specpdl_ptr->kind = SPECPDL_LET_DEFAULT; | 3150 | specpdl_ptr->let.kind = SPECPDL_LET_DEFAULT; |
| 3072 | } | 3151 | } |
| 3073 | else if (BUFFER_OBJFWDP (SYMBOL_FWD (sym))) | 3152 | else if (BUFFER_OBJFWDP (SYMBOL_FWD (sym))) |
| 3074 | { | 3153 | { |
| @@ -3079,14 +3158,14 @@ specbind (Lisp_Object symbol, Lisp_Object value) | |||
| 3079 | happens with other buffer-local variables. */ | 3158 | happens with other buffer-local variables. */ |
| 3080 | if (NILP (Flocal_variable_p (symbol, Qnil))) | 3159 | if (NILP (Flocal_variable_p (symbol, Qnil))) |
| 3081 | { | 3160 | { |
| 3082 | specpdl_ptr->kind = SPECPDL_LET_DEFAULT; | 3161 | specpdl_ptr->let.kind = SPECPDL_LET_DEFAULT; |
| 3083 | ++specpdl_ptr; | 3162 | ++specpdl_ptr; |
| 3084 | Fset_default (symbol, value); | 3163 | Fset_default (symbol, value); |
| 3085 | return; | 3164 | return; |
| 3086 | } | 3165 | } |
| 3087 | } | 3166 | } |
| 3088 | else | 3167 | else |
| 3089 | specpdl_ptr->kind = SPECPDL_LET; | 3168 | specpdl_ptr->let.kind = SPECPDL_LET; |
| 3090 | 3169 | ||
| 3091 | specpdl_ptr++; | 3170 | specpdl_ptr++; |
| 3092 | set_internal (symbol, value, Qnil, 1); | 3171 | set_internal (symbol, value, Qnil, 1); |
| @@ -3101,9 +3180,9 @@ record_unwind_protect (Lisp_Object (*function) (Lisp_Object), Lisp_Object arg) | |||
| 3101 | { | 3180 | { |
| 3102 | if (specpdl_ptr == specpdl + specpdl_size) | 3181 | if (specpdl_ptr == specpdl + specpdl_size) |
| 3103 | grow_specpdl (); | 3182 | grow_specpdl (); |
| 3104 | specpdl_ptr->kind = SPECPDL_UNWIND; | 3183 | specpdl_ptr->unwind.kind = SPECPDL_UNWIND; |
| 3105 | specpdl_ptr->v.unwind.func = function; | 3184 | specpdl_ptr->unwind.func = function; |
| 3106 | specpdl_ptr->v.unwind.arg = arg; | 3185 | specpdl_ptr->unwind.arg = arg; |
| 3107 | specpdl_ptr++; | 3186 | specpdl_ptr++; |
| 3108 | } | 3187 | } |
| 3109 | 3188 | ||
| @@ -3118,33 +3197,31 @@ unbind_to (ptrdiff_t count, Lisp_Object value) | |||
| 3118 | 3197 | ||
| 3119 | while (specpdl_ptr != specpdl + count) | 3198 | while (specpdl_ptr != specpdl + count) |
| 3120 | { | 3199 | { |
| 3121 | /* Copy the binding, and decrement specpdl_ptr, before we do | 3200 | /* Decrement specpdl_ptr before we do the work to unbind it, so |
| 3122 | the work to unbind it. We decrement first | 3201 | that an error in unbinding won't try to unbind the same entry |
| 3123 | so that an error in unbinding won't try to unbind | 3202 | again. Take care to copy any parts of the binding needed |
| 3124 | the same entry again, and we copy the binding first | 3203 | before invoking any code that can make more bindings. */ |
| 3125 | in case more bindings are made during some of the code we run. */ | ||
| 3126 | 3204 | ||
| 3127 | struct specbinding this_binding; | 3205 | specpdl_ptr--; |
| 3128 | this_binding = *--specpdl_ptr; | ||
| 3129 | 3206 | ||
| 3130 | switch (this_binding.kind) | 3207 | switch (specpdl_ptr->kind) |
| 3131 | { | 3208 | { |
| 3132 | case SPECPDL_UNWIND: | 3209 | case SPECPDL_UNWIND: |
| 3133 | (*specpdl_func (&this_binding)) (specpdl_arg (&this_binding)); | 3210 | specpdl_func (specpdl_ptr) (specpdl_arg (specpdl_ptr)); |
| 3134 | break; | 3211 | break; |
| 3135 | case SPECPDL_LET: | 3212 | case SPECPDL_LET: |
| 3136 | /* If variable has a trivial value (no forwarding), we can | 3213 | /* If variable has a trivial value (no forwarding), we can |
| 3137 | just set it. No need to check for constant symbols here, | 3214 | just set it. No need to check for constant symbols here, |
| 3138 | since that was already done by specbind. */ | 3215 | since that was already done by specbind. */ |
| 3139 | if (XSYMBOL (specpdl_symbol (&this_binding))->redirect | 3216 | if (XSYMBOL (specpdl_symbol (specpdl_ptr))->redirect |
| 3140 | == SYMBOL_PLAINVAL) | 3217 | == SYMBOL_PLAINVAL) |
| 3141 | SET_SYMBOL_VAL (XSYMBOL (specpdl_symbol (&this_binding)), | 3218 | SET_SYMBOL_VAL (XSYMBOL (specpdl_symbol (specpdl_ptr)), |
| 3142 | specpdl_old_value (&this_binding)); | 3219 | specpdl_old_value (specpdl_ptr)); |
| 3143 | else | 3220 | else |
| 3144 | /* NOTE: we only ever come here if make_local_foo was used for | 3221 | /* NOTE: we only ever come here if make_local_foo was used for |
| 3145 | the first time on this var within this let. */ | 3222 | the first time on this var within this let. */ |
| 3146 | Fset_default (specpdl_symbol (&this_binding), | 3223 | Fset_default (specpdl_symbol (specpdl_ptr), |
| 3147 | specpdl_old_value (&this_binding)); | 3224 | specpdl_old_value (specpdl_ptr)); |
| 3148 | break; | 3225 | break; |
| 3149 | case SPECPDL_BACKTRACE: | 3226 | case SPECPDL_BACKTRACE: |
| 3150 | break; | 3227 | break; |
| @@ -3157,17 +3234,17 @@ unbind_to (ptrdiff_t count, Lisp_Object value) | |||
| 3157 | binding. WHERE nil means that the variable had the default | 3234 | binding. WHERE nil means that the variable had the default |
| 3158 | value when it was bound. CURRENT-BUFFER is the buffer that | 3235 | value when it was bound. CURRENT-BUFFER is the buffer that |
| 3159 | was current when the variable was bound. */ | 3236 | was current when the variable was bound. */ |
| 3160 | Lisp_Object symbol = specpdl_symbol (&this_binding); | 3237 | Lisp_Object symbol = specpdl_symbol (specpdl_ptr); |
| 3161 | Lisp_Object where = specpdl_where (&this_binding); | 3238 | Lisp_Object where = specpdl_where (specpdl_ptr); |
| 3239 | Lisp_Object old_value = specpdl_old_value (specpdl_ptr); | ||
| 3162 | eassert (BUFFERP (where)); | 3240 | eassert (BUFFERP (where)); |
| 3163 | 3241 | ||
| 3164 | if (this_binding.kind == SPECPDL_LET_DEFAULT) | 3242 | if (specpdl_ptr->kind == SPECPDL_LET_DEFAULT) |
| 3165 | Fset_default (symbol, specpdl_old_value (&this_binding)); | 3243 | Fset_default (symbol, old_value); |
| 3166 | /* If this was a local binding, reset the value in the appropriate | 3244 | /* If this was a local binding, reset the value in the appropriate |
| 3167 | buffer, but only if that buffer's binding still exists. */ | 3245 | buffer, but only if that buffer's binding still exists. */ |
| 3168 | else if (!NILP (Flocal_variable_p (symbol, where))) | 3246 | else if (!NILP (Flocal_variable_p (symbol, where))) |
| 3169 | set_internal (symbol, specpdl_old_value (&this_binding), | 3247 | set_internal (symbol, old_value, where, 1); |
| 3170 | where, 1); | ||
| 3171 | } | 3248 | } |
| 3172 | break; | 3249 | break; |
| 3173 | } | 3250 | } |
| @@ -3196,7 +3273,7 @@ DEFUN ("backtrace-debug", Fbacktrace_debug, Sbacktrace_debug, 2, 2, 0, | |||
| 3196 | The debugger is entered when that frame exits, if the flag is non-nil. */) | 3273 | The debugger is entered when that frame exits, if the flag is non-nil. */) |
| 3197 | (Lisp_Object level, Lisp_Object flag) | 3274 | (Lisp_Object level, Lisp_Object flag) |
| 3198 | { | 3275 | { |
| 3199 | struct specbinding *pdl = backtrace_top (); | 3276 | union specbinding *pdl = backtrace_top (); |
| 3200 | register EMACS_INT i; | 3277 | register EMACS_INT i; |
| 3201 | 3278 | ||
| 3202 | CHECK_NUMBER (level); | 3279 | CHECK_NUMBER (level); |
| @@ -3215,7 +3292,7 @@ DEFUN ("backtrace", Fbacktrace, Sbacktrace, 0, 0, "", | |||
| 3215 | Output stream used is value of `standard-output'. */) | 3292 | Output stream used is value of `standard-output'. */) |
| 3216 | (void) | 3293 | (void) |
| 3217 | { | 3294 | { |
| 3218 | struct specbinding *pdl = backtrace_top (); | 3295 | union specbinding *pdl = backtrace_top (); |
| 3219 | Lisp_Object tem; | 3296 | Lisp_Object tem; |
| 3220 | Lisp_Object old_print_level = Vprint_level; | 3297 | Lisp_Object old_print_level = Vprint_level; |
| 3221 | 3298 | ||
| @@ -3265,7 +3342,7 @@ or a lambda expression for macro calls. | |||
| 3265 | If NFRAMES is more than the number of frames, the value is nil. */) | 3342 | If NFRAMES is more than the number of frames, the value is nil. */) |
| 3266 | (Lisp_Object nframes) | 3343 | (Lisp_Object nframes) |
| 3267 | { | 3344 | { |
| 3268 | struct specbinding *pdl = backtrace_top (); | 3345 | union specbinding *pdl = backtrace_top (); |
| 3269 | register EMACS_INT i; | 3346 | register EMACS_INT i; |
| 3270 | 3347 | ||
| 3271 | CHECK_NATNUM (nframes); | 3348 | CHECK_NATNUM (nframes); |
| @@ -3291,7 +3368,7 @@ If NFRAMES is more than the number of frames, the value is nil. */) | |||
| 3291 | void | 3368 | void |
| 3292 | mark_specpdl (void) | 3369 | mark_specpdl (void) |
| 3293 | { | 3370 | { |
| 3294 | struct specbinding *pdl; | 3371 | union specbinding *pdl; |
| 3295 | for (pdl = specpdl; pdl != specpdl_ptr; pdl++) | 3372 | for (pdl = specpdl; pdl != specpdl_ptr; pdl++) |
| 3296 | { | 3373 | { |
| 3297 | switch (pdl->kind) | 3374 | switch (pdl->kind) |
| @@ -3299,6 +3376,7 @@ mark_specpdl (void) | |||
| 3299 | case SPECPDL_UNWIND: | 3376 | case SPECPDL_UNWIND: |
| 3300 | mark_object (specpdl_arg (pdl)); | 3377 | mark_object (specpdl_arg (pdl)); |
| 3301 | break; | 3378 | break; |
| 3379 | |||
| 3302 | case SPECPDL_BACKTRACE: | 3380 | case SPECPDL_BACKTRACE: |
| 3303 | { | 3381 | { |
| 3304 | ptrdiff_t nargs = backtrace_nargs (pdl); | 3382 | ptrdiff_t nargs = backtrace_nargs (pdl); |
| @@ -3309,12 +3387,15 @@ mark_specpdl (void) | |||
| 3309 | mark_object (backtrace_args (pdl)[nargs]); | 3387 | mark_object (backtrace_args (pdl)[nargs]); |
| 3310 | } | 3388 | } |
| 3311 | break; | 3389 | break; |
| 3390 | |||
| 3312 | case SPECPDL_LET_DEFAULT: | 3391 | case SPECPDL_LET_DEFAULT: |
| 3313 | case SPECPDL_LET_LOCAL: | 3392 | case SPECPDL_LET_LOCAL: |
| 3314 | mark_object (specpdl_where (pdl)); | 3393 | mark_object (specpdl_where (pdl)); |
| 3394 | /* Fall through. */ | ||
| 3315 | case SPECPDL_LET: | 3395 | case SPECPDL_LET: |
| 3316 | mark_object (specpdl_symbol (pdl)); | 3396 | mark_object (specpdl_symbol (pdl)); |
| 3317 | mark_object (specpdl_old_value (pdl)); | 3397 | mark_object (specpdl_old_value (pdl)); |
| 3398 | break; | ||
| 3318 | } | 3399 | } |
| 3319 | } | 3400 | } |
| 3320 | } | 3401 | } |
| @@ -3322,7 +3403,7 @@ mark_specpdl (void) | |||
| 3322 | void | 3403 | void |
| 3323 | get_backtrace (Lisp_Object array) | 3404 | get_backtrace (Lisp_Object array) |
| 3324 | { | 3405 | { |
| 3325 | struct specbinding *pdl = backtrace_next (backtrace_top ()); | 3406 | union specbinding *pdl = backtrace_next (backtrace_top ()); |
| 3326 | ptrdiff_t i = 0, asize = ASIZE (array); | 3407 | ptrdiff_t i = 0, asize = ASIZE (array); |
| 3327 | 3408 | ||
| 3328 | /* Copy the backtrace contents into working memory. */ | 3409 | /* Copy the backtrace contents into working memory. */ |
| @@ -3340,7 +3421,7 @@ get_backtrace (Lisp_Object array) | |||
| 3340 | 3421 | ||
| 3341 | Lisp_Object backtrace_top_function (void) | 3422 | Lisp_Object backtrace_top_function (void) |
| 3342 | { | 3423 | { |
| 3343 | struct specbinding *pdl = backtrace_top (); | 3424 | union specbinding *pdl = backtrace_top (); |
| 3344 | return (backtrace_p (pdl) ? backtrace_function (pdl) : Qnil); | 3425 | return (backtrace_p (pdl) ? backtrace_function (pdl) : Qnil); |
| 3345 | } | 3426 | } |
| 3346 | 3427 | ||