Mercurial > hg > xemacs-beta
comparison lisp/bytecomp.el @ 5356:5dd1ba5e0113
Be better about eliminating `block's that are not `return-from'd, bytecomp.el
2011-02-12 Aidan Kehoe <kehoea@parhasard.net>
* bytecomp.el:
* bytecomp.el (byte-compile-initial-macro-environment):
* bytecomp.el (unwind-protect):
* bytecomp.el (byte-compile-active-blocks):
* bytecomp.el (byte-compile-catch):
* bytecomp.el ('return-from-1): Removed.
* bytecomp.el ('block-1): Removed.
* bytecomp.el (byte-compile-block-1): Removed.
* bytecomp.el (byte-compile-return-from-1): Removed.
* bytecomp.el (byte-compile-throw):
* cl-macs.el (block):
* cl-macs.el (return-from):
In my last change, the elimination of `block's that were never
`return-from'd didn't work if `cl-macroexpand-all' was called
explicitly, something much code in cl-macs.el does. Change the
implementation to something that doesn't require shadowing of the
macros in `byte-compile-initial-macro-environment', putting a
`cl-block-name' property on the gensym'd symbol argument to
`catch' instead.
author | Aidan Kehoe <kehoea@parhasard.net> |
---|---|
date | Sat, 12 Feb 2011 14:07:38 +0000 |
parents | 38e24b8be4ea |
children | 31475de17064 00e79bbbe48f |
comparison
equal
deleted
inserted
replaced
5355:70b15ac66ee5 | 5356:5dd1ba5e0113 |
---|---|
509 (or (eval (cl-make-type-test form type)) | 509 (or (eval (cl-make-type-test form type)) |
510 (byte-compile-warn | 510 (byte-compile-warn |
511 "%s is not of type %s" form type))) | 511 "%s is not of type %s" form type))) |
512 (if byte-compile-delete-errors | 512 (if byte-compile-delete-errors |
513 form | 513 form |
514 (funcall (cdr (symbol-function 'the)) type form)))) | 514 (funcall (cdr (symbol-function 'the)) type form))))) |
515 (return-from . | |
516 ,#'(lambda (name &optional result) `(return-from-1 ',name ,result))) | |
517 (block . | |
518 ,#'(lambda (name &rest body) `(block-1 ',name ,@body)))) | |
519 "The default macro-environment passed to macroexpand by the compiler. | 515 "The default macro-environment passed to macroexpand by the compiler. |
520 Placing a macro here will cause a macro to have different semantics when | 516 Placing a macro here will cause a macro to have different semantics when |
521 expanded by the compiler as when expanded by the interpreter.") | 517 expanded by the compiler as when expanded by the interpreter.") |
522 | 518 |
523 (defvar byte-compile-macro-environment byte-compile-initial-macro-environment | 519 (defvar byte-compile-macro-environment byte-compile-initial-macro-environment |
4184 (cdr form)))) | 4180 (cdr form)))) |
4185 | 4181 |
4186 ;;; other tricky macro-like special-operators | 4182 ;;; other tricky macro-like special-operators |
4187 | 4183 |
4188 (byte-defop-compiler-1 catch) | 4184 (byte-defop-compiler-1 catch) |
4189 (byte-defop-compiler-1 block-1) | |
4190 (byte-defop-compiler-1 return-from-1) | |
4191 (byte-defop-compiler-1 unwind-protect) | 4185 (byte-defop-compiler-1 unwind-protect) |
4192 (byte-defop-compiler-1 condition-case) | 4186 (byte-defop-compiler-1 condition-case) |
4193 (byte-defop-compiler-1 save-excursion) | 4187 (byte-defop-compiler-1 save-excursion) |
4194 (byte-defop-compiler-1 save-current-buffer) | 4188 (byte-defop-compiler-1 save-current-buffer) |
4195 (byte-defop-compiler-1 save-restriction) | 4189 (byte-defop-compiler-1 save-restriction) |
4196 (byte-defop-compiler-1 with-output-to-temp-buffer) | 4190 (byte-defop-compiler-1 with-output-to-temp-buffer) |
4197 ;; no track-mouse. | 4191 ;; no track-mouse. |
4198 | 4192 |
4193 (defvar byte-compile-active-blocks nil) | |
4194 | |
4199 (defun byte-compile-catch (form) | 4195 (defun byte-compile-catch (form) |
4200 (byte-compile-form (car (cdr form))) | 4196 "Byte-compile and return a `catch' from. |
4201 (byte-compile-push-constant | 4197 |
4202 (byte-compile-top-level (cons 'progn (cdr (cdr form))) for-effect)) | 4198 If FORM is the result of macroexpanding a `block' form (the TAG argument is |
4203 (byte-compile-out 'byte-catch 0)) | 4199 a quoted symbol with a non-nil `cl-block-name' property) and there is no |
4204 | 4200 corresponding `return-from' within the block--or equivalently, it was |
4205 ;; `return-from' and `block' are different from `throw' and `catch' when it | 4201 optimized away--just byte compile and return the BODY." |
4206 ;; comes to scope and extent. These differences are implemented for | 4202 (let* ((symbol (car-safe (cdr-safe (nth 1 form)))) |
4207 ;; interpreted code in cl-macs.el, in compiled code in bytecomp.el. There's | 4203 (block (and symbol (symbolp symbol) (get symbol 'cl-block-name))) |
4208 ;; a certain amount of bootstrapping needed for the latter, and until this | 4204 (elt (and block (cons block nil))) |
4209 ;; is done return-from and block behave as throw and catch in their scope | 4205 (byte-compile-active-blocks |
4210 ;; and extent. This is only relevant to people working on bytecomp.el. | 4206 (if block |
4211 | 4207 (cons elt byte-compile-active-blocks) |
4212 (defalias 'return-from-1 'throw) | 4208 byte-compile-active-blocks)) |
4213 (defalias 'block-1 'catch) | 4209 (body |
4214 | 4210 (byte-compile-top-level (cons 'progn (cddr form)) |
4215 (defvar byte-compile-active-blocks nil) | 4211 (if block nil for-effect)))) |
4216 | 4212 (if (and block (not (cdr elt))) |
4217 (defun byte-compile-block-1 (form) | 4213 ;; A lexical block without any contained return-from clauses: |
4218 (let* ((name (nth 1 (nth 1 form))) | 4214 (byte-compile-form body) |
4219 (elt (list name (copy-symbol name) nil)) | 4215 ;; A normal catch call, or a lexical block with a contained |
4220 (byte-compile-active-blocks (cons elt byte-compile-active-blocks)) | 4216 ;; return-from clause. |
4221 (body (byte-compile-top-level (cons 'progn (cddr form))))) | 4217 (byte-compile-form (car (cdr form))) |
4222 (if (nth 2 elt) | 4218 (byte-compile-push-constant body) |
4223 (byte-compile-catch `(catch ',(nth 1 elt) ,body)) | 4219 (byte-compile-out 'byte-catch 0)))) |
4224 (byte-compile-form body)))) | |
4225 | |
4226 (defun byte-compile-return-from-1 (form) | |
4227 (let* ((name (nth 1 (nth 1 form))) | |
4228 (assq (assq name byte-compile-active-blocks))) | |
4229 (if assq | |
4230 (setf (nth 2 assq) t) | |
4231 (byte-compile-warn | |
4232 "return-from: %S: no current lexical block with this name" | |
4233 name)) | |
4234 (byte-compile-throw | |
4235 `(throw ',(or (nth 1 assq) (copy-symbol name)) | |
4236 ,@(nthcdr 2 form))))) | |
4237 | 4220 |
4238 (defun byte-compile-unwind-protect (form) | 4221 (defun byte-compile-unwind-protect (form) |
4239 (byte-compile-push-constant | 4222 (byte-compile-push-constant |
4240 (byte-compile-top-level-body (cdr (cdr form)) t)) | 4223 (byte-compile-top-level-body (cdr (cdr form)) t)) |
4241 (byte-compile-out 'byte-unwind-protect 0) | 4224 (byte-compile-out 'byte-unwind-protect 0) |
4381 (progn | 4364 (progn |
4382 (byte-compile-warn-wrong-args form 2) | 4365 (byte-compile-warn-wrong-args form 2) |
4383 (byte-compile-normal-call | 4366 (byte-compile-normal-call |
4384 `(signal 'wrong-number-of-arguments '(,(car form) | 4367 `(signal 'wrong-number-of-arguments '(,(car form) |
4385 ,(length (cdr form)))))) | 4368 ,(length (cdr form)))))) |
4369 ;; If this form was macroexpanded from `return-from', mark the | |
4370 ;; corresponding block as having been referenced. | |
4371 (let* ((symbol (car-safe (cdr-safe (nth 1 form)))) | |
4372 (block (and symbol (symbolp symbol) (get symbol 'cl-block-name))) | |
4373 (assq (and block (assq block byte-compile-active-blocks)))) | |
4374 (and assq (setcdr assq t))) | |
4386 (byte-compile-form (nth 1 form)) ;; Push the arguments | 4375 (byte-compile-form (nth 1 form)) ;; Push the arguments |
4387 (byte-compile-form (nth 2 form)) | 4376 (byte-compile-form (nth 2 form)) |
4388 (byte-compile-out (get (car form) 'byte-opcode) 0) | 4377 (byte-compile-out (get (car form) 'byte-opcode) 0) |
4389 (pushnew '(null (function-max-args 'throw)) | 4378 (pushnew '(null (function-max-args 'throw)) |
4390 byte-compile-checks-on-load | 4379 byte-compile-checks-on-load |