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)
next prev parent 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).