GNU bug report logs - #71805
master: New interpreted function format prevents native compilation.

Previous Next

Package: emacs;

Reported by: Alan Mackenzie <acm <at> muc.de>

Date: Thu, 27 Jun 2024 16:02:02 UTC

Severity: normal

Full log


View this message in rfc822 format

From: Stefan Monnier <monnier <at> iro.umontreal.ca>
To: Alan Mackenzie <acm <at> muc.de>
Cc: 71805 <at> debbugs.gnu.org
Subject: bug#71805: master: New interpreted function format prevents native compilation.
Date: Sat, 29 Jun 2024 17:30:46 -0400
> With a recent master repo (likely also the emacs-30 branch):
> (i) mkdir ~/cc-mode.hg.
> (ii) chdir ~/cc-mode.hg.
> (iii) Copy cc-mode.hg.tar.gz from this bug report to ~/cc-mode.hg.
> (iv) tar -zxf cc-mode.tar.gz.
> The CC Mode source files should now be in the current directory.
>
> (v) emacs -Q -batch -f batch-byte-compile *.el
> The CC Mode .elc files should now be present.

I haven't tried quite that command, instead I went straight for:

    emacs -Q --batch -L .                                       \
          --eval '(setq debug-on-error t byte-compile-debug t)' \
          -f batch-byte-compile cc-fonts.el

