unofficial mirror of bug-gnu-emacs@gnu.org 
 help / color / mirror / code / Atom feed
From: Stefan Monnier <monnier@IRO.UMontreal.CA>
To: Eli Zaretskii <eliz@gnu.org>
Cc: 34757@debbugs.gnu.org, Pip Cet <pipcet@gmail.com>,
	chuntaro@sakura-games.jp
Subject: bug#34757: Invalid bytecode from byte compiler
Date: Fri, 15 Mar 2019 10:08:48 -0400	[thread overview]
Message-ID: <jwvimwkb5hj.fsf-monnier+emacs@gnu.org> (raw)
In-Reply-To: <838sxg1rwz.fsf@gnu.org> (Eli Zaretskii's message of "Fri, 15 Mar 2019 10:08:12 +0200")

>> diff --git a/lisp/emacs-lisp/bytecomp.el b/lisp/emacs-lisp/bytecomp.el
>> index 0b8f8824b4c..4e54e08ce14 100644
>> --- a/lisp/emacs-lisp/bytecomp.el
>> +++ b/lisp/emacs-lisp/bytecomp.el
>> @@ -3025,6 +3025,7 @@ byte-compile-out-toplevel
>>                         (or (null (cdr rest))
>>                             (and (memq output-type '(file progn t))
>>                                  (cdr (cdr rest))
>> +                                (eql (length body) (cdr (car rest)))
>>                                  (eq (car (nth 1 rest)) 'byte-discard)
>>                                  (progn (setq rest (cdr rest)) t))))
>>                    (setq maycall nil)    ; Only allow one real function call.
>
> Stefan, any comments?

Looks good to me, thanks.

I'm personally running with the following patch instead, which is much
more risky and hasn't been sufficiently tested yet.


        Stefan


diff --git a/lisp/emacs-lisp/bytecomp.el b/lisp/emacs-lisp/bytecomp.el
index f46cab2c17..573b0489d4 100644
*** a/lisp/emacs-lisp/bytecomp.el
--- b/lisp/emacs-lisp/bytecomp.el
***************
*** 2990,3059 ****
        (setq byte-compile-output
  	    (byte-optimize-lapcode byte-compile-output)))
  
!   ;; Decompile trivial functions:
!   ;; only constants and variables, or a single funcall except in lambdas.
!   ;; Except for Lisp_Compiled objects, forms like (foo "hi")
!   ;; are still quicker than (byte-code "..." [foo "hi"] 2).
!   ;; Note that even (quote foo) must be parsed just as any subr by the
!   ;; interpreter, so quote should be compiled into byte-code in some contexts.
!   ;; What to leave uncompiled:
!   ;;	lambda	-> never.  we used to leave it uncompiled if the body was
!   ;;		   a single atom, but that causes confusion if the docstring
!   ;;		   uses the (file . pos) syntax.  Besides, now that we have
!   ;;		   the Lisp_Compiled type, the compiled form is faster.
!   ;;	eval	-> atom, quote or (function atom atom atom)
!   ;;	progn	-> as <<same-as-eval>> or (progn <<same-as-eval>> atom)
!   ;;	file	-> as progn, but takes both quotes and atoms, and longer forms.
!   (let (rest
! 	(maycall (not (eq output-type 'lambda))) ; t if we may make a funcall.
! 	tmp body)
!     (cond
!      ;; #### This should be split out into byte-compile-nontrivial-function-p.
!      ((or (eq output-type 'lambda)
! 	  (nthcdr (if (eq output-type 'file) 50 8) byte-compile-output)
! 	  (assq 'TAG byte-compile-output) ; Not necessary, but speeds up a bit.
! 	  (not (setq tmp (assq 'byte-return byte-compile-output)))
! 	  (progn
! 	    (setq rest (nreverse
! 			(cdr (memq tmp (reverse byte-compile-output)))))
! 	    (while
!                 (cond
!                  ((memq (car (car rest)) '(byte-varref byte-constant))
!                   (setq tmp (car (cdr (car rest))))
!                   (if (if (eq (car (car rest)) 'byte-constant)
!                           (or (consp tmp)
!                               (and (symbolp tmp)
!                                    (not (macroexp--const-symbol-p tmp)))))
!                       (if maycall
!                           (setq body (cons (list 'quote tmp) body)))
!                     (setq body (cons tmp body))))
!                  ((and maycall
!                        ;; Allow a funcall if at most one atom follows it.
!                        (null (nthcdr 3 rest))
!                        (setq tmp (get (car (car rest)) 'byte-opcode-invert))
!                        (or (null (cdr rest))
!                            (and (memq output-type '(file progn t))
!                                 (cdr (cdr rest))
!                                 (eq (car (nth 1 rest)) 'byte-discard)
!                                 (progn (setq rest (cdr rest)) t))))
!                   (setq maycall nil)	; Only allow one real function call.
!                   (setq body (nreverse body))
!                   (setq body (list
!                               (if (and (eq tmp 'funcall)
!                                        (eq (car-safe (car body)) 'quote)
! 				       (symbolp (nth 1 (car body))))
!                                   (cons (nth 1 (car body)) (cdr body))
!                                 (cons tmp body))))
!                   (or (eq output-type 'file)
!                       (not (delq nil (mapcar 'consp (cdr (car body))))))))
! 	      (setq rest (cdr rest)))
! 	    rest))
!       (let ((byte-compile-vector (byte-compile-constants-vector)))
! 	(list 'byte-code (byte-compile-lapcode byte-compile-output)
! 	      byte-compile-vector byte-compile-maxdepth)))
!      ;; it's a trivial function
!      ((cdr body) (cons 'progn (nreverse body)))
!      ((car body)))))
  
  ;; Given BODY, compile it and return a new body.
  (defun byte-compile-top-level-body (body &optional for-effect)
--- 2993,3013 ----
        (setq byte-compile-output
  	    (byte-optimize-lapcode byte-compile-output)))
  
!   (cond
!    ((and (not (eq output-type 'lambda)) ;;The caller really wants (byte-code ...)
!          (null (cddr byte-compile-output))
!          (eq (car (nth 0 byte-compile-output)) 'byte-constant)
!          (eq (car (nth 1 byte-compile-output)) 'byte-return))
!     ;; Special case for trivial code returning a function.
!     ;; This is so that when compiling #'(lambda ...) we return
!     ;; a #[...] byte-code object instead of a (byte-code "...")
!     ;; expression that returns this object.  It's not indispensable,
!     ;; but it's cleaner.
!     (macroexp-quote (cadr (nth 0 byte-compile-output))))
!    (t
!     (let ((byte-compile-vector (byte-compile-constants-vector)))
!       (list 'byte-code (byte-compile-lapcode byte-compile-output)
! 	    byte-compile-vector byte-compile-maxdepth)))))
  
  ;; Given BODY, compile it and return a new body.
  (defun byte-compile-top-level-body (body &optional for-effect)





  reply	other threads:[~2019-03-15 14:08 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-03-05  8:01 bug#34757: Invalid bytecode from byte compiler chuntaro
2019-03-08 13:18 ` Eli Zaretskii
2019-03-08 13:50   ` Michael Heerdegen
2019-03-08 14:36     ` Eli Zaretskii
2019-03-08 21:13 ` Pip Cet
2019-03-15  8:08   ` Eli Zaretskii
2019-03-15 14:08     ` Stefan Monnier [this message]
2019-03-15 19:40       ` Pip Cet
2019-03-15 20:30         ` Stefan Monnier
2019-03-16 16:51           ` Pip Cet
2019-06-13 11:44             ` Pip Cet
2019-07-27 21:30   ` Stefan Monnier

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://www.gnu.org/software/emacs/

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=jwvimwkb5hj.fsf-monnier+emacs@gnu.org \
    --to=monnier@iro.umontreal.ca \
    --cc=34757@debbugs.gnu.org \
    --cc=chuntaro@sakura-games.jp \
    --cc=eliz@gnu.org \
    --cc=pipcet@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).