diff options
| author | Gerd Moellmann | 2000-02-20 15:55:07 +0000 |
|---|---|---|
| committer | Gerd Moellmann | 2000-02-20 15:55:07 +0000 |
| commit | 9ab90667d31851abf6e5334d5c8fc866d62dde2f (patch) | |
| tree | 33dea50ddb859743321cf5164aefc83ff956c889 /src/eval.c | |
| parent | 2d06696fdcae3c266b917fb0a98bea9c01fa02fa (diff) | |
| download | emacs-9ab90667d31851abf6e5334d5c8fc866d62dde2f.tar.gz emacs-9ab90667d31851abf6e5334d5c8fc866d62dde2f.zip | |
(funcall_lambda): Don't bind Qmocklisp_arguments unless
Vmocklisp_arguments is nil. Inline Fcar and Fcdr.
(specbind, unbind_to): Handle most common case of non-constant
symbol with trivial value specially.
Diffstat (limited to 'src/eval.c')
| -rw-r--r-- | src/eval.c | 140 |
1 files changed, 87 insertions, 53 deletions
diff --git a/src/eval.c b/src/eval.c index b3a8319d9fa..1cb6de6e442 100644 --- a/src/eval.c +++ b/src/eval.c | |||
| @@ -2642,31 +2642,35 @@ funcall_lambda (fun, nargs, arg_vector) | |||
| 2642 | int nargs; | 2642 | int nargs; |
| 2643 | register Lisp_Object *arg_vector; | 2643 | register Lisp_Object *arg_vector; |
| 2644 | { | 2644 | { |
| 2645 | Lisp_Object val, tem; | 2645 | Lisp_Object val, syms_left, next; |
| 2646 | register Lisp_Object syms_left; | ||
| 2647 | Lisp_Object numargs; | ||
| 2648 | register Lisp_Object next; | ||
| 2649 | int count = specpdl_ptr - specpdl; | 2646 | int count = specpdl_ptr - specpdl; |
| 2650 | register int i; | 2647 | int i, optional, rest; |
| 2651 | int optional = 0, rest = 0; | ||
| 2652 | |||
| 2653 | specbind (Qmocklisp_arguments, Qt); /* t means NOT mocklisp! */ | ||
| 2654 | 2648 | ||
| 2655 | XSETFASTINT (numargs, nargs); | 2649 | if (NILP (Vmocklisp_arguments)) |
| 2650 | specbind (Qmocklisp_arguments, Qt); /* t means NOT mocklisp! */ | ||
| 2656 | 2651 | ||
| 2657 | if (CONSP (fun)) | 2652 | if (CONSP (fun)) |
| 2658 | syms_left = Fcar (Fcdr (fun)); | 2653 | { |
| 2654 | syms_left = XCDR (fun); | ||
| 2655 | if (CONSP (syms_left)) | ||
| 2656 | syms_left = XCAR (syms_left); | ||
| 2657 | else | ||
| 2658 | return Fsignal (Qinvalid_function, Fcons (fun, Qnil)); | ||
| 2659 | } | ||
| 2659 | else if (COMPILEDP (fun)) | 2660 | else if (COMPILEDP (fun)) |
| 2660 | syms_left = XVECTOR (fun)->contents[COMPILED_ARGLIST]; | 2661 | syms_left = XVECTOR (fun)->contents[COMPILED_ARGLIST]; |
| 2661 | else abort (); | 2662 | else |
| 2663 | abort (); | ||
| 2662 | 2664 | ||
| 2663 | i = 0; | 2665 | i = optional = rest = 0; |
| 2664 | for (; !NILP (syms_left); syms_left = Fcdr (syms_left)) | 2666 | for (; CONSP (syms_left); syms_left = XCDR (syms_left)) |
| 2665 | { | 2667 | { |
| 2666 | QUIT; | 2668 | QUIT; |
| 2667 | next = Fcar (syms_left); | 2669 | |
| 2670 | next = XCAR (syms_left); | ||
| 2668 | while (!SYMBOLP (next)) | 2671 | while (!SYMBOLP (next)) |
| 2669 | next = Fsignal (Qinvalid_function, Fcons (fun, Qnil)); | 2672 | next = Fsignal (Qinvalid_function, Fcons (fun, Qnil)); |
| 2673 | |||
| 2670 | if (EQ (next, Qand_rest)) | 2674 | if (EQ (next, Qand_rest)) |
| 2671 | rest = 1; | 2675 | rest = 1; |
| 2672 | else if (EQ (next, Qand_optional)) | 2676 | else if (EQ (next, Qand_optional)) |
| @@ -2677,21 +2681,22 @@ funcall_lambda (fun, nargs, arg_vector) | |||
| 2677 | i = nargs; | 2681 | i = nargs; |
| 2678 | } | 2682 | } |
| 2679 | else if (i < nargs) | 2683 | else if (i < nargs) |
| 2680 | { | 2684 | specbind (next, arg_vector[i++]); |
| 2681 | tem = arg_vector[i++]; | ||
| 2682 | specbind (next, tem); | ||
| 2683 | } | ||
| 2684 | else if (!optional) | 2685 | else if (!optional) |
| 2685 | return Fsignal (Qwrong_number_of_arguments, Fcons (fun, Fcons (numargs, Qnil))); | 2686 | return Fsignal (Qwrong_number_of_arguments, |
| 2687 | Fcons (fun, Fcons (make_number (nargs), Qnil))); | ||
| 2686 | else | 2688 | else |
| 2687 | specbind (next, Qnil); | 2689 | specbind (next, Qnil); |
| 2688 | } | 2690 | } |
| 2689 | 2691 | ||
| 2690 | if (i < nargs) | 2692 | if (!NILP (syms_left)) |
| 2691 | return Fsignal (Qwrong_number_of_arguments, Fcons (fun, Fcons (numargs, Qnil))); | 2693 | return Fsignal (Qinvalid_function, Fcons (fun, Qnil)); |
| 2694 | else if (i < nargs) | ||
| 2695 | return Fsignal (Qwrong_number_of_arguments, | ||
| 2696 | Fcons (fun, Fcons (make_number (nargs), Qnil))); | ||
| 2692 | 2697 | ||
| 2693 | if (CONSP (fun)) | 2698 | if (CONSP (fun)) |
| 2694 | val = Fprogn (Fcdr (Fcdr (fun))); | 2699 | val = Fprogn (XCDR (XCDR (fun))); |
| 2695 | else | 2700 | else |
| 2696 | { | 2701 | { |
| 2697 | /* If we have not actually read the bytecode string | 2702 | /* If we have not actually read the bytecode string |
| @@ -2702,6 +2707,7 @@ funcall_lambda (fun, nargs, arg_vector) | |||
| 2702 | XVECTOR (fun)->contents[COMPILED_CONSTANTS], | 2707 | XVECTOR (fun)->contents[COMPILED_CONSTANTS], |
| 2703 | XVECTOR (fun)->contents[COMPILED_STACK_DEPTH]); | 2708 | XVECTOR (fun)->contents[COMPILED_STACK_DEPTH]); |
| 2704 | } | 2709 | } |
| 2710 | |||
| 2705 | return unbind_to (count, val); | 2711 | return unbind_to (count, val); |
| 2706 | } | 2712 | } |
| 2707 | 2713 | ||
| @@ -2754,40 +2760,59 @@ specbind (symbol, value) | |||
| 2754 | Lisp_Object symbol, value; | 2760 | Lisp_Object symbol, value; |
| 2755 | { | 2761 | { |
| 2756 | Lisp_Object ovalue; | 2762 | Lisp_Object ovalue; |
| 2763 | extern int keyword_symbols_constant_flag; | ||
| 2757 | 2764 | ||
| 2758 | CHECK_SYMBOL (symbol, 0); | 2765 | CHECK_SYMBOL (symbol, 0); |
| 2759 | |||
| 2760 | ovalue = find_symbol_value (symbol); | ||
| 2761 | |||
| 2762 | if (specpdl_ptr == specpdl + specpdl_size) | 2766 | if (specpdl_ptr == specpdl + specpdl_size) |
| 2763 | grow_specpdl (); | 2767 | grow_specpdl (); |
| 2764 | specpdl_ptr->func = 0; | 2768 | |
| 2765 | specpdl_ptr->old_value = ovalue; | 2769 | /* The most common case is that a non-constant symbol with a trivial |
| 2766 | 2770 | value. Make that as fast as we can. */ | |
| 2767 | if (BUFFER_LOCAL_VALUEP (XSYMBOL (symbol)->value) | 2771 | if (!MISCP (XSYMBOL (symbol)->value) |
| 2768 | || SOME_BUFFER_LOCAL_VALUEP (XSYMBOL (symbol)->value) | 2772 | && !EQ (symbol, Qnil) |
| 2769 | || BUFFER_OBJFWDP (XSYMBOL (symbol)->value)) | 2773 | && !EQ (symbol, Qt) |
| 2770 | { | 2774 | && !(XSYMBOL (symbol)->name->data[0] == ':' |
| 2771 | Lisp_Object current_buffer, binding_buffer; | 2775 | && EQ (XSYMBOL (symbol)->obarray, initial_obarray) |
| 2772 | /* For a local variable, record both the symbol and which | 2776 | && keyword_symbols_constant_flag |
| 2773 | buffer's value we are saving. */ | 2777 | && !EQ (value, symbol))) |
| 2774 | current_buffer = Fcurrent_buffer (); | 2778 | { |
| 2775 | binding_buffer = current_buffer; | 2779 | specpdl_ptr->symbol = symbol; |
| 2776 | /* If the variable is not local in this buffer, | 2780 | specpdl_ptr->old_value = XSYMBOL (symbol)->value; |
| 2777 | we are saving the global value, so restore that. */ | 2781 | specpdl_ptr->func = NULL; |
| 2778 | if (NILP (Flocal_variable_p (symbol, binding_buffer))) | 2782 | ++specpdl_ptr; |
| 2779 | binding_buffer = Qnil; | 2783 | XSYMBOL (symbol)->value = value; |
| 2780 | specpdl_ptr->symbol | ||
| 2781 | = Fcons (symbol, Fcons (binding_buffer, current_buffer)); | ||
| 2782 | } | 2784 | } |
| 2783 | else | 2785 | else |
| 2784 | specpdl_ptr->symbol = symbol; | 2786 | { |
| 2787 | ovalue = find_symbol_value (symbol); | ||
| 2788 | specpdl_ptr->func = 0; | ||
| 2789 | specpdl_ptr->old_value = ovalue; | ||
| 2785 | 2790 | ||
| 2786 | specpdl_ptr++; | 2791 | if (BUFFER_LOCAL_VALUEP (XSYMBOL (symbol)->value) |
| 2787 | if (BUFFER_OBJFWDP (ovalue) || KBOARD_OBJFWDP (ovalue)) | 2792 | || SOME_BUFFER_LOCAL_VALUEP (XSYMBOL (symbol)->value) |
| 2788 | store_symval_forwarding (symbol, ovalue, value); | 2793 | || BUFFER_OBJFWDP (XSYMBOL (symbol)->value)) |
| 2789 | else | 2794 | { |
| 2790 | set_internal (symbol, value, 0, 1); | 2795 | Lisp_Object current_buffer, binding_buffer; |
| 2796 | /* For a local variable, record both the symbol and which | ||
| 2797 | buffer's value we are saving. */ | ||
| 2798 | current_buffer = Fcurrent_buffer (); | ||
| 2799 | binding_buffer = current_buffer; | ||
| 2800 | /* If the variable is not local in this buffer, | ||
| 2801 | we are saving the global value, so restore that. */ | ||
| 2802 | if (NILP (Flocal_variable_p (symbol, binding_buffer))) | ||
| 2803 | binding_buffer = Qnil; | ||
| 2804 | specpdl_ptr->symbol | ||
| 2805 | = Fcons (symbol, Fcons (binding_buffer, current_buffer)); | ||
| 2806 | } | ||
| 2807 | else | ||
| 2808 | specpdl_ptr->symbol = symbol; | ||
| 2809 | |||
| 2810 | specpdl_ptr++; | ||
| 2811 | if (BUFFER_OBJFWDP (ovalue) || KBOARD_OBJFWDP (ovalue)) | ||
| 2812 | store_symval_forwarding (symbol, ovalue, value); | ||
| 2813 | else | ||
| 2814 | set_internal (symbol, value, 0, 1); | ||
| 2815 | } | ||
| 2791 | } | 2816 | } |
| 2792 | 2817 | ||
| 2793 | void | 2818 | void |
| @@ -2812,12 +2837,12 @@ unbind_to (count, value) | |||
| 2812 | struct gcpro gcpro1; | 2837 | struct gcpro gcpro1; |
| 2813 | 2838 | ||
| 2814 | GCPRO1 (value); | 2839 | GCPRO1 (value); |
| 2815 | |||
| 2816 | Vquit_flag = Qnil; | 2840 | Vquit_flag = Qnil; |
| 2817 | 2841 | ||
| 2818 | while (specpdl_ptr != specpdl + count) | 2842 | while (specpdl_ptr != specpdl + count) |
| 2819 | { | 2843 | { |
| 2820 | --specpdl_ptr; | 2844 | --specpdl_ptr; |
| 2845 | |||
| 2821 | if (specpdl_ptr->func != 0) | 2846 | if (specpdl_ptr->func != 0) |
| 2822 | (*specpdl_ptr->func) (specpdl_ptr->old_value); | 2847 | (*specpdl_ptr->func) (specpdl_ptr->old_value); |
| 2823 | /* Note that a "binding" of nil is really an unwind protect, | 2848 | /* Note that a "binding" of nil is really an unwind protect, |
| @@ -2843,12 +2868,21 @@ unbind_to (count, value) | |||
| 2843 | set_internal (symbol, specpdl_ptr->old_value, XBUFFER (buffer), 1); | 2868 | set_internal (symbol, specpdl_ptr->old_value, XBUFFER (buffer), 1); |
| 2844 | } | 2869 | } |
| 2845 | else | 2870 | else |
| 2846 | set_internal (specpdl_ptr->symbol, specpdl_ptr->old_value, 0, 1); | 2871 | { |
| 2872 | /* If variable has a trivial value (no forwarding), we can | ||
| 2873 | just set it. No need to check for constant symbols here, | ||
| 2874 | since that was already done by specbind. */ | ||
| 2875 | if (!MISCP (XSYMBOL (specpdl_ptr->symbol)->value)) | ||
| 2876 | XSYMBOL (specpdl_ptr->symbol)->value = specpdl_ptr->old_value; | ||
| 2877 | else | ||
| 2878 | set_internal (specpdl_ptr->symbol, specpdl_ptr->old_value, 0, 1); | ||
| 2879 | } | ||
| 2847 | } | 2880 | } |
| 2848 | if (NILP (Vquit_flag) && quitf) Vquit_flag = Qt; | 2881 | |
| 2882 | if (NILP (Vquit_flag) && quitf) | ||
| 2883 | Vquit_flag = Qt; | ||
| 2849 | 2884 | ||
| 2850 | UNGCPRO; | 2885 | UNGCPRO; |
| 2851 | |||
| 2852 | return value; | 2886 | return value; |
| 2853 | } | 2887 | } |
| 2854 | 2888 | ||