From 7961dee1827c7d30a238e7eec3ae0ba26dd6fd30 Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Sun, 7 Aug 2016 09:58:09 -0700 Subject: [PATCH] Tune interpretation of integer arglist descriptor * src/bytecode.c (exec_byte_code): Simplify and tune when INTEGERP (args_template). --- src/bytecode.c | 47 ++++++++++++----------------------------------- src/eval.c | 10 +++++----- 2 files changed, 17 insertions(+), 40 deletions(-) diff --git a/src/bytecode.c b/src/bytecode.c index ee1b79f1826..6ccad469efa 100644 --- a/src/bytecode.c +++ b/src/bytecode.c @@ -476,49 +476,26 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth, stacke = stack.bottom - 1 + XFASTINT (maxdepth); #endif - if (INTEGERP (args_template)) + if (!NILP (args_template)) { + eassert (INTEGERP (args_template)); ptrdiff_t at = XINT (args_template); bool rest = (at & 128) != 0; int mandatory = at & 127; ptrdiff_t nonrest = at >> 8; - eassert (mandatory <= nonrest); - if (nargs <= nonrest) - { - ptrdiff_t i; - for (i = 0 ; i < nargs; i++, args++) - PUSH (*args); - if (nargs < mandatory) - /* Too few arguments. */ - Fsignal (Qwrong_number_of_arguments, - list2 (Fcons (make_number (mandatory), - rest ? Qand_rest : make_number (nonrest)), - make_number (nargs))); - else - { - for (; i < nonrest; i++) - PUSH (Qnil); - if (rest) - PUSH (Qnil); - } - } - else if (rest) - { - ptrdiff_t i; - for (i = 0 ; i < nonrest; i++, args++) - PUSH (*args); - PUSH (Flist (nargs - nonrest, args)); - } - else - /* Too many arguments. */ + ptrdiff_t maxargs = rest ? PTRDIFF_MAX : nonrest; + if (! (mandatory <= nargs && nargs <= maxargs)) Fsignal (Qwrong_number_of_arguments, list2 (Fcons (make_number (mandatory), make_number (nonrest)), make_number (nargs))); - } - else if (! NILP (args_template)) - /* We should push some arguments on the stack. */ - { - error ("Unknown args template!"); + ptrdiff_t pushedargs = min (nonrest, nargs); + for (ptrdiff_t i = 0; i < pushedargs; i++, args++) + PUSH (*args); + if (nonrest < nargs) + PUSH (Flist (nargs - nonrest, args)); + else + for (ptrdiff_t i = nargs - rest; i < nonrest; i++) + PUSH (Qnil); } while (1) diff --git a/src/eval.c b/src/eval.c index d182f7f693d..7b7bdd8df7b 100644 --- a/src/eval.c +++ b/src/eval.c @@ -2863,14 +2863,14 @@ funcall_lambda (Lisp_Object fun, ptrdiff_t nargs, xsignal1 (Qinvalid_function, fun); syms_left = AREF (fun, COMPILED_ARGLIST); if (INTEGERP (syms_left)) - /* A byte-code object with a non-nil `push args' slot means we + /* A byte-code object with an integer args template means we shouldn't bind any arguments, instead just call the byte-code interpreter directly; it will push arguments as necessary. - Byte-code objects with either a non-existent, or a nil value for - the `push args' slot (the default), have dynamically-bound - arguments, and use the argument-binding code below instead (as do - all interpreted functions, even lexically bound ones). */ + Byte-code objects with a nil args template (the default) + have dynamically-bound arguments, and use the + argument-binding code below instead (as do all interpreted + functions, even lexically bound ones). */ { /* If we have not actually read the bytecode string and constants vector yet, fetch them from the file. */ -- 2.11.4.GIT