unofficial mirror of emacs-devel@gnu.org 
 help / color / mirror / code / Atom feed
From: Tom Tromey <tromey@redhat.com>
To: Wojciech Meyer <wojciech.meyer@googlemail.com>
Cc: emacs-devel@gnu.org
Subject: Re: Compiling Elisp to a native code with a GCC plugin
Date: Tue, 14 Sep 2010 19:38:37 -0600	[thread overview]
Message-ID: <m3aanj23c2.fsf@fleche.redhat.com> (raw)
In-Reply-To: <AANLkTimfVF8Wi7-U9akwr6PEoriVopBYeVBFN0iuZ=dn@mail.gmail.com> (Wojciech Meyer's message of "Wed, 15 Sep 2010 00:33:09 +0100")

[-- Attachment #1: Type: text/plain, Size: 1580 bytes --]

Wojciech> Yes please, I would like to take a look, thanks.

I attached the scripts.  They have a few comments, but probably not
enough, given that they are pretty much one-off hacks.  (Though,
funnily, today I'm going to repurpose one to rewrite gdb...)

The appended patch is needed to get GCC to emit error locations on the
`->' token when the token appears in the arguments to a macro.

Wojciech> I am just not sure how efficiently and reliably branches work
Wojciech> in bzr (I've managed to screw up some of my work once with
Wojciech> bzr), and I am not sure how reliable are git mirrors. I quite
Wojciech> like git, however there is a cost of troubles with integration
Wojciech> with bzr. On other hand I find forking <-> merging
Wojciech> unacceptable. I will try to mock something up, in the
Wojciech> meantime.

Yeah, bzr is a pain compared to git.  But, we're stuck with it.

Wojciech> BTW: If somebody would like to enlighten me on how reliably
Wojciech> mirrored git works with the Emacs source tree, I would be
Wojciech> grateful. Thanks.

I think the mirror is updated regularly.  I'm not using it myself, but I
gather it works ok.

Tom

Index: macro.c
===================================================================
--- macro.c	(revision 164202)
+++ macro.c	(working copy)
@@ -1350,7 +1350,7 @@
 
   pfile->set_invocation_location = true;
   result = cpp_get_token (pfile);
-  if (pfile->context->macro)
+  if (pfile->context->macro && pfile->invocation_location > result->src_loc)
     *loc = pfile->invocation_location;
   else
     *loc = result->src_loc;


[-- Attachment #2: hack-buffer-objfwd.el --]
[-- Type: text/plain, Size: 6649 bytes --]

;; Rewrite all references to buffer-objfwd fields in struct buffer
;; to use accessor macros.
;; This works in a tricky way: it renames all such fields, then
;; recompiles Emacs.  Then it visits each error location and
;; rewrites the expressions.
;; This has a few requirements in order to work.
;; First, Emacs must compile before the script is run.
;; It does not handle errors arising for other reasons.
;; Second, you need a GCC which has been hacked to emit proper
;; column location even when the -> expression in question has
;; been wrapped in a macro call.  (This is a one-liner in libcpp.)
;; After running this script, a few changes need to be made by hand.
;; These occur mostly in macros in headers, but also in
;; reset_buffer and reset_buffer_local_variables.  Finally,
;; DEFVAR_PER_BUFFER and the GC should not use these accessors.

(defvar gcc-prefix "/home/tromey/gnu/Trunk/install/")

(defvar emacs-src "/home/tromey/gnu/Emacs/Gitorious/emacs-mt/src/")
(defvar emacs-build "/home/tromey/gnu/Emacs/Gitorious/build/src/")

(defun file-error (text)
  (error "%s:%d:%d: error: expected %s"
	 buffer-file-name (line-number-at-pos (point))
	 (current-column)
	 text))

(defun assert-looking-at (exp)
  (unless (looking-at exp)
    (file-error exp)))

(defvar field-names nil)

(defvar field-regexp nil)

(defun modify-buffer.h ()
  (message "Modifying fields in struct buffer")
  (find-file (expand-file-name "buffer.h" emacs-src))
  (goto-char (point-min))
  (re-search-forward "^struct buffer$")
  (forward-line)
  (assert-looking-at "^{")
  (let ((starting-point (point))
	(closing-brace (save-excursion
			 (forward-sexp)
			 (point))))
    ;; Find each field.
    (while (re-search-forward "^\\s *Lisp_Object\\s +"
			      closing-brace 'move)
      (goto-char (match-end 0))
      (while (not (looking-at ";"))
	(assert-looking-at "\\([A-Za-z0-9_]+\\)\\(;\\|,\\s *\\)")
	;; Remember the name so we can generate accessors.
	(push (match-string 1) field-names)
	;; Rename it.
	(goto-char (match-beginning 2))
	(insert "_")
	;; On to the next one, if any.
	(if (looking-at ",\\s *")
	    (goto-char (match-end 0)))))
    ;; Generate accessors.
    (goto-char starting-point)
    (forward-sexp)
    (forward-line)
    (insert "\n")
    (dolist (name field-names)
      (insert "#define BUF_" (upcase name) "(BUF) "
	      "*find_variable_location (&((BUF)->"
	      name "_))\n"))
    (insert "\n"))
  (setq field-regexp (concat "\\(->\\|\\.\\)"
			     (regexp-opt field-names t)
			     "\\_>"))
  (save-buffer))

(defun get-field-name ()
  (save-excursion
    (assert-looking-at "\\(\\.\\|->\\)\\([A-Za-z0-9_]+\\)\\_>")
    (prog1
	(match-string 2)
      (delete-region (match-beginning 0) (match-end 0)))))

(defun skip-backward-lhs ()
  (skip-chars-backward " \t\n")
  (cond
   ((eq (char-before) ?\])
    (file-error "array ref!")
    ;; fixme
    )
   ((eq (char-before) ?\))
    ;; A paren expression is preceding.
    ;; See if this is just a paren expression or whether it is a
    ;; function call.
    ;; For now assume that there are no function-calls-via-expr.
    (backward-sexp)
    (skip-chars-backward " \t\n")
    (if (save-excursion
	  (backward-char)
	  (looking-at "[A-Za-z0-9_]"))
	(backward-sexp)))
   ((save-excursion
      (backward-char)
      (looking-at "[A-Za-z0-9_]"))
    (backward-sexp))
   (t
    (file-error "unhandled case!"))))

(defun do-fix-instance ()
  (cond
   ((looking-at "->")
    (let ((field-name (get-field-name)))
      (insert ")")
      (backward-char)
      (skip-backward-lhs)
      (insert "BUF_" (upcase field-name) " (")))
   ((eq (char-after) ?.)
    (let ((field-name (get-field-name)))
      (insert ")")
      (backward-char)
      (backward-sexp)
      (assert-looking-at "\\(buffer_defaults\\|buffer_local_flags\\)")
      (insert "BUF_" (upcase field-name) " (&")))
   (t
    (message "%s:%d:%d: warning: did not see -> or ., probably macro"
	     buffer-file-name (line-number-at-pos (point))
	     (current-column)))))

(defun update-header-files ()
  (dolist (file (directory-files emacs-src t "h$"))
    (message "Applying header changes to %s" file)
    (find-file file)
    (while (re-search-forward
	    "\\(current_buffer->\\|buffer_defaults\\.\\)"
	    nil 'move)
      (goto-char (match-end 0))
      (skip-chars-backward "->.")
      (when (looking-at field-regexp)
	(do-fix-instance)))
    (goto-char (point-min))
    (while (search-forward "XBUFFER (" nil 'move)
      (goto-char (- (match-end 0) 1))
      (forward-sexp)
      ;; This works even for the new #define BUF_ macros
      ;; because the field-regexp ends with \_>.
      (when (looking-at field-regexp)
	(do-fix-instance)))
    (save-buffer)))

(defun fix-one-instance (filename line column)
  (message "%s:%d:%d: info: fixing instance" filename line column)
  (find-file filename)
  (goto-char (point-min))
  (forward-line (- line 1))
  ;; (move-to-column (- column 1))
  (forward-char (- column 1))
  (do-fix-instance))

(defvar make-accumulation "")

(defvar last-error-line nil)
(defvar error-list nil)

(defun make-filter (process string)
  (setq make-accumulation (concat make-accumulation string))
  (while (string-match "^[^\n]*\n" make-accumulation)
    (let ((line (substring (match-string 0 make-accumulation) 0 -1)))
      (setq make-accumulation (substring make-accumulation
					 (match-end 0)))
      (message "%s" line)
      (if (string-match "^\\([^:]+\\):\\([0-9]+\\):\\([0-9]+\\)+: error:"
			line)
	  (save-excursion
	    (let ((file-name (match-string 1 line))
		  (line-no (string-to-number (match-string 2 line)))
		  (col-no (string-to-number (match-string 3 line))))
	      ;; Process all errors on a given line in reverse order.
	      (unless (eq line-no last-error-line)
		(dolist (one-item error-list)
		  (apply #'fix-one-instance one-item))
		(setq error-list nil)
		(setq last-error-line line-no))
	      (push (list file-name line-no col-no) error-list)))))))

(defvar make-done nil)

(defun make-sentinel (process string)
  (dolist (one-item error-list)
    (apply #'fix-one-instance one-item))
  (setq make-done t))

(defun recompile-emacs ()
  (let* ((default-directory emacs-build)
	 (output-buffer (get-buffer-create "*recompile*"))
	 (make (start-process "make" output-buffer "make" "-k")))
    (set-process-filter make #'make-filter)
    (set-process-sentinel make #'make-sentinel)
    (while (not make-done)
      (accept-process-output))))

(modify-buffer.h)
(update-header-files)
(recompile-emacs)
(dolist (buf (buffer-list))
  (with-current-buffer buf
    (when buffer-file-name
      (message "Saving %s" buffer-file-name)
      (save-buffer))))

[-- Attachment #3: rewrite-globals.el --]
[-- Type: text/plain, Size: 2007 bytes --]

;; Rewrite DEFVAR_LISP variables.
;; Each variable is renamed to start with impl_.
;; Compatibility defines are added to globals.h.
;; Invoke as:  emacs --script rewrite-globals.el

(defvar defvar-list '())

(defun extract-defvars ()
  (let ((case-fold-search nil))
    (while (re-search-forward "^[^#*]*\\(DEFVAR_[A-Z_]*\\)" nil 'move)
      (let ((kind (match-string 1)))
	(unless (member kind '("DEFVAR_KBOARD" "DEFVAR_PER_BUFFER"))
	  ;; Skip the paren and the first argument.
	  (skip-chars-forward " (")
	  (forward-sexp)
	  (skip-chars-forward ", \t\n&")
	  (if (looking-at "\\_<\\(\\sw\\|\\s_\\)+\\_>")
	      (let ((var-name (match-string 0)))
		  (if (equal kind "DEFVAR_LISP")
		      (push var-name defvar-list)))))))))

(defun munge-V ()
  (interactive)
  (while (re-search-forward "^\\(extern \\|static \\)?Lisp_Object " nil 'move)
    ;; skip function decls.
    (if (not (looking-at ".*("))
	(while (looking-at "[a-z0-9A-Z_]+")
	  (if (member (match-string 0) defvar-list)
	      (progn
		;; Rename them all to impl_
		(goto-char (match-beginning 0))
		(insert "impl_")))
	  (forward-sexp)
	  (skip-chars-forward ", \t\n")))))

(defconst V-dir ".")

(defun munge-V-directory ()
  ;; First extract all defvars.
  (dolist (file (directory-files V-dir t "[ch]$"))
    (save-excursion
      (message "Scanning %s" file)
      (find-file file)
      (extract-defvars)))

  (setq defvar-list (delete-dups (sort defvar-list #'string<)))

  (dolist (file (directory-files V-dir t "[ch]$"))
    (save-excursion
      (message "Processing %s" file)
      (find-file file)
      (goto-char (point-min))
      (munge-V)
      (save-buffer)))

  (find-file "globals.h")
  (erase-buffer)
  (dolist (v defvar-list)
    (insert "#define " v " *find_variable_location (&impl_" v ")\n"))

  ;; A few special cases for globals.h.
  (insert "\n")
  (dolist (v '("do_mouse_tracking" "Vmark_even_if_inactive" "Vprint_level"))
    (insert "extern Lisp_Object impl_" v ";\n"))
  (save-buffer))

(munge-V-directory)

  reply	other threads:[~2010-09-15  1:38 UTC|newest]

Thread overview: 97+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2010-09-14 19:12 Compiling Elisp to a native code with a GCC plugin Wojciech Meyer
2010-09-14 19:32 ` Tom Tromey
2010-09-14 19:45   ` Wojciech Meyer
2010-09-14 20:17     ` Lars Magne Ingebrigtsen
2010-09-14 20:52       ` Wojciech Meyer
2010-09-14 20:55       ` Tom Tromey
2010-09-14 21:05         ` Wojciech Meyer
2010-09-14 20:44     ` Tom Tromey
2010-09-14 21:00       ` Wojciech Meyer
2010-09-14 21:16         ` Tom Tromey
2010-09-14 21:29           ` Wojciech Meyer
2010-09-14 21:59             ` Tom Tromey
2010-09-14 22:37               ` Wojciech Meyer
2010-09-14 22:55                 ` Tom Tromey
2010-09-14 23:33                   ` Wojciech Meyer
2010-09-15  1:38                     ` Tom Tromey [this message]
2010-09-14 22:49               ` Wojciech Meyer
2010-09-14 23:13           ` Thomas Lord
2010-09-14 23:42             ` Wojciech Meyer
2010-09-15 10:47   ` Leo
2010-09-15 11:41     ` Andreas Schwab
2010-09-15 12:10       ` Wojciech Meyer
2010-09-15 14:07     ` Stefan Monnier
2010-09-15 14:27       ` Helmut Eller
2010-09-15 14:59         ` Stefan Monnier
2010-09-15 15:09           ` Lars Magne Ingebrigtsen
2010-09-15 15:31             ` Andreas Schwab
2010-09-15 15:35               ` Lars Magne Ingebrigtsen
2010-09-15 16:28                 ` Andreas Schwab
2010-09-16 16:57                   ` Lars Magne Ingebrigtsen
2010-09-15 15:42             ` Stefan Monnier
2010-09-15 15:51               ` Lars Magne Ingebrigtsen
2010-09-15 15:57                 ` Leo
2010-09-15 16:01                   ` Lars Magne Ingebrigtsen
2010-09-15 16:05                   ` David Kastrup
2010-09-15 16:23                     ` Leo
2010-09-15 16:37                       ` David Kastrup
2010-09-16 16:58                         ` Lars Magne Ingebrigtsen
2010-09-16 21:11                           ` Andreas Schwab
2010-09-16 23:17                             ` Lars Magne Ingebrigtsen
2010-09-17  8:13                               ` Eli Zaretskii
2010-09-17 13:17                                 ` Lars Magne Ingebrigtsen
2010-09-17 13:30                                   ` Eli Zaretskii
2010-09-17 13:34                                     ` Lars Magne Ingebrigtsen
2010-09-16 17:35                         ` Lars Magne Ingebrigtsen
2010-09-16  2:57                 ` Stephen J. Turnbull
2010-09-16  6:54                   ` David Kastrup
2010-09-16  8:10                     ` Stephen J. Turnbull
2010-09-16  8:31                       ` David Kastrup
2010-09-16 17:01                   ` Lars Magne Ingebrigtsen
2010-09-17  6:52                     ` Stephen J. Turnbull
2010-09-17 13:09                       ` Lars Magne Ingebrigtsen
2010-09-17 13:31                         ` David Kastrup
2010-09-17 13:39                           ` Lars Magne Ingebrigtsen
2010-09-17 13:55                             ` David Kastrup
2010-09-17 14:18                               ` Lars Magne Ingebrigtsen
2010-09-17 14:57                                 ` David Kastrup
2010-09-17 15:06                                   ` Lars Magne Ingebrigtsen
2010-09-17 15:24                                     ` Lars Magne Ingebrigtsen
2010-09-17 16:11                                       ` Eli Zaretskii
2010-09-17 16:33                                       ` David Kastrup
2010-09-17 16:41                                         ` Andreas Schwab
2010-09-17 17:17                                           ` David Kastrup
2010-09-17 18:24                                             ` David Kastrup
2010-09-17 20:30                                               ` David Kastrup
2010-09-17 20:49                                                 ` Lars Magne Ingebrigtsen
2010-09-18  4:31                                                   ` David Kastrup
2010-09-17 18:53                                             ` Stephen J. Turnbull
2010-09-17 20:57                                               ` Eli Zaretskii
2010-09-18 14:19                                                 ` Stephen J. Turnbull
2010-09-18 15:46                                                   ` Eli Zaretskii
2010-09-18 15:58                                                   ` Stefan Monnier
2010-09-17 17:24                                         ` Lars Magne Ingebrigtsen
2010-09-17 16:11                                     ` David Kastrup
2010-09-17 16:18                                 ` Eli Zaretskii
2010-09-17 16:24                                   ` Lars Magne Ingebrigtsen
2010-09-17 16:39                                     ` Eli Zaretskii
2010-09-17 17:30                                       ` Lars Magne Ingebrigtsen
2010-09-17 18:49                                         ` Eli Zaretskii
2010-09-17 16:39                                     ` Eli Zaretskii
2010-09-17 13:49                           ` Andreas Schwab
2010-09-17 13:55                             ` Lars Magne Ingebrigtsen
2010-09-17 14:31                               ` Wojciech Meyer
2010-09-17 14:40                               ` Andreas Schwab
2010-09-17 14:47                                 ` Lars Magne Ingebrigtsen
2010-09-17 15:10                                   ` Andreas Schwab
2010-09-17 15:16                                     ` Lars Magne Ingebrigtsen
2010-09-17 15:39                                       ` Andreas Schwab
2010-09-17 15:42                                         ` Lars Magne Ingebrigtsen
2010-09-17 16:04                                           ` Andreas Schwab
2010-09-17 16:14                                       ` Eli Zaretskii
2010-09-17 19:22                                         ` James Cloos
2010-09-17 17:40                         ` Stephen J. Turnbull
2010-09-17 19:40                           ` Lars Magne Ingebrigtsen
2010-09-15 15:46           ` Helmut Eller
2010-09-15 16:28             ` Thomas Lord
2010-09-15 21:04       ` Leo

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=m3aanj23c2.fsf@fleche.redhat.com \
    --to=tromey@redhat.com \
    --cc=emacs-devel@gnu.org \
    --cc=wojciech.meyer@googlemail.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).