Mercurial > emacs
changeset 27781:f84c7b8308c5
(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.
author | Gerd Moellmann <gerd@gnu.org> |
---|---|
date | Sun, 20 Feb 2000 15:55:07 +0000 |
parents | 72cae205b4f4 |
children | f53ecb062478 |
files | src/eval.c |
diffstat | 1 files changed, 89 insertions(+), 55 deletions(-) [+] |
line wrap: on
line diff
--- a/src/eval.c Sun Feb 20 14:31:40 2000 +0000 +++ b/src/eval.c Sun Feb 20 15:55:07 2000 +0000 @@ -2642,31 +2642,35 @@ int nargs; register Lisp_Object *arg_vector; { - Lisp_Object val, tem; - register Lisp_Object syms_left; - Lisp_Object numargs; - register Lisp_Object next; + Lisp_Object val, syms_left, next; int count = specpdl_ptr - specpdl; - register int i; - int optional = 0, rest = 0; - - specbind (Qmocklisp_arguments, Qt); /* t means NOT mocklisp! */ - - XSETFASTINT (numargs, nargs); + int i, optional, rest; + + if (NILP (Vmocklisp_arguments)) + specbind (Qmocklisp_arguments, Qt); /* t means NOT mocklisp! */ if (CONSP (fun)) - syms_left = Fcar (Fcdr (fun)); + { + syms_left = XCDR (fun); + if (CONSP (syms_left)) + syms_left = XCAR (syms_left); + else + return Fsignal (Qinvalid_function, Fcons (fun, Qnil)); + } else if (COMPILEDP (fun)) syms_left = XVECTOR (fun)->contents[COMPILED_ARGLIST]; - else abort (); - - i = 0; - for (; !NILP (syms_left); syms_left = Fcdr (syms_left)) + else + abort (); + + i = optional = rest = 0; + for (; CONSP (syms_left); syms_left = XCDR (syms_left)) { QUIT; - next = Fcar (syms_left); + + next = XCAR (syms_left); while (!SYMBOLP (next)) next = Fsignal (Qinvalid_function, Fcons (fun, Qnil)); + if (EQ (next, Qand_rest)) rest = 1; else if (EQ (next, Qand_optional)) @@ -2677,21 +2681,22 @@ i = nargs; } else if (i < nargs) - { - tem = arg_vector[i++]; - specbind (next, tem); - } + specbind (next, arg_vector[i++]); else if (!optional) - return Fsignal (Qwrong_number_of_arguments, Fcons (fun, Fcons (numargs, Qnil))); + return Fsignal (Qwrong_number_of_arguments, + Fcons (fun, Fcons (make_number (nargs), Qnil))); else specbind (next, Qnil); } - if (i < nargs) - return Fsignal (Qwrong_number_of_arguments, Fcons (fun, Fcons (numargs, Qnil))); + if (!NILP (syms_left)) + return Fsignal (Qinvalid_function, Fcons (fun, Qnil)); + else if (i < nargs) + return Fsignal (Qwrong_number_of_arguments, + Fcons (fun, Fcons (make_number (nargs), Qnil))); if (CONSP (fun)) - val = Fprogn (Fcdr (Fcdr (fun))); + val = Fprogn (XCDR (XCDR (fun))); else { /* If we have not actually read the bytecode string @@ -2702,6 +2707,7 @@ XVECTOR (fun)->contents[COMPILED_CONSTANTS], XVECTOR (fun)->contents[COMPILED_STACK_DEPTH]); } + return unbind_to (count, val); } @@ -2754,40 +2760,59 @@ Lisp_Object symbol, value; { Lisp_Object ovalue; + extern int keyword_symbols_constant_flag; CHECK_SYMBOL (symbol, 0); - - ovalue = find_symbol_value (symbol); - if (specpdl_ptr == specpdl + specpdl_size) grow_specpdl (); - specpdl_ptr->func = 0; - specpdl_ptr->old_value = ovalue; - - if (BUFFER_LOCAL_VALUEP (XSYMBOL (symbol)->value) - || SOME_BUFFER_LOCAL_VALUEP (XSYMBOL (symbol)->value) - || BUFFER_OBJFWDP (XSYMBOL (symbol)->value)) + + /* The most common case is that a non-constant symbol with a trivial + value. Make that as fast as we can. */ + if (!MISCP (XSYMBOL (symbol)->value) + && !EQ (symbol, Qnil) + && !EQ (symbol, Qt) + && !(XSYMBOL (symbol)->name->data[0] == ':' + && EQ (XSYMBOL (symbol)->obarray, initial_obarray) + && keyword_symbols_constant_flag + && !EQ (value, symbol))) { - Lisp_Object current_buffer, binding_buffer; - /* For a local variable, record both the symbol and which - buffer's value we are saving. */ - current_buffer = Fcurrent_buffer (); - binding_buffer = current_buffer; - /* If the variable is not local in this buffer, - we are saving the global value, so restore that. */ - if (NILP (Flocal_variable_p (symbol, binding_buffer))) - binding_buffer = Qnil; - specpdl_ptr->symbol - = Fcons (symbol, Fcons (binding_buffer, current_buffer)); + specpdl_ptr->symbol = symbol; + specpdl_ptr->old_value = XSYMBOL (symbol)->value; + specpdl_ptr->func = NULL; + ++specpdl_ptr; + XSYMBOL (symbol)->value = value; } else - specpdl_ptr->symbol = symbol; - - specpdl_ptr++; - if (BUFFER_OBJFWDP (ovalue) || KBOARD_OBJFWDP (ovalue)) - store_symval_forwarding (symbol, ovalue, value); - else - set_internal (symbol, value, 0, 1); + { + ovalue = find_symbol_value (symbol); + specpdl_ptr->func = 0; + specpdl_ptr->old_value = ovalue; + + if (BUFFER_LOCAL_VALUEP (XSYMBOL (symbol)->value) + || SOME_BUFFER_LOCAL_VALUEP (XSYMBOL (symbol)->value) + || BUFFER_OBJFWDP (XSYMBOL (symbol)->value)) + { + Lisp_Object current_buffer, binding_buffer; + /* For a local variable, record both the symbol and which + buffer's value we are saving. */ + current_buffer = Fcurrent_buffer (); + binding_buffer = current_buffer; + /* If the variable is not local in this buffer, + we are saving the global value, so restore that. */ + if (NILP (Flocal_variable_p (symbol, binding_buffer))) + binding_buffer = Qnil; + specpdl_ptr->symbol + = Fcons (symbol, Fcons (binding_buffer, current_buffer)); + } + else + specpdl_ptr->symbol = symbol; + + specpdl_ptr++; + if (BUFFER_OBJFWDP (ovalue) || KBOARD_OBJFWDP (ovalue)) + store_symval_forwarding (symbol, ovalue, value); + else + set_internal (symbol, value, 0, 1); + } } void @@ -2812,12 +2837,12 @@ struct gcpro gcpro1; GCPRO1 (value); - Vquit_flag = Qnil; while (specpdl_ptr != specpdl + count) { --specpdl_ptr; + if (specpdl_ptr->func != 0) (*specpdl_ptr->func) (specpdl_ptr->old_value); /* Note that a "binding" of nil is really an unwind protect, @@ -2843,12 +2868,21 @@ set_internal (symbol, specpdl_ptr->old_value, XBUFFER (buffer), 1); } else - set_internal (specpdl_ptr->symbol, specpdl_ptr->old_value, 0, 1); + { + /* If variable has a trivial value (no forwarding), we can + just set it. No need to check for constant symbols here, + since that was already done by specbind. */ + if (!MISCP (XSYMBOL (specpdl_ptr->symbol)->value)) + XSYMBOL (specpdl_ptr->symbol)->value = specpdl_ptr->old_value; + else + set_internal (specpdl_ptr->symbol, specpdl_ptr->old_value, 0, 1); + } } - if (NILP (Vquit_flag) && quitf) Vquit_flag = Qt; + + if (NILP (Vquit_flag) && quitf) + Vquit_flag = Qt; UNGCPRO; - return value; }