|
|
1.1 root 1: ;; Compilation of Lisp code into byte code.
2: ;; Copyright (C) 1985 Richard M. Stallman.
3:
4: ;; This file is part of GNU Emacs.
5:
6: ;; GNU Emacs is distributed in the hope that it will be useful,
7: ;; but WITHOUT ANY WARRANTY. No author or distributor
8: ;; accepts responsibility to anyone for the consequences of using it
9: ;; or for whether it serves any particular purpose or works at all,
10: ;; unless he says so in writing. Refer to the GNU Emacs General Public
11: ;; License for full details.
12:
13: ;; Everyone is granted permission to copy, modify and redistribute
14: ;; GNU Emacs, but only under the conditions described in the
15: ;; GNU Emacs General Public License. A copy of this license is
16: ;; supposed to have been given to you along with GNU Emacs so you
17: ;; can know your rights and responsibilities. It should be in a
18: ;; file named COPYING. Among other things, the copyright notice
19: ;; and this notice must be preserved on all copies.
20:
21:
22: (defvar byte-compile-constnum -1
23: "Transfer vector index of last constant allocated.")
24: (defvar byte-compile-constants nil
25: "Alist describing contents to put in transfer vector.
26: Each element is (CONTENTS . INDEX)")
27: (defvar byte-compile-macro-environment nil
28: "Alist of (MACRONAME . DEFINITION) macros defined in the file
29: which is being compiled.")
30: (defvar byte-compile-pc 0
31: "Index in byte string to store next opcode at.")
32: (defvar byte-compile-output nil
33: "Alist describing contents to put in byte code string.
34: Each element is (INDEX . VALUE)")
35: (defvar byte-compile-depth 0
36: "Current depth of execution stack.")
37: (defvar byte-compile-maxdepth 0
38: "Maximum depth of execution stack.")
39:
40: (defconst byte-varref 8
41: "Byte code opcode for variable reference.")
42: (defconst byte-varset 16
43: "Byte code opcode for setting a variable.")
44: (defconst byte-varbind 24
45: "Byte code opcode for binding a variable.")
46: (defconst byte-call 32
47: "Byte code opcode for calling a function.")
48: (defconst byte-unbind 40
49: "Byte code opcode for unbinding special bindings.")
50:
51: (defconst byte-constant 192
52: "Byte code opcode for reference to a constant.")
53: (defconst byte-constant-limit 64
54: "Maximum index usable in byte-constant opcode.")
55:
56: (defconst byte-constant2 129
57: "Byte code opcode for reference to a constant with vector index >= 0100.")
58:
59: (defconst byte-goto 130
60: "Byte code opcode for unconditional jump")
61:
62: (defconst byte-goto-if-nil 131
63: "Byte code opcode for pop value and jump if it's nil.")
64:
65: (defconst byte-goto-if-not-nil 132
66: "Byte code opcode for pop value and jump if it's not nil.")
67:
68: (defconst byte-goto-if-nil-else-pop 133
69: "Byte code opcode for examine top-of-stack, jump and don't pop it if it's nil,
70: otherwise pop it.")
71:
72: (defconst byte-goto-if-not-nil-else-pop 134
73: "Byte code opcode for examine top-of-stack, jump and don't pop it if it's not nil,
74: otherwise pop it.")
75:
76: (defconst byte-return 135
77: "Byte code opcode for pop value and return it from byte code interpreter.")
78:
79: (defconst byte-discard 136
80: "Byte code opcode to discard one value from stack.")
81:
82: (defconst byte-dup 137
83: "Byte code opcode to duplicate the top of the stack.")
84:
85: (defconst byte-save-excursion 138
86: "Byte code opcode to make a binding to record the buffer, point and mark.")
87:
88: (defconst byte-save-window-excursion 139
89: "Byte code opcode to make a binding to record entire window configuration.")
90:
91: (defconst byte-save-restriction 140
92: "Byte code opcode to make a binding to record the current buffer clipping restrictions.")
93:
94: (defconst byte-catch 141
95: "Byte code opcode for catch. Takes, on stack, the tag and an expression for the body.")
96:
97: (defconst byte-unwind-protect 142
98: "Byte code opcode for unwind-protect. Takes, on stack, an expression for the body
99: and an expression for the unwind-action.")
100:
101: (defconst byte-condition-case 143
102: "Byte code opcode for condition-case. Takes, on stack, the variable to bind,
103: an expression for the body, and a list of clauses.")
104:
105: (defconst byte-temp-output-buffer-setup 144
106: "Byte code opcode for entry to with-output-to-temp-buffer.
107: Takes, on stack, the buffer name.
108: Binds standard-output and does some other things.
109: Returns with temp buffer on the stack in place of buffer name.")
110:
111: (defconst byte-temp-output-buffer-show 145
112: "Byte code opcode for exit from with-output-to-temp-buffer.
113: Expects the temp buffer on the stack underneath value to return.
114: Pops them both, then pushes the value back on.
115: Unbinds standard-output and makes the temp buffer visible.")
116:
117: (defconst byte-nth 56)
118: (defconst byte-symbolp 57)
119: (defconst byte-consp 58)
120: (defconst byte-stringp 59)
121: (defconst byte-listp 60)
122: (defconst byte-eq 61)
123: (defconst byte-memq 62)
124: (defconst byte-not 63)
125: (defconst byte-car 64)
126: (defconst byte-cdr 65)
127: (defconst byte-cons 66)
128: (defconst byte-list1 67)
129: (defconst byte-list2 68)
130: (defconst byte-list3 69)
131: (defconst byte-list4 70)
132: (defconst byte-length 71)
133: (defconst byte-aref 72)
134: (defconst byte-aset 73)
135: (defconst byte-symbol-value 74)
136: (defconst byte-symbol-function 75)
137: (defconst byte-set 76)
138: (defconst byte-fset 77)
139: (defconst byte-get 78)
140: (defconst byte-substring 79)
141: (defconst byte-concat2 80)
142: (defconst byte-concat3 81)
143: (defconst byte-concat4 82)
144: (defconst byte-sub1 83)
145: (defconst byte-add1 84)
146: (defconst byte-eqlsign 85)
147: (defconst byte-gtr 86)
148: (defconst byte-lss 87)
149: (defconst byte-leq 88)
150: (defconst byte-geq 89)
151: (defconst byte-diff 90)
152: (defconst byte-negate 91)
153: (defconst byte-plus 92)
154: (defconst byte-max 93)
155: (defconst byte-min 94)
156:
157: (defconst byte-point 96)
158: (defconst byte-mark 97)
159: (defconst byte-goto-char 98)
160: (defconst byte-insert 99)
161: (defconst byte-point-max 100)
162: (defconst byte-point-min 101)
163: (defconst byte-char-after 102)
164: (defconst byte-following-char 103)
165: (defconst byte-preceding-char 104)
166: (defconst byte-current-column 105)
167: (defconst byte-indent-to 106)
168: (defconst byte-scan-buffer 107)
169: (defconst byte-eolp 108)
170: (defconst byte-eobp 109)
171: (defconst byte-bolp 110)
172: (defconst byte-bobp 111)
173: (defconst byte-current-buffer 112)
174: (defconst byte-set-buffer 113)
175: (defconst byte-read-char 114)
176: (defconst byte-set-mark 115)
177: (defconst byte-interactive-p 116)
178:
179: (defun byte-recompile-directory (directory &optional arg)
180: "Recompile every .el file in DIRECTORY that needs recompilation.
181: This is if a .elc file exists but is older than the .el file.
182: If the .elc file does not exist, offer to compile the .el file
183: only if a prefix argument has been specified."
184: (interactive "DByte recompile directory: \nP")
185: (save-some-buffers)
186: (setq directory (expand-file-name directory))
187: (let ((files (directory-files directory))
188: (count 0)
189: source)
190: (while files
191: (if (and (string-match ".el$" (car files))
192: (not (auto-save-file-name-p (car files)))
193: (setq source (expand-file-name (car files) directory))
194: (if (file-exists-p (concat source "c"))
195: (file-newer-than-file-p source (concat source "c"))
196: (and arg (y-or-n-p (concat "Compile " source "? ")))))
197: (progn (byte-compile-file source)
198: (setq count (1+ count))))
199: (setq files (cdr files)))
200: (message "Done (Total of %d file%s compiled)"
201: count (if (= count 1) "" "s"))))
202:
203: (defun file-newer-than-file-p (file1 file2)
204: "Return t if FILE1 modified more recently than FILE2."
205: (let ((mtime1 (car (nthcdr 5 (file-attributes file1))))
206: (mtime2 (car (nthcdr 5 (file-attributes file2)))))
207: (or (> (car mtime1) (car mtime2))
208: (and (= (car mtime1) (car mtime2))
209: (> (car (cdr mtime1)) (car (cdr mtime2)))))))
210:
211: (defun byte-compile-file (filename)
212: "Compile a file of Lisp code named FILENAME into a file of byte code.
213: The output file's name is made by appending \"c\" to the end of FILENAME."
214: (interactive "fByte compile file: ")
215: ;; Expand now so we get the current buffer's defaults
216: (setq filename (expand-file-name filename))
217: (message "Compiling %s..." filename)
218: (let ((inbuffer (get-buffer-create " *Compiler Input*"))
219: (outbuffer (get-buffer-create " *Compiler Output*"))
220: (byte-compile-macro-environment nil)
221:
222: (case-fold-search nil) ;I thought this was lisp, not unix!
223: sexp)
224: (save-excursion
225: (set-buffer inbuffer)
226: (erase-buffer)
227: (insert-file-contents filename)
228: (goto-char 1)
229: (set-buffer outbuffer)
230: (emacs-lisp-mode)
231: (erase-buffer)
232: (while (save-excursion
233: (set-buffer inbuffer)
234: (while (progn (skip-chars-forward " \t\n\^l")
235: (looking-at ";"))
236: (forward-line 1))
237: (not (eobp)))
238: (setq sexp (read inbuffer))
239: (print (byte-compile-file-form sexp) outbuffer))
240: (set-buffer outbuffer)
241: (goto-char 1)
242: (while (search-forward "\n(" nil t)
243: (cond ((looking-at "defun \\|autoload ")
244: (forward-sexp 3)
245: (skip-chars-forward " ")
246: (if (looking-at "\"")
247: (progn (forward-char 1)
248: (insert "\\\n"))))))
249: (write-region 1 (point-max) (concat filename "c"))
250: (kill-buffer (current-buffer))
251: (kill-buffer inbuffer)))
252: t)
253:
254:
255: (defun byte-compile-file-form (form)
256: (if (memq (car-safe form) '(defun defmacro))
257: (let* ((name (car (cdr form)))
258: (tem (assq name byte-compile-macro-environment)))
259: (if (eq (car form) 'defun)
260: (progn
261: (message "Compiling %s (%s)..." filename (nth 1 form))
262: (cond (tem (setcdr tem nil))
263: ((and (fboundp name)
264: (eq (car-safe (symbol-function name)) 'macro))
265: ;; shadow existing macro definition
266: (setq byte-compile-macro-environment
267: (cons (cons name nil)
268: byte-compile-macro-environment))))
269: (prog1 (cons 'defun (byte-compile-lambda (cdr form)))
270: (if (not noninteractive)
271: (message "Compiling %s..." filename))))
272: ;; defmacro
273: (if tem
274: (setcdr tem (cons 'lambda (cdr (cdr form))))
275: (setq byte-compile-macro-environment
276: (cons (cons name (cons 'lambda (cdr (cdr form))))
277: byte-compile-macro-environment)))
278: (cons 'defmacro (byte-compile-lambda (cdr form)))))
279: form))
280:
281: (defun byte-compile (funname)
282: "Byte-compile the definition of function FUNNAME (a symbol)."
283: (if (and (fboundp funname)
284: (eq (car-safe (symbol-function funname)) 'lambda))
285: (fset funname (byte-compile-lambda (symbol-function funname)))))
286:
287: (defun byte-compile-lambda (fun)
288: (let* ((bodyptr (cdr fun))
289: (int (assq 'interactive (cdr bodyptr)))
290: newbody)
291: ;; Skip doc string.
292: (if (stringp (car (cdr bodyptr)))
293: (setq bodyptr (cdr bodyptr)))
294: (setq newbody (list (byte-compile-top-level
295: (cons 'progn (cdr bodyptr)))))
296: (if int
297: (setq newbody (cons (if (or (stringp (car (cdr int)))
298: (null (car (cdr int))))
299: int
300: (list 'interactive
301: (byte-compile-top-level (car (cdr int)))))
302: newbody)))
303: (if (not (eq bodyptr (cdr fun)))
304: (setq newbody (cons (nth 2 fun) newbody)))
305: (cons (car fun) (cons (car (cdr fun)) newbody))))
306:
307: (defun byte-compile-top-level (form)
308: (let ((byte-compile-constants nil)
309: (byte-compile-constnum nil)
310: (byte-compile-pc 0)
311: (byte-compile-depth 0)
312: (byte-compile-maxdepth 0)
313: (byte-compile-output nil)
314: (byte-compile-string nil)
315: (byte-compile-vector nil))
316: (let ((vars (nreverse (byte-compile-find-vars form)))
317: (i -1))
318: (while vars
319: (setq i (1+ i))
320: (setq byte-compile-constants (cons (cons (car vars) i)
321: byte-compile-constants))
322: (setq vars (cdr vars)))
323: (setq byte-compile-constnum i))
324: (byte-compile-form form)
325: (byte-compile-out 'byte-return 0)
326: (setq byte-compile-vector (make-vector (1+ byte-compile-constnum)
327: nil))
328: (while byte-compile-constants
329: (aset byte-compile-vector (cdr (car byte-compile-constants))
330: (car (car byte-compile-constants)))
331: (setq byte-compile-constants (cdr byte-compile-constants)))
332: (setq byte-compile-string (make-string byte-compile-pc 0))
333: (while byte-compile-output
334: (aset byte-compile-string (car (car byte-compile-output))
335: (cdr (car byte-compile-output)))
336: (setq byte-compile-output (cdr byte-compile-output)))
337: (list 'byte-code byte-compile-string
338: byte-compile-vector byte-compile-maxdepth)))
339:
340: (defun byte-compile-find-vars (form)
341: (let ((all-vars nil))
342: (byte-compile-find-vars-1 form)
343: all-vars))
344:
345: (defun byte-compile-find-vars-1 (form)
346: (cond ((symbolp form)
347: (if (not (memq form all-vars))
348: (setq all-vars (cons form all-vars))))
349: ((or (not (consp form)) (eq (car form) 'quote))
350: nil)
351: ((memq (car form) '(let let*))
352: (let ((binds (car (cdr form)))
353: (body (cdr (cdr form))))
354: (while binds
355: (if (symbolp (car binds))
356: (if (not (memq (car binds) all-vars))
357: (setq all-vars (cons (car binds) all-vars)))
358: (if (consp (car binds))
359: (progn
360: (if (not (memq (car (car binds)) all-vars))
361: (setq all-vars (cons (car (car binds)) all-vars)))
362: (byte-compile-find-vars-1 (car (cdr (car binds)))))))
363: (setq binds (cdr binds)))
364: (while body
365: (byte-compile-find-vars-1 (car body))
366: (setq body (cdr body)))))
367: ((eq (car form) 'cond)
368: (let ((clauses (cdr form)))
369: (while clauses
370: (let ((body (car clauses)))
371: (while body
372: (byte-compile-find-vars-1 (car body))
373: (setq body (cdr body))))
374: (setq clauses (cdr clauses)))))
375: ((not (eq form (setq form (macroexpand form byte-compile-macro-environment))))
376: (byte-compile-find-vars-1 form))
377: (t
378: (let ((body (if (symbolp (car form)) (cdr form) form)))
379: (while body
380: (byte-compile-find-vars-1 (car body))
381: (setq body (cdr body)))))))
382:
383: ;; This is the recursive entry point for compiling each subform of an expression.
384:
385: ;; Note that handler functions SHOULD NOT increment byte-compile-depth
386: ;; for the values they are returning! That is done on return here.
387: ;; Handlers should make sure that the depth on exit is the same as
388: ;; it was when the handler was called.
389:
390: (defun byte-compile-form (form)
391: (setq form (macroexpand form byte-compile-macro-environment))
392: (if (symbolp form)
393: (byte-compile-variable-ref 'byte-varref form)
394: (if (not (consp form))
395: (byte-compile-constant form)
396: (let ((handler (get (car form) 'byte-compile)))
397: (if handler
398: (funcall handler form)
399: (byte-compile-push-constant (car form))
400: (let ((copy (cdr form)))
401: (while copy (byte-compile-form (car copy)) (setq copy (cdr copy))))
402: (byte-compile-out 'byte-call (length (cdr form)))
403: (setq byte-compile-depth (- byte-compile-depth (length (cdr form))))))))
404: (setq byte-compile-maxdepth
405: (max byte-compile-maxdepth
406: (setq byte-compile-depth (1+ byte-compile-depth)))))
407:
408: (defun byte-compile-variable-ref (base-op var)
409: (let ((data (assq var byte-compile-constants)))
410: (if data
411: (byte-compile-out base-op (cdr data))
412: (error (format "Variable %s seen on pass 2 of byte compiler but not pass 1"
413: (prin1-to-string var))))))
414:
415: ;; Use this when the value of a form is a constant,
416: ;; because byte-compile-depth will be incremented accordingly
417: ;; on return to byte-compile-form, so it should not be done by the handler.
418: (defun byte-compile-constant (const)
419: (let ((data (if (stringp const)
420: (assoc const byte-compile-constants)
421: (assq const byte-compile-constants))))
422: (if data
423: (byte-compile-out-const (cdr data))
424: (setq byte-compile-constants
425: (cons (cons const (setq byte-compile-constnum (1+ byte-compile-constnum)))
426: byte-compile-constants))
427: (byte-compile-out-const byte-compile-constnum))))
428:
429: ;; Use this for a constant that is not the value of its containing form.
430: ;; Note that the calling function must explicitly decrement byte-compile-depth
431: ;; (or perhaps call byte-compile-discard to do so)
432: ;; for the word pushed by this function.
433: (defun byte-compile-push-constant (const)
434: (byte-compile-constant const)
435: (setq byte-compile-maxdepth
436: (max byte-compile-maxdepth
437: (setq byte-compile-depth (1+ byte-compile-depth)))))
438:
439: ;; Compile those primitive ordinary functions
440: ;; which have special byte codes just for speed.
441:
442: (put 'point 'byte-compile 'byte-compile-no-args)
443: (put 'point 'byte-opcode 'byte-point)
444:
445: (put 'dot 'byte-compile 'byte-compile-no-args)
446: (put 'dot 'byte-opcode 'byte-point)
447:
448: (put 'mark 'byte-compile 'byte-compile-no-args)
449: (put 'mark 'byte-opcode 'byte-mark)
450:
451: (put 'point-max 'byte-compile 'byte-compile-no-args)
452: (put 'point-max 'byte-opcode 'byte-point-max)
453:
454: (put 'point-min 'byte-compile 'byte-compile-no-args)
455: (put 'point-min 'byte-opcode 'byte-point-min)
456:
457: (put 'dot-max 'byte-compile 'byte-compile-no-args)
458: (put 'dot-max 'byte-opcode 'byte-point-max)
459:
460: (put 'dot-min 'byte-compile 'byte-compile-no-args)
461: (put 'dot-min 'byte-opcode 'byte-point-min)
462:
463: (put 'following-char 'byte-compile 'byte-compile-no-args)
464: (put 'following-char 'byte-opcode 'byte-following-char)
465:
466: (put 'preceding-char 'byte-compile 'byte-compile-no-args)
467: (put 'preceding-char 'byte-opcode 'byte-preceding-char)
468:
469: (put 'current-column 'byte-compile 'byte-compile-no-args)
470: (put 'current-column 'byte-opcode 'byte-current-column)
471:
472: (put 'eolp 'byte-compile 'byte-compile-no-args)
473: (put 'eolp 'byte-opcode 'byte-eolp)
474:
475: (put 'eobp 'byte-compile 'byte-compile-no-args)
476: (put 'eobp 'byte-opcode 'byte-eobp)
477:
478: (put 'bolp 'byte-compile 'byte-compile-no-args)
479: (put 'bolp 'byte-opcode 'byte-bolp)
480:
481: (put 'bobp 'byte-compile 'byte-compile-no-args)
482: (put 'bobp 'byte-opcode 'byte-bobp)
483:
484: (put 'current-buffer 'byte-compile 'byte-compile-no-args)
485: (put 'current-buffer 'byte-opcode 'byte-current-buffer)
486:
487: (put 'read-char 'byte-compile 'byte-compile-no-args)
488: (put 'read-char 'byte-opcode 'byte-read-char)
489:
490:
491: (put 'symbolp 'byte-compile 'byte-compile-one-arg)
492: (put 'symbolp 'byte-opcode 'byte-symbolp)
493:
494: (put 'consp 'byte-compile 'byte-compile-one-arg)
495: (put 'consp 'byte-opcode 'byte-consp)
496:
497: (put 'stringp 'byte-compile 'byte-compile-one-arg)
498: (put 'stringp 'byte-opcode 'byte-stringp)
499:
500: (put 'listp 'byte-compile 'byte-compile-one-arg)
501: (put 'listp 'byte-opcode 'byte-listp)
502:
503: (put 'not 'byte-compile 'byte-compile-one-arg)
504: (put 'not 'byte-opcode 'byte-not)
505:
506: (put 'null 'byte-compile 'byte-compile-one-arg)
507: (put 'null 'byte-opcode 'byte-not)
508:
509: (put 'car 'byte-compile 'byte-compile-one-arg)
510: (put 'car 'byte-opcode 'byte-car)
511:
512: (put 'cdr 'byte-compile 'byte-compile-one-arg)
513: (put 'cdr 'byte-opcode 'byte-cdr)
514:
515: (put 'length 'byte-compile 'byte-compile-one-arg)
516: (put 'length 'byte-opcode 'byte-length)
517:
518: (put 'symbol-value 'byte-compile 'byte-compile-one-arg)
519: (put 'symbol-value 'byte-opcode 'byte-symbol-value)
520:
521: (put 'symbol-function 'byte-compile 'byte-compile-one-arg)
522: (put 'symbol-function 'byte-opcode 'byte-symbol-function)
523:
524: (put '1+ 'byte-compile 'byte-compile-one-arg)
525: (put '1+ 'byte-opcode 'byte-add1)
526:
527: (put '1- 'byte-compile 'byte-compile-one-arg)
528: (put '1- 'byte-opcode 'byte-sub1)
529:
530: (put 'goto-char 'byte-compile 'byte-compile-one-arg)
531: (put 'goto-char 'byte-opcode 'byte-goto-char)
532:
533: (put 'char-after 'byte-compile 'byte-compile-one-arg)
534: (put 'char-after 'byte-opcode 'byte-char-after)
535:
536: (put 'set-buffer 'byte-compile 'byte-compile-one-arg)
537: (put 'set-buffer 'byte-opcode 'byte-set-buffer)
538:
539: (put 'set-mark 'byte-compile 'byte-compile-one-arg)
540: (put 'set-mark 'byte-opcode 'byte-set-mark)
541:
542: (put 'interactive-p 'byte-compile 'byte-compile-one-arg)
543: (put 'interactive-p 'byte-opcode 'byte-interactive-p)
544:
545:
546: (put 'eq 'byte-compile 'byte-compile-two-args)
547: (put 'eq 'byte-opcode 'byte-eq)
548:
549: (put 'memq 'byte-compile 'byte-compile-two-args)
550: (put 'memq 'byte-opcode 'byte-memq)
551:
552: (put 'cons 'byte-compile 'byte-compile-two-args)
553: (put 'cons 'byte-opcode 'byte-cons)
554:
555: (put 'aref 'byte-compile 'byte-compile-two-args)
556: (put 'aref 'byte-opcode 'byte-aref)
557:
558: (put 'set 'byte-compile 'byte-compile-two-args)
559: (put 'set 'byte-opcode 'byte-set)
560:
561: (put 'fset 'byte-compile 'byte-compile-two-args)
562: (put 'fset 'byte-opcode 'byte-fset)
563:
564: (put '= 'byte-compile 'byte-compile-two-args)
565: (put '= 'byte-opcode 'byte-eqlsign)
566:
567: (put '< 'byte-compile 'byte-compile-two-args)
568: (put '< 'byte-opcode 'byte-lss)
569:
570: (put '> 'byte-compile 'byte-compile-two-args)
571: (put '> 'byte-opcode 'byte-gtr)
572:
573: (put '<= 'byte-compile 'byte-compile-two-args)
574: (put '<= 'byte-opcode 'byte-leq)
575:
576: (put '>= 'byte-compile 'byte-compile-two-args)
577: (put '>= 'byte-opcode 'byte-geq)
578:
579: (put 'get 'byte-compile 'byte-compile-two-args)
580: (put 'get 'byte-opcode 'byte-get)
581:
582: (put 'nth 'byte-compile 'byte-compile-two-args)
583: (put 'nth 'byte-opcode 'byte-nth)
584:
585: (put 'aset 'byte-compile 'byte-compile-three-args)
586: (put 'aset 'byte-opcode 'byte-aset)
587:
588: (put 'substring 'byte-compile 'byte-compile-three-args)
589: (put 'substring 'byte-opcode 'byte-substring)
590:
591: (put 'scan-buffer 'byte-compile 'byte-compile-three-args)
592: (put 'scan-buffer 'byte-opcode 'byte-scan-buffer)
593:
594: (defun byte-compile-no-args (form)
595: (byte-compile-out (symbol-value (get (car form) 'byte-opcode)) 0))
596:
597: (defun byte-compile-one-arg (form)
598: (byte-compile-form (or (car (cdr form)) ''nil)) ;; Push the argument
599: (setq byte-compile-depth (1- byte-compile-depth))
600: (byte-compile-out (symbol-value (get (car form) 'byte-opcode)) 0))
601:
602: (defun byte-compile-two-args (form)
603: (byte-compile-form (or (car (cdr form)) ''nil)) ;; Push the arguments
604: (byte-compile-form (or (nth 2 form) ''nil))
605: (setq byte-compile-depth (- byte-compile-depth 2))
606: (byte-compile-out (symbol-value (get (car form) 'byte-opcode)) 0))
607:
608: (defun byte-compile-three-args (form)
609: (byte-compile-form (or (car (cdr form)) ''nil)) ;; Push the arguments
610: (byte-compile-form (or (nth 2 form) ''nil))
611: (byte-compile-form (or (nth 3 form) ''nil))
612: (setq byte-compile-depth (- byte-compile-depth 3))
613: (byte-compile-out (symbol-value (get (car form) 'byte-opcode)) 0))
614:
615: (put 'list 'byte-compile 'byte-compile-list)
616: (defun byte-compile-list (form)
617: (let ((len (length form)))
618: (if (= len 1)
619: (byte-compile-constant nil)
620: (if (< len 6)
621: (let ((args (cdr form)))
622: (while args
623: (byte-compile-form (car args))
624: (setq args (cdr args)))
625: (setq byte-compile-depth (- byte-compile-depth (1- len)))
626: (byte-compile-out (symbol-value
627: (nth (- len 2)
628: '(byte-list1 byte-list2 byte-list3 byte-list4)))
629: 0))
630: (byte-compile-normal-call form)))))
631:
632: (put 'concat 'byte-compile 'byte-compile-concat)
633: (defun byte-compile-concat (form)
634: (let ((len (length form)))
635: (cond ((= len 1)
636: (byte-compile-form ""))
637: ((= len 2)
638: ;; Concat of one arg is not a no-op if arg is not a string.
639: (byte-compile-normal-call form))
640: ((< len 6)
641: (let ((args (cdr form)))
642: (while args
643: (byte-compile-form (car args))
644: (setq args (cdr args)))
645: (setq byte-compile-depth (- byte-compile-depth (1- len)))
646: (byte-compile-out
647: (symbol-value (nth (- len 3)
648: '(byte-concat2 byte-concat3 byte-concat4)))
649: 0)))
650: (t
651: (byte-compile-normal-call form)))))
652:
653: (put '- 'byte-compile 'byte-compile-minus)
654: (defun byte-compile-minus (form)
655: (let ((len (length form)))
656: (cond ((= len 2)
657: (byte-compile-form (car (cdr form)))
658: (setq byte-compile-depth (- byte-compile-depth 1))
659: (byte-compile-out byte-negate 0))
660: ((= len 3)
661: (byte-compile-form (car (cdr form)))
662: (byte-compile-form (nth 2 form))
663: (setq byte-compile-depth (- byte-compile-depth 2))
664: (byte-compile-out byte-diff 0))
665: (t (byte-compile-normal-call form)))))
666:
667: (put '+ 'byte-compile 'byte-compile-maybe-two-args)
668: (put '+ 'byte-opcode 'byte-plus)
669:
670: (put 'max 'byte-compile 'byte-compile-maybe-two-args)
671: (put 'max 'byte-opcode 'byte-max)
672:
673: (put 'min 'byte-compile 'byte-compile-maybe-two-args)
674: (put 'min 'byte-opcode 'byte-min)
675:
676: (defun byte-compile-maybe-two-args (form)
677: (let ((len (length form)))
678: (if (= len 3)
679: (progn
680: (byte-compile-form (car (cdr form)))
681: (byte-compile-form (nth 2 form))
682: (setq byte-compile-depth (- byte-compile-depth 2))
683: (byte-compile-out (symbol-value (get (car form) 'byte-opcode)) 0))
684: (byte-compile-normal-call form))))
685:
686: (defun byte-compile-normal-call (form)
687: (byte-compile-push-constant (car form))
688: (let ((copy (cdr form)))
689: (while copy (byte-compile-form (car copy)) (setq copy (cdr copy))))
690: (byte-compile-out 'byte-call (length (cdr form)))
691: (setq byte-compile-depth (- byte-compile-depth (length (cdr form)))))
692:
693: (put 'function 'byte-compile 'byte-compile-function-form)
694: (defun byte-compile-function-form (form)
695: (byte-compile-constant (byte-compile-lambda (car (cdr form)))))
696:
697: (put 'indent-to 'byte-compile 'byte-compile-indent-to)
698: (defun byte-compile-indent-to (form)
699: (let ((len (length form)))
700: (if (= len 2)
701: (progn
702: (byte-compile-form (car (cdr form)))
703: (setq byte-compile-depth (- byte-compile-depth 1))
704: (byte-compile-out byte-indent-to 0))
705: (byte-compile-normal-call form))))
706:
707: (put 'insert 'byte-compile 'byte-compile-insert)
708: (defun byte-compile-insert (form)
709: (let ((len (length form)))
710: (if (< len 3)
711: (let ((args (cdr form)))
712: (while args
713: (byte-compile-form (car args))
714: (setq byte-compile-depth (- byte-compile-depth 1))
715: (byte-compile-out byte-insert 0)
716: (setq args (cdr args))))
717: (byte-compile-normal-call form))))
718:
719: (put 'quote 'byte-compile 'byte-compile-quote)
720: (defun byte-compile-quote (form)
721: (byte-compile-constant (car (cdr form))))
722:
723: (put 'setq 'byte-compile 'byte-compile-setq)
724: (defun byte-compile-setq (form)
725: (let ((args (cdr form)))
726: (while args
727: (byte-compile-form (car (cdr args)))
728: (if (null (cdr (cdr args)))
729: (progn
730: (byte-compile-out 'byte-dup 0)
731: (setq byte-compile-maxdepth (max byte-compile-maxdepth (1+ byte-compile-depth)))))
732: (setq byte-compile-depth (1- byte-compile-depth))
733: (byte-compile-variable-ref 'byte-varset (car args))
734: (setq args (cdr (cdr args))))))
735:
736: (put 'let 'byte-compile 'byte-compile-let)
737: (defun byte-compile-let (form)
738: (let ((varlist (car (cdr form))))
739: (while varlist
740: (if (symbolp (car varlist))
741: (byte-compile-push-constant nil)
742: (byte-compile-form (car (cdr (car varlist)))))
743: (setq varlist (cdr varlist))))
744: (let ((varlist (reverse (car (cdr form)))))
745: (setq byte-compile-depth (- byte-compile-depth (length varlist)))
746: (while varlist
747: (if (symbolp (car varlist))
748: (byte-compile-variable-ref 'byte-varbind (car varlist))
749: (byte-compile-variable-ref 'byte-varbind (car (car varlist))))
750: (setq varlist (cdr varlist))))
751: (byte-compile-body (cdr (cdr form)))
752: (byte-compile-out 'byte-unbind (length (car (cdr form)))))
753:
754: (put 'let* 'byte-compile 'byte-compile-let*)
755: (defun byte-compile-let* (form)
756: (let ((varlist (car (cdr form))))
757: (while varlist
758: (if (symbolp (car varlist))
759: (byte-compile-push-constant nil)
760: (byte-compile-form (car (cdr (car varlist)))))
761: (setq byte-compile-depth (1- byte-compile-depth))
762: (if (symbolp (car varlist))
763: (byte-compile-variable-ref 'byte-varbind (car varlist))
764: (byte-compile-variable-ref 'byte-varbind (car (car varlist))))
765: (setq varlist (cdr varlist))))
766: (byte-compile-body (cdr (cdr form)))
767: (byte-compile-out 'byte-unbind (length (car (cdr form)))))
768:
769: (put 'save-excursion 'byte-compile 'byte-compile-save-excursion)
770: (defun byte-compile-save-excursion (form)
771: (byte-compile-out 'byte-save-excursion 0)
772: (byte-compile-body (cdr form))
773: (byte-compile-out 'byte-unbind 1))
774:
775: (put 'save-restriction 'byte-compile 'byte-compile-save-restriction)
776: (defun byte-compile-save-restriction (form)
777: (byte-compile-out 'byte-save-restriction 0)
778: (byte-compile-body (cdr form))
779: (byte-compile-out 'byte-unbind 1))
780:
781: (put 'with-output-to-temp-buffer 'byte-compile 'byte-compile-with-output-to-temp-buffer)
782: (defun byte-compile-with-output-to-temp-buffer (form)
783: (byte-compile-form (car (cdr form)))
784: (byte-compile-out 'byte-temp-output-buffer-setup 0)
785: (byte-compile-body (cdr (cdr form)))
786: (byte-compile-out 'byte-temp-output-buffer-show 0)
787: (setq byte-compile-depth (1- byte-compile-depth)))
788:
789: (put 'progn 'byte-compile 'byte-compile-progn)
790: (defun byte-compile-progn (form)
791: (byte-compile-body (cdr form)))
792:
793: (put 'interactive 'byte-compile 'byte-compile-noop)
794: (defun byte-compile-noop (form)
795: (byte-compile-constant nil))
796:
797: (defun byte-compile-body (body)
798: (if (null body)
799: (byte-compile-constant nil)
800: (while body
801: (byte-compile-form (car body))
802: (if (cdr body)
803: (byte-compile-discard)
804: ;; Convention is this will be counted after we return.
805: (setq byte-compile-depth (1- byte-compile-depth)))
806: (setq body (cdr body)))))
807:
808: (put 'prog1 'byte-compile 'byte-compile-prog1)
809: (defun byte-compile-prog1 (form)
810: (byte-compile-form (car (cdr form)))
811: (if (cdr (cdr form))
812: (progn
813: (byte-compile-body (cdr (cdr form)))
814: ;; This discards the value pushed by ..-body
815: ;; (which is not counted now in byte-compile-depth)
816: ;; and decrements byte-compile-depth for the value
817: ;; pushed by byte-compile-form above, which by convention
818: ;; will be counted in byte-compile-depth after we return.
819: (byte-compile-discard))))
820:
821: (put 'prog2 'byte-compile 'byte-compile-prog2)
822: (defun byte-compile-prog2 (form)
823: (byte-compile-form (car (cdr form)))
824: (byte-compile-discard)
825: (byte-compile-form (nth 2 form))
826: (if (cdr (cdr (cdr form)))
827: (progn
828: (byte-compile-body (cdr (cdr (cdr form))))
829: (byte-compile-discard))))
830:
831: (defun byte-compile-discard ()
832: (byte-compile-out 'byte-discard 0)
833: (setq byte-compile-depth (1- byte-compile-depth)))
834:
835: (put 'if 'byte-compile 'byte-compile-if)
836: (defun byte-compile-if (form)
837: (if (null (cdr (cdr form)))
838: ;; No else-forms
839: (let ((donetag (byte-compile-make-tag)))
840: (byte-compile-form (car (cdr form)))
841: (byte-compile-goto 'byte-goto-if-nil-else-pop donetag)
842: (setq byte-compile-depth (1- byte-compile-depth))
843: (byte-compile-form (nth 2 form))
844: (setq byte-compile-depth (1- byte-compile-depth))
845: (byte-compile-out-tag donetag))
846: (let ((donetag (byte-compile-make-tag)) (elsetag (byte-compile-make-tag)))
847: (byte-compile-form (car (cdr form)))
848: (byte-compile-goto 'byte-goto-if-nil elsetag)
849: (setq byte-compile-depth (1- byte-compile-depth))
850: (byte-compile-form (nth 2 form))
851: (setq byte-compile-depth (1- byte-compile-depth))
852: (byte-compile-goto 'byte-goto donetag)
853: (byte-compile-out-tag elsetag)
854: (byte-compile-body (cdr (cdr (cdr form))))
855: (byte-compile-out-tag donetag))))
856:
857: (put 'cond 'byte-compile 'byte-compile-cond)
858: (defun byte-compile-cond (form)
859: (if (cdr form)
860: (byte-compile-cond-1 (cdr form))))
861: (defun byte-compile-cond-1 (clauses)
862: (if (null (cdr clauses))
863: ;; Only one clause
864: (let ((donetag (byte-compile-make-tag)))
865: (byte-compile-form (car (car clauses)))
866: (cond ((cdr (car clauses))
867: (byte-compile-goto 'byte-goto-if-nil-else-pop donetag)
868: (setq byte-compile-depth (1- byte-compile-depth))
869: (byte-compile-body (cdr (car clauses)))
870: (byte-compile-out-tag donetag))))
871: (let ((donetag (byte-compile-make-tag))
872: (elsetag (byte-compile-make-tag)))
873: (byte-compile-form (car (car clauses)))
874: (byte-compile-goto 'byte-goto-if-nil elsetag)
875: (setq byte-compile-depth (1- byte-compile-depth))
876: (byte-compile-body (cdr (car clauses)))
877: (byte-compile-goto 'byte-goto donetag)
878: (byte-compile-out-tag elsetag)
879: (byte-compile-cond-1 (cdr clauses))
880: (byte-compile-out-tag donetag))))
881:
882: (put 'and 'byte-compile 'byte-compile-and)
883: (defun byte-compile-and (form)
884: (let ((failtag (byte-compile-make-tag))
885: (args (cdr form)))
886: (if (null args)
887: (progn
888: (byte-compile-form t)
889: (setq byte-compile-depth (1- byte-compile-depth)))
890: (while args
891: (byte-compile-form (car args))
892: (setq byte-compile-depth (1- byte-compile-depth))
893: (if (null (cdr args))
894: (byte-compile-out-tag failtag)
895: (byte-compile-goto 'byte-goto-if-nil-else-pop failtag))
896: (setq args (cdr args))))))
897:
898: (put 'or 'byte-compile 'byte-compile-or)
899: (defun byte-compile-or (form)
900: (let ((wintag (byte-compile-make-tag))
901: (args (cdr form)))
902: (if (null args)
903: (byte-compile-constant nil)
904: (while args
905: (byte-compile-form (car args))
906: (setq byte-compile-depth (1- byte-compile-depth))
907: (if (null (cdr args))
908: (byte-compile-out-tag wintag)
909: (byte-compile-goto 'byte-goto-if-not-nil-else-pop wintag))
910: (setq args (cdr args))))))
911:
912: (put 'while 'byte-compile 'byte-compile-while)
913: (defun byte-compile-while (form)
914: (let ((endtag (byte-compile-make-tag))
915: (looptag (byte-compile-make-tag))
916: (args (cdr (cdr form))))
917: (byte-compile-out-tag looptag)
918: (byte-compile-form (car (cdr form)))
919: (byte-compile-goto 'byte-goto-if-nil-else-pop endtag)
920: (byte-compile-body (cdr (cdr form)))
921: (byte-compile-discard)
922: (byte-compile-goto 'byte-goto looptag)
923: (byte-compile-out-tag endtag)))
924:
925: (put 'catch 'byte-compile 'byte-compile-catch)
926: (defun byte-compile-catch (form)
927: (byte-compile-form (car (cdr form)))
928: (byte-compile-push-constant (byte-compile-top-level (cons 'progn (cdr (cdr form)))))
929: (setq byte-compile-depth (- byte-compile-depth 2))
930: (byte-compile-out 'byte-catch 0))
931:
932: (put 'save-window-excursion 'byte-compile 'byte-compile-save-window-excursion)
933: (defun byte-compile-save-window-excursion (form)
934: (byte-compile-push-constant
935: (list (byte-compile-top-level (cons 'progn (cdr form)))))
936: (setq byte-compile-depth (1- byte-compile-depth))
937: (byte-compile-out 'byte-save-window-excursion 0))
938:
939: (put 'unwind-protect 'byte-compile 'byte-compile-unwind-protect)
940: (defun byte-compile-unwind-protect (form)
941: (byte-compile-push-constant
942: (list (byte-compile-top-level (cons 'progn (cdr (cdr form))))))
943: (setq byte-compile-depth (1- byte-compile-depth))
944: (byte-compile-out 'byte-unwind-protect 0)
945: (byte-compile-form (car (cdr form)))
946: (setq byte-compile-depth (1- byte-compile-depth))
947: (byte-compile-out 'byte-unbind 1))
948:
949: (put 'condition-case 'byte-compile 'byte-compile-condition-case)
950: (defun byte-compile-condition-case (form)
951: (byte-compile-push-constant (car (cdr form)))
952: (byte-compile-push-constant (byte-compile-top-level (nth 2 form)))
953: (let ((clauses (cdr (cdr (cdr form))))
954: compiled-clauses)
955: (while clauses
956: (let ((clause (car clauses)))
957: (setq compiled-clauses
958: (cons (list (car clause)
959: (byte-compile-top-level (cons 'progn (cdr clause))))
960: compiled-clauses)))
961: (setq clauses (cdr clauses)))
962: (byte-compile-push-constant (nreverse compiled-clauses)))
963: (setq byte-compile-depth (- byte-compile-depth 3))
964: (byte-compile-out 'byte-condition-case 0))
965:
966: (defun byte-compile-make-tag ()
967: (cons nil nil))
968:
969: (defun byte-compile-out-tag (tag)
970: (let ((uses (car tag)))
971: (setcar tag byte-compile-pc)
972: (while uses
973: (byte-compile-store-goto (car uses) byte-compile-pc)
974: (setq uses (cdr uses)))))
975:
976: (defun byte-compile-goto (opcode tag)
977: (byte-compile-out opcode 0)
978: (if (integerp (car tag))
979: (byte-compile-store-goto byte-compile-pc (car tag))
980: (setcar tag (cons byte-compile-pc (car tag))))
981: (setq byte-compile-pc (+ byte-compile-pc 2)))
982:
983: (defun byte-compile-store-goto (at-pc to-pc)
984: (setq byte-compile-output
985: (cons (cons at-pc (logand to-pc 255))
986: byte-compile-output))
987: (setq byte-compile-output
988: (cons (cons (1+ at-pc) (lsh to-pc -8))
989: byte-compile-output)))
990:
991: (defun byte-compile-out (opcode offset)
992: (setq opcode (eval opcode))
993: (if (< offset 6)
994: (byte-compile-out-1 (+ opcode offset))
995: (if (< offset 256)
996: (progn
997: (byte-compile-out-1 (+ opcode 6))
998: (byte-compile-out-1 offset))
999: (byte-compile-out-1 (+ opcode 7))
1000: (byte-compile-out-1 (logand offset 255))
1001: (byte-compile-out-1 (lsh offset -8)))))
1002:
1003: (defun byte-compile-out-const (offset)
1004: (if (< offset byte-constant-limit)
1005: (byte-compile-out-1 (+ byte-constant offset))
1006: (byte-compile-out-1 byte-constant2)
1007: (byte-compile-out-1 (logand offset 255))
1008: (byte-compile-out-1 (lsh offset -8))))
1009:
1010: (defun byte-compile-out-1 (code)
1011: (setq byte-compile-output
1012: (cons (cons byte-compile-pc code)
1013: byte-compile-output))
1014: (setq byte-compile-pc (1+ byte-compile-pc)))
1015:
1016: ;;; by [email protected]
1017: ;;; Only works noninteractively.
1018: (defun batch-byte-compile ()
1019: "Runs byte-compile-file on the files remaining on the command line.
1020: Must be used only with -batch, and kills emacs on completion.
1021: Each file will be processed even if an error occurred previously.
1022: For example, invoke \"emacs -batch -f batch-byte-compile $emacs/ ~/*.el\""
1023: ;; command-line-args is what is left of the command line (from startup.el)
1024: (if (not noninteractive)
1025: (error "batch-byte-compile is to be used only with -batch"))
1026: (let ((error nil))
1027: (while command-line-args
1028: (if (file-directory-p (expand-file-name (car command-line-args)))
1029: (let ((files (directory-files (car command-line-args)))
1030: source)
1031: (while files
1032: (if (and (string-match ".el$" (car files))
1033: (not (auto-save-file-name-p (car files)))
1034: (setq source (expand-file-name (car files)
1035: (car command-line-args)))
1036: (file-exists-p (concat source "c"))
1037: (file-newer-than-file-p source (concat source "c")))
1038: (if (null (batch-byte-compile-file source))
1039: (setq error t)))
1040: (setq files (cdr files))))
1041: (if (null (batch-byte-compile-file (car command-line-args)))
1042: (setq error t)))
1043: (setq command-line-args (cdr command-line-args)))
1044: (message "Done")
1045: (kill-emacs (if error 1 0))))
1046:
1047: (defun batch-byte-compile-file (file)
1048: (condition-case err
1049: (progn (byte-compile-file file) t)
1050: (error
1051: (message (if (cdr err)
1052: ">>Error occurred processing %s: %s (%s)"
1053: ">>Error occurred processing %s: %s")
1054: file
1055: (get (car err) 'error-message)
1056: (prin1-to-string (cdr err)))
1057: nil)))
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.