which gave me an error with the following backtrace:

    Debugger entered--Lisp error: (wrong-type-argument listp #f(lambda (form) :dynbind `(cdr (backquote-process ,form))))
      car(#f(lambda (form) :dynbind `(cdr (backquote-process ,form))))
      #f(compiled-function (evald func args flags) #<bytecode -0x1893e2b83afae926>)(nil defmacro (bq-process macro . #f(lambda (form) :dynbind `(cdr (backquote-process ,form)))) nil)
      mapbacktrace(#f(compiled-function (evald func args flags) #<bytecode -0x1893e2b83afae926>) debug-early--handler)
      debug-early-backtrace(debug-early--handler)
      debug--early((wrong-type-argument listp #f(lambda (form) :dynbind `(cdr (backquote-process ,form)))) debug-early--handler)
      debug-early--handler((wrong-type-argument listp #f(lambda (form) :dynbind `(cdr (backquote-process ,form)))))
      (defmacro bq-process macro . #f(lambda (form) :dynbind `(cdr (backquote-process ,form))))
      eval((defmacro bq-process macro . #f(lambda (form) :dynbind `(cdr (backquote-process ,form)))))
      (progn (eval (cons 'defmacro (cons fun temp-macro))) nil)
      (if temp-macro (progn (eval (cons 'defmacro (cons fun temp-macro))) nil) (fset fun (intern (concat "cc-bytecomp-ignore-fun:" (symbol-name fun)))) nil)
      (if (not (fboundp fun)) (if temp-macro (progn (eval (cons 'defmacro (cons fun temp-macro))) nil) (fset fun (intern (concat "cc-bytecomp-ignore-fun:" (symbol-name fun)))) nil))
      (let ((fun (car (car p))) (temp-macro (car (cdr (car p))))) (if (not (fboundp fun)) (if temp-macro (progn (eval (cons 'defmacro (cons fun temp-macro))) nil) (fset fun (intern (concat "cc-bytecomp-ignore-fun:" (symbol-name fun)))) nil)))
      (while p (message "(car p) == %S" (car p)) (let ((fun (car (car p))) (temp-macro (car (cdr (car p))))) (if (not (fboundp fun)) (if temp-macro (progn (eval (cons 'defmacro (cons fun temp-macro))) nil) (fset fun (intern (concat "cc-bytecomp-ignore-fun:" (symbol-name fun)))) nil))) (setq p (cdr p)))
      (let (p) (if cc-bytecomp-environment-set (error "Byte compilation environment already set - perhaps a `cc-bytecomp-restore-environment' is forgotten somewhere")) (setq p cc-bytecomp-unbound-variables) (while p (if (not (boundp (car p))) (progn (eval (list 'defvar (car p))) (set (car p) (intern (concat "cc-bytecomp-ignore-var:" (symbol-name ...)))) nil)) (setq p (cdr p))) (setq p cc-bytecomp-original-functions) (while p (message "(car p) == %S" (car p)) (let ((fun (car (car p))) (temp-macro (car (cdr (car p))))) (if (not (fboundp fun)) (if temp-macro (progn (eval (cons ... ...)) nil) (fset fun (intern (concat "cc-bytecomp-ignore-fun:" ...))) nil))) (setq p (cdr p))) (setq p cc-bytecomp-original-properties) (while p (let ((sym (car (car (car p)))) (prop (cdr (car (car p)))) (tempdef (car (cdr (car p))))) (put sym prop tempdef) nil) (setq p (cdr p))) (setq p (reverse cc-bytecomp-push-vars)) (while p (let ((var (car (car p))) (setqd-val (car (cdr (cdr ...))))) (set var setqd-val) nil) (setq p (cdr p))) (setq cc-bytecomp-environment-set t) nil)
      (if (not (cc-bytecomp-is-loading)) (let (p) (if cc-bytecomp-environment-set (error "Byte compilation environment already set - perhaps a `cc-bytecomp-restore-environment' is forgotten somewhere")) (setq p cc-bytecomp-unbound-variables) (while p (if (not (boundp (car p))) (progn (eval (list 'defvar (car p))) (set (car p) (intern (concat "cc-bytecomp-ignore-var:" ...))) nil)) (setq p (cdr p))) (setq p cc-bytecomp-original-functions) (while p (message "(car p) == %S" (car p)) (let ((fun (car (car p))) (temp-macro (car (cdr ...)))) (if (not (fboundp fun)) (if temp-macro (progn (eval ...) nil) (fset fun (intern ...)) nil))) (setq p (cdr p))) (setq p cc-bytecomp-original-properties) (while p (let ((sym (car (car ...))) (prop (cdr (car ...))) (tempdef (car (cdr ...)))) (put sym prop tempdef) nil) (setq p (cdr p))) (setq p (reverse cc-bytecomp-push-vars)) (while p (let ((var (car (car p))) (setqd-val (car (cdr ...)))) (set var setqd-val) nil) (setq p (cdr p))) (setq cc-bytecomp-environment-set t) nil))
      cc-bytecomp-setup-environment()

So I added some `message`s in the `while p` loop of
`cc-bytecomp-setup-environment` where there's the funny

    (eval `(defmacro ,fun ,@temp-macro))

and tried again with an older version of Emacs, to see how that worked:

    /usr/bin/emacs -Q --batch -L .                                       \
                   --eval '(setq debug-on-error t byte-compile-debug t)' \
                   -f batch-byte-compile cc-fonts.el

    (car p) == (c-clear-char-property-fun nil unbound)
    [...]
    (car p) == (bq-process (macro lambda (form) `(cdr (backquote-process ,form))) unbound)
    [...]
    (car p) == (bq-process (macro lambda (form) `(cdr (backquote-process ,form))) unbound)
    evalling: (defmacro bq-process macro lambda (form) `(cdr (backquote-process ,form)))

And indeed in Emacs-28, it seems that

    (eval '(defmacro bq-process macro lambda (form) `(cdr (backquote-process ,form))))

did not signal an error (tho it resulted in an incorrect definition):

    ELISP> (eval '(defmacro bq-process macro lambda (form) `(cdr (backquote-process ,form))))
    bq-process
    ELISP> (symbol-function 'bq-process)
    (macro lambda macro lambda
           (form)
           `(cdr (backquote-process ,form)))
    
    ELISP> 

I don't know what your code intends to do but doing

    (eval `(defmacro ,fun ,@temp-macro))

when `temp-macro` comes from the output of `symbol-function`
(apparently in `cc-bytecomp-defmacro`) doesn't seem to make much sense.


        Stefan





This bug report was last modified 350 days ago.

Previous Next


GNU bug tracking system
Copyright (C) 1999 Darren O. Benham, 1997,2003 nCipher Corporation Ltd, 1994-97 Ian Jackson.