comparison lisp/emacs-lisp/bytecomp.el @ 99544:d0522fd272de

(byte-compile-associative) (byte-compile-minus, byte-compile-quo): If there are more than two operands, don't use binary operation code (bug#1334).
author Chong Yidong <cyd@stupidchicken.com>
date Fri, 14 Nov 2008 18:08:10 +0000
parents c3512b2085a0
children 51f96d4c63b0
comparison
equal deleted inserted replaced
99543:f96d00b9bf04 99544:d0522fd272de
3215 ;; We treat the one-arg case, as in (+ x), like (+ x 0). 3215 ;; We treat the one-arg case, as in (+ x), like (+ x 0).
3216 ;; in order to convert markers to numbers, and trigger expected errors. 3216 ;; in order to convert markers to numbers, and trigger expected errors.
3217 (defun byte-compile-associative (form) 3217 (defun byte-compile-associative (form)
3218 (if (cdr form) 3218 (if (cdr form)
3219 (let ((opcode (get (car form) 'byte-opcode)) 3219 (let ((opcode (get (car form) 'byte-opcode))
3220 (args (copy-sequence (cdr form)))) 3220 args)
3221 (byte-compile-form (car args)) 3221 (if (and (< 3 (length form))
3222 (setq args (cdr args)) 3222 (memq opcode (list (get '+ 'byte-opcode)
3223 (or args (setq args '(0) 3223 (get '* 'byte-opcode))))
3224 opcode (get '+ 'byte-opcode))) 3224 ;; Don't use binary operations for > 2 operands, as that
3225 (dolist (arg args) 3225 ;; may cause overflow/truncation in float operations.
3226 (byte-compile-form arg) 3226 (byte-compile-normal-call form)
3227 (byte-compile-out opcode 0))) 3227 (setq args (copy-sequence (cdr form)))
3228 (byte-compile-form (car args))
3229 (setq args (cdr args))
3230 (or args (setq args '(0)
3231 opcode (get '+ 'byte-opcode)))
3232 (dolist (arg args)
3233 (byte-compile-form arg)
3234 (byte-compile-out opcode 0))))
3228 (byte-compile-constant (eval form)))) 3235 (byte-compile-constant (eval form))))
3229 3236
3230 3237
3231 ;; more complicated compiler macros 3238 ;; more complicated compiler macros
3232 3239
3301 (mapc 'byte-compile-form (cdr form)) 3308 (mapc 'byte-compile-form (cdr form))
3302 (byte-compile-out 'byte-concatN count)) 3309 (byte-compile-out 'byte-concatN count))
3303 ((byte-compile-normal-call form))))) 3310 ((byte-compile-normal-call form)))))
3304 3311
3305 (defun byte-compile-minus (form) 3312 (defun byte-compile-minus (form)
3306 (if (null (setq form (cdr form))) 3313 (let ((len (length form)))
3307 (byte-compile-constant 0) 3314 (cond
3308 (byte-compile-form (car form)) 3315 ((= 1 len) (byte-compile-constant 0))
3309 (if (cdr form) 3316 ((= 2 len)
3310 (while (setq form (cdr form)) 3317 (byte-compile-form (cadr form))
3311 (byte-compile-form (car form)) 3318 (byte-compile-out 'byte-negate 0))
3312 (byte-compile-out 'byte-diff 0)) 3319 ((= 3 len)
3313 (byte-compile-out 'byte-negate 0)))) 3320 (byte-compile-form (nth 1 form))
3321 (byte-compile-form (nth 2 form))
3322 (byte-compile-out 'byte-diff 0))
3323 ;; Don't use binary operations for > 2 operands, as that may
3324 ;; cause overflow/truncation in float operations.
3325 (t (byte-compile-normal-call form)))))
3314 3326
3315 (defun byte-compile-quo (form) 3327 (defun byte-compile-quo (form)
3316 (let ((len (length form))) 3328 (let ((len (length form)))
3317 (cond ((<= len 2) 3329 (cond ((<= len 2)
3318 (byte-compile-subr-wrong-args form "2 or more")) 3330 (byte-compile-subr-wrong-args form "2 or more"))
3331 ((= len 3)
3332 (byte-compile-two-args form))
3319 (t 3333 (t
3320 (byte-compile-form (car (setq form (cdr form)))) 3334 ;; Don't use binary operations for > 2 operands, as that
3321 (while (setq form (cdr form)) 3335 ;; may cause overflow/truncation in float operations.
3322 (byte-compile-form (car form)) 3336 (byte-compile-normal-call form)))))
3323 (byte-compile-out 'byte-quo 0))))))
3324 3337
3325 (defun byte-compile-nconc (form) 3338 (defun byte-compile-nconc (form)
3326 (let ((len (length form))) 3339 (let ((len (length form)))
3327 (cond ((= len 1) 3340 (cond ((= len 1)
3328 (byte-compile-constant nil)) 3341 (byte-compile-constant nil))