diff options
Diffstat (limited to 'src/eval.c')
| -rw-r--r-- | src/eval.c | 206 |
1 files changed, 107 insertions, 99 deletions
diff --git a/src/eval.c b/src/eval.c index bbc1518be54..724f0018a58 100644 --- a/src/eval.c +++ b/src/eval.c | |||
| @@ -593,12 +593,12 @@ The return value is BASE-VARIABLE. */) | |||
| 593 | CHECK_SYMBOL (new_alias); | 593 | CHECK_SYMBOL (new_alias); |
| 594 | CHECK_SYMBOL (base_variable); | 594 | CHECK_SYMBOL (base_variable); |
| 595 | 595 | ||
| 596 | sym = XSYMBOL (new_alias); | 596 | if (SYMBOL_CONSTANT_P (new_alias)) |
| 597 | 597 | /* Making it an alias effectively changes its value. */ | |
| 598 | if (sym->constant) | ||
| 599 | /* Not sure why, but why not? */ | ||
| 600 | error ("Cannot make a constant an alias"); | 598 | error ("Cannot make a constant an alias"); |
| 601 | 599 | ||
| 600 | sym = XSYMBOL (new_alias); | ||
| 601 | |||
| 602 | switch (sym->redirect) | 602 | switch (sym->redirect) |
| 603 | { | 603 | { |
| 604 | case SYMBOL_FORWARDED: | 604 | case SYMBOL_FORWARDED: |
| @@ -617,8 +617,8 @@ The return value is BASE-VARIABLE. */) | |||
| 617 | so that old-code that affects n_a before the aliasing is setup | 617 | so that old-code that affects n_a before the aliasing is setup |
| 618 | still works. */ | 618 | still works. */ |
| 619 | if (NILP (Fboundp (base_variable))) | 619 | if (NILP (Fboundp (base_variable))) |
| 620 | set_internal (base_variable, find_symbol_value (new_alias), Qnil, 1); | 620 | set_internal (base_variable, find_symbol_value (new_alias), |
| 621 | 621 | Qnil, SET_INTERNAL_BIND); | |
| 622 | { | 622 | { |
| 623 | union specbinding *p; | 623 | union specbinding *p; |
| 624 | 624 | ||
| @@ -628,11 +628,14 @@ The return value is BASE-VARIABLE. */) | |||
| 628 | error ("Don't know how to make a let-bound variable an alias"); | 628 | error ("Don't know how to make a let-bound variable an alias"); |
| 629 | } | 629 | } |
| 630 | 630 | ||
| 631 | if (sym->trapped_write == SYMBOL_TRAPPED_WRITE) | ||
| 632 | notify_variable_watchers (new_alias, base_variable, Qdefvaralias, Qnil); | ||
| 633 | |||
| 631 | sym->declared_special = 1; | 634 | sym->declared_special = 1; |
| 632 | XSYMBOL (base_variable)->declared_special = 1; | 635 | XSYMBOL (base_variable)->declared_special = 1; |
| 633 | sym->redirect = SYMBOL_VARALIAS; | 636 | sym->redirect = SYMBOL_VARALIAS; |
| 634 | SET_SYMBOL_ALIAS (sym, XSYMBOL (base_variable)); | 637 | SET_SYMBOL_ALIAS (sym, XSYMBOL (base_variable)); |
| 635 | sym->constant = SYMBOL_CONSTANT_P (base_variable); | 638 | sym->trapped_write = XSYMBOL (base_variable)->trapped_write; |
| 636 | LOADHIST_ATTACH (new_alias); | 639 | LOADHIST_ATTACH (new_alias); |
| 637 | /* Even if docstring is nil: remove old docstring. */ | 640 | /* Even if docstring is nil: remove old docstring. */ |
| 638 | Fput (new_alias, Qvariable_documentation, docstring); | 641 | Fput (new_alias, Qvariable_documentation, docstring); |
| @@ -2645,9 +2648,7 @@ usage: (funcall FUNCTION &rest ARGUMENTS) */) | |||
| 2645 | Lisp_Object fun, original_fun; | 2648 | Lisp_Object fun, original_fun; |
| 2646 | Lisp_Object funcar; | 2649 | Lisp_Object funcar; |
| 2647 | ptrdiff_t numargs = nargs - 1; | 2650 | ptrdiff_t numargs = nargs - 1; |
| 2648 | Lisp_Object lisp_numargs; | ||
| 2649 | Lisp_Object val; | 2651 | Lisp_Object val; |
| 2650 | Lisp_Object *internal_args; | ||
| 2651 | ptrdiff_t count; | 2652 | ptrdiff_t count; |
| 2652 | 2653 | ||
| 2653 | QUIT; | 2654 | QUIT; |
| @@ -2680,86 +2681,7 @@ usage: (funcall FUNCTION &rest ARGUMENTS) */) | |||
| 2680 | fun = indirect_function (fun); | 2681 | fun = indirect_function (fun); |
| 2681 | 2682 | ||
| 2682 | if (SUBRP (fun)) | 2683 | if (SUBRP (fun)) |
| 2683 | { | 2684 | val = funcall_subr (XSUBR (fun), numargs, args + 1); |
| 2684 | if (numargs < XSUBR (fun)->min_args | ||
| 2685 | || (XSUBR (fun)->max_args >= 0 && XSUBR (fun)->max_args < numargs)) | ||
| 2686 | { | ||
| 2687 | XSETFASTINT (lisp_numargs, numargs); | ||
| 2688 | xsignal2 (Qwrong_number_of_arguments, original_fun, lisp_numargs); | ||
| 2689 | } | ||
| 2690 | |||
| 2691 | else if (XSUBR (fun)->max_args == UNEVALLED) | ||
| 2692 | xsignal1 (Qinvalid_function, original_fun); | ||
| 2693 | |||
| 2694 | else if (XSUBR (fun)->max_args == MANY) | ||
| 2695 | val = (XSUBR (fun)->function.aMANY) (numargs, args + 1); | ||
| 2696 | else | ||
| 2697 | { | ||
| 2698 | Lisp_Object internal_argbuf[8]; | ||
| 2699 | if (XSUBR (fun)->max_args > numargs) | ||
| 2700 | { | ||
| 2701 | eassert (XSUBR (fun)->max_args <= ARRAYELTS (internal_argbuf)); | ||
| 2702 | internal_args = internal_argbuf; | ||
| 2703 | memcpy (internal_args, args + 1, numargs * word_size); | ||
| 2704 | memclear (internal_args + numargs, | ||
| 2705 | (XSUBR (fun)->max_args - numargs) * word_size); | ||
| 2706 | } | ||
| 2707 | else | ||
| 2708 | internal_args = args + 1; | ||
| 2709 | switch (XSUBR (fun)->max_args) | ||
| 2710 | { | ||
| 2711 | case 0: | ||
| 2712 | val = (XSUBR (fun)->function.a0 ()); | ||
| 2713 | break; | ||
| 2714 | case 1: | ||
| 2715 | val = (XSUBR (fun)->function.a1 (internal_args[0])); | ||
| 2716 | break; | ||
| 2717 | case 2: | ||
| 2718 | val = (XSUBR (fun)->function.a2 | ||
| 2719 | (internal_args[0], internal_args[1])); | ||
| 2720 | break; | ||
| 2721 | case 3: | ||
| 2722 | val = (XSUBR (fun)->function.a3 | ||
| 2723 | (internal_args[0], internal_args[1], internal_args[2])); | ||
| 2724 | break; | ||
| 2725 | case 4: | ||
| 2726 | val = (XSUBR (fun)->function.a4 | ||
| 2727 | (internal_args[0], internal_args[1], internal_args[2], | ||
| 2728 | internal_args[3])); | ||
| 2729 | break; | ||
| 2730 | case 5: | ||
| 2731 | val = (XSUBR (fun)->function.a5 | ||
| 2732 | (internal_args[0], internal_args[1], internal_args[2], | ||
| 2733 | internal_args[3], internal_args[4])); | ||
| 2734 | break; | ||
| 2735 | case 6: | ||
| 2736 | val = (XSUBR (fun)->function.a6 | ||
| 2737 | (internal_args[0], internal_args[1], internal_args[2], | ||
| 2738 | internal_args[3], internal_args[4], internal_args[5])); | ||
| 2739 | break; | ||
| 2740 | case 7: | ||
| 2741 | val = (XSUBR (fun)->function.a7 | ||
| 2742 | (internal_args[0], internal_args[1], internal_args[2], | ||
| 2743 | internal_args[3], internal_args[4], internal_args[5], | ||
| 2744 | internal_args[6])); | ||
| 2745 | break; | ||
| 2746 | |||
| 2747 | case 8: | ||
| 2748 | val = (XSUBR (fun)->function.a8 | ||
| 2749 | (internal_args[0], internal_args[1], internal_args[2], | ||
| 2750 | internal_args[3], internal_args[4], internal_args[5], | ||
| 2751 | internal_args[6], internal_args[7])); | ||
| 2752 | break; | ||
| 2753 | |||
| 2754 | default: | ||
| 2755 | |||
| 2756 | /* If a subr takes more than 8 arguments without using MANY | ||
| 2757 | or UNEVALLED, we need to extend this function to support it. | ||
| 2758 | Until this is done, there is no way to call the function. */ | ||
| 2759 | emacs_abort (); | ||
| 2760 | } | ||
| 2761 | } | ||
| 2762 | } | ||
| 2763 | else if (COMPILEDP (fun)) | 2685 | else if (COMPILEDP (fun)) |
| 2764 | val = funcall_lambda (fun, numargs, args + 1); | 2686 | val = funcall_lambda (fun, numargs, args + 1); |
| 2765 | else | 2687 | else |
| @@ -2791,6 +2713,89 @@ usage: (funcall FUNCTION &rest ARGUMENTS) */) | |||
| 2791 | return val; | 2713 | return val; |
| 2792 | } | 2714 | } |
| 2793 | 2715 | ||
| 2716 | |||
| 2717 | /* Apply a C subroutine SUBR to the NUMARGS evaluated arguments in ARG_VECTOR | ||
| 2718 | and return the result of evaluation. */ | ||
| 2719 | |||
| 2720 | Lisp_Object | ||
| 2721 | funcall_subr (struct Lisp_Subr *subr, ptrdiff_t numargs, Lisp_Object *args) | ||
| 2722 | { | ||
| 2723 | if (numargs < subr->min_args | ||
| 2724 | || (subr->max_args >= 0 && subr->max_args < numargs)) | ||
| 2725 | { | ||
| 2726 | Lisp_Object fun; | ||
| 2727 | XSETSUBR (fun, subr); | ||
| 2728 | xsignal2 (Qwrong_number_of_arguments, fun, make_number (numargs)); | ||
| 2729 | } | ||
| 2730 | |||
| 2731 | else if (subr->max_args == UNEVALLED) | ||
| 2732 | { | ||
| 2733 | Lisp_Object fun; | ||
| 2734 | XSETSUBR (fun, subr); | ||
| 2735 | xsignal1 (Qinvalid_function, fun); | ||
| 2736 | } | ||
| 2737 | |||
| 2738 | else if (subr->max_args == MANY) | ||
| 2739 | return (subr->function.aMANY) (numargs, args); | ||
| 2740 | else | ||
| 2741 | { | ||
| 2742 | Lisp_Object internal_argbuf[8]; | ||
| 2743 | Lisp_Object *internal_args; | ||
| 2744 | if (subr->max_args > numargs) | ||
| 2745 | { | ||
| 2746 | eassert (subr->max_args <= ARRAYELTS (internal_argbuf)); | ||
| 2747 | internal_args = internal_argbuf; | ||
| 2748 | memcpy (internal_args, args, numargs * word_size); | ||
| 2749 | memclear (internal_args + numargs, | ||
| 2750 | (subr->max_args - numargs) * word_size); | ||
| 2751 | } | ||
| 2752 | else | ||
| 2753 | internal_args = args; | ||
| 2754 | switch (subr->max_args) | ||
| 2755 | { | ||
| 2756 | case 0: | ||
| 2757 | return (subr->function.a0 ()); | ||
| 2758 | case 1: | ||
| 2759 | return (subr->function.a1 (internal_args[0])); | ||
| 2760 | case 2: | ||
| 2761 | return (subr->function.a2 | ||
| 2762 | (internal_args[0], internal_args[1])); | ||
| 2763 | case 3: | ||
| 2764 | return (subr->function.a3 | ||
| 2765 | (internal_args[0], internal_args[1], internal_args[2])); | ||
| 2766 | case 4: | ||
| 2767 | return (subr->function.a4 | ||
| 2768 | (internal_args[0], internal_args[1], internal_args[2], | ||
| 2769 | internal_args[3])); | ||
| 2770 | case 5: | ||
| 2771 | return (subr->function.a5 | ||
| 2772 | (internal_args[0], internal_args[1], internal_args[2], | ||
| 2773 | internal_args[3], internal_args[4])); | ||
| 2774 | case 6: | ||
| 2775 | return (subr->function.a6 | ||
| 2776 | (internal_args[0], internal_args[1], internal_args[2], | ||
| 2777 | internal_args[3], internal_args[4], internal_args[5])); | ||
| 2778 | case 7: | ||
| 2779 | return (subr->function.a7 | ||
| 2780 | (internal_args[0], internal_args[1], internal_args[2], | ||
| 2781 | internal_args[3], internal_args[4], internal_args[5], | ||
| 2782 | internal_args[6])); | ||
| 2783 | case 8: | ||
| 2784 | return (subr->function.a8 | ||
| 2785 | (internal_args[0], internal_args[1], internal_args[2], | ||
| 2786 | internal_args[3], internal_args[4], internal_args[5], | ||
| 2787 | internal_args[6], internal_args[7])); | ||
| 2788 | |||
| 2789 | default: | ||
| 2790 | |||
| 2791 | /* If a subr takes more than 8 arguments without using MANY | ||
| 2792 | or UNEVALLED, we need to extend this function to support it. | ||
| 2793 | Until this is done, there is no way to call the function. */ | ||
| 2794 | emacs_abort (); | ||
| 2795 | } | ||
| 2796 | } | ||
| 2797 | } | ||
| 2798 | |||
| 2794 | static Lisp_Object | 2799 | static Lisp_Object |
| 2795 | apply_lambda (Lisp_Object fun, Lisp_Object args, ptrdiff_t count) | 2800 | apply_lambda (Lisp_Object fun, Lisp_Object args, ptrdiff_t count) |
| 2796 | { | 2801 | { |
| @@ -3171,10 +3176,10 @@ specbind (Lisp_Object symbol, Lisp_Object value) | |||
| 3171 | specpdl_ptr->let.symbol = symbol; | 3176 | specpdl_ptr->let.symbol = symbol; |
| 3172 | specpdl_ptr->let.old_value = SYMBOL_VAL (sym); | 3177 | specpdl_ptr->let.old_value = SYMBOL_VAL (sym); |
| 3173 | grow_specpdl (); | 3178 | grow_specpdl (); |
| 3174 | if (!sym->constant) | 3179 | if (!sym->trapped_write) |
| 3175 | SET_SYMBOL_VAL (sym, value); | 3180 | SET_SYMBOL_VAL (sym, value); |
| 3176 | else | 3181 | else |
| 3177 | set_internal (symbol, value, Qnil, 1); | 3182 | set_internal (symbol, value, Qnil, SET_INTERNAL_BIND); |
| 3178 | break; | 3183 | break; |
| 3179 | case SYMBOL_LOCALIZED: | 3184 | case SYMBOL_LOCALIZED: |
| 3180 | if (SYMBOL_BLV (sym)->frame_local) | 3185 | if (SYMBOL_BLV (sym)->frame_local) |
| @@ -3214,7 +3219,7 @@ specbind (Lisp_Object symbol, Lisp_Object value) | |||
| 3214 | specpdl_ptr->let.kind = SPECPDL_LET; | 3219 | specpdl_ptr->let.kind = SPECPDL_LET; |
| 3215 | 3220 | ||
| 3216 | grow_specpdl (); | 3221 | grow_specpdl (); |
| 3217 | set_internal (symbol, value, Qnil, 1); | 3222 | set_internal (symbol, value, Qnil, SET_INTERNAL_BIND); |
| 3218 | break; | 3223 | break; |
| 3219 | } | 3224 | } |
| 3220 | default: emacs_abort (); | 3225 | default: emacs_abort (); |
| @@ -3341,14 +3346,16 @@ unbind_to (ptrdiff_t count, Lisp_Object value) | |||
| 3341 | case SPECPDL_BACKTRACE: | 3346 | case SPECPDL_BACKTRACE: |
| 3342 | break; | 3347 | break; |
| 3343 | case SPECPDL_LET: | 3348 | case SPECPDL_LET: |
| 3344 | { /* If variable has a trivial value (no forwarding), we can | 3349 | { /* If variable has a trivial value (no forwarding), and |
| 3345 | just set it. No need to check for constant symbols here, | 3350 | isn't trapped, we can just set it. */ |
| 3346 | since that was already done by specbind. */ | ||
| 3347 | Lisp_Object sym = specpdl_symbol (specpdl_ptr); | 3351 | Lisp_Object sym = specpdl_symbol (specpdl_ptr); |
| 3348 | if (SYMBOLP (sym) && XSYMBOL (sym)->redirect == SYMBOL_PLAINVAL) | 3352 | if (SYMBOLP (sym) && XSYMBOL (sym)->redirect == SYMBOL_PLAINVAL) |
| 3349 | { | 3353 | { |
| 3350 | SET_SYMBOL_VAL (XSYMBOL (sym), | 3354 | if (XSYMBOL (sym)->trapped_write == SYMBOL_UNTRAPPED_WRITE) |
| 3351 | specpdl_old_value (specpdl_ptr)); | 3355 | SET_SYMBOL_VAL (XSYMBOL (sym), specpdl_old_value (specpdl_ptr)); |
| 3356 | else | ||
| 3357 | set_internal (sym, specpdl_old_value (specpdl_ptr), | ||
| 3358 | Qnil, SET_INTERNAL_UNBIND); | ||
| 3352 | break; | 3359 | break; |
| 3353 | } | 3360 | } |
| 3354 | else | 3361 | else |
| @@ -3371,7 +3378,7 @@ unbind_to (ptrdiff_t count, Lisp_Object value) | |||
| 3371 | /* If this was a local binding, reset the value in the appropriate | 3378 | /* If this was a local binding, reset the value in the appropriate |
| 3372 | buffer, but only if that buffer's binding still exists. */ | 3379 | buffer, but only if that buffer's binding still exists. */ |
| 3373 | if (!NILP (Flocal_variable_p (symbol, where))) | 3380 | if (!NILP (Flocal_variable_p (symbol, where))) |
| 3374 | set_internal (symbol, old_value, where, 1); | 3381 | set_internal (symbol, old_value, where, SET_INTERNAL_UNBIND); |
| 3375 | } | 3382 | } |
| 3376 | break; | 3383 | break; |
| 3377 | } | 3384 | } |
| @@ -3596,7 +3603,7 @@ backtrace_eval_unrewind (int distance) | |||
| 3596 | { | 3603 | { |
| 3597 | set_specpdl_old_value | 3604 | set_specpdl_old_value |
| 3598 | (tmp, Fbuffer_local_value (symbol, where)); | 3605 | (tmp, Fbuffer_local_value (symbol, where)); |
| 3599 | set_internal (symbol, old_value, where, 1); | 3606 | set_internal (symbol, old_value, where, SET_INTERNAL_UNBIND); |
| 3600 | } | 3607 | } |
| 3601 | } | 3608 | } |
| 3602 | break; | 3609 | break; |
| @@ -3940,6 +3947,7 @@ alist of active lexical bindings. */); | |||
| 3940 | defsubr (&Sset_default_toplevel_value); | 3947 | defsubr (&Sset_default_toplevel_value); |
| 3941 | defsubr (&Sdefvar); | 3948 | defsubr (&Sdefvar); |
| 3942 | defsubr (&Sdefvaralias); | 3949 | defsubr (&Sdefvaralias); |
| 3950 | DEFSYM (Qdefvaralias, "defvaralias"); | ||
| 3943 | defsubr (&Sdefconst); | 3951 | defsubr (&Sdefconst); |
| 3944 | defsubr (&Smake_var_non_special); | 3952 | defsubr (&Smake_var_non_special); |
| 3945 | defsubr (&Slet); | 3953 | defsubr (&Slet); |