]> git.eshelyaron.com Git - emacs.git/commitdiff
Remove nil check in exec_byte_code
authorMattias Engdegård <mattiase@acm.org>
Sat, 1 Jan 2022 21:39:17 +0000 (22:39 +0100)
committerMattias Engdegård <mattiase@acm.org>
Mon, 24 Jan 2022 10:41:46 +0000 (11:41 +0100)
Since we pass no arguments to a non-lexbind bytecode function, we can
specify its arity as 0 instead of nil and save a test and branch.

* src/bytecode.c (Fbyte_code, exec_byte_code):
* src/eval.c (fetch_and_exec_byte_code, funcall_lambda):
* src/lisp.h:
Change the args_template parameter type to ptrdiff_t, since it is now
always a small integer, in exec_byte_code and
fetch_and_exec_byte_code, all callers adjusted.

src/bytecode.c
src/eval.c
src/lisp.h

index 7a9966e20ef066da171a0a3a19b68aaf893c3134..8e0f3d3e4b22bd8092b2a0aa29698e137002683c 100644 (file)
@@ -333,7 +333,7 @@ If the third argument is incorrect, Emacs may crash.  */)
     }
   pin_string (bytestr);  // Bytecode must be immovable.
 
-  return exec_byte_code (bytestr, vector, maxdepth, Qnil, 0, NULL);
+  return exec_byte_code (bytestr, vector, maxdepth, 0, 0, NULL);
 }
 
 static void
@@ -344,15 +344,14 @@ bcall0 (Lisp_Object f)
 
 /* Execute the byte-code in BYTESTR.  VECTOR is the constant vector, and
    MAXDEPTH is the maximum stack depth used (if MAXDEPTH is incorrect,
-   emacs may crash!).  If ARGS_TEMPLATE is non-nil, it should be a lisp
-   argument list (including &rest, &optional, etc.), and ARGS, of size
-   NARGS, should be a vector of the actual arguments.  The arguments in
-   ARGS are pushed on the stack according to ARGS_TEMPLATE before
-   executing BYTESTR.  */
+   emacs may crash!).  ARGS_TEMPLATE is the function arity encoded as an
+   integer, and ARGS, of size NARGS, should be a vector of the actual
+   arguments.  The arguments in ARGS are pushed on the stack according
+   to ARGS_TEMPLATE before executing BYTESTR.  */
 
 Lisp_Object
 exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth,
-               Lisp_Object args_template, ptrdiff_t nargs, Lisp_Object *args)
+               ptrdiff_t args_template, ptrdiff_t nargs, Lisp_Object *args)
 {
 #ifdef BYTE_CODE_METER
   int volatile this_op = 0;
@@ -384,26 +383,25 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth,
   unsigned char const *pc = bytestr_data;
   ptrdiff_t count = SPECPDL_INDEX ();
 
-  if (!NILP (args_template))
-    {
-      eassert (FIXNUMP (args_template));
-      ptrdiff_t at = XFIXNUM (args_template);
-      bool rest = (at & 128) != 0;
-      int mandatory = at & 127;
-      ptrdiff_t nonrest = at >> 8;
-      if (! (mandatory <= nargs && (rest || nargs <= nonrest)))
-       Fsignal (Qwrong_number_of_arguments,
-                list2 (Fcons (make_fixnum (mandatory), make_fixnum (nonrest)),
-                       make_fixnum (nargs)));
-      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);
-    }
+  /* ARGS_TEMPLATE is composed of bit fields:
+     bits 0..6    minimum number of arguments
+     bits 7       1 iff &rest argument present
+     bits 8..14   maximum number of arguments */
+  bool rest = (args_template & 128) != 0;
+  int mandatory = args_template & 127;
+  ptrdiff_t nonrest = args_template >> 8;
+  if (! (mandatory <= nargs && (rest || nargs <= nonrest)))
+    Fsignal (Qwrong_number_of_arguments,
+            list2 (Fcons (make_fixnum (mandatory), make_fixnum (nonrest)),
+                   make_fixnum (nargs)));
+  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 (true)
     {
@@ -671,7 +669,7 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth,
              val = exec_byte_code (bytecode,
                                    AREF (fun, COMPILED_CONSTANTS),
                                    AREF (fun, COMPILED_STACK_DEPTH),
-                                   template, numargs, args);
+                                   XFIXNUM (template), numargs, args);
            else if (SUBRP (fun) && !SUBR_NATIVE_COMPILED_DYNP (fun))
              val = funcall_subr (XSUBR (fun), numargs, args);
            else
index 8912e285252ddf1b081d3c96e7652b46144ddce1..910777e23d5a22c6b4093e61c25e6c988eaa3a67 100644 (file)
@@ -3222,15 +3222,16 @@ funcall_subr (struct Lisp_Subr *subr, ptrdiff_t numargs, Lisp_Object *args)
    bytecode string and constants vector, fetch them from the file first.  */
 
 static Lisp_Object
-fetch_and_exec_byte_code (Lisp_Object fun, Lisp_Object syms_left,
+fetch_and_exec_byte_code (Lisp_Object fun, ptrdiff_t args_template,
                          ptrdiff_t nargs, Lisp_Object *args)
 {
   if (CONSP (AREF (fun, COMPILED_BYTECODE)))
     Ffetch_bytecode (fun);
+
   return exec_byte_code (AREF (fun, COMPILED_BYTECODE),
                         AREF (fun, COMPILED_CONSTANTS),
                         AREF (fun, COMPILED_STACK_DEPTH),
-                        syms_left, nargs, args);
+                        args_template, nargs, args);
 }
 
 static Lisp_Object
@@ -3308,7 +3309,8 @@ funcall_lambda (Lisp_Object fun, ptrdiff_t nargs,
           argument-binding code below instead (as do all interpreted
           functions, even lexically bound ones).  */
        {
-         return fetch_and_exec_byte_code (fun, syms_left, nargs, arg_vector);
+         return fetch_and_exec_byte_code (fun, XFIXNUM (syms_left),
+                                          nargs, arg_vector);
        }
       lexenv = Qnil;
     }
@@ -3394,7 +3396,7 @@ funcall_lambda (Lisp_Object fun, ptrdiff_t nargs,
       val = XSUBR (fun)->function.a0 ();
     }
   else
-    val = fetch_and_exec_byte_code (fun, Qnil, 0, NULL);
+    val = fetch_and_exec_byte_code (fun, 0, 0, NULL);
 
   return unbind_to (count, val);
 }
index fdcb7f39d59c8a72613276de0f9c0044e653feb4..54e8c30ccf1a98da35298467318750feed001a4c 100644 (file)
@@ -4700,7 +4700,7 @@ extern int read_bytecode_char (bool);
 /* Defined in bytecode.c.  */
 extern void syms_of_bytecode (void);
 extern Lisp_Object exec_byte_code (Lisp_Object, Lisp_Object, Lisp_Object,
-                                  Lisp_Object, ptrdiff_t, Lisp_Object *);
+                                  ptrdiff_t, ptrdiff_t, Lisp_Object *);
 extern Lisp_Object get_byte_code_arity (Lisp_Object);
 
 /* Defined in macros.c.  */