aboutsummaryrefslogtreecommitdiffstats
path: root/src/eval.c
diff options
context:
space:
mode:
authorGerd Moellmann2000-02-20 15:55:07 +0000
committerGerd Moellmann2000-02-20 15:55:07 +0000
commit9ab90667d31851abf6e5334d5c8fc866d62dde2f (patch)
tree33dea50ddb859743321cf5164aefc83ff956c889 /src/eval.c
parent2d06696fdcae3c266b917fb0a98bea9c01fa02fa (diff)
downloademacs-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.c140
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
2793void 2818void
@@ -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