diff options
| author | Stefan Monnier | 2015-03-06 23:35:04 -0500 |
|---|---|---|
| committer | Stefan Monnier | 2015-03-06 23:35:04 -0500 |
| commit | 25058c3ab82cff0105c31de0c1934da6602c6bee (patch) | |
| tree | 6ad0891c7e86162e5cadb641320a85eb07b2e2d9 | |
| parent | e1acc3c7efb805d659f9edf345fc18a4647df538 (diff) | |
| download | emacs-25058c3ab82cff0105c31de0c1934da6602c6bee.tar.gz emacs-25058c3ab82cff0105c31de0c1934da6602c6bee.zip | |
* lisp/emacs-lisp/byte-opt.el (byte-optimize-form-code-walker): Don't try to
unfold `closure's since byte-compile-unfold-lambda doesn't know how to
do it.
| -rw-r--r-- | lisp/ChangeLog | 6 | ||||
| -rw-r--r-- | lisp/emacs-lisp/byte-opt.el | 121 |
2 files changed, 67 insertions, 60 deletions
diff --git a/lisp/ChangeLog b/lisp/ChangeLog index c81ab9b6d22..1bd45c07c3e 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog | |||
| @@ -1,3 +1,9 @@ | |||
| 1 | 2015-03-07 Stefan Monnier <monnier@iro.umontreal.ca> | ||
| 2 | |||
| 3 | * emacs-lisp/byte-opt.el (byte-optimize-form-code-walker): Don't try to | ||
| 4 | unfold `closure's since byte-compile-unfold-lambda doesn't know how to | ||
| 5 | do it. | ||
| 6 | |||
| 1 | 2015-03-06 Oscar Fuentes <ofv@wanadoo.es> | 7 | 2015-03-06 Oscar Fuentes <ofv@wanadoo.es> |
| 2 | 8 | ||
| 3 | * net/browse-url.el (browse-url-firefox): Removed outdated | 9 | * net/browse-url.el (browse-url-firefox): Removed outdated |
diff --git a/lisp/emacs-lisp/byte-opt.el b/lisp/emacs-lisp/byte-opt.el index e149f80db8e..06a11063025 100644 --- a/lisp/emacs-lisp/byte-opt.el +++ b/lisp/emacs-lisp/byte-opt.el | |||
| @@ -302,65 +302,65 @@ | |||
| 302 | ;; doesn't matter here, because function's behavior is underspecified so it | 302 | ;; doesn't matter here, because function's behavior is underspecified so it |
| 303 | ;; can safely be turned into a `let', even though the reverse is not true. | 303 | ;; can safely be turned into a `let', even though the reverse is not true. |
| 304 | (or name (setq name "anonymous lambda")) | 304 | (or name (setq name "anonymous lambda")) |
| 305 | (let ((lambda (car form)) | 305 | (let* ((lambda (car form)) |
| 306 | (values (cdr form))) | 306 | (values (cdr form)) |
| 307 | (let ((arglist (nth 1 lambda)) | 307 | (arglist (nth 1 lambda)) |
| 308 | (body (cdr (cdr lambda))) | 308 | (body (cdr (cdr lambda))) |
| 309 | optionalp restp | 309 | optionalp restp |
| 310 | bindings) | 310 | bindings) |
| 311 | (if (and (stringp (car body)) (cdr body)) | 311 | (if (and (stringp (car body)) (cdr body)) |
| 312 | (setq body (cdr body))) | 312 | (setq body (cdr body))) |
| 313 | (if (and (consp (car body)) (eq 'interactive (car (car body)))) | 313 | (if (and (consp (car body)) (eq 'interactive (car (car body)))) |
| 314 | (setq body (cdr body))) | 314 | (setq body (cdr body))) |
| 315 | ;; FIXME: The checks below do not belong in an optimization phase. | 315 | ;; FIXME: The checks below do not belong in an optimization phase. |
| 316 | (while arglist | 316 | (while arglist |
| 317 | (cond ((eq (car arglist) '&optional) | 317 | (cond ((eq (car arglist) '&optional) |
| 318 | ;; ok, I'll let this slide because funcall_lambda() does... | 318 | ;; ok, I'll let this slide because funcall_lambda() does... |
| 319 | ;; (if optionalp (error "multiple &optional keywords in %s" name)) | 319 | ;; (if optionalp (error "multiple &optional keywords in %s" name)) |
| 320 | (if restp (error "&optional found after &rest in %s" name)) | 320 | (if restp (error "&optional found after &rest in %s" name)) |
| 321 | (if (null (cdr arglist)) | 321 | (if (null (cdr arglist)) |
| 322 | (error "nothing after &optional in %s" name)) | 322 | (error "nothing after &optional in %s" name)) |
| 323 | (setq optionalp t)) | 323 | (setq optionalp t)) |
| 324 | ((eq (car arglist) '&rest) | 324 | ((eq (car arglist) '&rest) |
| 325 | ;; ...but it is by no stretch of the imagination a reasonable | 325 | ;; ...but it is by no stretch of the imagination a reasonable |
| 326 | ;; thing that funcall_lambda() allows (&rest x y) and | 326 | ;; thing that funcall_lambda() allows (&rest x y) and |
| 327 | ;; (&rest x &optional y) in arglists. | 327 | ;; (&rest x &optional y) in arglists. |
| 328 | (if (null (cdr arglist)) | 328 | (if (null (cdr arglist)) |
| 329 | (error "nothing after &rest in %s" name)) | 329 | (error "nothing after &rest in %s" name)) |
| 330 | (if (cdr (cdr arglist)) | 330 | (if (cdr (cdr arglist)) |
| 331 | (error "multiple vars after &rest in %s" name)) | 331 | (error "multiple vars after &rest in %s" name)) |
| 332 | (setq restp t)) | 332 | (setq restp t)) |
| 333 | (restp | 333 | (restp |
| 334 | (setq bindings (cons (list (car arglist) | 334 | (setq bindings (cons (list (car arglist) |
| 335 | (and values (cons 'list values))) | 335 | (and values (cons 'list values))) |
| 336 | bindings) | 336 | bindings) |
| 337 | values nil)) | 337 | values nil)) |
| 338 | ((and (not optionalp) (null values)) | 338 | ((and (not optionalp) (null values)) |
| 339 | (byte-compile-warn "attempt to open-code `%s' with too few arguments" name) | 339 | (byte-compile-warn "attempt to open-code `%s' with too few arguments" name) |
| 340 | (setq arglist nil values 'too-few)) | 340 | (setq arglist nil values 'too-few)) |
| 341 | (t | 341 | (t |
| 342 | (setq bindings (cons (list (car arglist) (car values)) | 342 | (setq bindings (cons (list (car arglist) (car values)) |
| 343 | bindings) | 343 | bindings) |
| 344 | values (cdr values)))) | 344 | values (cdr values)))) |
| 345 | (setq arglist (cdr arglist))) | 345 | (setq arglist (cdr arglist))) |
| 346 | (if values | 346 | (if values |
| 347 | (progn | 347 | (progn |
| 348 | (or (eq values 'too-few) | 348 | (or (eq values 'too-few) |
| 349 | (byte-compile-warn | 349 | (byte-compile-warn |
| 350 | "attempt to open-code `%s' with too many arguments" name)) | 350 | "attempt to open-code `%s' with too many arguments" name)) |
| 351 | form) | 351 | form) |
| 352 | 352 | ||
| 353 | ;; The following leads to infinite recursion when loading a | 353 | ;; The following leads to infinite recursion when loading a |
| 354 | ;; file containing `(defsubst f () (f))', and then trying to | 354 | ;; file containing `(defsubst f () (f))', and then trying to |
| 355 | ;; byte-compile that file. | 355 | ;; byte-compile that file. |
| 356 | ;(setq body (mapcar 'byte-optimize-form body))) | 356 | ;(setq body (mapcar 'byte-optimize-form body))) |
| 357 | 357 | ||
| 358 | (let ((newform | 358 | (let ((newform |
| 359 | (if bindings | 359 | (if bindings |
| 360 | (cons 'let (cons (nreverse bindings) body)) | 360 | (cons 'let (cons (nreverse bindings) body)) |
| 361 | (cons 'progn body)))) | 361 | (cons 'progn body)))) |
| 362 | (byte-compile-log " %s\t==>\t%s" form newform) | 362 | (byte-compile-log " %s\t==>\t%s" form newform) |
| 363 | newform))))) | 363 | newform)))) |
| 364 | 364 | ||
| 365 | 365 | ||
| 366 | ;;; implementing source-level optimizers | 366 | ;;; implementing source-level optimizers |
| @@ -390,12 +390,13 @@ | |||
| 390 | (and (nth 1 form) | 390 | (and (nth 1 form) |
| 391 | (not for-effect) | 391 | (not for-effect) |
| 392 | form)) | 392 | form)) |
| 393 | ((memq (car-safe fn) '(lambda closure)) | 393 | ((eq (car-safe fn) 'lambda) |
| 394 | (let ((newform (byte-compile-unfold-lambda form))) | 394 | (let ((newform (byte-compile-unfold-lambda form))) |
| 395 | (if (eq newform form) | 395 | (if (eq newform form) |
| 396 | ;; Some error occurred, avoid infinite recursion | 396 | ;; Some error occurred, avoid infinite recursion |
| 397 | form | 397 | form |
| 398 | (byte-optimize-form-code-walker newform for-effect)))) | 398 | (byte-optimize-form-code-walker newform for-effect)))) |
| 399 | ((eq (car-safe fn) 'closure) form) | ||
| 399 | ((memq fn '(let let*)) | 400 | ((memq fn '(let let*)) |
| 400 | ;; recursively enter the optimizer for the bindings and body | 401 | ;; recursively enter the optimizer for the bindings and body |
| 401 | ;; of a let or let*. This for depth-firstness: forms that | 402 | ;; of a let or let*. This for depth-firstness: forms that |