diff options
| author | Tom Tromey | 2013-07-26 14:02:53 -0600 |
|---|---|---|
| committer | Tom Tromey | 2013-07-26 14:02:53 -0600 |
| commit | cc231cbe45d27a1906d268fb72d3b4105a2e9c65 (patch) | |
| tree | c011828e2a3a18e77eaa8849e3cccb805d798f42 /src/eval.c | |
| parent | b34a529f177a6ea32da5cb1254f91bf9d71838db (diff) | |
| parent | fec9206062b420aca84f53d05a72c3ee43244022 (diff) | |
| download | emacs-cc231cbe45d27a1906d268fb72d3b4105a2e9c65.tar.gz emacs-cc231cbe45d27a1906d268fb72d3b4105a2e9c65.zip | |
merge from trunk
Diffstat (limited to 'src/eval.c')
| -rw-r--r-- | src/eval.c | 420 |
1 files changed, 314 insertions, 106 deletions
diff --git a/src/eval.c b/src/eval.c index 97e812dd890..e93c3473ae8 100644 --- a/src/eval.c +++ b/src/eval.c | |||
| @@ -138,6 +138,13 @@ specpdl_old_value (union specbinding *pdl) | |||
| 138 | return pdl->let.old_value; | 138 | return pdl->let.old_value; |
| 139 | } | 139 | } |
| 140 | 140 | ||
| 141 | static void | ||
| 142 | set_specpdl_old_value (union specbinding *pdl, Lisp_Object val) | ||
| 143 | { | ||
| 144 | eassert (pdl->kind >= SPECPDL_LET); | ||
| 145 | pdl->let.old_value = val; | ||
| 146 | } | ||
| 147 | |||
| 141 | static Lisp_Object | 148 | static Lisp_Object |
| 142 | specpdl_where (union specbinding *pdl) | 149 | specpdl_where (union specbinding *pdl) |
| 143 | { | 150 | { |
| @@ -159,13 +166,6 @@ specpdl_arg (union specbinding *pdl) | |||
| 159 | return pdl->unwind.arg; | 166 | return pdl->unwind.arg; |
| 160 | } | 167 | } |
| 161 | 168 | ||
| 162 | static specbinding_func | ||
| 163 | specpdl_func (union specbinding *pdl) | ||
| 164 | { | ||
| 165 | eassert (pdl->kind == SPECPDL_UNWIND); | ||
| 166 | return pdl->unwind.func; | ||
| 167 | } | ||
| 168 | |||
| 169 | Lisp_Object | 169 | Lisp_Object |
| 170 | backtrace_function (union specbinding *pdl) | 170 | backtrace_function (union specbinding *pdl) |
| 171 | { | 171 | { |
| @@ -287,12 +287,11 @@ mark_catchlist (struct catchtag *catch) | |||
| 287 | 287 | ||
| 288 | /* Unwind-protect function used by call_debugger. */ | 288 | /* Unwind-protect function used by call_debugger. */ |
| 289 | 289 | ||
| 290 | static Lisp_Object | 290 | static void |
| 291 | restore_stack_limits (Lisp_Object data) | 291 | restore_stack_limits (Lisp_Object data) |
| 292 | { | 292 | { |
| 293 | max_specpdl_size = XINT (XCAR (data)); | 293 | max_specpdl_size = XINT (XCAR (data)); |
| 294 | max_lisp_eval_depth = XINT (XCDR (data)); | 294 | max_lisp_eval_depth = XINT (XCDR (data)); |
| 295 | return Qnil; | ||
| 296 | } | 295 | } |
| 297 | 296 | ||
| 298 | /* Call the Lisp debugger, giving it argument ARG. */ | 297 | /* Call the Lisp debugger, giving it argument ARG. */ |
| @@ -358,7 +357,7 @@ do_debug_on_call (Lisp_Object code) | |||
| 358 | { | 357 | { |
| 359 | debug_on_next_call = 0; | 358 | debug_on_next_call = 0; |
| 360 | set_backtrace_debug_on_exit (specpdl_ptr - 1, true); | 359 | set_backtrace_debug_on_exit (specpdl_ptr - 1, true); |
| 361 | call_debugger (Fcons (code, Qnil)); | 360 | call_debugger (list1 (code)); |
| 362 | } | 361 | } |
| 363 | 362 | ||
| 364 | /* NOTE!!! Every function that can call EVAL must protect its args | 363 | /* NOTE!!! Every function that can call EVAL must protect its args |
| @@ -421,16 +420,16 @@ If COND yields nil, and there are no ELSE's, the value is nil. | |||
| 421 | usage: (if COND THEN ELSE...) */) | 420 | usage: (if COND THEN ELSE...) */) |
| 422 | (Lisp_Object args) | 421 | (Lisp_Object args) |
| 423 | { | 422 | { |
| 424 | register Lisp_Object cond; | 423 | Lisp_Object cond; |
| 425 | struct gcpro gcpro1; | 424 | struct gcpro gcpro1; |
| 426 | 425 | ||
| 427 | GCPRO1 (args); | 426 | GCPRO1 (args); |
| 428 | cond = eval_sub (Fcar (args)); | 427 | cond = eval_sub (XCAR (args)); |
| 429 | UNGCPRO; | 428 | UNGCPRO; |
| 430 | 429 | ||
| 431 | if (!NILP (cond)) | 430 | if (!NILP (cond)) |
| 432 | return eval_sub (Fcar (Fcdr (args))); | 431 | return eval_sub (Fcar (XCDR (args))); |
| 433 | return Fprogn (Fcdr (Fcdr (args))); | 432 | return Fprogn (XCDR (XCDR (args))); |
| 434 | } | 433 | } |
| 435 | 434 | ||
| 436 | DEFUN ("cond", Fcond, Scond, 0, UNEVALLED, 0, | 435 | DEFUN ("cond", Fcond, Scond, 0, UNEVALLED, 0, |
| @@ -445,18 +444,17 @@ CONDITION's value if non-nil is returned from the cond-form. | |||
| 445 | usage: (cond CLAUSES...) */) | 444 | usage: (cond CLAUSES...) */) |
| 446 | (Lisp_Object args) | 445 | (Lisp_Object args) |
| 447 | { | 446 | { |
| 448 | register Lisp_Object clause, val; | 447 | Lisp_Object val = args; |
| 449 | struct gcpro gcpro1; | 448 | struct gcpro gcpro1; |
| 450 | 449 | ||
| 451 | val = Qnil; | ||
| 452 | GCPRO1 (args); | 450 | GCPRO1 (args); |
| 453 | while (!NILP (args)) | 451 | while (CONSP (args)) |
| 454 | { | 452 | { |
| 455 | clause = Fcar (args); | 453 | Lisp_Object clause = XCAR (args); |
| 456 | val = eval_sub (Fcar (clause)); | 454 | val = eval_sub (Fcar (clause)); |
| 457 | if (!NILP (val)) | 455 | if (!NILP (val)) |
| 458 | { | 456 | { |
| 459 | if (!EQ (XCDR (clause), Qnil)) | 457 | if (!NILP (XCDR (clause))) |
| 460 | val = Fprogn (XCDR (clause)); | 458 | val = Fprogn (XCDR (clause)); |
| 461 | break; | 459 | break; |
| 462 | } | 460 | } |
| @@ -470,23 +468,32 @@ usage: (cond CLAUSES...) */) | |||
| 470 | DEFUN ("progn", Fprogn, Sprogn, 0, UNEVALLED, 0, | 468 | DEFUN ("progn", Fprogn, Sprogn, 0, UNEVALLED, 0, |
| 471 | doc: /* Eval BODY forms sequentially and return value of last one. | 469 | doc: /* Eval BODY forms sequentially and return value of last one. |
| 472 | usage: (progn BODY...) */) | 470 | usage: (progn BODY...) */) |
| 473 | (Lisp_Object args) | 471 | (Lisp_Object body) |
| 474 | { | 472 | { |
| 475 | register Lisp_Object val = Qnil; | 473 | Lisp_Object val = Qnil; |
| 476 | struct gcpro gcpro1; | 474 | struct gcpro gcpro1; |
| 477 | 475 | ||
| 478 | GCPRO1 (args); | 476 | GCPRO1 (body); |
| 479 | 477 | ||
| 480 | while (CONSP (args)) | 478 | while (CONSP (body)) |
| 481 | { | 479 | { |
| 482 | val = eval_sub (XCAR (args)); | 480 | val = eval_sub (XCAR (body)); |
| 483 | args = XCDR (args); | 481 | body = XCDR (body); |
| 484 | } | 482 | } |
| 485 | 483 | ||
| 486 | UNGCPRO; | 484 | UNGCPRO; |
| 487 | return val; | 485 | return val; |
| 488 | } | 486 | } |
| 489 | 487 | ||
| 488 | /* Evaluate BODY sequentially, discarding its value. Suitable for | ||
| 489 | record_unwind_protect. */ | ||
| 490 | |||
| 491 | void | ||
| 492 | unwind_body (Lisp_Object body) | ||
| 493 | { | ||
| 494 | Fprogn (body); | ||
| 495 | } | ||
| 496 | |||
| 490 | DEFUN ("prog1", Fprog1, Sprog1, 1, UNEVALLED, 0, | 497 | DEFUN ("prog1", Fprog1, Sprog1, 1, UNEVALLED, 0, |
| 491 | doc: /* Eval FIRST and BODY sequentially; return value from FIRST. | 498 | doc: /* Eval FIRST and BODY sequentially; return value from FIRST. |
| 492 | The value of FIRST is saved during the evaluation of the remaining args, | 499 | The value of FIRST is saved during the evaluation of the remaining args, |
| @@ -495,11 +502,11 @@ usage: (prog1 FIRST BODY...) */) | |||
| 495 | (Lisp_Object args) | 502 | (Lisp_Object args) |
| 496 | { | 503 | { |
| 497 | Lisp_Object val; | 504 | Lisp_Object val; |
| 498 | register Lisp_Object args_left; | 505 | Lisp_Object args_left; |
| 499 | struct gcpro gcpro1, gcpro2; | 506 | struct gcpro gcpro1, gcpro2; |
| 500 | 507 | ||
| 501 | args_left = args; | 508 | args_left = args; |
| 502 | val = Qnil; | 509 | val = args; |
| 503 | GCPRO2 (args, val); | 510 | GCPRO2 (args, val); |
| 504 | 511 | ||
| 505 | val = eval_sub (XCAR (args_left)); | 512 | val = eval_sub (XCAR (args_left)); |
| @@ -536,36 +543,37 @@ The return value of the `setq' form is the value of the last VAL. | |||
| 536 | usage: (setq [SYM VAL]...) */) | 543 | usage: (setq [SYM VAL]...) */) |
| 537 | (Lisp_Object args) | 544 | (Lisp_Object args) |
| 538 | { | 545 | { |
| 539 | register Lisp_Object args_left; | 546 | Lisp_Object val, sym, lex_binding; |
| 540 | register Lisp_Object val, sym, lex_binding; | ||
| 541 | struct gcpro gcpro1; | ||
| 542 | |||
| 543 | if (NILP (args)) | ||
| 544 | return Qnil; | ||
| 545 | 547 | ||
| 546 | args_left = args; | 548 | val = args; |
| 547 | GCPRO1 (args); | 549 | if (CONSP (args)) |
| 548 | |||
| 549 | do | ||
| 550 | { | 550 | { |
| 551 | val = eval_sub (Fcar (Fcdr (args_left))); | 551 | Lisp_Object args_left = args; |
| 552 | sym = Fcar (args_left); | 552 | struct gcpro gcpro1; |
| 553 | GCPRO1 (args); | ||
| 553 | 554 | ||
| 554 | /* Like for eval_sub, we do not check declared_special here since | 555 | do |
| 555 | it's been done when let-binding. */ | 556 | { |
| 556 | if (!NILP (Vinternal_interpreter_environment) /* Mere optimization! */ | 557 | val = eval_sub (Fcar (XCDR (args_left))); |
| 557 | && SYMBOLP (sym) | 558 | sym = XCAR (args_left); |
| 558 | && !NILP (lex_binding | 559 | |
| 559 | = Fassq (sym, Vinternal_interpreter_environment))) | 560 | /* Like for eval_sub, we do not check declared_special here since |
| 560 | XSETCDR (lex_binding, val); /* SYM is lexically bound. */ | 561 | it's been done when let-binding. */ |
| 561 | else | 562 | if (!NILP (Vinternal_interpreter_environment) /* Mere optimization! */ |
| 562 | Fset (sym, val); /* SYM is dynamically bound. */ | 563 | && SYMBOLP (sym) |
| 564 | && !NILP (lex_binding | ||
| 565 | = Fassq (sym, Vinternal_interpreter_environment))) | ||
| 566 | XSETCDR (lex_binding, val); /* SYM is lexically bound. */ | ||
| 567 | else | ||
| 568 | Fset (sym, val); /* SYM is dynamically bound. */ | ||
| 569 | |||
| 570 | args_left = Fcdr (XCDR (args_left)); | ||
| 571 | } | ||
| 572 | while (CONSP (args_left)); | ||
| 563 | 573 | ||
| 564 | args_left = Fcdr (Fcdr (args_left)); | 574 | UNGCPRO; |
| 565 | } | 575 | } |
| 566 | while (!NILP (args_left)); | ||
| 567 | 576 | ||
| 568 | UNGCPRO; | ||
| 569 | return val; | 577 | return val; |
| 570 | } | 578 | } |
| 571 | 579 | ||
| @@ -582,9 +590,9 @@ of unexpected results when a quoted object is modified. | |||
| 582 | usage: (quote ARG) */) | 590 | usage: (quote ARG) */) |
| 583 | (Lisp_Object args) | 591 | (Lisp_Object args) |
| 584 | { | 592 | { |
| 585 | if (!NILP (Fcdr (args))) | 593 | if (CONSP (XCDR (args))) |
| 586 | xsignal2 (Qwrong_number_of_arguments, Qquote, Flength (args)); | 594 | xsignal2 (Qwrong_number_of_arguments, Qquote, Flength (args)); |
| 587 | return Fcar (args); | 595 | return XCAR (args); |
| 588 | } | 596 | } |
| 589 | 597 | ||
| 590 | DEFUN ("function", Ffunction, Sfunction, 1, UNEVALLED, 0, | 598 | DEFUN ("function", Ffunction, Sfunction, 1, UNEVALLED, 0, |
| @@ -596,7 +604,7 @@ usage: (function ARG) */) | |||
| 596 | { | 604 | { |
| 597 | Lisp_Object quoted = XCAR (args); | 605 | Lisp_Object quoted = XCAR (args); |
| 598 | 606 | ||
| 599 | if (!NILP (Fcdr (args))) | 607 | if (CONSP (XCDR (args))) |
| 600 | xsignal2 (Qwrong_number_of_arguments, Qfunction, Flength (args)); | 608 | xsignal2 (Qwrong_number_of_arguments, Qfunction, Flength (args)); |
| 601 | 609 | ||
| 602 | if (!NILP (Vinternal_interpreter_environment) | 610 | if (!NILP (Vinternal_interpreter_environment) |
| @@ -698,21 +706,23 @@ To define a user option, use `defcustom' instead of `defvar'. | |||
| 698 | usage: (defvar SYMBOL &optional INITVALUE DOCSTRING) */) | 706 | usage: (defvar SYMBOL &optional INITVALUE DOCSTRING) */) |
| 699 | (Lisp_Object args) | 707 | (Lisp_Object args) |
| 700 | { | 708 | { |
| 701 | register Lisp_Object sym, tem, tail; | 709 | Lisp_Object sym, tem, tail; |
| 702 | 710 | ||
| 703 | sym = Fcar (args); | 711 | sym = XCAR (args); |
| 704 | tail = Fcdr (args); | 712 | tail = XCDR (args); |
| 705 | if (!NILP (Fcdr (Fcdr (tail)))) | ||
| 706 | error ("Too many arguments"); | ||
| 707 | 713 | ||
| 708 | tem = Fdefault_boundp (sym); | 714 | if (CONSP (tail)) |
| 709 | if (!NILP (tail)) | ||
| 710 | { | 715 | { |
| 716 | if (CONSP (XCDR (tail)) && CONSP (XCDR (XCDR (tail)))) | ||
| 717 | error ("Too many arguments"); | ||
| 718 | |||
| 719 | tem = Fdefault_boundp (sym); | ||
| 720 | |||
| 711 | /* Do it before evaluating the initial value, for self-references. */ | 721 | /* Do it before evaluating the initial value, for self-references. */ |
| 712 | XSYMBOL (sym)->declared_special = 1; | 722 | XSYMBOL (sym)->declared_special = 1; |
| 713 | 723 | ||
| 714 | if (NILP (tem)) | 724 | if (NILP (tem)) |
| 715 | Fset_default (sym, eval_sub (Fcar (tail))); | 725 | Fset_default (sym, eval_sub (XCAR (tail))); |
| 716 | else | 726 | else |
| 717 | { /* Check if there is really a global binding rather than just a let | 727 | { /* Check if there is really a global binding rather than just a let |
| 718 | binding that shadows the global unboundness of the var. */ | 728 | binding that shadows the global unboundness of the var. */ |
| @@ -730,7 +740,7 @@ usage: (defvar SYMBOL &optional INITVALUE DOCSTRING) */) | |||
| 730 | } | 740 | } |
| 731 | } | 741 | } |
| 732 | } | 742 | } |
| 733 | tail = Fcdr (tail); | 743 | tail = XCDR (tail); |
| 734 | tem = Fcar (tail); | 744 | tem = Fcar (tail); |
| 735 | if (!NILP (tem)) | 745 | if (!NILP (tem)) |
| 736 | { | 746 | { |
| @@ -775,18 +785,18 @@ The optional DOCSTRING specifies the variable's documentation string. | |||
| 775 | usage: (defconst SYMBOL INITVALUE [DOCSTRING]) */) | 785 | usage: (defconst SYMBOL INITVALUE [DOCSTRING]) */) |
| 776 | (Lisp_Object args) | 786 | (Lisp_Object args) |
| 777 | { | 787 | { |
| 778 | register Lisp_Object sym, tem; | 788 | Lisp_Object sym, tem; |
| 779 | 789 | ||
| 780 | sym = Fcar (args); | 790 | sym = XCAR (args); |
| 781 | if (!NILP (Fcdr (Fcdr (Fcdr (args))))) | 791 | if (CONSP (Fcdr (XCDR (XCDR (args))))) |
| 782 | error ("Too many arguments"); | 792 | error ("Too many arguments"); |
| 783 | 793 | ||
| 784 | tem = eval_sub (Fcar (Fcdr (args))); | 794 | tem = eval_sub (Fcar (XCDR (args))); |
| 785 | if (!NILP (Vpurify_flag)) | 795 | if (!NILP (Vpurify_flag)) |
| 786 | tem = Fpurecopy (tem); | 796 | tem = Fpurecopy (tem); |
| 787 | Fset_default (sym, tem); | 797 | Fset_default (sym, tem); |
| 788 | XSYMBOL (sym)->declared_special = 1; | 798 | XSYMBOL (sym)->declared_special = 1; |
| 789 | tem = Fcar (Fcdr (Fcdr (args))); | 799 | tem = Fcar (XCDR (XCDR (args))); |
| 790 | if (!NILP (tem)) | 800 | if (!NILP (tem)) |
| 791 | { | 801 | { |
| 792 | if (!NILP (Vpurify_flag)) | 802 | if (!NILP (Vpurify_flag)) |
| @@ -827,7 +837,7 @@ usage: (let* VARLIST BODY...) */) | |||
| 827 | 837 | ||
| 828 | lexenv = Vinternal_interpreter_environment; | 838 | lexenv = Vinternal_interpreter_environment; |
| 829 | 839 | ||
| 830 | varlist = Fcar (args); | 840 | varlist = XCAR (args); |
| 831 | while (CONSP (varlist)) | 841 | while (CONSP (varlist)) |
| 832 | { | 842 | { |
| 833 | QUIT; | 843 | QUIT; |
| @@ -868,7 +878,7 @@ usage: (let* VARLIST BODY...) */) | |||
| 868 | varlist = XCDR (varlist); | 878 | varlist = XCDR (varlist); |
| 869 | } | 879 | } |
| 870 | UNGCPRO; | 880 | UNGCPRO; |
| 871 | val = Fprogn (Fcdr (args)); | 881 | val = Fprogn (XCDR (args)); |
| 872 | return unbind_to (count, val); | 882 | return unbind_to (count, val); |
| 873 | } | 883 | } |
| 874 | 884 | ||
| @@ -888,7 +898,7 @@ usage: (let VARLIST BODY...) */) | |||
| 888 | struct gcpro gcpro1, gcpro2; | 898 | struct gcpro gcpro1, gcpro2; |
| 889 | USE_SAFE_ALLOCA; | 899 | USE_SAFE_ALLOCA; |
| 890 | 900 | ||
| 891 | varlist = Fcar (args); | 901 | varlist = XCAR (args); |
| 892 | 902 | ||
| 893 | /* Make space to hold the values to give the bound variables. */ | 903 | /* Make space to hold the values to give the bound variables. */ |
| 894 | elt = Flength (varlist); | 904 | elt = Flength (varlist); |
| @@ -915,7 +925,7 @@ usage: (let VARLIST BODY...) */) | |||
| 915 | 925 | ||
| 916 | lexenv = Vinternal_interpreter_environment; | 926 | lexenv = Vinternal_interpreter_environment; |
| 917 | 927 | ||
| 918 | varlist = Fcar (args); | 928 | varlist = XCAR (args); |
| 919 | for (argnum = 0; CONSP (varlist); varlist = XCDR (varlist)) | 929 | for (argnum = 0; CONSP (varlist); varlist = XCDR (varlist)) |
| 920 | { | 930 | { |
| 921 | Lisp_Object var; | 931 | Lisp_Object var; |
| @@ -938,7 +948,7 @@ usage: (let VARLIST BODY...) */) | |||
| 938 | /* Instantiate a new lexical environment. */ | 948 | /* Instantiate a new lexical environment. */ |
| 939 | specbind (Qinternal_interpreter_environment, lexenv); | 949 | specbind (Qinternal_interpreter_environment, lexenv); |
| 940 | 950 | ||
| 941 | elt = Fprogn (Fcdr (args)); | 951 | elt = Fprogn (XCDR (args)); |
| 942 | SAFE_FREE (); | 952 | SAFE_FREE (); |
| 943 | return unbind_to (count, elt); | 953 | return unbind_to (count, elt); |
| 944 | } | 954 | } |
| @@ -955,8 +965,8 @@ usage: (while TEST BODY...) */) | |||
| 955 | 965 | ||
| 956 | GCPRO2 (test, body); | 966 | GCPRO2 (test, body); |
| 957 | 967 | ||
| 958 | test = Fcar (args); | 968 | test = XCAR (args); |
| 959 | body = Fcdr (args); | 969 | body = XCDR (args); |
| 960 | while (!NILP (eval_sub (test))) | 970 | while (!NILP (eval_sub (test))) |
| 961 | { | 971 | { |
| 962 | QUIT; | 972 | QUIT; |
| @@ -1053,9 +1063,9 @@ usage: (catch TAG BODY...) */) | |||
| 1053 | struct gcpro gcpro1; | 1063 | struct gcpro gcpro1; |
| 1054 | 1064 | ||
| 1055 | GCPRO1 (args); | 1065 | GCPRO1 (args); |
| 1056 | tag = eval_sub (Fcar (args)); | 1066 | tag = eval_sub (XCAR (args)); |
| 1057 | UNGCPRO; | 1067 | UNGCPRO; |
| 1058 | return internal_catch (tag, Fprogn, Fcdr (args)); | 1068 | return internal_catch (tag, Fprogn, XCDR (args)); |
| 1059 | } | 1069 | } |
| 1060 | 1070 | ||
| 1061 | /* Set up a catch, then call C function FUNC on argument ARG. | 1071 | /* Set up a catch, then call C function FUNC on argument ARG. |
| @@ -1169,8 +1179,8 @@ usage: (unwind-protect BODYFORM UNWINDFORMS...) */) | |||
| 1169 | Lisp_Object val; | 1179 | Lisp_Object val; |
| 1170 | ptrdiff_t count = SPECPDL_INDEX (); | 1180 | ptrdiff_t count = SPECPDL_INDEX (); |
| 1171 | 1181 | ||
| 1172 | record_unwind_protect (Fprogn, Fcdr (args)); | 1182 | record_unwind_protect (unwind_body, XCDR (args)); |
| 1173 | val = eval_sub (Fcar (args)); | 1183 | val = eval_sub (XCAR (args)); |
| 1174 | return unbind_to (count, val); | 1184 | return unbind_to (count, val); |
| 1175 | } | 1185 | } |
| 1176 | 1186 | ||
| @@ -1202,9 +1212,9 @@ See also the function `signal' for more info. | |||
| 1202 | usage: (condition-case VAR BODYFORM &rest HANDLERS) */) | 1212 | usage: (condition-case VAR BODYFORM &rest HANDLERS) */) |
| 1203 | (Lisp_Object args) | 1213 | (Lisp_Object args) |
| 1204 | { | 1214 | { |
| 1205 | Lisp_Object var = Fcar (args); | 1215 | Lisp_Object var = XCAR (args); |
| 1206 | Lisp_Object bodyform = Fcar (Fcdr (args)); | 1216 | Lisp_Object bodyform = XCAR (XCDR (args)); |
| 1207 | Lisp_Object handlers = Fcdr (Fcdr (args)); | 1217 | Lisp_Object handlers = XCDR (XCDR (args)); |
| 1208 | 1218 | ||
| 1209 | return internal_lisp_condition_case (var, bodyform, handlers); | 1219 | return internal_lisp_condition_case (var, bodyform, handlers); |
| 1210 | } | 1220 | } |
| @@ -1631,7 +1641,7 @@ signal_error (const char *s, Lisp_Object arg) | |||
| 1631 | } | 1641 | } |
| 1632 | 1642 | ||
| 1633 | if (!NILP (hare)) | 1643 | if (!NILP (hare)) |
| 1634 | arg = Fcons (arg, Qnil); /* Make it a list. */ | 1644 | arg = list1 (arg); |
| 1635 | 1645 | ||
| 1636 | xsignal (Qerror, Fcons (build_string (s), arg)); | 1646 | xsignal (Qerror, Fcons (build_string (s), arg)); |
| 1637 | } | 1647 | } |
| @@ -1723,7 +1733,7 @@ maybe_call_debugger (Lisp_Object conditions, Lisp_Object sig, Lisp_Object data) | |||
| 1723 | /* RMS: What's this for? */ | 1733 | /* RMS: What's this for? */ |
| 1724 | && when_entered_debugger < num_nonmacro_input_events) | 1734 | && when_entered_debugger < num_nonmacro_input_events) |
| 1725 | { | 1735 | { |
| 1726 | call_debugger (Fcons (Qerror, Fcons (combined_data, Qnil))); | 1736 | call_debugger (list2 (Qerror, combined_data)); |
| 1727 | return 1; | 1737 | return 1; |
| 1728 | } | 1738 | } |
| 1729 | 1739 | ||
| @@ -1910,10 +1920,10 @@ this does nothing and returns nil. */) | |||
| 1910 | Qnil); | 1920 | Qnil); |
| 1911 | } | 1921 | } |
| 1912 | 1922 | ||
| 1913 | Lisp_Object | 1923 | void |
| 1914 | un_autoload (Lisp_Object oldqueue) | 1924 | un_autoload (Lisp_Object oldqueue) |
| 1915 | { | 1925 | { |
| 1916 | register Lisp_Object queue, first, second; | 1926 | Lisp_Object queue, first, second; |
| 1917 | 1927 | ||
| 1918 | /* Queue to unwind is current value of Vautoload_queue. | 1928 | /* Queue to unwind is current value of Vautoload_queue. |
| 1919 | oldqueue is the shadowed value to leave in Vautoload_queue. */ | 1929 | oldqueue is the shadowed value to leave in Vautoload_queue. */ |
| @@ -1930,7 +1940,6 @@ un_autoload (Lisp_Object oldqueue) | |||
| 1930 | Ffset (first, second); | 1940 | Ffset (first, second); |
| 1931 | queue = XCDR (queue); | 1941 | queue = XCDR (queue); |
| 1932 | } | 1942 | } |
| 1933 | return Qnil; | ||
| 1934 | } | 1943 | } |
| 1935 | 1944 | ||
| 1936 | /* Load an autoloaded function. | 1945 | /* Load an autoloaded function. |
| @@ -2012,7 +2021,7 @@ If LEXICAL is t, evaluate using lexical scoping. */) | |||
| 2012 | { | 2021 | { |
| 2013 | ptrdiff_t count = SPECPDL_INDEX (); | 2022 | ptrdiff_t count = SPECPDL_INDEX (); |
| 2014 | specbind (Qinternal_interpreter_environment, | 2023 | specbind (Qinternal_interpreter_environment, |
| 2015 | CONSP (lexical) || NILP (lexical) ? lexical : Fcons (Qt, Qnil)); | 2024 | CONSP (lexical) || NILP (lexical) ? lexical : list1 (Qt)); |
| 2016 | return unbind_to (count, eval_sub (form)); | 2025 | return unbind_to (count, eval_sub (form)); |
| 2017 | } | 2026 | } |
| 2018 | 2027 | ||
| @@ -2277,7 +2286,7 @@ eval_sub (Lisp_Object form) | |||
| 2277 | 2286 | ||
| 2278 | lisp_eval_depth--; | 2287 | lisp_eval_depth--; |
| 2279 | if (backtrace_debug_on_exit (specpdl_ptr - 1)) | 2288 | if (backtrace_debug_on_exit (specpdl_ptr - 1)) |
| 2280 | val = call_debugger (Fcons (Qexit, Fcons (val, Qnil))); | 2289 | val = call_debugger (list2 (Qexit, val)); |
| 2281 | specpdl_ptr--; | 2290 | specpdl_ptr--; |
| 2282 | 2291 | ||
| 2283 | return val; | 2292 | return val; |
| @@ -2898,7 +2907,7 @@ usage: (funcall FUNCTION &rest ARGUMENTS) */) | |||
| 2898 | check_cons_list (); | 2907 | check_cons_list (); |
| 2899 | lisp_eval_depth--; | 2908 | lisp_eval_depth--; |
| 2900 | if (backtrace_debug_on_exit (specpdl_ptr - 1)) | 2909 | if (backtrace_debug_on_exit (specpdl_ptr - 1)) |
| 2901 | val = call_debugger (Fcons (Qexit, Fcons (val, Qnil))); | 2910 | val = call_debugger (list2 (Qexit, val)); |
| 2902 | specpdl_ptr--; | 2911 | specpdl_ptr--; |
| 2903 | return val; | 2912 | return val; |
| 2904 | } | 2913 | } |
| @@ -2940,7 +2949,7 @@ apply_lambda (Lisp_Object fun, Lisp_Object args) | |||
| 2940 | { | 2949 | { |
| 2941 | /* Don't do it again when we return to eval. */ | 2950 | /* Don't do it again when we return to eval. */ |
| 2942 | set_backtrace_debug_on_exit (specpdl_ptr - 1, false); | 2951 | set_backtrace_debug_on_exit (specpdl_ptr - 1, false); |
| 2943 | tem = call_debugger (Fcons (Qexit, Fcons (tem, Qnil))); | 2952 | tem = call_debugger (list2 (Qexit, tem)); |
| 2944 | } | 2953 | } |
| 2945 | SAFE_FREE (); | 2954 | SAFE_FREE (); |
| 2946 | return tem; | 2955 | return tem; |
| @@ -3255,8 +3264,10 @@ specbind (Lisp_Object symbol, Lisp_Object value) | |||
| 3255 | } | 3264 | } |
| 3256 | } | 3265 | } |
| 3257 | 3266 | ||
| 3267 | /* Push unwind-protect entries of various types. */ | ||
| 3268 | |||
| 3258 | void | 3269 | void |
| 3259 | record_unwind_protect (Lisp_Object (*function) (Lisp_Object), Lisp_Object arg) | 3270 | record_unwind_protect (void (*function) (Lisp_Object), Lisp_Object arg) |
| 3260 | { | 3271 | { |
| 3261 | specpdl_ptr->unwind.kind = SPECPDL_UNWIND; | 3272 | specpdl_ptr->unwind.kind = SPECPDL_UNWIND; |
| 3262 | specpdl_ptr->unwind.func = function; | 3273 | specpdl_ptr->unwind.func = function; |
| @@ -3265,6 +3276,32 @@ record_unwind_protect (Lisp_Object (*function) (Lisp_Object), Lisp_Object arg) | |||
| 3265 | } | 3276 | } |
| 3266 | 3277 | ||
| 3267 | void | 3278 | void |
| 3279 | record_unwind_protect_ptr (void (*function) (void *), void *arg) | ||
| 3280 | { | ||
| 3281 | specpdl_ptr->unwind_ptr.kind = SPECPDL_UNWIND_PTR; | ||
| 3282 | specpdl_ptr->unwind_ptr.func = function; | ||
| 3283 | specpdl_ptr->unwind_ptr.arg = arg; | ||
| 3284 | grow_specpdl (); | ||
| 3285 | } | ||
| 3286 | |||
| 3287 | void | ||
| 3288 | record_unwind_protect_int (void (*function) (int), int arg) | ||
| 3289 | { | ||
| 3290 | specpdl_ptr->unwind_int.kind = SPECPDL_UNWIND_INT; | ||
| 3291 | specpdl_ptr->unwind_int.func = function; | ||
| 3292 | specpdl_ptr->unwind_int.arg = arg; | ||
| 3293 | grow_specpdl (); | ||
| 3294 | } | ||
| 3295 | |||
| 3296 | void | ||
| 3297 | record_unwind_protect_void (void (*function) (void)) | ||
| 3298 | { | ||
| 3299 | specpdl_ptr->unwind_void.kind = SPECPDL_UNWIND_VOID; | ||
| 3300 | specpdl_ptr->unwind_void.func = function; | ||
| 3301 | grow_specpdl (); | ||
| 3302 | } | ||
| 3303 | |||
| 3304 | void | ||
| 3268 | rebind_for_thread_switch (void) | 3305 | rebind_for_thread_switch (void) |
| 3269 | { | 3306 | { |
| 3270 | union specbinding *bind; | 3307 | union specbinding *bind; |
| @@ -3288,7 +3325,18 @@ do_one_unbind (union specbinding *this_binding, int unwinding) | |||
| 3288 | switch (this_binding->kind) | 3325 | switch (this_binding->kind) |
| 3289 | { | 3326 | { |
| 3290 | case SPECPDL_UNWIND: | 3327 | case SPECPDL_UNWIND: |
| 3291 | specpdl_func (this_binding) (specpdl_arg (this_binding)); | 3328 | specpdl_ptr->unwind.func (specpdl_ptr->unwind.arg); |
| 3329 | break; | ||
| 3330 | case SPECPDL_UNWIND_PTR: | ||
| 3331 | specpdl_ptr->unwind_ptr.func (specpdl_ptr->unwind_ptr.arg); | ||
| 3332 | break; | ||
| 3333 | case SPECPDL_UNWIND_INT: | ||
| 3334 | specpdl_ptr->unwind_int.func (specpdl_ptr->unwind_int.arg); | ||
| 3335 | break; | ||
| 3336 | case SPECPDL_UNWIND_VOID: | ||
| 3337 | specpdl_ptr->unwind_void.func (); | ||
| 3338 | break; | ||
| 3339 | case SPECPDL_BACKTRACE: | ||
| 3292 | break; | 3340 | break; |
| 3293 | case SPECPDL_LET: | 3341 | case SPECPDL_LET: |
| 3294 | /* If variable has a trivial value (no forwarding), we can | 3342 | /* If variable has a trivial value (no forwarding), we can |
| @@ -3304,8 +3352,6 @@ do_one_unbind (union specbinding *this_binding, int unwinding) | |||
| 3304 | Fset_default (specpdl_symbol (this_binding), | 3352 | Fset_default (specpdl_symbol (this_binding), |
| 3305 | specpdl_old_value (this_binding)); | 3353 | specpdl_old_value (this_binding)); |
| 3306 | break; | 3354 | break; |
| 3307 | case SPECPDL_BACKTRACE: | ||
| 3308 | break; | ||
| 3309 | case SPECPDL_LET_LOCAL: | 3355 | case SPECPDL_LET_LOCAL: |
| 3310 | case SPECPDL_LET_DEFAULT: | 3356 | case SPECPDL_LET_DEFAULT: |
| 3311 | { /* If the symbol is a list, it is really (SYMBOL WHERE | 3357 | { /* If the symbol is a list, it is really (SYMBOL WHERE |
| @@ -3331,6 +3377,46 @@ do_one_unbind (union specbinding *this_binding, int unwinding) | |||
| 3331 | } | 3377 | } |
| 3332 | } | 3378 | } |
| 3333 | 3379 | ||
| 3380 | void | ||
| 3381 | do_nothing (void) | ||
| 3382 | {} | ||
| 3383 | |||
| 3384 | /* Push an unwind-protect entry that does nothing, so that | ||
| 3385 | set_unwind_protect_ptr can overwrite it later. */ | ||
| 3386 | |||
| 3387 | void | ||
| 3388 | record_unwind_protect_nothing (void) | ||
| 3389 | { | ||
| 3390 | record_unwind_protect_void (do_nothing); | ||
| 3391 | } | ||
| 3392 | |||
| 3393 | /* Clear the unwind-protect entry COUNT, so that it does nothing. | ||
| 3394 | It need not be at the top of the stack. */ | ||
| 3395 | |||
| 3396 | void | ||
| 3397 | clear_unwind_protect (ptrdiff_t count) | ||
| 3398 | { | ||
| 3399 | union specbinding *p = specpdl + count; | ||
| 3400 | p->unwind_void.kind = SPECPDL_UNWIND_VOID; | ||
| 3401 | p->unwind_void.func = do_nothing; | ||
| 3402 | } | ||
| 3403 | |||
| 3404 | /* Set the unwind-protect entry COUNT so that it invokes FUNC (ARG). | ||
| 3405 | It need not be at the top of the stack. Discard the entry's | ||
| 3406 | previous value without invoking it. */ | ||
| 3407 | |||
| 3408 | void | ||
| 3409 | set_unwind_protect_ptr (ptrdiff_t count, void (*func) (void *), void *arg) | ||
| 3410 | { | ||
| 3411 | union specbinding *p = specpdl + count; | ||
| 3412 | p->unwind_ptr.kind = SPECPDL_UNWIND_PTR; | ||
| 3413 | p->unwind_ptr.func = func; | ||
| 3414 | p->unwind_ptr.arg = arg; | ||
| 3415 | } | ||
| 3416 | |||
| 3417 | /* Pop and execute entries from the unwind-protect stack until the | ||
| 3418 | depth COUNT is reached. Return VALUE. */ | ||
| 3419 | |||
| 3334 | Lisp_Object | 3420 | Lisp_Object |
| 3335 | unbind_to (ptrdiff_t count, Lisp_Object value) | 3421 | unbind_to (ptrdiff_t count, Lisp_Object value) |
| 3336 | { | 3422 | { |
| @@ -3449,7 +3535,30 @@ Output stream used is value of `standard-output'. */) | |||
| 3449 | return Qnil; | 3535 | return Qnil; |
| 3450 | } | 3536 | } |
| 3451 | 3537 | ||
| 3452 | DEFUN ("backtrace-frame", Fbacktrace_frame, Sbacktrace_frame, 1, 1, NULL, | 3538 | static union specbinding * |
| 3539 | get_backtrace_frame (Lisp_Object nframes, Lisp_Object base) | ||
| 3540 | { | ||
| 3541 | union specbinding *pdl = backtrace_top (); | ||
| 3542 | register EMACS_INT i; | ||
| 3543 | |||
| 3544 | CHECK_NATNUM (nframes); | ||
| 3545 | |||
| 3546 | if (!NILP (base)) | ||
| 3547 | { /* Skip up to `base'. */ | ||
| 3548 | base = Findirect_function (base, Qt); | ||
| 3549 | while (backtrace_p (pdl) | ||
| 3550 | && !EQ (base, Findirect_function (backtrace_function (pdl), Qt))) | ||
| 3551 | pdl = backtrace_next (pdl); | ||
| 3552 | } | ||
| 3553 | |||
| 3554 | /* Find the frame requested. */ | ||
| 3555 | for (i = XFASTINT (nframes); i > 0 && backtrace_p (pdl); i--) | ||
| 3556 | pdl = backtrace_next (pdl); | ||
| 3557 | |||
| 3558 | return pdl; | ||
| 3559 | } | ||
| 3560 | |||
| 3561 | DEFUN ("backtrace-frame", Fbacktrace_frame, Sbacktrace_frame, 1, 2, NULL, | ||
| 3453 | doc: /* Return the function and arguments NFRAMES up from current execution point. | 3562 | doc: /* Return the function and arguments NFRAMES up from current execution point. |
| 3454 | If that frame has not evaluated the arguments yet (or is a special form), | 3563 | If that frame has not evaluated the arguments yet (or is a special form), |
| 3455 | the value is (nil FUNCTION ARG-FORMS...). | 3564 | the value is (nil FUNCTION ARG-FORMS...). |
| @@ -3458,17 +3567,12 @@ the value is (t FUNCTION ARG-VALUES...). | |||
| 3458 | A &rest arg is represented as the tail of the list ARG-VALUES. | 3567 | A &rest arg is represented as the tail of the list ARG-VALUES. |
| 3459 | FUNCTION is whatever was supplied as car of evaluated list, | 3568 | FUNCTION is whatever was supplied as car of evaluated list, |
| 3460 | or a lambda expression for macro calls. | 3569 | or a lambda expression for macro calls. |
| 3461 | If NFRAMES is more than the number of frames, the value is nil. */) | 3570 | If NFRAMES is more than the number of frames, the value is nil. |
| 3462 | (Lisp_Object nframes) | 3571 | If BASE is non-nil, it should be a function and NFRAMES counts from its |
| 3572 | nearest activation frame. */) | ||
| 3573 | (Lisp_Object nframes, Lisp_Object base) | ||
| 3463 | { | 3574 | { |
| 3464 | union specbinding *pdl = backtrace_top (); | 3575 | union specbinding *pdl = get_backtrace_frame (nframes, base); |
| 3465 | register EMACS_INT i; | ||
| 3466 | |||
| 3467 | CHECK_NATNUM (nframes); | ||
| 3468 | |||
| 3469 | /* Find the frame requested. */ | ||
| 3470 | for (i = 0; backtrace_p (pdl) && i < XFASTINT (nframes); i++) | ||
| 3471 | pdl = backtrace_next (pdl); | ||
| 3472 | 3576 | ||
| 3473 | if (!backtrace_p (pdl)) | 3577 | if (!backtrace_p (pdl)) |
| 3474 | return Qnil; | 3578 | return Qnil; |
| @@ -3483,6 +3587,109 @@ If NFRAMES is more than the number of frames, the value is nil. */) | |||
| 3483 | } | 3587 | } |
| 3484 | } | 3588 | } |
| 3485 | 3589 | ||
| 3590 | /* For backtrace-eval, we want to temporarily unwind the last few elements of | ||
| 3591 | the specpdl stack, and then rewind them. We store the pre-unwind values | ||
| 3592 | directly in the pre-existing specpdl elements (i.e. we swap the current | ||
| 3593 | value and the old value stored in the specpdl), kind of like the inplace | ||
| 3594 | pointer-reversal trick. As it turns out, the rewind does the same as the | ||
| 3595 | unwind, except it starts from the other end of the spepdl stack, so we use | ||
| 3596 | the same function for both unwind and rewind. */ | ||
| 3597 | static void | ||
| 3598 | backtrace_eval_unrewind (int distance) | ||
| 3599 | { | ||
| 3600 | union specbinding *tmp = specpdl_ptr; | ||
| 3601 | int step = -1; | ||
| 3602 | if (distance < 0) | ||
| 3603 | { /* It's a rewind rather than unwind. */ | ||
| 3604 | tmp += distance - 1; | ||
| 3605 | step = 1; | ||
| 3606 | distance = -distance; | ||
| 3607 | } | ||
| 3608 | |||
| 3609 | for (; distance > 0; distance--) | ||
| 3610 | { | ||
| 3611 | tmp += step; | ||
| 3612 | /* */ | ||
| 3613 | switch (tmp->kind) | ||
| 3614 | { | ||
| 3615 | /* FIXME: Ideally we'd like to "temporarily unwind" (some of) those | ||
| 3616 | unwind_protect, but the problem is that we don't know how to | ||
| 3617 | rewind them afterwards. */ | ||
| 3618 | case SPECPDL_UNWIND: | ||
| 3619 | case SPECPDL_UNWIND_PTR: | ||
| 3620 | case SPECPDL_UNWIND_INT: | ||
| 3621 | case SPECPDL_UNWIND_VOID: | ||
| 3622 | case SPECPDL_BACKTRACE: | ||
| 3623 | break; | ||
| 3624 | case SPECPDL_LET: | ||
| 3625 | /* If variable has a trivial value (no forwarding), we can | ||
| 3626 | just set it. No need to check for constant symbols here, | ||
| 3627 | since that was already done by specbind. */ | ||
| 3628 | if (XSYMBOL (specpdl_symbol (tmp))->redirect | ||
| 3629 | == SYMBOL_PLAINVAL) | ||
| 3630 | { | ||
| 3631 | struct Lisp_Symbol *sym = XSYMBOL (specpdl_symbol (tmp)); | ||
| 3632 | Lisp_Object old_value = specpdl_old_value (tmp); | ||
| 3633 | set_specpdl_old_value (tmp, SYMBOL_VAL (sym)); | ||
| 3634 | SET_SYMBOL_VAL (sym, old_value); | ||
| 3635 | break; | ||
| 3636 | } | ||
| 3637 | else | ||
| 3638 | { | ||
| 3639 | /* FALLTHROUGH! | ||
| 3640 | NOTE: we only ever come here if make_local_foo was used for | ||
| 3641 | the first time on this var within this let. */ | ||
| 3642 | } | ||
| 3643 | case SPECPDL_LET_DEFAULT: | ||
| 3644 | { | ||
| 3645 | Lisp_Object sym = specpdl_symbol (tmp); | ||
| 3646 | Lisp_Object old_value = specpdl_old_value (tmp); | ||
| 3647 | set_specpdl_old_value (tmp, Fdefault_value (sym)); | ||
| 3648 | Fset_default (sym, old_value); | ||
| 3649 | } | ||
| 3650 | break; | ||
| 3651 | case SPECPDL_LET_LOCAL: | ||
| 3652 | { | ||
| 3653 | Lisp_Object symbol = specpdl_symbol (tmp); | ||
| 3654 | Lisp_Object where = specpdl_where (tmp); | ||
| 3655 | Lisp_Object old_value = specpdl_old_value (tmp); | ||
| 3656 | eassert (BUFFERP (where)); | ||
| 3657 | |||
| 3658 | /* If this was a local binding, reset the value in the appropriate | ||
| 3659 | buffer, but only if that buffer's binding still exists. */ | ||
| 3660 | if (!NILP (Flocal_variable_p (symbol, where))) | ||
| 3661 | { | ||
| 3662 | set_specpdl_old_value | ||
| 3663 | (tmp, Fbuffer_local_value (symbol, where)); | ||
| 3664 | set_internal (symbol, old_value, where, 1); | ||
| 3665 | } | ||
| 3666 | } | ||
| 3667 | break; | ||
| 3668 | } | ||
| 3669 | } | ||
| 3670 | } | ||
| 3671 | |||
| 3672 | DEFUN ("backtrace-eval", Fbacktrace_eval, Sbacktrace_eval, 2, 3, NULL, | ||
| 3673 | doc: /* Evaluate EXP in the context of some activation frame. | ||
| 3674 | NFRAMES and BASE specify the activation frame to use, as in `backtrace-frame'. */) | ||
| 3675 | (Lisp_Object exp, Lisp_Object nframes, Lisp_Object base) | ||
| 3676 | { | ||
| 3677 | union specbinding *pdl = get_backtrace_frame (nframes, base); | ||
| 3678 | ptrdiff_t count = SPECPDL_INDEX (); | ||
| 3679 | ptrdiff_t distance = specpdl_ptr - pdl; | ||
| 3680 | eassert (distance >= 0); | ||
| 3681 | |||
| 3682 | if (!backtrace_p (pdl)) | ||
| 3683 | error ("Activation frame not found!"); | ||
| 3684 | |||
| 3685 | backtrace_eval_unrewind (distance); | ||
| 3686 | record_unwind_protect_int (backtrace_eval_unrewind, -distance); | ||
| 3687 | |||
| 3688 | /* Use eval_sub rather than Feval since the main motivation behind | ||
| 3689 | backtrace-eval is to be able to get/set the value of lexical variables | ||
| 3690 | from the debugger. */ | ||
| 3691 | return unbind_to (count, eval_sub (exp)); | ||
| 3692 | } | ||
| 3486 | 3693 | ||
| 3487 | void | 3694 | void |
| 3488 | mark_specpdl (union specbinding *first, union specbinding *ptr) | 3695 | mark_specpdl (union specbinding *first, union specbinding *ptr) |
| @@ -3729,6 +3936,7 @@ alist of active lexical bindings. */); | |||
| 3729 | defsubr (&Sbacktrace_debug); | 3936 | defsubr (&Sbacktrace_debug); |
| 3730 | defsubr (&Sbacktrace); | 3937 | defsubr (&Sbacktrace); |
| 3731 | defsubr (&Sbacktrace_frame); | 3938 | defsubr (&Sbacktrace_frame); |
| 3939 | defsubr (&Sbacktrace_eval); | ||
| 3732 | defsubr (&Sspecial_variable_p); | 3940 | defsubr (&Sspecial_variable_p); |
| 3733 | defsubr (&Sfunctionp); | 3941 | defsubr (&Sfunctionp); |
| 3734 | } | 3942 | } |