Subject: bug#39709: closed (Re: #39709: 28.0.50; [PATCH] substring and the byte compiler)

From: [email-masked] (GNU bug Tracking System)
Date: Tue, 25 Feb 2020 15:43:02 +0000

Your bug report

#39709: 28.0.50; [PATCH] substring and the byte compiler

which was filed against the emacs package, has been closed.

The explanation is attached below, along with your original report.
If you require more details, please reply to [email-masked].

-- 
39709: http://debbugs.gnu.org/cgi/bugreport.cgi?bug=39709
GNU Bug Tracking System
Contact [email-masked] with problems

Subject: Re: #39709: 28.0.50; [PATCH] substring and the byte compiler
From: Mattias Engdegård <[email-masked]>
To: Mark Oteiza <[email-masked]>
Cc: [email-masked], Stefan Monnier <[email-masked]>
Date: Tue, 25 Feb 2020 16:42:28 +0100
List-Id: <debbugs-submit.debbugs.gnu.org>

No objection arrived -- pushed to master.

Subject: 28.0.50; [PATCH] substring and the byte compiler
From: Mark Oteiza <[email-masked]>
To: [email-masked]
Date: Fri, 21 Feb 2020 01:22:06 -0500
List-Id: <debbugs-submit.debbugs.gnu.org>

Hi,

I don't really understand the byte compiler, but I noticed in
disassembly that substring, despite having an opcode, is getting
call'd:

10      constant  substring
11      stack-ref 3
12      constant  0
13      stack-ref 7
15      call      3

when really I'd expect to see something like

57      stack-ref 2
58      stack-ref 7
60      min       
61      stack-ref 7
63      substring 

The only relevant change I found is bug#33807.  Enlightenment welcome.
Naive patch below.

diff --git a/lisp/emacs-lisp/bytecomp.el b/lisp/emacs-lisp/bytecomp.el
index fce5e4aed6..ec340cd451 100644
--- a/lisp/emacs-lisp/bytecomp.el
+++ b/lisp/emacs-lisp/bytecomp.el
@@ -3506,6 +3506,7 @@ byte-defop-compiler
 					(0-1 . byte-compile-zero-or-one-arg)
 					(1-2 . byte-compile-one-or-two-args)
 					(2-3 . byte-compile-two-or-three-args)
+					(1-3 . byte-compile-one-to-three-args)
 					)))
 			   compile-handler
 			   (intern (concat "byte-compile-"
@@ -3690,6 +3691,13 @@ byte-compile-two-or-three-args
 	  ((= len 4) (byte-compile-three-args form))
 	  (t (byte-compile-subr-wrong-args form "2-3")))))
 
+(defun byte-compile-one-to-three-args (form)
+  (let ((len (length form)))
+    (cond ((= len 2) (byte-compile-one-arg form))
+          ((= len 3) (byte-compile-two-args form))
+          ((= len 4) (byte-compile-three-args form))
+	  (t (byte-compile-subr-wrong-args form "1-3")))))
+
 (defun byte-compile-noop (_form)
   (byte-compile-constant nil))
 
diff --git a/lisp/emacs-lisp/byte-opt.el b/lisp/emacs-lisp/byte-opt.el
index fe0930c684..d3c84335ec 100644
--- a/lisp/emacs-lisp/byte-opt.el
+++ b/lisp/emacs-lisp/byte-opt.el
@@ -1511,11 +1511,11 @@ byte-compile-side-effect-and-error-free-ops
 (defconst byte-compile-side-effect-free-ops
   (nconc
    '(byte-varref byte-nth byte-memq byte-car byte-cdr byte-length byte-aref
-     byte-symbol-value byte-get byte-concat2 byte-concat3 byte-sub1 byte-add1
-     byte-eqlsign byte-gtr byte-lss byte-leq byte-geq byte-diff byte-negate
-     byte-plus byte-max byte-min byte-mult byte-char-after byte-char-syntax
-     byte-buffer-substring byte-string= byte-string< byte-nthcdr byte-elt
-     byte-member byte-assq byte-quo byte-rem)
+     byte-symbol-value byte-get byte-substring byte-concat2 byte-concat3
+     byte-sub1 byte-add1 byte-eqlsign byte-gtr byte-lss byte-leq byte-geq
+     byte-diff byte-negate byte-plus byte-max byte-min byte-mult byte-char-after
+     byte-char-syntax byte-buffer-substring byte-string= byte-string<
+     byte-nthcdr byte-elt byte-member byte-assq byte-quo byte-rem)
    byte-compile-side-effect-and-error-free-ops))
 
 ;; This crock is because of the way DEFVAR_BOOL variables work.