diff options
| author | Ken Raeburn | 2015-11-01 01:42:21 -0400 |
|---|---|---|
| committer | Ken Raeburn | 2015-11-01 01:42:21 -0400 |
| commit | 39372e1a1032521be74575bb06f95a3898fbae30 (patch) | |
| tree | 754bd242a23d2358ea116126fcb0a629947bd9ec /src/eval.c | |
| parent | 6a3121904d76e3b2f63007341d48c5c1af55de80 (diff) | |
| parent | e11aaee266da52937a3a031cb108fe13f68958c3 (diff) | |
| download | emacs-39372e1a1032521be74575bb06f95a3898fbae30.tar.gz emacs-39372e1a1032521be74575bb06f95a3898fbae30.zip | |
merge from trunk
Diffstat (limited to 'src/eval.c')
| -rw-r--r-- | src/eval.c | 1042 |
1 files changed, 457 insertions, 585 deletions
diff --git a/src/eval.c b/src/eval.c index fc16c15e626..cc3cf3257ea 100644 --- a/src/eval.c +++ b/src/eval.c | |||
| @@ -1,6 +1,7 @@ | |||
| 1 | /* Evaluator for GNU Emacs Lisp interpreter. | 1 | /* Evaluator for GNU Emacs Lisp interpreter. |
| 2 | Copyright (C) 1985-1987, 1993-1995, 1999-2013 Free Software | 2 | |
| 3 | Foundation, Inc. | 3 | Copyright (C) 1985-1987, 1993-1995, 1999-2015 Free Software Foundation, |
| 4 | Inc. | ||
| 4 | 5 | ||
| 5 | This file is part of GNU Emacs. | 6 | This file is part of GNU Emacs. |
| 6 | 7 | ||
| @@ -26,49 +27,12 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ | |||
| 26 | #include "commands.h" | 27 | #include "commands.h" |
| 27 | #include "keyboard.h" | 28 | #include "keyboard.h" |
| 28 | #include "dispextern.h" | 29 | #include "dispextern.h" |
| 29 | #include "frame.h" /* For XFRAME. */ | 30 | #include "buffer.h" |
| 30 | |||
| 31 | #if HAVE_X_WINDOWS | ||
| 32 | #include "xterm.h" | ||
| 33 | #endif | ||
| 34 | |||
| 35 | /* #if !BYTE_MARK_STACK */ | ||
| 36 | /* static */ | ||
| 37 | /* #endif */ | ||
| 38 | /* struct catchtag *catchlist; */ | ||
| 39 | 31 | ||
| 40 | /* Chain of condition handlers currently in effect. | 32 | /* Chain of condition and catch handlers currently in effect. */ |
| 41 | The elements of this chain are contained in the stack frames | ||
| 42 | of Fcondition_case and internal_condition_case. | ||
| 43 | When an error is signaled (by calling Fsignal, below), | ||
| 44 | this chain is searched for an element that applies. */ | ||
| 45 | 33 | ||
| 46 | /* #if !BYTE_MARK_STACK */ | ||
| 47 | /* static */ | ||
| 48 | /* #endif */ | ||
| 49 | /* struct handler *handlerlist; */ | 34 | /* struct handler *handlerlist; */ |
| 50 | 35 | ||
| 51 | #ifdef DEBUG_GCPRO | ||
| 52 | /* Count levels of GCPRO to detect failure to UNGCPRO. */ | ||
| 53 | int gcpro_level; | ||
| 54 | #endif | ||
| 55 | |||
| 56 | Lisp_Object Qautoload, Qmacro, Qexit, Qinteractive, Qcommandp; | ||
| 57 | Lisp_Object Qinhibit_quit; | ||
| 58 | Lisp_Object Qand_rest; | ||
| 59 | static Lisp_Object Qand_optional; | ||
| 60 | static Lisp_Object Qinhibit_debugger; | ||
| 61 | static Lisp_Object Qdeclare; | ||
| 62 | Lisp_Object Qinternal_interpreter_environment, Qclosure; | ||
| 63 | |||
| 64 | static Lisp_Object Qdebug; | ||
| 65 | |||
| 66 | /* This holds either the symbol `run-hooks' or nil. | ||
| 67 | It is nil at an early stage of startup, and when Emacs | ||
| 68 | is shutting down. */ | ||
| 69 | |||
| 70 | Lisp_Object Vrun_hooks; | ||
| 71 | |||
| 72 | /* Non-nil means record all fset's and provide's, to be undone | 36 | /* Non-nil means record all fset's and provide's, to be undone |
| 73 | if the file being autoloaded is not fully loaded. | 37 | if the file being autoloaded is not fully loaded. |
| 74 | They are recorded by being consed onto the front of Vautoload_queue: | 38 | They are recorded by being consed onto the front of Vautoload_queue: |
| @@ -76,6 +40,11 @@ Lisp_Object Vrun_hooks; | |||
| 76 | 40 | ||
| 77 | Lisp_Object Vautoload_queue; | 41 | Lisp_Object Vautoload_queue; |
| 78 | 42 | ||
| 43 | /* This holds either the symbol `run-hooks' or nil. | ||
| 44 | It is nil at an early stage of startup, and when Emacs | ||
| 45 | is shutting down. */ | ||
| 46 | Lisp_Object Vrun_hooks; | ||
| 47 | |||
| 79 | /* Current number of specbindings allocated in specpdl, not counting | 48 | /* Current number of specbindings allocated in specpdl, not counting |
| 80 | the dummy entry specpdl[-1]. */ | 49 | the dummy entry specpdl[-1]. */ |
| 81 | 50 | ||
| @@ -92,7 +61,7 @@ Lisp_Object Vautoload_queue; | |||
| 92 | 61 | ||
| 93 | /* Depth in Lisp evaluations and function calls. */ | 62 | /* Depth in Lisp evaluations and function calls. */ |
| 94 | 63 | ||
| 95 | /* static EMACS_INT lisp_eval_depth; */ | 64 | /* EMACS_INT lisp_eval_depth; */ |
| 96 | 65 | ||
| 97 | /* The value of num_nonmacro_input_events as of the last time we | 66 | /* The value of num_nonmacro_input_events as of the last time we |
| 98 | started to enter the debugger. If we decide to enter the debugger | 67 | started to enter the debugger. If we decide to enter the debugger |
| @@ -108,10 +77,8 @@ static EMACS_INT when_entered_debugger; | |||
| 108 | /* FIXME: We should probably get rid of this! */ | 77 | /* FIXME: We should probably get rid of this! */ |
| 109 | Lisp_Object Vsignaling_function; | 78 | Lisp_Object Vsignaling_function; |
| 110 | 79 | ||
| 111 | /* If non-nil, Lisp code must not be run since some part of Emacs is | 80 | /* If non-nil, Lisp code must not be run since some part of Emacs is in |
| 112 | in an inconsistent state. Currently, x-create-frame uses this to | 81 | an inconsistent state. Currently unused. */ |
| 113 | avoid triggering window-configuration-change-hook while the new | ||
| 114 | frame is half-initialized. */ | ||
| 115 | Lisp_Object inhibit_lisp_code; | 82 | Lisp_Object inhibit_lisp_code; |
| 116 | 83 | ||
| 117 | /* These would ordinarily be static, but they need to be visible to GDB. */ | 84 | /* These would ordinarily be static, but they need to be visible to GDB. */ |
| @@ -122,7 +89,7 @@ union specbinding *backtrace_next (union specbinding *) EXTERNALLY_VISIBLE; | |||
| 122 | union specbinding *backtrace_top (void) EXTERNALLY_VISIBLE; | 89 | union specbinding *backtrace_top (void) EXTERNALLY_VISIBLE; |
| 123 | 90 | ||
| 124 | static Lisp_Object funcall_lambda (Lisp_Object, ptrdiff_t, Lisp_Object *); | 91 | static Lisp_Object funcall_lambda (Lisp_Object, ptrdiff_t, Lisp_Object *); |
| 125 | static Lisp_Object apply_lambda (Lisp_Object fun, Lisp_Object args); | 92 | static Lisp_Object apply_lambda (Lisp_Object, Lisp_Object, ptrdiff_t); |
| 126 | 93 | ||
| 127 | static Lisp_Object | 94 | static Lisp_Object |
| 128 | specpdl_symbol (union specbinding *pdl) | 95 | specpdl_symbol (union specbinding *pdl) |
| @@ -197,17 +164,11 @@ backtrace_debug_on_exit (union specbinding *pdl) | |||
| 197 | /* Functions to modify slots of backtrace records. */ | 164 | /* Functions to modify slots of backtrace records. */ |
| 198 | 165 | ||
| 199 | static void | 166 | static void |
| 200 | set_backtrace_args (union specbinding *pdl, Lisp_Object *args) | 167 | set_backtrace_args (union specbinding *pdl, Lisp_Object *args, ptrdiff_t nargs) |
| 201 | { | 168 | { |
| 202 | eassert (pdl->kind == SPECPDL_BACKTRACE); | 169 | eassert (pdl->kind == SPECPDL_BACKTRACE); |
| 203 | pdl->bt.args = args; | 170 | pdl->bt.args = args; |
| 204 | } | 171 | pdl->bt.nargs = nargs; |
| 205 | |||
| 206 | static void | ||
| 207 | set_backtrace_nargs (union specbinding *pdl, ptrdiff_t n) | ||
| 208 | { | ||
| 209 | eassert (pdl->kind == SPECPDL_BACKTRACE); | ||
| 210 | pdl->bt.nargs = n; | ||
| 211 | } | 172 | } |
| 212 | 173 | ||
| 213 | static void | 174 | static void |
| @@ -241,6 +202,12 @@ backtrace_next (union specbinding *pdl) | |||
| 241 | return pdl; | 202 | return pdl; |
| 242 | } | 203 | } |
| 243 | 204 | ||
| 205 | /* Return a pointer to somewhere near the top of the C stack. */ | ||
| 206 | void * | ||
| 207 | near_C_stack_top (void) | ||
| 208 | { | ||
| 209 | return backtrace_args (backtrace_top ()); | ||
| 210 | } | ||
| 244 | 211 | ||
| 245 | void | 212 | void |
| 246 | init_eval_once (void) | 213 | init_eval_once (void) |
| @@ -251,40 +218,36 @@ init_eval_once (void) | |||
| 251 | specpdl = specpdl_ptr = pdlvec + 1; | 218 | specpdl = specpdl_ptr = pdlvec + 1; |
| 252 | /* Don't forget to update docs (lispref node "Local Variables"). */ | 219 | /* Don't forget to update docs (lispref node "Local Variables"). */ |
| 253 | max_specpdl_size = 1300; /* 1000 is not enough for CEDET's c-by.el. */ | 220 | max_specpdl_size = 1300; /* 1000 is not enough for CEDET's c-by.el. */ |
| 254 | max_lisp_eval_depth = 600; | 221 | max_lisp_eval_depth = 800; |
| 255 | 222 | ||
| 256 | Vrun_hooks = Qnil; | 223 | Vrun_hooks = Qnil; |
| 257 | } | 224 | } |
| 258 | 225 | ||
| 226 | /* static struct handler handlerlist_sentinel; */ | ||
| 227 | |||
| 259 | void | 228 | void |
| 260 | init_eval (void) | 229 | init_eval (void) |
| 261 | { | 230 | { |
| 231 | byte_stack_list = 0; | ||
| 262 | specpdl_ptr = specpdl; | 232 | specpdl_ptr = specpdl; |
| 263 | catchlist = 0; | 233 | { /* Put a dummy catcher at top-level so that handlerlist is never NULL. |
| 264 | handlerlist = 0; | 234 | This is important since handlerlist->nextfree holds the freelist |
| 235 | which would otherwise leak every time we unwind back to top-level. */ | ||
| 236 | struct handler *c; | ||
| 237 | handlerlist_sentinel = xzalloc (sizeof (struct handler)); | ||
| 238 | handlerlist = handlerlist_sentinel->nextfree = handlerlist_sentinel; | ||
| 239 | PUSH_HANDLER (c, Qunbound, CATCHER); | ||
| 240 | eassert (c == handlerlist_sentinel); | ||
| 241 | handlerlist_sentinel->nextfree = NULL; | ||
| 242 | handlerlist_sentinel->next = NULL; | ||
| 243 | } | ||
| 265 | Vquit_flag = Qnil; | 244 | Vquit_flag = Qnil; |
| 266 | debug_on_next_call = 0; | 245 | debug_on_next_call = 0; |
| 267 | lisp_eval_depth = 0; | 246 | lisp_eval_depth = 0; |
| 268 | #ifdef DEBUG_GCPRO | ||
| 269 | gcpro_level = 0; | ||
| 270 | #endif | ||
| 271 | /* This is less than the initial value of num_nonmacro_input_events. */ | 247 | /* This is less than the initial value of num_nonmacro_input_events. */ |
| 272 | when_entered_debugger = -1; | 248 | when_entered_debugger = -1; |
| 273 | } | 249 | } |
| 274 | 250 | ||
| 275 | #if (GC_MARK_STACK == GC_MAKE_GCPROS_NOOPS \ | ||
| 276 | || GC_MARK_STACK == GC_MARK_STACK_CHECK_GCPROS) | ||
| 277 | void | ||
| 278 | mark_catchlist (struct catchtag *catch) | ||
| 279 | { | ||
| 280 | for (; catch; catch = catch->next) | ||
| 281 | { | ||
| 282 | mark_object (catch->tag); | ||
| 283 | mark_object (catch->val); | ||
| 284 | } | ||
| 285 | } | ||
| 286 | #endif | ||
| 287 | |||
| 288 | /* Unwind-protect function used by call_debugger. */ | 251 | /* Unwind-protect function used by call_debugger. */ |
| 289 | 252 | ||
| 290 | static void | 253 | static void |
| @@ -294,6 +257,8 @@ restore_stack_limits (Lisp_Object data) | |||
| 294 | max_lisp_eval_depth = XINT (XCDR (data)); | 257 | max_lisp_eval_depth = XINT (XCDR (data)); |
| 295 | } | 258 | } |
| 296 | 259 | ||
| 260 | static void grow_specpdl (void); | ||
| 261 | |||
| 297 | /* Call the Lisp debugger, giving it argument ARG. */ | 262 | /* Call the Lisp debugger, giving it argument ARG. */ |
| 298 | 263 | ||
| 299 | Lisp_Object | 264 | Lisp_Object |
| @@ -302,22 +267,29 @@ call_debugger (Lisp_Object arg) | |||
| 302 | bool debug_while_redisplaying; | 267 | bool debug_while_redisplaying; |
| 303 | ptrdiff_t count = SPECPDL_INDEX (); | 268 | ptrdiff_t count = SPECPDL_INDEX (); |
| 304 | Lisp_Object val; | 269 | Lisp_Object val; |
| 305 | EMACS_INT old_max = max_specpdl_size; | 270 | EMACS_INT old_depth = max_lisp_eval_depth; |
| 306 | 271 | /* Do not allow max_specpdl_size less than actual depth (Bug#16603). */ | |
| 307 | /* Temporarily bump up the stack limits, | 272 | EMACS_INT old_max = max (max_specpdl_size, count); |
| 308 | so the debugger won't run out of stack. */ | ||
| 309 | |||
| 310 | max_specpdl_size += 1; | ||
| 311 | record_unwind_protect (restore_stack_limits, | ||
| 312 | Fcons (make_number (old_max), | ||
| 313 | make_number (max_lisp_eval_depth))); | ||
| 314 | max_specpdl_size = old_max; | ||
| 315 | 273 | ||
| 316 | if (lisp_eval_depth + 40 > max_lisp_eval_depth) | 274 | if (lisp_eval_depth + 40 > max_lisp_eval_depth) |
| 317 | max_lisp_eval_depth = lisp_eval_depth + 40; | 275 | max_lisp_eval_depth = lisp_eval_depth + 40; |
| 318 | 276 | ||
| 319 | if (max_specpdl_size - 100 < SPECPDL_INDEX ()) | 277 | /* While debugging Bug#16603, previous value of 100 was found |
| 320 | max_specpdl_size = SPECPDL_INDEX () + 100; | 278 | too small to avoid specpdl overflow in the debugger itself. */ |
| 279 | if (max_specpdl_size - 200 < count) | ||
| 280 | max_specpdl_size = count + 200; | ||
| 281 | |||
| 282 | if (old_max == count) | ||
| 283 | { | ||
| 284 | /* We can enter the debugger due to specpdl overflow (Bug#16603). */ | ||
| 285 | specpdl_ptr--; | ||
| 286 | grow_specpdl (); | ||
| 287 | } | ||
| 288 | |||
| 289 | /* Restore limits after leaving the debugger. */ | ||
| 290 | record_unwind_protect (restore_stack_limits, | ||
| 291 | Fcons (make_number (old_max), | ||
| 292 | make_number (old_depth))); | ||
| 321 | 293 | ||
| 322 | #ifdef HAVE_WINDOW_SYSTEM | 294 | #ifdef HAVE_WINDOW_SYSTEM |
| 323 | if (display_hourglass_p) | 295 | if (display_hourglass_p) |
| @@ -353,10 +325,10 @@ call_debugger (Lisp_Object arg) | |||
| 353 | } | 325 | } |
| 354 | 326 | ||
| 355 | static void | 327 | static void |
| 356 | do_debug_on_call (Lisp_Object code) | 328 | do_debug_on_call (Lisp_Object code, ptrdiff_t count) |
| 357 | { | 329 | { |
| 358 | debug_on_next_call = 0; | 330 | debug_on_next_call = 0; |
| 359 | set_backtrace_debug_on_exit (specpdl_ptr - 1, true); | 331 | set_backtrace_debug_on_exit (specpdl + count, true); |
| 360 | call_debugger (list1 (code)); | 332 | call_debugger (list1 (code)); |
| 361 | } | 333 | } |
| 362 | 334 | ||
| @@ -371,10 +343,7 @@ If all args return nil, return nil. | |||
| 371 | usage: (or CONDITIONS...) */) | 343 | usage: (or CONDITIONS...) */) |
| 372 | (Lisp_Object args) | 344 | (Lisp_Object args) |
| 373 | { | 345 | { |
| 374 | register Lisp_Object val = Qnil; | 346 | Lisp_Object val = Qnil; |
| 375 | struct gcpro gcpro1; | ||
| 376 | |||
| 377 | GCPRO1 (args); | ||
| 378 | 347 | ||
| 379 | while (CONSP (args)) | 348 | while (CONSP (args)) |
| 380 | { | 349 | { |
| @@ -384,7 +353,6 @@ usage: (or CONDITIONS...) */) | |||
| 384 | args = XCDR (args); | 353 | args = XCDR (args); |
| 385 | } | 354 | } |
| 386 | 355 | ||
| 387 | UNGCPRO; | ||
| 388 | return val; | 356 | return val; |
| 389 | } | 357 | } |
| 390 | 358 | ||
| @@ -395,10 +363,7 @@ If no arg yields nil, return the last arg's value. | |||
| 395 | usage: (and CONDITIONS...) */) | 363 | usage: (and CONDITIONS...) */) |
| 396 | (Lisp_Object args) | 364 | (Lisp_Object args) |
| 397 | { | 365 | { |
| 398 | register Lisp_Object val = Qt; | 366 | Lisp_Object val = Qt; |
| 399 | struct gcpro gcpro1; | ||
| 400 | |||
| 401 | GCPRO1 (args); | ||
| 402 | 367 | ||
| 403 | while (CONSP (args)) | 368 | while (CONSP (args)) |
| 404 | { | 369 | { |
| @@ -408,7 +373,6 @@ usage: (and CONDITIONS...) */) | |||
| 408 | args = XCDR (args); | 373 | args = XCDR (args); |
| 409 | } | 374 | } |
| 410 | 375 | ||
| 411 | UNGCPRO; | ||
| 412 | return val; | 376 | return val; |
| 413 | } | 377 | } |
| 414 | 378 | ||
| @@ -421,11 +385,8 @@ usage: (if COND THEN ELSE...) */) | |||
| 421 | (Lisp_Object args) | 385 | (Lisp_Object args) |
| 422 | { | 386 | { |
| 423 | Lisp_Object cond; | 387 | Lisp_Object cond; |
| 424 | struct gcpro gcpro1; | ||
| 425 | 388 | ||
| 426 | GCPRO1 (args); | ||
| 427 | cond = eval_sub (XCAR (args)); | 389 | cond = eval_sub (XCAR (args)); |
| 428 | UNGCPRO; | ||
| 429 | 390 | ||
| 430 | if (!NILP (cond)) | 391 | if (!NILP (cond)) |
| 431 | return eval_sub (Fcar (XCDR (args))); | 392 | return eval_sub (Fcar (XCDR (args))); |
| @@ -438,16 +399,14 @@ Each clause looks like (CONDITION BODY...). CONDITION is evaluated | |||
| 438 | and, if the value is non-nil, this clause succeeds: | 399 | and, if the value is non-nil, this clause succeeds: |
| 439 | then the expressions in BODY are evaluated and the last one's | 400 | then the expressions in BODY are evaluated and the last one's |
| 440 | value is the value of the cond-form. | 401 | value is the value of the cond-form. |
| 402 | If a clause has one element, as in (CONDITION), then the cond-form | ||
| 403 | returns CONDITION's value, if that is non-nil. | ||
| 441 | If no clause succeeds, cond returns nil. | 404 | If no clause succeeds, cond returns nil. |
| 442 | If a clause has one element, as in (CONDITION), | ||
| 443 | CONDITION's value if non-nil is returned from the cond-form. | ||
| 444 | usage: (cond CLAUSES...) */) | 405 | usage: (cond CLAUSES...) */) |
| 445 | (Lisp_Object args) | 406 | (Lisp_Object args) |
| 446 | { | 407 | { |
| 447 | Lisp_Object val = args; | 408 | Lisp_Object val = args; |
| 448 | struct gcpro gcpro1; | ||
| 449 | 409 | ||
| 450 | GCPRO1 (args); | ||
| 451 | while (CONSP (args)) | 410 | while (CONSP (args)) |
| 452 | { | 411 | { |
| 453 | Lisp_Object clause = XCAR (args); | 412 | Lisp_Object clause = XCAR (args); |
| @@ -460,7 +419,6 @@ usage: (cond CLAUSES...) */) | |||
| 460 | } | 419 | } |
| 461 | args = XCDR (args); | 420 | args = XCDR (args); |
| 462 | } | 421 | } |
| 463 | UNGCPRO; | ||
| 464 | 422 | ||
| 465 | return val; | 423 | return val; |
| 466 | } | 424 | } |
| @@ -471,9 +429,6 @@ usage: (progn BODY...) */) | |||
| 471 | (Lisp_Object body) | 429 | (Lisp_Object body) |
| 472 | { | 430 | { |
| 473 | Lisp_Object val = Qnil; | 431 | Lisp_Object val = Qnil; |
| 474 | struct gcpro gcpro1; | ||
| 475 | |||
| 476 | GCPRO1 (body); | ||
| 477 | 432 | ||
| 478 | while (CONSP (body)) | 433 | while (CONSP (body)) |
| 479 | { | 434 | { |
| @@ -481,7 +436,6 @@ usage: (progn BODY...) */) | |||
| 481 | body = XCDR (body); | 436 | body = XCDR (body); |
| 482 | } | 437 | } |
| 483 | 438 | ||
| 484 | UNGCPRO; | ||
| 485 | return val; | 439 | return val; |
| 486 | } | 440 | } |
| 487 | 441 | ||
| @@ -503,17 +457,14 @@ usage: (prog1 FIRST BODY...) */) | |||
| 503 | { | 457 | { |
| 504 | Lisp_Object val; | 458 | Lisp_Object val; |
| 505 | Lisp_Object args_left; | 459 | Lisp_Object args_left; |
| 506 | struct gcpro gcpro1, gcpro2; | ||
| 507 | 460 | ||
| 508 | args_left = args; | 461 | args_left = args; |
| 509 | val = args; | 462 | val = args; |
| 510 | GCPRO2 (args, val); | ||
| 511 | 463 | ||
| 512 | val = eval_sub (XCAR (args_left)); | 464 | val = eval_sub (XCAR (args_left)); |
| 513 | while (CONSP (args_left = XCDR (args_left))) | 465 | while (CONSP (args_left = XCDR (args_left))) |
| 514 | eval_sub (XCAR (args_left)); | 466 | eval_sub (XCAR (args_left)); |
| 515 | 467 | ||
| 516 | UNGCPRO; | ||
| 517 | return val; | 468 | return val; |
| 518 | } | 469 | } |
| 519 | 470 | ||
| @@ -524,11 +475,7 @@ remaining args, whose values are discarded. | |||
| 524 | usage: (prog2 FORM1 FORM2 BODY...) */) | 475 | usage: (prog2 FORM1 FORM2 BODY...) */) |
| 525 | (Lisp_Object args) | 476 | (Lisp_Object args) |
| 526 | { | 477 | { |
| 527 | struct gcpro gcpro1; | ||
| 528 | |||
| 529 | GCPRO1 (args); | ||
| 530 | eval_sub (XCAR (args)); | 478 | eval_sub (XCAR (args)); |
| 531 | UNGCPRO; | ||
| 532 | return Fprog1 (XCDR (args)); | 479 | return Fprog1 (XCDR (args)); |
| 533 | } | 480 | } |
| 534 | 481 | ||
| @@ -549,8 +496,6 @@ usage: (setq [SYM VAL]...) */) | |||
| 549 | if (CONSP (args)) | 496 | if (CONSP (args)) |
| 550 | { | 497 | { |
| 551 | Lisp_Object args_left = args; | 498 | Lisp_Object args_left = args; |
| 552 | struct gcpro gcpro1; | ||
| 553 | GCPRO1 (args); | ||
| 554 | 499 | ||
| 555 | do | 500 | do |
| 556 | { | 501 | { |
| @@ -570,8 +515,6 @@ usage: (setq [SYM VAL]...) */) | |||
| 570 | args_left = Fcdr (XCDR (args_left)); | 515 | args_left = Fcdr (XCDR (args_left)); |
| 571 | } | 516 | } |
| 572 | while (CONSP (args_left)); | 517 | while (CONSP (args_left)); |
| 573 | |||
| 574 | UNGCPRO; | ||
| 575 | } | 518 | } |
| 576 | 519 | ||
| 577 | return val; | 520 | return val; |
| @@ -582,7 +525,7 @@ DEFUN ("quote", Fquote, Squote, 1, UNEVALLED, 0, | |||
| 582 | Warning: `quote' does not construct its return value, but just returns | 525 | Warning: `quote' does not construct its return value, but just returns |
| 583 | the value that was pre-constructed by the Lisp reader (see info node | 526 | the value that was pre-constructed by the Lisp reader (see info node |
| 584 | `(elisp)Printed Representation'). | 527 | `(elisp)Printed Representation'). |
| 585 | This means that '(a . b) is not identical to (cons 'a 'b): the former | 528 | This means that \\='(a . b) is not identical to (cons \\='a \\='b): the former |
| 586 | does not cons. Quoting should be reserved for constants that will | 529 | does not cons. Quoting should be reserved for constants that will |
| 587 | never be modified by side-effects, unless you like self-modifying code. | 530 | never be modified by side-effects, unless you like self-modifying code. |
| 588 | See the common pitfall in info node `(elisp)Rearrangement' for an example | 531 | See the common pitfall in info node `(elisp)Rearrangement' for an example |
| @@ -610,10 +553,23 @@ usage: (function ARG) */) | |||
| 610 | if (!NILP (Vinternal_interpreter_environment) | 553 | if (!NILP (Vinternal_interpreter_environment) |
| 611 | && CONSP (quoted) | 554 | && CONSP (quoted) |
| 612 | && EQ (XCAR (quoted), Qlambda)) | 555 | && EQ (XCAR (quoted), Qlambda)) |
| 613 | /* This is a lambda expression within a lexical environment; | 556 | { /* This is a lambda expression within a lexical environment; |
| 614 | return an interpreted closure instead of a simple lambda. */ | 557 | return an interpreted closure instead of a simple lambda. */ |
| 615 | return Fcons (Qclosure, Fcons (Vinternal_interpreter_environment, | 558 | Lisp_Object cdr = XCDR (quoted); |
| 616 | XCDR (quoted))); | 559 | Lisp_Object tmp = cdr; |
| 560 | if (CONSP (tmp) | ||
| 561 | && (tmp = XCDR (tmp), CONSP (tmp)) | ||
| 562 | && (tmp = XCAR (tmp), CONSP (tmp)) | ||
| 563 | && (EQ (QCdocumentation, XCAR (tmp)))) | ||
| 564 | { /* Handle the special (:documentation <form>) to build the docstring | ||
| 565 | dynamically. */ | ||
| 566 | Lisp_Object docstring = eval_sub (Fcar (XCDR (tmp))); | ||
| 567 | CHECK_STRING (docstring); | ||
| 568 | cdr = Fcons (XCAR (cdr), Fcons (docstring, XCDR (XCDR (cdr)))); | ||
| 569 | } | ||
| 570 | return Fcons (Qclosure, Fcons (Vinternal_interpreter_environment, | ||
| 571 | cdr)); | ||
| 572 | } | ||
| 617 | else | 573 | else |
| 618 | /* Simply quote the argument. */ | 574 | /* Simply quote the argument. */ |
| 619 | return quoted; | 575 | return quoted; |
| @@ -648,6 +604,11 @@ The return value is BASE-VARIABLE. */) | |||
| 648 | error ("Cannot make an internal variable an alias"); | 604 | error ("Cannot make an internal variable an alias"); |
| 649 | case SYMBOL_LOCALIZED: | 605 | case SYMBOL_LOCALIZED: |
| 650 | error ("Don't know how to make a localized variable an alias"); | 606 | error ("Don't know how to make a localized variable an alias"); |
| 607 | case SYMBOL_PLAINVAL: | ||
| 608 | case SYMBOL_VARALIAS: | ||
| 609 | break; | ||
| 610 | default: | ||
| 611 | emacs_abort (); | ||
| 651 | } | 612 | } |
| 652 | 613 | ||
| 653 | /* http://lists.gnu.org/archive/html/emacs-devel/2008-04/msg00834.html | 614 | /* http://lists.gnu.org/archive/html/emacs-devel/2008-04/msg00834.html |
| @@ -692,6 +653,17 @@ default_toplevel_binding (Lisp_Object symbol) | |||
| 692 | if (EQ (specpdl_symbol (pdl), symbol)) | 653 | if (EQ (specpdl_symbol (pdl), symbol)) |
| 693 | binding = pdl; | 654 | binding = pdl; |
| 694 | break; | 655 | break; |
| 656 | |||
| 657 | case SPECPDL_UNWIND: | ||
| 658 | case SPECPDL_UNWIND_PTR: | ||
| 659 | case SPECPDL_UNWIND_INT: | ||
| 660 | case SPECPDL_UNWIND_VOID: | ||
| 661 | case SPECPDL_BACKTRACE: | ||
| 662 | case SPECPDL_LET_LOCAL: | ||
| 663 | break; | ||
| 664 | |||
| 665 | default: | ||
| 666 | emacs_abort (); | ||
| 695 | } | 667 | } |
| 696 | } | 668 | } |
| 697 | return binding; | 669 | return binding; |
| @@ -741,7 +713,7 @@ If SYMBOL has a local binding, then this form affects the local | |||
| 741 | binding. This is usually not what you want. Thus, if you need to | 713 | binding. This is usually not what you want. Thus, if you need to |
| 742 | load a file defining variables, with this form or with `defconst' or | 714 | load a file defining variables, with this form or with `defconst' or |
| 743 | `defcustom', you should always load that file _outside_ any bindings | 715 | `defcustom', you should always load that file _outside_ any bindings |
| 744 | for these variables. \(`defconst' and `defcustom' behave similarly in | 716 | for these variables. (`defconst' and `defcustom' behave similarly in |
| 745 | this respect.) | 717 | this respect.) |
| 746 | 718 | ||
| 747 | The optional argument DOCSTRING is a documentation string for the | 719 | The optional argument DOCSTRING is a documentation string for the |
| @@ -868,9 +840,6 @@ usage: (let* VARLIST BODY...) */) | |||
| 868 | { | 840 | { |
| 869 | Lisp_Object varlist, var, val, elt, lexenv; | 841 | Lisp_Object varlist, var, val, elt, lexenv; |
| 870 | ptrdiff_t count = SPECPDL_INDEX (); | 842 | ptrdiff_t count = SPECPDL_INDEX (); |
| 871 | struct gcpro gcpro1, gcpro2, gcpro3; | ||
| 872 | |||
| 873 | GCPRO3 (args, elt, varlist); | ||
| 874 | 843 | ||
| 875 | lexenv = Vinternal_interpreter_environment; | 844 | lexenv = Vinternal_interpreter_environment; |
| 876 | 845 | ||
| @@ -914,7 +883,7 @@ usage: (let* VARLIST BODY...) */) | |||
| 914 | 883 | ||
| 915 | varlist = XCDR (varlist); | 884 | varlist = XCDR (varlist); |
| 916 | } | 885 | } |
| 917 | UNGCPRO; | 886 | |
| 918 | val = Fprogn (XCDR (args)); | 887 | val = Fprogn (XCDR (args)); |
| 919 | return unbind_to (count, val); | 888 | return unbind_to (count, val); |
| 920 | } | 889 | } |
| @@ -929,10 +898,9 @@ usage: (let VARLIST BODY...) */) | |||
| 929 | (Lisp_Object args) | 898 | (Lisp_Object args) |
| 930 | { | 899 | { |
| 931 | Lisp_Object *temps, tem, lexenv; | 900 | Lisp_Object *temps, tem, lexenv; |
| 932 | register Lisp_Object elt, varlist; | 901 | Lisp_Object elt, varlist; |
| 933 | ptrdiff_t count = SPECPDL_INDEX (); | 902 | ptrdiff_t count = SPECPDL_INDEX (); |
| 934 | ptrdiff_t argnum; | 903 | ptrdiff_t argnum; |
| 935 | struct gcpro gcpro1, gcpro2; | ||
| 936 | USE_SAFE_ALLOCA; | 904 | USE_SAFE_ALLOCA; |
| 937 | 905 | ||
| 938 | varlist = XCAR (args); | 906 | varlist = XCAR (args); |
| @@ -943,9 +911,6 @@ usage: (let VARLIST BODY...) */) | |||
| 943 | 911 | ||
| 944 | /* Compute the values and store them in `temps'. */ | 912 | /* Compute the values and store them in `temps'. */ |
| 945 | 913 | ||
| 946 | GCPRO2 (args, *temps); | ||
| 947 | gcpro2.nvars = 0; | ||
| 948 | |||
| 949 | for (argnum = 0; CONSP (varlist); varlist = XCDR (varlist)) | 914 | for (argnum = 0; CONSP (varlist); varlist = XCDR (varlist)) |
| 950 | { | 915 | { |
| 951 | QUIT; | 916 | QUIT; |
| @@ -956,9 +921,7 @@ usage: (let VARLIST BODY...) */) | |||
| 956 | signal_error ("`let' bindings can have only one value-form", elt); | 921 | signal_error ("`let' bindings can have only one value-form", elt); |
| 957 | else | 922 | else |
| 958 | temps [argnum++] = eval_sub (Fcar (Fcdr (elt))); | 923 | temps [argnum++] = eval_sub (Fcar (Fcdr (elt))); |
| 959 | gcpro2.nvars = argnum; | ||
| 960 | } | 924 | } |
| 961 | UNGCPRO; | ||
| 962 | 925 | ||
| 963 | lexenv = Vinternal_interpreter_environment; | 926 | lexenv = Vinternal_interpreter_environment; |
| 964 | 927 | ||
| @@ -998,9 +961,6 @@ usage: (while TEST BODY...) */) | |||
| 998 | (Lisp_Object args) | 961 | (Lisp_Object args) |
| 999 | { | 962 | { |
| 1000 | Lisp_Object test, body; | 963 | Lisp_Object test, body; |
| 1001 | struct gcpro gcpro1, gcpro2; | ||
| 1002 | |||
| 1003 | GCPRO2 (test, body); | ||
| 1004 | 964 | ||
| 1005 | test = XCAR (args); | 965 | test = XCAR (args); |
| 1006 | body = XCDR (args); | 966 | body = XCDR (args); |
| @@ -1010,7 +970,6 @@ usage: (while TEST BODY...) */) | |||
| 1010 | Fprogn (body); | 970 | Fprogn (body); |
| 1011 | } | 971 | } |
| 1012 | 972 | ||
| 1013 | UNGCPRO; | ||
| 1014 | return Qnil; | 973 | return Qnil; |
| 1015 | } | 974 | } |
| 1016 | 975 | ||
| @@ -1057,10 +1016,7 @@ definitions to shadow the loaded ones for use in file byte-compilation. */) | |||
| 1057 | { | 1016 | { |
| 1058 | /* SYM is not mentioned in ENVIRONMENT. | 1017 | /* SYM is not mentioned in ENVIRONMENT. |
| 1059 | Look at its function definition. */ | 1018 | Look at its function definition. */ |
| 1060 | struct gcpro gcpro1; | ||
| 1061 | GCPRO1 (form); | ||
| 1062 | def = Fautoload_do_load (def, sym, Qmacro); | 1019 | def = Fautoload_do_load (def, sym, Qmacro); |
| 1063 | UNGCPRO; | ||
| 1064 | if (!CONSP (def)) | 1020 | if (!CONSP (def)) |
| 1065 | /* Not defined or definition not suitable. */ | 1021 | /* Not defined or definition not suitable. */ |
| 1066 | break; | 1022 | break; |
| @@ -1096,15 +1052,16 @@ If a throw happens, it specifies the value to return from `catch'. | |||
| 1096 | usage: (catch TAG BODY...) */) | 1052 | usage: (catch TAG BODY...) */) |
| 1097 | (Lisp_Object args) | 1053 | (Lisp_Object args) |
| 1098 | { | 1054 | { |
| 1099 | register Lisp_Object tag; | 1055 | Lisp_Object tag = eval_sub (XCAR (args)); |
| 1100 | struct gcpro gcpro1; | ||
| 1101 | |||
| 1102 | GCPRO1 (args); | ||
| 1103 | tag = eval_sub (XCAR (args)); | ||
| 1104 | UNGCPRO; | ||
| 1105 | return internal_catch (tag, Fprogn, XCDR (args)); | 1056 | return internal_catch (tag, Fprogn, XCDR (args)); |
| 1106 | } | 1057 | } |
| 1107 | 1058 | ||
| 1059 | /* Assert that E is true, as a comment only. Use this instead of | ||
| 1060 | eassert (E) when E contains variables that might be clobbered by a | ||
| 1061 | longjmp. */ | ||
| 1062 | |||
| 1063 | #define clobbered_eassert(E) ((void) 0) | ||
| 1064 | |||
| 1108 | /* Set up a catch, then call C function FUNC on argument ARG. | 1065 | /* Set up a catch, then call C function FUNC on argument ARG. |
| 1109 | FUNC should return a Lisp_Object. | 1066 | FUNC should return a Lisp_Object. |
| 1110 | This is how catches are done from within C code. */ | 1067 | This is how catches are done from within C code. */ |
| @@ -1113,28 +1070,26 @@ Lisp_Object | |||
| 1113 | internal_catch (Lisp_Object tag, Lisp_Object (*func) (Lisp_Object), Lisp_Object arg) | 1070 | internal_catch (Lisp_Object tag, Lisp_Object (*func) (Lisp_Object), Lisp_Object arg) |
| 1114 | { | 1071 | { |
| 1115 | /* This structure is made part of the chain `catchlist'. */ | 1072 | /* This structure is made part of the chain `catchlist'. */ |
| 1116 | struct catchtag c; | 1073 | struct handler *c; |
| 1117 | 1074 | ||
| 1118 | /* Fill in the components of c, and put it on the list. */ | 1075 | /* Fill in the components of c, and put it on the list. */ |
| 1119 | c.next = catchlist; | 1076 | PUSH_HANDLER (c, tag, CATCHER); |
| 1120 | c.tag = tag; | ||
| 1121 | c.val = Qnil; | ||
| 1122 | c.f_handlerlist = handlerlist; | ||
| 1123 | c.f_lisp_eval_depth = lisp_eval_depth; | ||
| 1124 | c.pdlcount = SPECPDL_INDEX (); | ||
| 1125 | c.poll_suppress_count = poll_suppress_count; | ||
| 1126 | c.interrupt_input_blocked = interrupt_input_blocked; | ||
| 1127 | c.gcpro = gcprolist; | ||
| 1128 | c.byte_stack = byte_stack_list; | ||
| 1129 | catchlist = &c; | ||
| 1130 | 1077 | ||
| 1131 | /* Call FUNC. */ | 1078 | /* Call FUNC. */ |
| 1132 | if (! sys_setjmp (c.jmp)) | 1079 | if (! sys_setjmp (c->jmp)) |
| 1133 | c.val = (*func) (arg); | 1080 | { |
| 1134 | 1081 | Lisp_Object val = (*func) (arg); | |
| 1135 | /* Throw works by a longjmp that comes right here. */ | 1082 | clobbered_eassert (handlerlist == c); |
| 1136 | catchlist = c.next; | 1083 | handlerlist = handlerlist->next; |
| 1137 | return c.val; | 1084 | return val; |
| 1085 | } | ||
| 1086 | else | ||
| 1087 | { /* Throw works by a longjmp that comes right here. */ | ||
| 1088 | Lisp_Object val = handlerlist->val; | ||
| 1089 | clobbered_eassert (handlerlist == c); | ||
| 1090 | handlerlist = handlerlist->next; | ||
| 1091 | return val; | ||
| 1092 | } | ||
| 1138 | } | 1093 | } |
| 1139 | 1094 | ||
| 1140 | /* Unwind the specbind, catch, and handler stacks back to CATCH, and | 1095 | /* Unwind the specbind, catch, and handler stacks back to CATCH, and |
| @@ -1154,10 +1109,12 @@ internal_catch (Lisp_Object tag, Lisp_Object (*func) (Lisp_Object), Lisp_Object | |||
| 1154 | This is used for correct unwinding in Fthrow and Fsignal. */ | 1109 | This is used for correct unwinding in Fthrow and Fsignal. */ |
| 1155 | 1110 | ||
| 1156 | static _Noreturn void | 1111 | static _Noreturn void |
| 1157 | unwind_to_catch (struct catchtag *catch, Lisp_Object value) | 1112 | unwind_to_catch (struct handler *catch, Lisp_Object value) |
| 1158 | { | 1113 | { |
| 1159 | bool last_time; | 1114 | bool last_time; |
| 1160 | 1115 | ||
| 1116 | eassert (catch->next); | ||
| 1117 | |||
| 1161 | /* Save the value in the tag. */ | 1118 | /* Save the value in the tag. */ |
| 1162 | catch->val = value; | 1119 | catch->val = value; |
| 1163 | 1120 | ||
| @@ -1168,21 +1125,18 @@ unwind_to_catch (struct catchtag *catch, Lisp_Object value) | |||
| 1168 | 1125 | ||
| 1169 | do | 1126 | do |
| 1170 | { | 1127 | { |
| 1171 | last_time = catchlist == catch; | ||
| 1172 | |||
| 1173 | /* Unwind the specpdl stack, and then restore the proper set of | 1128 | /* Unwind the specpdl stack, and then restore the proper set of |
| 1174 | handlers. */ | 1129 | handlers. */ |
| 1175 | unbind_to (catchlist->pdlcount, Qnil); | 1130 | unbind_to (handlerlist->pdlcount, Qnil); |
| 1176 | handlerlist = catchlist->f_handlerlist; | 1131 | last_time = handlerlist == catch; |
| 1177 | catchlist = catchlist->next; | 1132 | if (! last_time) |
| 1133 | handlerlist = handlerlist->next; | ||
| 1178 | } | 1134 | } |
| 1179 | while (! last_time); | 1135 | while (! last_time); |
| 1180 | 1136 | ||
| 1137 | eassert (handlerlist == catch); | ||
| 1138 | |||
| 1181 | byte_stack_list = catch->byte_stack; | 1139 | byte_stack_list = catch->byte_stack; |
| 1182 | gcprolist = catch->gcpro; | ||
| 1183 | #ifdef DEBUG_GCPRO | ||
| 1184 | gcpro_level = gcprolist ? gcprolist->level + 1 : 0; | ||
| 1185 | #endif | ||
| 1186 | lisp_eval_depth = catch->f_lisp_eval_depth; | 1140 | lisp_eval_depth = catch->f_lisp_eval_depth; |
| 1187 | 1141 | ||
| 1188 | sys_longjmp (catch->jmp, 1); | 1142 | sys_longjmp (catch->jmp, 1); |
| @@ -1190,15 +1144,16 @@ unwind_to_catch (struct catchtag *catch, Lisp_Object value) | |||
| 1190 | 1144 | ||
| 1191 | DEFUN ("throw", Fthrow, Sthrow, 2, 2, 0, | 1145 | DEFUN ("throw", Fthrow, Sthrow, 2, 2, 0, |
| 1192 | doc: /* Throw to the catch for TAG and return VALUE from it. | 1146 | doc: /* Throw to the catch for TAG and return VALUE from it. |
| 1193 | Both TAG and VALUE are evalled. */) | 1147 | Both TAG and VALUE are evalled. */ |
| 1148 | attributes: noreturn) | ||
| 1194 | (register Lisp_Object tag, Lisp_Object value) | 1149 | (register Lisp_Object tag, Lisp_Object value) |
| 1195 | { | 1150 | { |
| 1196 | register struct catchtag *c; | 1151 | struct handler *c; |
| 1197 | 1152 | ||
| 1198 | if (!NILP (tag)) | 1153 | if (!NILP (tag)) |
| 1199 | for (c = catchlist; c; c = c->next) | 1154 | for (c = handlerlist; c; c = c->next) |
| 1200 | { | 1155 | { |
| 1201 | if (EQ (c->tag, tag)) | 1156 | if (c->type == CATCHER && EQ (c->tag_or_ch, tag)) |
| 1202 | unwind_to_catch (c, value); | 1157 | unwind_to_catch (c, value); |
| 1203 | } | 1158 | } |
| 1204 | xsignal2 (Qno_catch, tag, value); | 1159 | xsignal2 (Qno_catch, tag, value); |
| @@ -1241,7 +1196,7 @@ suppresses the debugger). | |||
| 1241 | When a handler handles an error, control returns to the `condition-case' | 1196 | When a handler handles an error, control returns to the `condition-case' |
| 1242 | and it executes the handler's BODY... | 1197 | and it executes the handler's BODY... |
| 1243 | with VAR bound to (ERROR-SYMBOL . SIGNAL-DATA) from the error. | 1198 | with VAR bound to (ERROR-SYMBOL . SIGNAL-DATA) from the error. |
| 1244 | \(If VAR is nil, the handler can't access that information.) | 1199 | (If VAR is nil, the handler can't access that information.) |
| 1245 | Then the value of the last BODY form is returned from the `condition-case' | 1200 | Then the value of the last BODY form is returned from the `condition-case' |
| 1246 | expression. | 1201 | expression. |
| 1247 | 1202 | ||
| @@ -1264,15 +1219,16 @@ internal_lisp_condition_case (volatile Lisp_Object var, Lisp_Object bodyform, | |||
| 1264 | Lisp_Object handlers) | 1219 | Lisp_Object handlers) |
| 1265 | { | 1220 | { |
| 1266 | Lisp_Object val; | 1221 | Lisp_Object val; |
| 1267 | struct catchtag c; | 1222 | struct handler *c; |
| 1268 | struct handler h; | 1223 | struct handler *oldhandlerlist = handlerlist; |
| 1224 | int clausenb = 0; | ||
| 1269 | 1225 | ||
| 1270 | CHECK_SYMBOL (var); | 1226 | CHECK_SYMBOL (var); |
| 1271 | 1227 | ||
| 1272 | for (val = handlers; CONSP (val); val = XCDR (val)) | 1228 | for (val = handlers; CONSP (val); val = XCDR (val)) |
| 1273 | { | 1229 | { |
| 1274 | Lisp_Object tem; | 1230 | Lisp_Object tem = XCAR (val); |
| 1275 | tem = XCAR (val); | 1231 | clausenb++; |
| 1276 | if (! (NILP (tem) | 1232 | if (! (NILP (tem) |
| 1277 | || (CONSP (tem) | 1233 | || (CONSP (tem) |
| 1278 | && (SYMBOLP (XCAR (tem)) | 1234 | && (SYMBOLP (XCAR (tem)) |
| @@ -1281,39 +1237,54 @@ internal_lisp_condition_case (volatile Lisp_Object var, Lisp_Object bodyform, | |||
| 1281 | SDATA (Fprin1_to_string (tem, Qt))); | 1237 | SDATA (Fprin1_to_string (tem, Qt))); |
| 1282 | } | 1238 | } |
| 1283 | 1239 | ||
| 1284 | c.tag = Qnil; | 1240 | { /* The first clause is the one that should be checked first, so it should |
| 1285 | c.val = Qnil; | 1241 | be added to handlerlist last. So we build in `clauses' a table that |
| 1286 | c.f_handlerlist = handlerlist; | 1242 | contains `handlers' but in reverse order. SAFE_ALLOCA won't work |
| 1287 | c.f_lisp_eval_depth = lisp_eval_depth; | 1243 | here due to the setjmp, so impose a MAX_ALLOCA limit. */ |
| 1288 | c.pdlcount = SPECPDL_INDEX (); | 1244 | if (MAX_ALLOCA / word_size < clausenb) |
| 1289 | c.poll_suppress_count = poll_suppress_count; | 1245 | memory_full (SIZE_MAX); |
| 1290 | c.interrupt_input_blocked = interrupt_input_blocked; | 1246 | Lisp_Object *clauses = alloca (clausenb * sizeof *clauses); |
| 1291 | c.gcpro = gcprolist; | 1247 | Lisp_Object *volatile clauses_volatile = clauses; |
| 1292 | c.byte_stack = byte_stack_list; | 1248 | int i = clausenb; |
| 1293 | if (sys_setjmp (c.jmp)) | 1249 | for (val = handlers; CONSP (val); val = XCDR (val)) |
| 1294 | { | 1250 | clauses[--i] = XCAR (val); |
| 1295 | if (!NILP (h.var)) | 1251 | for (i = 0; i < clausenb; i++) |
| 1296 | specbind (h.var, c.val); | 1252 | { |
| 1297 | val = Fprogn (Fcdr (h.chosen_clause)); | 1253 | Lisp_Object clause = clauses[i]; |
| 1298 | 1254 | Lisp_Object condition = XCAR (clause); | |
| 1299 | /* Note that this just undoes the binding of h.var; whoever | 1255 | if (!CONSP (condition)) |
| 1300 | longjumped to us unwound the stack to c.pdlcount before | 1256 | condition = Fcons (condition, Qnil); |
| 1301 | throwing. */ | 1257 | PUSH_HANDLER (c, condition, CONDITION_CASE); |
| 1302 | unbind_to (c.pdlcount, Qnil); | 1258 | if (sys_setjmp (c->jmp)) |
| 1303 | return val; | 1259 | { |
| 1304 | } | 1260 | ptrdiff_t count = SPECPDL_INDEX (); |
| 1305 | c.next = catchlist; | 1261 | Lisp_Object val = handlerlist->val; |
| 1306 | catchlist = &c; | 1262 | Lisp_Object *chosen_clause = clauses_volatile; |
| 1307 | 1263 | for (c = handlerlist->next; c != oldhandlerlist; c = c->next) | |
| 1308 | h.var = var; | 1264 | chosen_clause++; |
| 1309 | h.handler = handlers; | 1265 | handlerlist = oldhandlerlist; |
| 1310 | h.next = handlerlist; | 1266 | if (!NILP (var)) |
| 1311 | h.tag = &c; | 1267 | { |
| 1312 | handlerlist = &h; | 1268 | if (!NILP (Vinternal_interpreter_environment)) |
| 1269 | specbind (Qinternal_interpreter_environment, | ||
| 1270 | Fcons (Fcons (var, val), | ||
| 1271 | Vinternal_interpreter_environment)); | ||
| 1272 | else | ||
| 1273 | specbind (var, val); | ||
| 1274 | } | ||
| 1275 | val = Fprogn (XCDR (*chosen_clause)); | ||
| 1276 | /* Note that this just undoes the binding of var; whoever | ||
| 1277 | longjumped to us unwound the stack to c.pdlcount before | ||
| 1278 | throwing. */ | ||
| 1279 | if (!NILP (var)) | ||
| 1280 | unbind_to (count, Qnil); | ||
| 1281 | return val; | ||
| 1282 | } | ||
| 1283 | } | ||
| 1284 | } | ||
| 1313 | 1285 | ||
| 1314 | val = eval_sub (bodyform); | 1286 | val = eval_sub (bodyform); |
| 1315 | catchlist = c.next; | 1287 | handlerlist = oldhandlerlist; |
| 1316 | handlerlist = h.next; | ||
| 1317 | return val; | 1288 | return val; |
| 1318 | } | 1289 | } |
| 1319 | 1290 | ||
| @@ -1332,33 +1303,20 @@ internal_condition_case (Lisp_Object (*bfun) (void), Lisp_Object handlers, | |||
| 1332 | Lisp_Object (*hfun) (Lisp_Object)) | 1303 | Lisp_Object (*hfun) (Lisp_Object)) |
| 1333 | { | 1304 | { |
| 1334 | Lisp_Object val; | 1305 | Lisp_Object val; |
| 1335 | struct catchtag c; | 1306 | struct handler *c; |
| 1336 | struct handler h; | 1307 | |
| 1337 | 1308 | PUSH_HANDLER (c, handlers, CONDITION_CASE); | |
| 1338 | c.tag = Qnil; | 1309 | if (sys_setjmp (c->jmp)) |
| 1339 | c.val = Qnil; | 1310 | { |
| 1340 | c.f_handlerlist = handlerlist; | 1311 | Lisp_Object val = handlerlist->val; |
| 1341 | c.f_lisp_eval_depth = lisp_eval_depth; | 1312 | clobbered_eassert (handlerlist == c); |
| 1342 | c.pdlcount = SPECPDL_INDEX (); | 1313 | handlerlist = handlerlist->next; |
| 1343 | c.poll_suppress_count = poll_suppress_count; | 1314 | return (*hfun) (val); |
| 1344 | c.interrupt_input_blocked = interrupt_input_blocked; | 1315 | } |
| 1345 | c.gcpro = gcprolist; | ||
| 1346 | c.byte_stack = byte_stack_list; | ||
| 1347 | if (sys_setjmp (c.jmp)) | ||
| 1348 | { | ||
| 1349 | return (*hfun) (c.val); | ||
| 1350 | } | ||
| 1351 | c.next = catchlist; | ||
| 1352 | catchlist = &c; | ||
| 1353 | h.handler = handlers; | ||
| 1354 | h.var = Qnil; | ||
| 1355 | h.next = handlerlist; | ||
| 1356 | h.tag = &c; | ||
| 1357 | handlerlist = &h; | ||
| 1358 | 1316 | ||
| 1359 | val = (*bfun) (); | 1317 | val = (*bfun) (); |
| 1360 | catchlist = c.next; | 1318 | clobbered_eassert (handlerlist == c); |
| 1361 | handlerlist = h.next; | 1319 | handlerlist = handlerlist->next; |
| 1362 | return val; | 1320 | return val; |
| 1363 | } | 1321 | } |
| 1364 | 1322 | ||
| @@ -1369,33 +1327,20 @@ internal_condition_case_1 (Lisp_Object (*bfun) (Lisp_Object), Lisp_Object arg, | |||
| 1369 | Lisp_Object handlers, Lisp_Object (*hfun) (Lisp_Object)) | 1327 | Lisp_Object handlers, Lisp_Object (*hfun) (Lisp_Object)) |
| 1370 | { | 1328 | { |
| 1371 | Lisp_Object val; | 1329 | Lisp_Object val; |
| 1372 | struct catchtag c; | 1330 | struct handler *c; |
| 1373 | struct handler h; | 1331 | |
| 1374 | 1332 | PUSH_HANDLER (c, handlers, CONDITION_CASE); | |
| 1375 | c.tag = Qnil; | 1333 | if (sys_setjmp (c->jmp)) |
| 1376 | c.val = Qnil; | 1334 | { |
| 1377 | c.f_handlerlist = handlerlist; | 1335 | Lisp_Object val = handlerlist->val; |
| 1378 | c.f_lisp_eval_depth = lisp_eval_depth; | 1336 | clobbered_eassert (handlerlist == c); |
| 1379 | c.pdlcount = SPECPDL_INDEX (); | 1337 | handlerlist = handlerlist->next; |
| 1380 | c.poll_suppress_count = poll_suppress_count; | 1338 | return (*hfun) (val); |
| 1381 | c.interrupt_input_blocked = interrupt_input_blocked; | 1339 | } |
| 1382 | c.gcpro = gcprolist; | ||
| 1383 | c.byte_stack = byte_stack_list; | ||
| 1384 | if (sys_setjmp (c.jmp)) | ||
| 1385 | { | ||
| 1386 | return (*hfun) (c.val); | ||
| 1387 | } | ||
| 1388 | c.next = catchlist; | ||
| 1389 | catchlist = &c; | ||
| 1390 | h.handler = handlers; | ||
| 1391 | h.var = Qnil; | ||
| 1392 | h.next = handlerlist; | ||
| 1393 | h.tag = &c; | ||
| 1394 | handlerlist = &h; | ||
| 1395 | 1340 | ||
| 1396 | val = (*bfun) (arg); | 1341 | val = (*bfun) (arg); |
| 1397 | catchlist = c.next; | 1342 | clobbered_eassert (handlerlist == c); |
| 1398 | handlerlist = h.next; | 1343 | handlerlist = handlerlist->next; |
| 1399 | return val; | 1344 | return val; |
| 1400 | } | 1345 | } |
| 1401 | 1346 | ||
| @@ -1410,33 +1355,20 @@ internal_condition_case_2 (Lisp_Object (*bfun) (Lisp_Object, Lisp_Object), | |||
| 1410 | Lisp_Object (*hfun) (Lisp_Object)) | 1355 | Lisp_Object (*hfun) (Lisp_Object)) |
| 1411 | { | 1356 | { |
| 1412 | Lisp_Object val; | 1357 | Lisp_Object val; |
| 1413 | struct catchtag c; | 1358 | struct handler *c; |
| 1414 | struct handler h; | 1359 | |
| 1415 | 1360 | PUSH_HANDLER (c, handlers, CONDITION_CASE); | |
| 1416 | c.tag = Qnil; | 1361 | if (sys_setjmp (c->jmp)) |
| 1417 | c.val = Qnil; | 1362 | { |
| 1418 | c.f_handlerlist = handlerlist; | 1363 | Lisp_Object val = handlerlist->val; |
| 1419 | c.f_lisp_eval_depth = lisp_eval_depth; | 1364 | clobbered_eassert (handlerlist == c); |
| 1420 | c.pdlcount = SPECPDL_INDEX (); | 1365 | handlerlist = handlerlist->next; |
| 1421 | c.poll_suppress_count = poll_suppress_count; | 1366 | return (*hfun) (val); |
| 1422 | c.interrupt_input_blocked = interrupt_input_blocked; | 1367 | } |
| 1423 | c.gcpro = gcprolist; | ||
| 1424 | c.byte_stack = byte_stack_list; | ||
| 1425 | if (sys_setjmp (c.jmp)) | ||
| 1426 | { | ||
| 1427 | return (*hfun) (c.val); | ||
| 1428 | } | ||
| 1429 | c.next = catchlist; | ||
| 1430 | catchlist = &c; | ||
| 1431 | h.handler = handlers; | ||
| 1432 | h.var = Qnil; | ||
| 1433 | h.next = handlerlist; | ||
| 1434 | h.tag = &c; | ||
| 1435 | handlerlist = &h; | ||
| 1436 | 1368 | ||
| 1437 | val = (*bfun) (arg1, arg2); | 1369 | val = (*bfun) (arg1, arg2); |
| 1438 | catchlist = c.next; | 1370 | clobbered_eassert (handlerlist == c); |
| 1439 | handlerlist = h.next; | 1371 | handlerlist = handlerlist->next; |
| 1440 | return val; | 1372 | return val; |
| 1441 | } | 1373 | } |
| 1442 | 1374 | ||
| @@ -1453,33 +1385,20 @@ internal_condition_case_n (Lisp_Object (*bfun) (ptrdiff_t, Lisp_Object *), | |||
| 1453 | Lisp_Object *args)) | 1385 | Lisp_Object *args)) |
| 1454 | { | 1386 | { |
| 1455 | Lisp_Object val; | 1387 | Lisp_Object val; |
| 1456 | struct catchtag c; | 1388 | struct handler *c; |
| 1457 | struct handler h; | 1389 | |
| 1458 | 1390 | PUSH_HANDLER (c, handlers, CONDITION_CASE); | |
| 1459 | c.tag = Qnil; | 1391 | if (sys_setjmp (c->jmp)) |
| 1460 | c.val = Qnil; | 1392 | { |
| 1461 | c.f_handlerlist = handlerlist; | 1393 | Lisp_Object val = handlerlist->val; |
| 1462 | c.f_lisp_eval_depth = lisp_eval_depth; | 1394 | clobbered_eassert (handlerlist == c); |
| 1463 | c.pdlcount = SPECPDL_INDEX (); | 1395 | handlerlist = handlerlist->next; |
| 1464 | c.poll_suppress_count = poll_suppress_count; | 1396 | return (*hfun) (val, nargs, args); |
| 1465 | c.interrupt_input_blocked = interrupt_input_blocked; | 1397 | } |
| 1466 | c.gcpro = gcprolist; | ||
| 1467 | c.byte_stack = byte_stack_list; | ||
| 1468 | if (sys_setjmp (c.jmp)) | ||
| 1469 | { | ||
| 1470 | return (*hfun) (c.val, nargs, args); | ||
| 1471 | } | ||
| 1472 | c.next = catchlist; | ||
| 1473 | catchlist = &c; | ||
| 1474 | h.handler = handlers; | ||
| 1475 | h.var = Qnil; | ||
| 1476 | h.next = handlerlist; | ||
| 1477 | h.tag = &c; | ||
| 1478 | handlerlist = &h; | ||
| 1479 | 1398 | ||
| 1480 | val = (*bfun) (nargs, args); | 1399 | val = (*bfun) (nargs, args); |
| 1481 | catchlist = c.next; | 1400 | clobbered_eassert (handlerlist == c); |
| 1482 | handlerlist = h.next; | 1401 | handlerlist = handlerlist->next; |
| 1483 | return val; | 1402 | return val; |
| 1484 | } | 1403 | } |
| 1485 | 1404 | ||
| @@ -1571,7 +1490,9 @@ See also the function `condition-case'. */) | |||
| 1571 | 1490 | ||
| 1572 | for (h = handlerlist; h; h = h->next) | 1491 | for (h = handlerlist; h; h = h->next) |
| 1573 | { | 1492 | { |
| 1574 | clause = find_handler_clause (h->handler, conditions); | 1493 | if (h->type != CONDITION_CASE) |
| 1494 | continue; | ||
| 1495 | clause = find_handler_clause (h->tag_or_ch, conditions); | ||
| 1575 | if (!NILP (clause)) | 1496 | if (!NILP (clause)) |
| 1576 | break; | 1497 | break; |
| 1577 | } | 1498 | } |
| @@ -1584,11 +1505,10 @@ See also the function `condition-case'. */) | |||
| 1584 | || NILP (clause) | 1505 | || NILP (clause) |
| 1585 | /* A `debug' symbol in the handler list disables the normal | 1506 | /* A `debug' symbol in the handler list disables the normal |
| 1586 | suppression of the debugger. */ | 1507 | suppression of the debugger. */ |
| 1587 | || (CONSP (clause) && CONSP (XCAR (clause)) | 1508 | || (CONSP (clause) && !NILP (Fmemq (Qdebug, clause))) |
| 1588 | && !NILP (Fmemq (Qdebug, XCAR (clause)))) | ||
| 1589 | /* Special handler that means "print a message and run debugger | 1509 | /* Special handler that means "print a message and run debugger |
| 1590 | if requested". */ | 1510 | if requested". */ |
| 1591 | || EQ (h->handler, Qerror))) | 1511 | || EQ (h->tag_or_ch, Qerror))) |
| 1592 | { | 1512 | { |
| 1593 | bool debugger_called | 1513 | bool debugger_called |
| 1594 | = maybe_call_debugger (conditions, error_symbol, data); | 1514 | = maybe_call_debugger (conditions, error_symbol, data); |
| @@ -1603,12 +1523,14 @@ See also the function `condition-case'. */) | |||
| 1603 | Lisp_Object unwind_data | 1523 | Lisp_Object unwind_data |
| 1604 | = (NILP (error_symbol) ? data : Fcons (error_symbol, data)); | 1524 | = (NILP (error_symbol) ? data : Fcons (error_symbol, data)); |
| 1605 | 1525 | ||
| 1606 | h->chosen_clause = clause; | 1526 | unwind_to_catch (h, unwind_data); |
| 1607 | unwind_to_catch (h->tag, unwind_data); | ||
| 1608 | } | 1527 | } |
| 1609 | else | 1528 | else |
| 1610 | { | 1529 | { |
| 1611 | if (catchlist != 0) | 1530 | if (handlerlist != handlerlist_sentinel) |
| 1531 | /* FIXME: This will come right back here if there's no `top-level' | ||
| 1532 | catcher. A better solution would be to abort here, and instead | ||
| 1533 | add a catch-all condition handler so we never come here. */ | ||
| 1612 | Fthrow (Qtop_level, Qt); | 1534 | Fthrow (Qtop_level, Qt); |
| 1613 | } | 1535 | } |
| 1614 | 1536 | ||
| @@ -1794,29 +1716,8 @@ find_handler_clause (Lisp_Object handlers, Lisp_Object conditions) | |||
| 1794 | for (h = handlers; CONSP (h); h = XCDR (h)) | 1716 | for (h = handlers; CONSP (h); h = XCDR (h)) |
| 1795 | { | 1717 | { |
| 1796 | Lisp_Object handler = XCAR (h); | 1718 | Lisp_Object handler = XCAR (h); |
| 1797 | Lisp_Object condit, tem; | 1719 | if (!NILP (Fmemq (handler, conditions))) |
| 1798 | 1720 | return handlers; | |
| 1799 | if (!CONSP (handler)) | ||
| 1800 | continue; | ||
| 1801 | condit = XCAR (handler); | ||
| 1802 | /* Handle a single condition name in handler HANDLER. */ | ||
| 1803 | if (SYMBOLP (condit)) | ||
| 1804 | { | ||
| 1805 | tem = Fmemq (Fcar (handler), conditions); | ||
| 1806 | if (!NILP (tem)) | ||
| 1807 | return handler; | ||
| 1808 | } | ||
| 1809 | /* Handle a list of condition names in handler HANDLER. */ | ||
| 1810 | else if (CONSP (condit)) | ||
| 1811 | { | ||
| 1812 | Lisp_Object tail; | ||
| 1813 | for (tail = condit; CONSP (tail); tail = XCDR (tail)) | ||
| 1814 | { | ||
| 1815 | tem = Fmemq (XCAR (tail), conditions); | ||
| 1816 | if (!NILP (tem)) | ||
| 1817 | return handler; | ||
| 1818 | } | ||
| 1819 | } | ||
| 1820 | } | 1721 | } |
| 1821 | 1722 | ||
| 1822 | return Qnil; | 1723 | return Qnil; |
| @@ -1988,11 +1889,10 @@ DEFUN ("autoload-do-load", Fautoload_do_load, Sautoload_do_load, 1, 3, 0, | |||
| 1988 | If non-nil, FUNNAME should be the symbol whose function value is FUNDEF, | 1889 | If non-nil, FUNNAME should be the symbol whose function value is FUNDEF, |
| 1989 | in which case the function returns the new autoloaded function value. | 1890 | in which case the function returns the new autoloaded function value. |
| 1990 | If equal to `macro', MACRO-ONLY specifies that FUNDEF should only be loaded if | 1891 | If equal to `macro', MACRO-ONLY specifies that FUNDEF should only be loaded if |
| 1991 | it is defines a macro. */) | 1892 | it defines a macro. */) |
| 1992 | (Lisp_Object fundef, Lisp_Object funname, Lisp_Object macro_only) | 1893 | (Lisp_Object fundef, Lisp_Object funname, Lisp_Object macro_only) |
| 1993 | { | 1894 | { |
| 1994 | ptrdiff_t count = SPECPDL_INDEX (); | 1895 | ptrdiff_t count = SPECPDL_INDEX (); |
| 1995 | struct gcpro gcpro1, gcpro2, gcpro3; | ||
| 1996 | 1896 | ||
| 1997 | if (!CONSP (fundef) || !EQ (Qautoload, XCAR (fundef))) | 1897 | if (!CONSP (fundef) || !EQ (Qautoload, XCAR (fundef))) |
| 1998 | return fundef; | 1898 | return fundef; |
| @@ -2011,7 +1911,6 @@ it is defines a macro. */) | |||
| 2011 | SDATA (SYMBOL_NAME (funname))); | 1911 | SDATA (SYMBOL_NAME (funname))); |
| 2012 | 1912 | ||
| 2013 | CHECK_SYMBOL (funname); | 1913 | CHECK_SYMBOL (funname); |
| 2014 | GCPRO3 (funname, fundef, macro_only); | ||
| 2015 | 1914 | ||
| 2016 | /* Preserve the match data. */ | 1915 | /* Preserve the match data. */ |
| 2017 | record_unwind_save_match_data (); | 1916 | record_unwind_save_match_data (); |
| @@ -2034,8 +1933,6 @@ it is defines a macro. */) | |||
| 2034 | Vautoload_queue = Qt; | 1933 | Vautoload_queue = Qt; |
| 2035 | unbind_to (count, Qnil); | 1934 | unbind_to (count, Qnil); |
| 2036 | 1935 | ||
| 2037 | UNGCPRO; | ||
| 2038 | |||
| 2039 | if (NILP (funname)) | 1936 | if (NILP (funname)) |
| 2040 | return Qnil; | 1937 | return Qnil; |
| 2041 | else | 1938 | else |
| @@ -2053,7 +1950,9 @@ it is defines a macro. */) | |||
| 2053 | 1950 | ||
| 2054 | DEFUN ("eval", Feval, Seval, 1, 2, 0, | 1951 | DEFUN ("eval", Feval, Seval, 1, 2, 0, |
| 2055 | doc: /* Evaluate FORM and return its value. | 1952 | doc: /* Evaluate FORM and return its value. |
| 2056 | If LEXICAL is t, evaluate using lexical scoping. */) | 1953 | If LEXICAL is t, evaluate using lexical scoping. |
| 1954 | LEXICAL can also be an actual lexical environment, in the form of an | ||
| 1955 | alist mapping symbols to their value. */) | ||
| 2057 | (Lisp_Object form, Lisp_Object lexical) | 1956 | (Lisp_Object form, Lisp_Object lexical) |
| 2058 | { | 1957 | { |
| 2059 | ptrdiff_t count = SPECPDL_INDEX (); | 1958 | ptrdiff_t count = SPECPDL_INDEX (); |
| @@ -2098,9 +1997,11 @@ grow_specpdl (void) | |||
| 2098 | } | 1997 | } |
| 2099 | } | 1998 | } |
| 2100 | 1999 | ||
| 2101 | void | 2000 | ptrdiff_t |
| 2102 | record_in_backtrace (Lisp_Object function, Lisp_Object *args, ptrdiff_t nargs) | 2001 | record_in_backtrace (Lisp_Object function, Lisp_Object *args, ptrdiff_t nargs) |
| 2103 | { | 2002 | { |
| 2003 | ptrdiff_t count = SPECPDL_INDEX (); | ||
| 2004 | |||
| 2104 | eassert (nargs >= UNEVALLED); | 2005 | eassert (nargs >= UNEVALLED); |
| 2105 | specpdl_ptr->bt.kind = SPECPDL_BACKTRACE; | 2006 | specpdl_ptr->bt.kind = SPECPDL_BACKTRACE; |
| 2106 | specpdl_ptr->bt.debug_on_exit = false; | 2007 | specpdl_ptr->bt.debug_on_exit = false; |
| @@ -2108,6 +2009,8 @@ record_in_backtrace (Lisp_Object function, Lisp_Object *args, ptrdiff_t nargs) | |||
| 2108 | specpdl_ptr->bt.args = args; | 2009 | specpdl_ptr->bt.args = args; |
| 2109 | specpdl_ptr->bt.nargs = nargs; | 2010 | specpdl_ptr->bt.nargs = nargs; |
| 2110 | grow_specpdl (); | 2011 | grow_specpdl (); |
| 2012 | |||
| 2013 | return count; | ||
| 2111 | } | 2014 | } |
| 2112 | 2015 | ||
| 2113 | /* Eval a sub-expression of the current expression (i.e. in the same | 2016 | /* Eval a sub-expression of the current expression (i.e. in the same |
| @@ -2117,7 +2020,7 @@ eval_sub (Lisp_Object form) | |||
| 2117 | { | 2020 | { |
| 2118 | Lisp_Object fun, val, original_fun, original_args; | 2021 | Lisp_Object fun, val, original_fun, original_args; |
| 2119 | Lisp_Object funcar; | 2022 | Lisp_Object funcar; |
| 2120 | struct gcpro gcpro1, gcpro2, gcpro3; | 2023 | ptrdiff_t count; |
| 2121 | 2024 | ||
| 2122 | if (SYMBOLP (form)) | 2025 | if (SYMBOLP (form)) |
| 2123 | { | 2026 | { |
| @@ -2139,9 +2042,7 @@ eval_sub (Lisp_Object form) | |||
| 2139 | 2042 | ||
| 2140 | QUIT; | 2043 | QUIT; |
| 2141 | 2044 | ||
| 2142 | GCPRO1 (form); | ||
| 2143 | maybe_gc (); | 2045 | maybe_gc (); |
| 2144 | UNGCPRO; | ||
| 2145 | 2046 | ||
| 2146 | if (++lisp_eval_depth > max_lisp_eval_depth) | 2047 | if (++lisp_eval_depth > max_lisp_eval_depth) |
| 2147 | { | 2048 | { |
| @@ -2155,10 +2056,10 @@ eval_sub (Lisp_Object form) | |||
| 2155 | original_args = XCDR (form); | 2056 | original_args = XCDR (form); |
| 2156 | 2057 | ||
| 2157 | /* This also protects them from gc. */ | 2058 | /* This also protects them from gc. */ |
| 2158 | record_in_backtrace (original_fun, &original_args, UNEVALLED); | 2059 | count = record_in_backtrace (original_fun, &original_args, UNEVALLED); |
| 2159 | 2060 | ||
| 2160 | if (debug_on_next_call) | 2061 | if (debug_on_next_call) |
| 2161 | do_debug_on_call (Qt); | 2062 | do_debug_on_call (Qt, count); |
| 2162 | 2063 | ||
| 2163 | /* At this point, only original_fun and original_args | 2064 | /* At this point, only original_fun and original_args |
| 2164 | have values that will be used below. */ | 2065 | have values that will be used below. */ |
| @@ -2166,8 +2067,9 @@ eval_sub (Lisp_Object form) | |||
| 2166 | 2067 | ||
| 2167 | /* Optimize for no indirection. */ | 2068 | /* Optimize for no indirection. */ |
| 2168 | fun = original_fun; | 2069 | fun = original_fun; |
| 2169 | if (SYMBOLP (fun) && !NILP (fun) | 2070 | if (!SYMBOLP (fun)) |
| 2170 | && (fun = XSYMBOL (fun)->function, SYMBOLP (fun))) | 2071 | fun = Ffunction (Fcons (fun, Qnil)); |
| 2072 | else if (!NILP (fun) && (fun = XSYMBOL (fun)->function, SYMBOLP (fun))) | ||
| 2171 | fun = indirect_function (fun); | 2073 | fun = indirect_function (fun); |
| 2172 | 2074 | ||
| 2173 | if (SUBRP (fun)) | 2075 | if (SUBRP (fun)) |
| @@ -2198,41 +2100,27 @@ eval_sub (Lisp_Object form) | |||
| 2198 | 2100 | ||
| 2199 | SAFE_ALLOCA_LISP (vals, XINT (numargs)); | 2101 | SAFE_ALLOCA_LISP (vals, XINT (numargs)); |
| 2200 | 2102 | ||
| 2201 | GCPRO3 (args_left, fun, fun); | ||
| 2202 | gcpro3.var = vals; | ||
| 2203 | gcpro3.nvars = 0; | ||
| 2204 | |||
| 2205 | while (!NILP (args_left)) | 2103 | while (!NILP (args_left)) |
| 2206 | { | 2104 | { |
| 2207 | vals[argnum++] = eval_sub (Fcar (args_left)); | 2105 | vals[argnum++] = eval_sub (Fcar (args_left)); |
| 2208 | args_left = Fcdr (args_left); | 2106 | args_left = Fcdr (args_left); |
| 2209 | gcpro3.nvars = argnum; | ||
| 2210 | } | 2107 | } |
| 2211 | 2108 | ||
| 2212 | set_backtrace_args (specpdl_ptr - 1, vals); | 2109 | set_backtrace_args (specpdl + count, vals, XINT (numargs)); |
| 2213 | set_backtrace_nargs (specpdl_ptr - 1, XINT (numargs)); | ||
| 2214 | 2110 | ||
| 2215 | val = (XSUBR (fun)->function.aMANY) (XINT (numargs), vals); | 2111 | val = (XSUBR (fun)->function.aMANY) (XINT (numargs), vals); |
| 2216 | UNGCPRO; | ||
| 2217 | SAFE_FREE (); | 2112 | SAFE_FREE (); |
| 2218 | } | 2113 | } |
| 2219 | else | 2114 | else |
| 2220 | { | 2115 | { |
| 2221 | GCPRO3 (args_left, fun, fun); | ||
| 2222 | gcpro3.var = argvals; | ||
| 2223 | gcpro3.nvars = 0; | ||
| 2224 | |||
| 2225 | maxargs = XSUBR (fun)->max_args; | 2116 | maxargs = XSUBR (fun)->max_args; |
| 2226 | for (i = 0; i < maxargs; args_left = Fcdr (args_left)) | 2117 | for (i = 0; i < maxargs; i++) |
| 2227 | { | 2118 | { |
| 2228 | argvals[i] = eval_sub (Fcar (args_left)); | 2119 | argvals[i] = eval_sub (Fcar (args_left)); |
| 2229 | gcpro3.nvars = ++i; | 2120 | args_left = Fcdr (args_left); |
| 2230 | } | 2121 | } |
| 2231 | 2122 | ||
| 2232 | UNGCPRO; | 2123 | set_backtrace_args (specpdl + count, argvals, XINT (numargs)); |
| 2233 | |||
| 2234 | set_backtrace_args (specpdl_ptr - 1, argvals); | ||
| 2235 | set_backtrace_nargs (specpdl_ptr - 1, XINT (numargs)); | ||
| 2236 | 2124 | ||
| 2237 | switch (i) | 2125 | switch (i) |
| 2238 | { | 2126 | { |
| @@ -2285,7 +2173,7 @@ eval_sub (Lisp_Object form) | |||
| 2285 | } | 2173 | } |
| 2286 | } | 2174 | } |
| 2287 | else if (COMPILEDP (fun)) | 2175 | else if (COMPILEDP (fun)) |
| 2288 | val = apply_lambda (fun, original_args); | 2176 | val = apply_lambda (fun, original_args, count); |
| 2289 | else | 2177 | else |
| 2290 | { | 2178 | { |
| 2291 | if (NILP (fun)) | 2179 | if (NILP (fun)) |
| @@ -2302,7 +2190,7 @@ eval_sub (Lisp_Object form) | |||
| 2302 | } | 2190 | } |
| 2303 | if (EQ (funcar, Qmacro)) | 2191 | if (EQ (funcar, Qmacro)) |
| 2304 | { | 2192 | { |
| 2305 | ptrdiff_t count = SPECPDL_INDEX (); | 2193 | ptrdiff_t count1 = SPECPDL_INDEX (); |
| 2306 | Lisp_Object exp; | 2194 | Lisp_Object exp; |
| 2307 | /* Bind lexical-binding during expansion of the macro, so the | 2195 | /* Bind lexical-binding during expansion of the macro, so the |
| 2308 | macro can know reliably if the code it outputs will be | 2196 | macro can know reliably if the code it outputs will be |
| @@ -2310,19 +2198,19 @@ eval_sub (Lisp_Object form) | |||
| 2310 | specbind (Qlexical_binding, | 2198 | specbind (Qlexical_binding, |
| 2311 | NILP (Vinternal_interpreter_environment) ? Qnil : Qt); | 2199 | NILP (Vinternal_interpreter_environment) ? Qnil : Qt); |
| 2312 | exp = apply1 (Fcdr (fun), original_args); | 2200 | exp = apply1 (Fcdr (fun), original_args); |
| 2313 | unbind_to (count, Qnil); | 2201 | unbind_to (count1, Qnil); |
| 2314 | val = eval_sub (exp); | 2202 | val = eval_sub (exp); |
| 2315 | } | 2203 | } |
| 2316 | else if (EQ (funcar, Qlambda) | 2204 | else if (EQ (funcar, Qlambda) |
| 2317 | || EQ (funcar, Qclosure)) | 2205 | || EQ (funcar, Qclosure)) |
| 2318 | val = apply_lambda (fun, original_args); | 2206 | val = apply_lambda (fun, original_args, count); |
| 2319 | else | 2207 | else |
| 2320 | xsignal1 (Qinvalid_function, original_fun); | 2208 | xsignal1 (Qinvalid_function, original_fun); |
| 2321 | } | 2209 | } |
| 2322 | check_cons_list (); | 2210 | check_cons_list (); |
| 2323 | 2211 | ||
| 2324 | lisp_eval_depth--; | 2212 | lisp_eval_depth--; |
| 2325 | if (backtrace_debug_on_exit (specpdl_ptr - 1)) | 2213 | if (backtrace_debug_on_exit (specpdl + count)) |
| 2326 | val = call_debugger (list2 (Qexit, val)); | 2214 | val = call_debugger (list2 (Qexit, val)); |
| 2327 | specpdl_ptr--; | 2215 | specpdl_ptr--; |
| 2328 | 2216 | ||
| @@ -2332,21 +2220,17 @@ eval_sub (Lisp_Object form) | |||
| 2332 | DEFUN ("apply", Fapply, Sapply, 1, MANY, 0, | 2220 | DEFUN ("apply", Fapply, Sapply, 1, MANY, 0, |
| 2333 | doc: /* Call FUNCTION with our remaining args, using our last arg as list of args. | 2221 | doc: /* Call FUNCTION with our remaining args, using our last arg as list of args. |
| 2334 | Then return the value FUNCTION returns. | 2222 | Then return the value FUNCTION returns. |
| 2335 | Thus, (apply '+ 1 2 '(3 4)) returns 10. | 2223 | Thus, (apply \\='+ 1 2 \\='(3 4)) returns 10. |
| 2336 | usage: (apply FUNCTION &rest ARGUMENTS) */) | 2224 | usage: (apply FUNCTION &rest ARGUMENTS) */) |
| 2337 | (ptrdiff_t nargs, Lisp_Object *args) | 2225 | (ptrdiff_t nargs, Lisp_Object *args) |
| 2338 | { | 2226 | { |
| 2339 | ptrdiff_t i; | 2227 | ptrdiff_t i, numargs, funcall_nargs; |
| 2340 | EMACS_INT numargs; | 2228 | register Lisp_Object *funcall_args = NULL; |
| 2341 | register Lisp_Object spread_arg; | 2229 | register Lisp_Object spread_arg = args[nargs - 1]; |
| 2342 | register Lisp_Object *funcall_args; | 2230 | Lisp_Object fun = args[0]; |
| 2343 | Lisp_Object fun, retval; | 2231 | Lisp_Object retval; |
| 2344 | struct gcpro gcpro1; | ||
| 2345 | USE_SAFE_ALLOCA; | 2232 | USE_SAFE_ALLOCA; |
| 2346 | 2233 | ||
| 2347 | fun = args [0]; | ||
| 2348 | funcall_args = 0; | ||
| 2349 | spread_arg = args [nargs - 1]; | ||
| 2350 | CHECK_LIST (spread_arg); | 2234 | CHECK_LIST (spread_arg); |
| 2351 | 2235 | ||
| 2352 | numargs = XINT (Flength (spread_arg)); | 2236 | numargs = XINT (Flength (spread_arg)); |
| @@ -2364,38 +2248,29 @@ usage: (apply FUNCTION &rest ARGUMENTS) */) | |||
| 2364 | /* Optimize for no indirection. */ | 2248 | /* Optimize for no indirection. */ |
| 2365 | if (SYMBOLP (fun) && !NILP (fun) | 2249 | if (SYMBOLP (fun) && !NILP (fun) |
| 2366 | && (fun = XSYMBOL (fun)->function, SYMBOLP (fun))) | 2250 | && (fun = XSYMBOL (fun)->function, SYMBOLP (fun))) |
| 2367 | fun = indirect_function (fun); | ||
| 2368 | if (NILP (fun)) | ||
| 2369 | { | 2251 | { |
| 2370 | /* Let funcall get the error. */ | 2252 | fun = indirect_function (fun); |
| 2371 | fun = args[0]; | 2253 | if (NILP (fun)) |
| 2372 | goto funcall; | 2254 | /* Let funcall get the error. */ |
| 2255 | fun = args[0]; | ||
| 2373 | } | 2256 | } |
| 2374 | 2257 | ||
| 2375 | if (SUBRP (fun)) | 2258 | if (SUBRP (fun) && XSUBR (fun)->max_args > numargs |
| 2259 | /* Don't hide an error by adding missing arguments. */ | ||
| 2260 | && numargs >= XSUBR (fun)->min_args) | ||
| 2376 | { | 2261 | { |
| 2377 | if (numargs < XSUBR (fun)->min_args | 2262 | /* Avoid making funcall cons up a yet another new vector of arguments |
| 2378 | || (XSUBR (fun)->max_args >= 0 && XSUBR (fun)->max_args < numargs)) | 2263 | by explicitly supplying nil's for optional values. */ |
| 2379 | goto funcall; /* Let funcall get the error. */ | 2264 | SAFE_ALLOCA_LISP (funcall_args, 1 + XSUBR (fun)->max_args); |
| 2380 | else if (XSUBR (fun)->max_args >= 0 && XSUBR (fun)->max_args > numargs) | 2265 | memclear (funcall_args + numargs + 1, |
| 2381 | { | 2266 | (XSUBR (fun)->max_args - numargs) * word_size); |
| 2382 | /* Avoid making funcall cons up a yet another new vector of arguments | 2267 | funcall_nargs = 1 + XSUBR (fun)->max_args; |
| 2383 | by explicitly supplying nil's for optional values. */ | ||
| 2384 | SAFE_ALLOCA_LISP (funcall_args, 1 + XSUBR (fun)->max_args); | ||
| 2385 | for (i = numargs; i < XSUBR (fun)->max_args;) | ||
| 2386 | funcall_args[++i] = Qnil; | ||
| 2387 | GCPRO1 (*funcall_args); | ||
| 2388 | gcpro1.nvars = 1 + XSUBR (fun)->max_args; | ||
| 2389 | } | ||
| 2390 | } | 2268 | } |
| 2391 | funcall: | 2269 | else |
| 2392 | /* We add 1 to numargs because funcall_args includes the | 2270 | { /* We add 1 to numargs because funcall_args includes the |
| 2393 | function itself as well as its arguments. */ | 2271 | function itself as well as its arguments. */ |
| 2394 | if (!funcall_args) | ||
| 2395 | { | ||
| 2396 | SAFE_ALLOCA_LISP (funcall_args, 1 + numargs); | 2272 | SAFE_ALLOCA_LISP (funcall_args, 1 + numargs); |
| 2397 | GCPRO1 (*funcall_args); | 2273 | funcall_nargs = 1 + numargs; |
| 2398 | gcpro1.nvars = 1 + numargs; | ||
| 2399 | } | 2274 | } |
| 2400 | 2275 | ||
| 2401 | memcpy (funcall_args, args, nargs * word_size); | 2276 | memcpy (funcall_args, args, nargs * word_size); |
| @@ -2408,11 +2283,9 @@ usage: (apply FUNCTION &rest ARGUMENTS) */) | |||
| 2408 | spread_arg = XCDR (spread_arg); | 2283 | spread_arg = XCDR (spread_arg); |
| 2409 | } | 2284 | } |
| 2410 | 2285 | ||
| 2411 | /* By convention, the caller needs to gcpro Ffuncall's args. */ | 2286 | retval = Ffuncall (funcall_nargs, funcall_args); |
| 2412 | retval = Ffuncall (gcpro1.nvars, funcall_args); | ||
| 2413 | UNGCPRO; | ||
| 2414 | SAFE_FREE (); | ||
| 2415 | 2287 | ||
| 2288 | SAFE_FREE (); | ||
| 2416 | return retval; | 2289 | return retval; |
| 2417 | } | 2290 | } |
| 2418 | 2291 | ||
| @@ -2442,14 +2315,10 @@ Instead, use `add-hook' and specify t for the LOCAL argument. | |||
| 2442 | usage: (run-hooks &rest HOOKS) */) | 2315 | usage: (run-hooks &rest HOOKS) */) |
| 2443 | (ptrdiff_t nargs, Lisp_Object *args) | 2316 | (ptrdiff_t nargs, Lisp_Object *args) |
| 2444 | { | 2317 | { |
| 2445 | Lisp_Object hook[1]; | ||
| 2446 | ptrdiff_t i; | 2318 | ptrdiff_t i; |
| 2447 | 2319 | ||
| 2448 | for (i = 0; i < nargs; i++) | 2320 | for (i = 0; i < nargs; i++) |
| 2449 | { | 2321 | run_hook (args[i]); |
| 2450 | hook[0] = args[i]; | ||
| 2451 | run_hook_with_args (1, hook, funcall_nil); | ||
| 2452 | } | ||
| 2453 | 2322 | ||
| 2454 | return Qnil; | 2323 | return Qnil; |
| 2455 | } | 2324 | } |
| @@ -2505,7 +2374,7 @@ may be nil, a function, or a list of functions. Call each | |||
| 2505 | function in order with arguments ARGS, stopping at the first | 2374 | function in order with arguments ARGS, stopping at the first |
| 2506 | one that returns nil, and return nil. Otherwise (if all functions | 2375 | one that returns nil, and return nil. Otherwise (if all functions |
| 2507 | return non-nil, or if there are no functions to call), return non-nil | 2376 | return non-nil, or if there are no functions to call), return non-nil |
| 2508 | \(do not rely on the precise return value in this case). | 2377 | (do not rely on the precise return value in this case). |
| 2509 | 2378 | ||
| 2510 | Do not use `make-local-variable' to make a hook variable buffer-local. | 2379 | Do not use `make-local-variable' to make a hook variable buffer-local. |
| 2511 | Instead, use `add-hook' and specify t for the LOCAL argument. | 2380 | Instead, use `add-hook' and specify t for the LOCAL argument. |
| @@ -2542,16 +2411,13 @@ usage: (run-hook-wrapped HOOK WRAP-FUNCTION &rest ARGS) */) | |||
| 2542 | /* ARGS[0] should be a hook symbol. | 2411 | /* ARGS[0] should be a hook symbol. |
| 2543 | Call each of the functions in the hook value, passing each of them | 2412 | Call each of the functions in the hook value, passing each of them |
| 2544 | as arguments all the rest of ARGS (all NARGS - 1 elements). | 2413 | as arguments all the rest of ARGS (all NARGS - 1 elements). |
| 2545 | FUNCALL specifies how to call each function on the hook. | 2414 | FUNCALL specifies how to call each function on the hook. */ |
| 2546 | The caller (or its caller, etc) must gcpro all of ARGS, | ||
| 2547 | except that it isn't necessary to gcpro ARGS[0]. */ | ||
| 2548 | 2415 | ||
| 2549 | Lisp_Object | 2416 | Lisp_Object |
| 2550 | run_hook_with_args (ptrdiff_t nargs, Lisp_Object *args, | 2417 | run_hook_with_args (ptrdiff_t nargs, Lisp_Object *args, |
| 2551 | Lisp_Object (*funcall) (ptrdiff_t nargs, Lisp_Object *args)) | 2418 | Lisp_Object (*funcall) (ptrdiff_t nargs, Lisp_Object *args)) |
| 2552 | { | 2419 | { |
| 2553 | Lisp_Object sym, val, ret = Qnil; | 2420 | Lisp_Object sym, val, ret = Qnil; |
| 2554 | struct gcpro gcpro1, gcpro2, gcpro3; | ||
| 2555 | 2421 | ||
| 2556 | /* If we are dying or still initializing, | 2422 | /* If we are dying or still initializing, |
| 2557 | don't do anything--it would probably crash if we tried. */ | 2423 | don't do anything--it would probably crash if we tried. */ |
| @@ -2563,7 +2429,7 @@ run_hook_with_args (ptrdiff_t nargs, Lisp_Object *args, | |||
| 2563 | 2429 | ||
| 2564 | if (EQ (val, Qunbound) || NILP (val)) | 2430 | if (EQ (val, Qunbound) || NILP (val)) |
| 2565 | return ret; | 2431 | return ret; |
| 2566 | else if (!CONSP (val) || EQ (XCAR (val), Qlambda)) | 2432 | else if (!CONSP (val) || FUNCTIONP (val)) |
| 2567 | { | 2433 | { |
| 2568 | args[0] = val; | 2434 | args[0] = val; |
| 2569 | return funcall (nargs, args); | 2435 | return funcall (nargs, args); |
| @@ -2571,7 +2437,6 @@ run_hook_with_args (ptrdiff_t nargs, Lisp_Object *args, | |||
| 2571 | else | 2437 | else |
| 2572 | { | 2438 | { |
| 2573 | Lisp_Object global_vals = Qnil; | 2439 | Lisp_Object global_vals = Qnil; |
| 2574 | GCPRO3 (sym, val, global_vals); | ||
| 2575 | 2440 | ||
| 2576 | for (; | 2441 | for (; |
| 2577 | CONSP (val) && NILP (ret); | 2442 | CONSP (val) && NILP (ret); |
| @@ -2610,51 +2475,38 @@ run_hook_with_args (ptrdiff_t nargs, Lisp_Object *args, | |||
| 2610 | } | 2475 | } |
| 2611 | } | 2476 | } |
| 2612 | 2477 | ||
| 2613 | UNGCPRO; | ||
| 2614 | return ret; | 2478 | return ret; |
| 2615 | } | 2479 | } |
| 2616 | } | 2480 | } |
| 2617 | 2481 | ||
| 2482 | /* Run the hook HOOK, giving each function no args. */ | ||
| 2483 | |||
| 2484 | void | ||
| 2485 | run_hook (Lisp_Object hook) | ||
| 2486 | { | ||
| 2487 | Frun_hook_with_args (1, &hook); | ||
| 2488 | } | ||
| 2489 | |||
| 2618 | /* Run the hook HOOK, giving each function the two args ARG1 and ARG2. */ | 2490 | /* Run the hook HOOK, giving each function the two args ARG1 and ARG2. */ |
| 2619 | 2491 | ||
| 2620 | void | 2492 | void |
| 2621 | run_hook_with_args_2 (Lisp_Object hook, Lisp_Object arg1, Lisp_Object arg2) | 2493 | run_hook_with_args_2 (Lisp_Object hook, Lisp_Object arg1, Lisp_Object arg2) |
| 2622 | { | 2494 | { |
| 2623 | Lisp_Object temp[3]; | 2495 | CALLN (Frun_hook_with_args, hook, arg1, arg2); |
| 2624 | temp[0] = hook; | ||
| 2625 | temp[1] = arg1; | ||
| 2626 | temp[2] = arg2; | ||
| 2627 | |||
| 2628 | Frun_hook_with_args (3, temp); | ||
| 2629 | } | 2496 | } |
| 2630 | 2497 | ||
| 2631 | /* Apply fn to arg. */ | 2498 | /* Apply fn to arg. */ |
| 2632 | Lisp_Object | 2499 | Lisp_Object |
| 2633 | apply1 (Lisp_Object fn, Lisp_Object arg) | 2500 | apply1 (Lisp_Object fn, Lisp_Object arg) |
| 2634 | { | 2501 | { |
| 2635 | struct gcpro gcpro1; | 2502 | return NILP (arg) ? Ffuncall (1, &fn) : CALLN (Fapply, fn, arg); |
| 2636 | |||
| 2637 | GCPRO1 (fn); | ||
| 2638 | if (NILP (arg)) | ||
| 2639 | RETURN_UNGCPRO (Ffuncall (1, &fn)); | ||
| 2640 | gcpro1.nvars = 2; | ||
| 2641 | { | ||
| 2642 | Lisp_Object args[2]; | ||
| 2643 | args[0] = fn; | ||
| 2644 | args[1] = arg; | ||
| 2645 | gcpro1.var = args; | ||
| 2646 | RETURN_UNGCPRO (Fapply (2, args)); | ||
| 2647 | } | ||
| 2648 | } | 2503 | } |
| 2649 | 2504 | ||
| 2650 | /* Call function fn on no arguments. */ | 2505 | /* Call function fn on no arguments. */ |
| 2651 | Lisp_Object | 2506 | Lisp_Object |
| 2652 | call0 (Lisp_Object fn) | 2507 | call0 (Lisp_Object fn) |
| 2653 | { | 2508 | { |
| 2654 | struct gcpro gcpro1; | 2509 | return Ffuncall (1, &fn); |
| 2655 | |||
| 2656 | GCPRO1 (fn); | ||
| 2657 | RETURN_UNGCPRO (Ffuncall (1, &fn)); | ||
| 2658 | } | 2510 | } |
| 2659 | 2511 | ||
| 2660 | /* Call function fn with 1 argument arg1. */ | 2512 | /* Call function fn with 1 argument arg1. */ |
| @@ -2662,14 +2514,7 @@ call0 (Lisp_Object fn) | |||
| 2662 | Lisp_Object | 2514 | Lisp_Object |
| 2663 | call1 (Lisp_Object fn, Lisp_Object arg1) | 2515 | call1 (Lisp_Object fn, Lisp_Object arg1) |
| 2664 | { | 2516 | { |
| 2665 | struct gcpro gcpro1; | 2517 | return CALLN (Ffuncall, fn, arg1); |
| 2666 | Lisp_Object args[2]; | ||
| 2667 | |||
| 2668 | args[0] = fn; | ||
| 2669 | args[1] = arg1; | ||
| 2670 | GCPRO1 (args[0]); | ||
| 2671 | gcpro1.nvars = 2; | ||
| 2672 | RETURN_UNGCPRO (Ffuncall (2, args)); | ||
| 2673 | } | 2518 | } |
| 2674 | 2519 | ||
| 2675 | /* Call function fn with 2 arguments arg1, arg2. */ | 2520 | /* Call function fn with 2 arguments arg1, arg2. */ |
| @@ -2677,14 +2522,7 @@ call1 (Lisp_Object fn, Lisp_Object arg1) | |||
| 2677 | Lisp_Object | 2522 | Lisp_Object |
| 2678 | call2 (Lisp_Object fn, Lisp_Object arg1, Lisp_Object arg2) | 2523 | call2 (Lisp_Object fn, Lisp_Object arg1, Lisp_Object arg2) |
| 2679 | { | 2524 | { |
| 2680 | struct gcpro gcpro1; | 2525 | return CALLN (Ffuncall, fn, arg1, arg2); |
| 2681 | Lisp_Object args[3]; | ||
| 2682 | args[0] = fn; | ||
| 2683 | args[1] = arg1; | ||
| 2684 | args[2] = arg2; | ||
| 2685 | GCPRO1 (args[0]); | ||
| 2686 | gcpro1.nvars = 3; | ||
| 2687 | RETURN_UNGCPRO (Ffuncall (3, args)); | ||
| 2688 | } | 2526 | } |
| 2689 | 2527 | ||
| 2690 | /* Call function fn with 3 arguments arg1, arg2, arg3. */ | 2528 | /* Call function fn with 3 arguments arg1, arg2, arg3. */ |
| @@ -2692,15 +2530,7 @@ call2 (Lisp_Object fn, Lisp_Object arg1, Lisp_Object arg2) | |||
| 2692 | Lisp_Object | 2530 | Lisp_Object |
| 2693 | call3 (Lisp_Object fn, Lisp_Object arg1, Lisp_Object arg2, Lisp_Object arg3) | 2531 | call3 (Lisp_Object fn, Lisp_Object arg1, Lisp_Object arg2, Lisp_Object arg3) |
| 2694 | { | 2532 | { |
| 2695 | struct gcpro gcpro1; | 2533 | return CALLN (Ffuncall, fn, arg1, arg2, arg3); |
| 2696 | Lisp_Object args[4]; | ||
| 2697 | args[0] = fn; | ||
| 2698 | args[1] = arg1; | ||
| 2699 | args[2] = arg2; | ||
| 2700 | args[3] = arg3; | ||
| 2701 | GCPRO1 (args[0]); | ||
| 2702 | gcpro1.nvars = 4; | ||
| 2703 | RETURN_UNGCPRO (Ffuncall (4, args)); | ||
| 2704 | } | 2534 | } |
| 2705 | 2535 | ||
| 2706 | /* Call function fn with 4 arguments arg1, arg2, arg3, arg4. */ | 2536 | /* Call function fn with 4 arguments arg1, arg2, arg3, arg4. */ |
| @@ -2709,16 +2539,7 @@ Lisp_Object | |||
| 2709 | call4 (Lisp_Object fn, Lisp_Object arg1, Lisp_Object arg2, Lisp_Object arg3, | 2539 | call4 (Lisp_Object fn, Lisp_Object arg1, Lisp_Object arg2, Lisp_Object arg3, |
| 2710 | Lisp_Object arg4) | 2540 | Lisp_Object arg4) |
| 2711 | { | 2541 | { |
| 2712 | struct gcpro gcpro1; | 2542 | return CALLN (Ffuncall, fn, arg1, arg2, arg3, arg4); |
| 2713 | Lisp_Object args[5]; | ||
| 2714 | args[0] = fn; | ||
| 2715 | args[1] = arg1; | ||
| 2716 | args[2] = arg2; | ||
| 2717 | args[3] = arg3; | ||
| 2718 | args[4] = arg4; | ||
| 2719 | GCPRO1 (args[0]); | ||
| 2720 | gcpro1.nvars = 5; | ||
| 2721 | RETURN_UNGCPRO (Ffuncall (5, args)); | ||
| 2722 | } | 2543 | } |
| 2723 | 2544 | ||
| 2724 | /* Call function fn with 5 arguments arg1, arg2, arg3, arg4, arg5. */ | 2545 | /* Call function fn with 5 arguments arg1, arg2, arg3, arg4, arg5. */ |
| @@ -2727,17 +2548,7 @@ Lisp_Object | |||
| 2727 | call5 (Lisp_Object fn, Lisp_Object arg1, Lisp_Object arg2, Lisp_Object arg3, | 2548 | call5 (Lisp_Object fn, Lisp_Object arg1, Lisp_Object arg2, Lisp_Object arg3, |
| 2728 | Lisp_Object arg4, Lisp_Object arg5) | 2549 | Lisp_Object arg4, Lisp_Object arg5) |
| 2729 | { | 2550 | { |
| 2730 | struct gcpro gcpro1; | 2551 | return CALLN (Ffuncall, fn, arg1, arg2, arg3, arg4, arg5); |
| 2731 | Lisp_Object args[6]; | ||
| 2732 | args[0] = fn; | ||
| 2733 | args[1] = arg1; | ||
| 2734 | args[2] = arg2; | ||
| 2735 | args[3] = arg3; | ||
| 2736 | args[4] = arg4; | ||
| 2737 | args[5] = arg5; | ||
| 2738 | GCPRO1 (args[0]); | ||
| 2739 | gcpro1.nvars = 6; | ||
| 2740 | RETURN_UNGCPRO (Ffuncall (6, args)); | ||
| 2741 | } | 2552 | } |
| 2742 | 2553 | ||
| 2743 | /* Call function fn with 6 arguments arg1, arg2, arg3, arg4, arg5, arg6. */ | 2554 | /* Call function fn with 6 arguments arg1, arg2, arg3, arg4, arg5, arg6. */ |
| @@ -2746,18 +2557,7 @@ Lisp_Object | |||
| 2746 | call6 (Lisp_Object fn, Lisp_Object arg1, Lisp_Object arg2, Lisp_Object arg3, | 2557 | call6 (Lisp_Object fn, Lisp_Object arg1, Lisp_Object arg2, Lisp_Object arg3, |
| 2747 | Lisp_Object arg4, Lisp_Object arg5, Lisp_Object arg6) | 2558 | Lisp_Object arg4, Lisp_Object arg5, Lisp_Object arg6) |
| 2748 | { | 2559 | { |
| 2749 | struct gcpro gcpro1; | 2560 | return CALLN (Ffuncall, fn, arg1, arg2, arg3, arg4, arg5, arg6); |
| 2750 | Lisp_Object args[7]; | ||
| 2751 | args[0] = fn; | ||
| 2752 | args[1] = arg1; | ||
| 2753 | args[2] = arg2; | ||
| 2754 | args[3] = arg3; | ||
| 2755 | args[4] = arg4; | ||
| 2756 | args[5] = arg5; | ||
| 2757 | args[6] = arg6; | ||
| 2758 | GCPRO1 (args[0]); | ||
| 2759 | gcpro1.nvars = 7; | ||
| 2760 | RETURN_UNGCPRO (Ffuncall (7, args)); | ||
| 2761 | } | 2561 | } |
| 2762 | 2562 | ||
| 2763 | /* Call function fn with 7 arguments arg1, arg2, arg3, arg4, arg5, arg6, arg7. */ | 2563 | /* Call function fn with 7 arguments arg1, arg2, arg3, arg4, arg5, arg6, arg7. */ |
| @@ -2766,23 +2566,9 @@ Lisp_Object | |||
| 2766 | call7 (Lisp_Object fn, Lisp_Object arg1, Lisp_Object arg2, Lisp_Object arg3, | 2566 | call7 (Lisp_Object fn, Lisp_Object arg1, Lisp_Object arg2, Lisp_Object arg3, |
| 2767 | Lisp_Object arg4, Lisp_Object arg5, Lisp_Object arg6, Lisp_Object arg7) | 2567 | Lisp_Object arg4, Lisp_Object arg5, Lisp_Object arg6, Lisp_Object arg7) |
| 2768 | { | 2568 | { |
| 2769 | struct gcpro gcpro1; | 2569 | return CALLN (Ffuncall, fn, arg1, arg2, arg3, arg4, arg5, arg6, arg7); |
| 2770 | Lisp_Object args[8]; | ||
| 2771 | args[0] = fn; | ||
| 2772 | args[1] = arg1; | ||
| 2773 | args[2] = arg2; | ||
| 2774 | args[3] = arg3; | ||
| 2775 | args[4] = arg4; | ||
| 2776 | args[5] = arg5; | ||
| 2777 | args[6] = arg6; | ||
| 2778 | args[7] = arg7; | ||
| 2779 | GCPRO1 (args[0]); | ||
| 2780 | gcpro1.nvars = 8; | ||
| 2781 | RETURN_UNGCPRO (Ffuncall (8, args)); | ||
| 2782 | } | 2570 | } |
| 2783 | 2571 | ||
| 2784 | /* The caller should GCPRO all the elements of ARGS. */ | ||
| 2785 | |||
| 2786 | DEFUN ("functionp", Ffunctionp, Sfunctionp, 1, 1, 0, | 2572 | DEFUN ("functionp", Ffunctionp, Sfunctionp, 1, 1, 0, |
| 2787 | doc: /* Non-nil if OBJECT is a function. */) | 2573 | doc: /* Non-nil if OBJECT is a function. */) |
| 2788 | (Lisp_Object object) | 2574 | (Lisp_Object object) |
| @@ -2795,7 +2581,7 @@ DEFUN ("functionp", Ffunctionp, Sfunctionp, 1, 1, 0, | |||
| 2795 | DEFUN ("funcall", Ffuncall, Sfuncall, 1, MANY, 0, | 2581 | DEFUN ("funcall", Ffuncall, Sfuncall, 1, MANY, 0, |
| 2796 | doc: /* Call first argument as a function, passing remaining arguments to it. | 2582 | doc: /* Call first argument as a function, passing remaining arguments to it. |
| 2797 | Return the value that function returns. | 2583 | Return the value that function returns. |
| 2798 | Thus, (funcall 'cons 'x 'y) returns (x . y). | 2584 | Thus, (funcall \\='cons \\='x \\='y) returns (x . y). |
| 2799 | usage: (funcall FUNCTION &rest ARGUMENTS) */) | 2585 | usage: (funcall FUNCTION &rest ARGUMENTS) */) |
| 2800 | (ptrdiff_t nargs, Lisp_Object *args) | 2586 | (ptrdiff_t nargs, Lisp_Object *args) |
| 2801 | { | 2587 | { |
| @@ -2804,8 +2590,8 @@ usage: (funcall FUNCTION &rest ARGUMENTS) */) | |||
| 2804 | ptrdiff_t numargs = nargs - 1; | 2590 | ptrdiff_t numargs = nargs - 1; |
| 2805 | Lisp_Object lisp_numargs; | 2591 | Lisp_Object lisp_numargs; |
| 2806 | Lisp_Object val; | 2592 | Lisp_Object val; |
| 2807 | register Lisp_Object *internal_args; | 2593 | Lisp_Object *internal_args; |
| 2808 | ptrdiff_t i; | 2594 | ptrdiff_t count; |
| 2809 | 2595 | ||
| 2810 | QUIT; | 2596 | QUIT; |
| 2811 | 2597 | ||
| @@ -2817,14 +2603,12 @@ usage: (funcall FUNCTION &rest ARGUMENTS) */) | |||
| 2817 | error ("Lisp nesting exceeds `max-lisp-eval-depth'"); | 2603 | error ("Lisp nesting exceeds `max-lisp-eval-depth'"); |
| 2818 | } | 2604 | } |
| 2819 | 2605 | ||
| 2820 | /* This also GCPROs them. */ | 2606 | count = record_in_backtrace (args[0], &args[1], nargs - 1); |
| 2821 | record_in_backtrace (args[0], &args[1], nargs - 1); | ||
| 2822 | 2607 | ||
| 2823 | /* Call GC after setting up the backtrace, so the latter GCPROs the args. */ | ||
| 2824 | maybe_gc (); | 2608 | maybe_gc (); |
| 2825 | 2609 | ||
| 2826 | if (debug_on_next_call) | 2610 | if (debug_on_next_call) |
| 2827 | do_debug_on_call (Qlambda); | 2611 | do_debug_on_call (Qlambda, count); |
| 2828 | 2612 | ||
| 2829 | check_cons_list (); | 2613 | check_cons_list (); |
| 2830 | 2614 | ||
| @@ -2854,13 +2638,14 @@ usage: (funcall FUNCTION &rest ARGUMENTS) */) | |||
| 2854 | val = (XSUBR (fun)->function.aMANY) (numargs, args + 1); | 2638 | val = (XSUBR (fun)->function.aMANY) (numargs, args + 1); |
| 2855 | else | 2639 | else |
| 2856 | { | 2640 | { |
| 2641 | Lisp_Object internal_argbuf[8]; | ||
| 2857 | if (XSUBR (fun)->max_args > numargs) | 2642 | if (XSUBR (fun)->max_args > numargs) |
| 2858 | { | 2643 | { |
| 2859 | internal_args = alloca (XSUBR (fun)->max_args | 2644 | eassert (XSUBR (fun)->max_args <= ARRAYELTS (internal_argbuf)); |
| 2860 | * sizeof *internal_args); | 2645 | internal_args = internal_argbuf; |
| 2861 | memcpy (internal_args, args + 1, numargs * word_size); | 2646 | memcpy (internal_args, args + 1, numargs * word_size); |
| 2862 | for (i = numargs; i < XSUBR (fun)->max_args; i++) | 2647 | memclear (internal_args + numargs, |
| 2863 | internal_args[i] = Qnil; | 2648 | (XSUBR (fun)->max_args - numargs) * word_size); |
| 2864 | } | 2649 | } |
| 2865 | else | 2650 | else |
| 2866 | internal_args = args + 1; | 2651 | internal_args = args + 1; |
| @@ -2943,49 +2728,41 @@ usage: (funcall FUNCTION &rest ARGUMENTS) */) | |||
| 2943 | } | 2728 | } |
| 2944 | check_cons_list (); | 2729 | check_cons_list (); |
| 2945 | lisp_eval_depth--; | 2730 | lisp_eval_depth--; |
| 2946 | if (backtrace_debug_on_exit (specpdl_ptr - 1)) | 2731 | if (backtrace_debug_on_exit (specpdl + count)) |
| 2947 | val = call_debugger (list2 (Qexit, val)); | 2732 | val = call_debugger (list2 (Qexit, val)); |
| 2948 | specpdl_ptr--; | 2733 | specpdl_ptr--; |
| 2949 | return val; | 2734 | return val; |
| 2950 | } | 2735 | } |
| 2951 | 2736 | ||
| 2952 | static Lisp_Object | 2737 | static Lisp_Object |
| 2953 | apply_lambda (Lisp_Object fun, Lisp_Object args) | 2738 | apply_lambda (Lisp_Object fun, Lisp_Object args, ptrdiff_t count) |
| 2954 | { | 2739 | { |
| 2955 | Lisp_Object args_left; | 2740 | Lisp_Object args_left; |
| 2956 | ptrdiff_t i; | 2741 | ptrdiff_t i; |
| 2957 | EMACS_INT numargs; | 2742 | EMACS_INT numargs; |
| 2958 | register Lisp_Object *arg_vector; | 2743 | Lisp_Object *arg_vector; |
| 2959 | struct gcpro gcpro1, gcpro2, gcpro3; | 2744 | Lisp_Object tem; |
| 2960 | register Lisp_Object tem; | ||
| 2961 | USE_SAFE_ALLOCA; | 2745 | USE_SAFE_ALLOCA; |
| 2962 | 2746 | ||
| 2963 | numargs = XFASTINT (Flength (args)); | 2747 | numargs = XFASTINT (Flength (args)); |
| 2964 | SAFE_ALLOCA_LISP (arg_vector, numargs); | 2748 | SAFE_ALLOCA_LISP (arg_vector, numargs); |
| 2965 | args_left = args; | 2749 | args_left = args; |
| 2966 | 2750 | ||
| 2967 | GCPRO3 (*arg_vector, args_left, fun); | ||
| 2968 | gcpro1.nvars = 0; | ||
| 2969 | |||
| 2970 | for (i = 0; i < numargs; ) | 2751 | for (i = 0; i < numargs; ) |
| 2971 | { | 2752 | { |
| 2972 | tem = Fcar (args_left), args_left = Fcdr (args_left); | 2753 | tem = Fcar (args_left), args_left = Fcdr (args_left); |
| 2973 | tem = eval_sub (tem); | 2754 | tem = eval_sub (tem); |
| 2974 | arg_vector[i++] = tem; | 2755 | arg_vector[i++] = tem; |
| 2975 | gcpro1.nvars = i; | ||
| 2976 | } | 2756 | } |
| 2977 | 2757 | ||
| 2978 | UNGCPRO; | 2758 | set_backtrace_args (specpdl + count, arg_vector, i); |
| 2979 | |||
| 2980 | set_backtrace_args (specpdl_ptr - 1, arg_vector); | ||
| 2981 | set_backtrace_nargs (specpdl_ptr - 1, i); | ||
| 2982 | tem = funcall_lambda (fun, numargs, arg_vector); | 2759 | tem = funcall_lambda (fun, numargs, arg_vector); |
| 2983 | 2760 | ||
| 2984 | /* Do the debug-on-exit now, while arg_vector still exists. */ | 2761 | /* Do the debug-on-exit now, while arg_vector still exists. */ |
| 2985 | if (backtrace_debug_on_exit (specpdl_ptr - 1)) | 2762 | if (backtrace_debug_on_exit (specpdl + count)) |
| 2986 | { | 2763 | { |
| 2987 | /* Don't do it again when we return to eval. */ | 2764 | /* Don't do it again when we return to eval. */ |
| 2988 | set_backtrace_debug_on_exit (specpdl_ptr - 1, false); | 2765 | set_backtrace_debug_on_exit (specpdl + count, false); |
| 2989 | tem = call_debugger (list2 (Qexit, tem)); | 2766 | tem = call_debugger (list2 (Qexit, tem)); |
| 2990 | } | 2767 | } |
| 2991 | SAFE_FREE (); | 2768 | SAFE_FREE (); |
| @@ -3209,20 +2986,17 @@ do_specbind (struct Lisp_Symbol *sym, union specbinding *bind, | |||
| 3209 | } | 2986 | } |
| 3210 | } | 2987 | } |
| 3211 | 2988 | ||
| 3212 | /* `specpdl_ptr->symbol' is a field which describes which variable is | 2989 | /* `specpdl_ptr' describes which variable is |
| 3213 | let-bound, so it can be properly undone when we unbind_to. | 2990 | let-bound, so it can be properly undone when we unbind_to. |
| 3214 | It can have the following two shapes: | 2991 | It can be either a plain SPECPDL_LET or a SPECPDL_LET_LOCAL/DEFAULT. |
| 3215 | - SYMBOL : if it's a plain symbol, it means that we have let-bound | 2992 | - SYMBOL is the variable being bound. Note that it should not be |
| 3216 | a symbol that is not buffer-local (at least at the time | ||
| 3217 | the let binding started). Note also that it should not be | ||
| 3218 | aliased (i.e. when let-binding V1 that's aliased to V2, we want | 2993 | aliased (i.e. when let-binding V1 that's aliased to V2, we want |
| 3219 | to record V2 here). | 2994 | to record V2 here). |
| 3220 | - (SYMBOL WHERE . BUFFER) : this means that it is a let-binding for | 2995 | - WHERE tells us in which buffer the binding took place. |
| 3221 | variable SYMBOL which can be buffer-local. WHERE tells us | 2996 | This is used for SPECPDL_LET_LOCAL bindings (i.e. bindings to a |
| 3222 | which buffer is affected (or nil if the let-binding affects the | 2997 | buffer-local variable) as well as for SPECPDL_LET_DEFAULT bindings, |
| 3223 | global value of the variable) and BUFFER tells us which buffer was | 2998 | i.e. bindings to the default value of a variable which can be |
| 3224 | current (i.e. if WHERE is non-nil, then BUFFER==WHERE, otherwise | 2999 | buffer-local. */ |
| 3225 | BUFFER did not yet have a buffer-local value). */ | ||
| 3226 | 3000 | ||
| 3227 | void | 3001 | void |
| 3228 | specbind (Lisp_Object symbol, Lisp_Object value) | 3002 | specbind (Lisp_Object symbol, Lisp_Object value) |
| @@ -3457,9 +3231,7 @@ Lisp_Object | |||
| 3457 | unbind_to (ptrdiff_t count, Lisp_Object value) | 3231 | unbind_to (ptrdiff_t count, Lisp_Object value) |
| 3458 | { | 3232 | { |
| 3459 | Lisp_Object quitf = Vquit_flag; | 3233 | Lisp_Object quitf = Vquit_flag; |
| 3460 | struct gcpro gcpro1, gcpro2; | ||
| 3461 | 3234 | ||
| 3462 | GCPRO2 (value, quitf); | ||
| 3463 | Vquit_flag = Qnil; | 3235 | Vquit_flag = Qnil; |
| 3464 | 3236 | ||
| 3465 | while (specpdl_ptr != specpdl + count) | 3237 | while (specpdl_ptr != specpdl + count) |
| @@ -3479,7 +3251,6 @@ unbind_to (ptrdiff_t count, Lisp_Object value) | |||
| 3479 | if (NILP (Vquit_flag) && !NILP (quitf)) | 3251 | if (NILP (Vquit_flag) && !NILP (quitf)) |
| 3480 | Vquit_flag = quitf; | 3252 | Vquit_flag = quitf; |
| 3481 | 3253 | ||
| 3482 | UNGCPRO; | ||
| 3483 | return value; | 3254 | return value; |
| 3484 | } | 3255 | } |
| 3485 | 3256 | ||
| @@ -3542,27 +3313,27 @@ Output stream used is value of `standard-output'. */) | |||
| 3542 | 3313 | ||
| 3543 | while (backtrace_p (pdl)) | 3314 | while (backtrace_p (pdl)) |
| 3544 | { | 3315 | { |
| 3545 | write_string (backtrace_debug_on_exit (pdl) ? "* " : " ", 2); | 3316 | write_string (backtrace_debug_on_exit (pdl) ? "* " : " "); |
| 3546 | if (backtrace_nargs (pdl) == UNEVALLED) | 3317 | if (backtrace_nargs (pdl) == UNEVALLED) |
| 3547 | { | 3318 | { |
| 3548 | Fprin1 (Fcons (backtrace_function (pdl), *backtrace_args (pdl)), | 3319 | Fprin1 (Fcons (backtrace_function (pdl), *backtrace_args (pdl)), |
| 3549 | Qnil); | 3320 | Qnil); |
| 3550 | write_string ("\n", -1); | 3321 | write_string ("\n"); |
| 3551 | } | 3322 | } |
| 3552 | else | 3323 | else |
| 3553 | { | 3324 | { |
| 3554 | tem = backtrace_function (pdl); | 3325 | tem = backtrace_function (pdl); |
| 3555 | Fprin1 (tem, Qnil); /* This can QUIT. */ | 3326 | Fprin1 (tem, Qnil); /* This can QUIT. */ |
| 3556 | write_string ("(", -1); | 3327 | write_string ("("); |
| 3557 | { | 3328 | { |
| 3558 | ptrdiff_t i; | 3329 | ptrdiff_t i; |
| 3559 | for (i = 0; i < backtrace_nargs (pdl); i++) | 3330 | for (i = 0; i < backtrace_nargs (pdl); i++) |
| 3560 | { | 3331 | { |
| 3561 | if (i) write_string (" ", -1); | 3332 | if (i) write_string (" "); |
| 3562 | Fprin1 (backtrace_args (pdl)[i], Qnil); | 3333 | Fprin1 (backtrace_args (pdl)[i], Qnil); |
| 3563 | } | 3334 | } |
| 3564 | } | 3335 | } |
| 3565 | write_string (")\n", -1); | 3336 | write_string (")\n"); |
| 3566 | } | 3337 | } |
| 3567 | pdl = backtrace_next (pdl); | 3338 | pdl = backtrace_next (pdl); |
| 3568 | } | 3339 | } |
| @@ -3645,13 +3416,24 @@ backtrace_eval_unrewind (int distance) | |||
| 3645 | for (; distance > 0; distance--) | 3416 | for (; distance > 0; distance--) |
| 3646 | { | 3417 | { |
| 3647 | tmp += step; | 3418 | tmp += step; |
| 3648 | /* */ | ||
| 3649 | switch (tmp->kind) | 3419 | switch (tmp->kind) |
| 3650 | { | 3420 | { |
| 3651 | /* FIXME: Ideally we'd like to "temporarily unwind" (some of) those | 3421 | /* FIXME: Ideally we'd like to "temporarily unwind" (some of) those |
| 3652 | unwind_protect, but the problem is that we don't know how to | 3422 | unwind_protect, but the problem is that we don't know how to |
| 3653 | rewind them afterwards. */ | 3423 | rewind them afterwards. */ |
| 3654 | case SPECPDL_UNWIND: | 3424 | case SPECPDL_UNWIND: |
| 3425 | { | ||
| 3426 | Lisp_Object oldarg = tmp->unwind.arg; | ||
| 3427 | if (tmp->unwind.func == set_buffer_if_live) | ||
| 3428 | tmp->unwind.arg = Fcurrent_buffer (); | ||
| 3429 | else if (tmp->unwind.func == save_excursion_restore) | ||
| 3430 | tmp->unwind.arg = save_excursion_save (); | ||
| 3431 | else | ||
| 3432 | break; | ||
| 3433 | tmp->unwind.func (oldarg); | ||
| 3434 | break; | ||
| 3435 | } | ||
| 3436 | |||
| 3655 | case SPECPDL_UNWIND_PTR: | 3437 | case SPECPDL_UNWIND_PTR: |
| 3656 | case SPECPDL_UNWIND_INT: | 3438 | case SPECPDL_UNWIND_INT: |
| 3657 | case SPECPDL_UNWIND_VOID: | 3439 | case SPECPDL_UNWIND_VOID: |
| @@ -3725,6 +3507,84 @@ NFRAMES and BASE specify the activation frame to use, as in `backtrace-frame'. | |||
| 3725 | from the debugger. */ | 3507 | from the debugger. */ |
| 3726 | return unbind_to (count, eval_sub (exp)); | 3508 | return unbind_to (count, eval_sub (exp)); |
| 3727 | } | 3509 | } |
| 3510 | |||
| 3511 | DEFUN ("backtrace--locals", Fbacktrace__locals, Sbacktrace__locals, 1, 2, NULL, | ||
| 3512 | doc: /* Return names and values of local variables of a stack frame. | ||
| 3513 | NFRAMES and BASE specify the activation frame to use, as in `backtrace-frame'. */) | ||
| 3514 | (Lisp_Object nframes, Lisp_Object base) | ||
| 3515 | { | ||
| 3516 | union specbinding *frame = get_backtrace_frame (nframes, base); | ||
| 3517 | union specbinding *prevframe | ||
| 3518 | = get_backtrace_frame (make_number (XFASTINT (nframes) - 1), base); | ||
| 3519 | ptrdiff_t distance = specpdl_ptr - frame; | ||
| 3520 | Lisp_Object result = Qnil; | ||
| 3521 | eassert (distance >= 0); | ||
| 3522 | |||
| 3523 | if (!backtrace_p (prevframe)) | ||
| 3524 | error ("Activation frame not found!"); | ||
| 3525 | if (!backtrace_p (frame)) | ||
| 3526 | error ("Activation frame not found!"); | ||
| 3527 | |||
| 3528 | /* The specpdl entries normally contain the symbol being bound along with its | ||
| 3529 | `old_value', so it can be restored. The new value to which it is bound is | ||
| 3530 | available in one of two places: either in the current value of the | ||
| 3531 | variable (if it hasn't been rebound yet) or in the `old_value' slot of the | ||
| 3532 | next specpdl entry for it. | ||
| 3533 | `backtrace_eval_unrewind' happens to swap the role of `old_value' | ||
| 3534 | and "new value", so we abuse it here, to fetch the new value. | ||
| 3535 | It's ugly (we'd rather not modify global data) and a bit inefficient, | ||
| 3536 | but it does the job for now. */ | ||
| 3537 | backtrace_eval_unrewind (distance); | ||
| 3538 | |||
| 3539 | /* Grab values. */ | ||
| 3540 | { | ||
| 3541 | union specbinding *tmp = prevframe; | ||
| 3542 | for (; tmp > frame; tmp--) | ||
| 3543 | { | ||
| 3544 | switch (tmp->kind) | ||
| 3545 | { | ||
| 3546 | case SPECPDL_LET: | ||
| 3547 | case SPECPDL_LET_DEFAULT: | ||
| 3548 | case SPECPDL_LET_LOCAL: | ||
| 3549 | { | ||
| 3550 | Lisp_Object sym = specpdl_symbol (tmp); | ||
| 3551 | Lisp_Object val = specpdl_old_value (tmp); | ||
| 3552 | if (EQ (sym, Qinternal_interpreter_environment)) | ||
| 3553 | { | ||
| 3554 | Lisp_Object env = val; | ||
| 3555 | for (; CONSP (env); env = XCDR (env)) | ||
| 3556 | { | ||
| 3557 | Lisp_Object binding = XCAR (env); | ||
| 3558 | if (CONSP (binding)) | ||
| 3559 | result = Fcons (Fcons (XCAR (binding), | ||
| 3560 | XCDR (binding)), | ||
| 3561 | result); | ||
| 3562 | } | ||
| 3563 | } | ||
| 3564 | else | ||
| 3565 | result = Fcons (Fcons (sym, val), result); | ||
| 3566 | } | ||
| 3567 | break; | ||
| 3568 | |||
| 3569 | case SPECPDL_UNWIND: | ||
| 3570 | case SPECPDL_UNWIND_PTR: | ||
| 3571 | case SPECPDL_UNWIND_INT: | ||
| 3572 | case SPECPDL_UNWIND_VOID: | ||
| 3573 | case SPECPDL_BACKTRACE: | ||
| 3574 | break; | ||
| 3575 | |||
| 3576 | default: | ||
| 3577 | emacs_abort (); | ||
| 3578 | } | ||
| 3579 | } | ||
| 3580 | } | ||
| 3581 | |||
| 3582 | /* Restore values from specpdl to original place. */ | ||
| 3583 | backtrace_eval_unrewind (-distance); | ||
| 3584 | |||
| 3585 | return result; | ||
| 3586 | } | ||
| 3587 | |||
| 3728 | 3588 | ||
| 3729 | void | 3589 | void |
| 3730 | mark_specpdl (union specbinding *first, union specbinding *ptr) | 3590 | mark_specpdl (union specbinding *first, union specbinding *ptr) |
| @@ -3758,6 +3618,14 @@ mark_specpdl (union specbinding *first, union specbinding *ptr) | |||
| 3758 | mark_object (specpdl_old_value (pdl)); | 3618 | mark_object (specpdl_old_value (pdl)); |
| 3759 | mark_object (specpdl_saved_value (pdl)); | 3619 | mark_object (specpdl_saved_value (pdl)); |
| 3760 | break; | 3620 | break; |
| 3621 | |||
| 3622 | case SPECPDL_UNWIND_PTR: | ||
| 3623 | case SPECPDL_UNWIND_INT: | ||
| 3624 | case SPECPDL_UNWIND_VOID: | ||
| 3625 | break; | ||
| 3626 | |||
| 3627 | default: | ||
| 3628 | emacs_abort (); | ||
| 3761 | } | 3629 | } |
| 3762 | } | 3630 | } |
| 3763 | } | 3631 | } |
| @@ -3796,7 +3664,9 @@ If Lisp code tries to increase the total number past this amount, | |||
| 3796 | an error is signaled. | 3664 | an error is signaled. |
| 3797 | You can safely use a value considerably larger than the default value, | 3665 | You can safely use a value considerably larger than the default value, |
| 3798 | if that proves inconveniently small. However, if you increase it too far, | 3666 | if that proves inconveniently small. However, if you increase it too far, |
| 3799 | Emacs could run out of memory trying to make the stack bigger. */); | 3667 | Emacs could run out of memory trying to make the stack bigger. |
| 3668 | Note that this limit may be silently increased by the debugger | ||
| 3669 | if `debug-on-error' or `debug-on-quit' is set. */); | ||
| 3800 | 3670 | ||
| 3801 | DEFVAR_INT ("max-lisp-eval-depth", max_lisp_eval_depth, | 3671 | DEFVAR_INT ("max-lisp-eval-depth", max_lisp_eval_depth, |
| 3802 | doc: /* Limit on depth in `eval', `apply' and `funcall' before error. | 3672 | doc: /* Limit on depth in `eval', `apply' and `funcall' before error. |
| @@ -3828,7 +3698,6 @@ before making `inhibit-quit' nil. */); | |||
| 3828 | DEFSYM (Qautoload, "autoload"); | 3698 | DEFSYM (Qautoload, "autoload"); |
| 3829 | DEFSYM (Qinhibit_debugger, "inhibit-debugger"); | 3699 | DEFSYM (Qinhibit_debugger, "inhibit-debugger"); |
| 3830 | DEFSYM (Qmacro, "macro"); | 3700 | DEFSYM (Qmacro, "macro"); |
| 3831 | DEFSYM (Qdeclare, "declare"); | ||
| 3832 | 3701 | ||
| 3833 | /* Note that the process handling also uses Qexit, but we don't want | 3702 | /* Note that the process handling also uses Qexit, but we don't want |
| 3834 | to staticpro it twice, so we just do it here. */ | 3703 | to staticpro it twice, so we just do it here. */ |
| @@ -3839,6 +3708,7 @@ before making `inhibit-quit' nil. */); | |||
| 3839 | DEFSYM (Qand_rest, "&rest"); | 3708 | DEFSYM (Qand_rest, "&rest"); |
| 3840 | DEFSYM (Qand_optional, "&optional"); | 3709 | DEFSYM (Qand_optional, "&optional"); |
| 3841 | DEFSYM (Qclosure, "closure"); | 3710 | DEFSYM (Qclosure, "closure"); |
| 3711 | DEFSYM (QCdocumentation, ":documentation"); | ||
| 3842 | DEFSYM (Qdebug, "debug"); | 3712 | DEFSYM (Qdebug, "debug"); |
| 3843 | 3713 | ||
| 3844 | DEFVAR_LISP ("inhibit-debugger", Vinhibit_debugger, | 3714 | DEFVAR_LISP ("inhibit-debugger", Vinhibit_debugger, |
| @@ -3924,7 +3794,8 @@ alist of active lexical bindings. */); | |||
| 3924 | (Just imagine if someone makes it buffer-local). */ | 3794 | (Just imagine if someone makes it buffer-local). */ |
| 3925 | Funintern (Qinternal_interpreter_environment, Qnil); | 3795 | Funintern (Qinternal_interpreter_environment, Qnil); |
| 3926 | 3796 | ||
| 3927 | DEFSYM (Vrun_hooks, "run-hooks"); | 3797 | Vrun_hooks = intern_c_string ("run-hooks"); |
| 3798 | staticpro (&Vrun_hooks); | ||
| 3928 | 3799 | ||
| 3929 | staticpro (&Vautoload_queue); | 3800 | staticpro (&Vautoload_queue); |
| 3930 | Vautoload_queue = Qnil; | 3801 | Vautoload_queue = Qnil; |
| @@ -3974,6 +3845,7 @@ alist of active lexical bindings. */); | |||
| 3974 | defsubr (&Sbacktrace); | 3845 | defsubr (&Sbacktrace); |
| 3975 | defsubr (&Sbacktrace_frame); | 3846 | defsubr (&Sbacktrace_frame); |
| 3976 | defsubr (&Sbacktrace_eval); | 3847 | defsubr (&Sbacktrace_eval); |
| 3848 | defsubr (&Sbacktrace__locals); | ||
| 3977 | defsubr (&Sspecial_variable_p); | 3849 | defsubr (&Sspecial_variable_p); |
| 3978 | defsubr (&Sfunctionp); | 3850 | defsubr (&Sfunctionp); |
| 3979 | } | 3851 | } |