The purpose of this is to detect circular structures.")
-(defalias 'byte-run--circular-list-p
- #'(lambda (l)
- "Return non-nil when the list L is a circular list.
-Note that this algorithm doesn't check any circularity in the
-CARs of list elements."
- (let ((hare l)
- (tortoise l))
- (condition-case err
- (progn
- (while (progn
- (setq hare (cdr (cdr hare))
- tortoise (cdr tortoise))
- (not (or (eq tortoise hare)
- (null hare)))))
- (eq tortoise hare))
- (wrong-type-argument nil)
- (error (signal (car err) (cdr err)))))))
-
(defalias 'byte-run--strip-s-p-1
#'(lambda (arg)
"Strip all positions from symbols in ARG, modifying ARG.
(bare-symbol arg))
((consp arg)
- (let* ((round (byte-run--circular-list-p arg))
- (hash (and round (gethash arg byte-run--ssp-seen))))
- (or hash
- (let ((a arg) new)
- (while
- (progn
- (when round
- (puthash a new byte-run--ssp-seen))
- (setq new (byte-run--strip-s-p-1 (car a)))
- (when (not (eq new (car a))) ; For read-only things.
- (setcar a new))
- (and (consp (cdr a))
- (not
- (setq hash
- (and round
- (gethash (cdr a) byte-run--ssp-seen))))))
- (setq a (cdr a)))
- (setq new (byte-run--strip-s-p-1 (cdr a)))
- (when (not (eq new (cdr a)))
- (setcdr a (or hash new)))
- arg))))
+ (let* ((hash (gethash arg byte-run--ssp-seen)))
+ (if hash ; Already processed this node.
+ arg
+ (let ((a arg) new)
+ (while
+ (progn
+ (puthash a t byte-run--ssp-seen)
+ (setq new (byte-run--strip-s-p-1 (car a)))
+ (setcar a new)
+ (and (consp (cdr a))
+ (not
+ (setq hash (gethash (cdr a) byte-run--ssp-seen)))))
+ (setq a (cdr a)))
+ (setq new (byte-run--strip-s-p-1 (cdr a)))
+ (setcdr a new)
+ arg))))
((or (vectorp arg) (recordp arg))
(let ((hash (gethash arg byte-run--ssp-seen)))
- (or hash
- (let* ((len (length arg))
- (i 0)
- new)
- (puthash arg arg byte-run--ssp-seen)
- (while (< i len)
- (setq new (byte-run--strip-s-p-1 (aref arg i)))
- (when (not (eq new (aref arg i)))
- (aset arg i new))
- (setq i (1+ i)))
- arg))))
+ (if hash
+ arg
+ (let* ((len (length arg))
+ (i 0)
+ new)
+ (puthash arg t byte-run--ssp-seen)
+ (while (< i len)
+ (setq new (byte-run--strip-s-p-1 (aref arg i)))
+ (aset arg i new)
+ (setq i (1+ i)))
+ arg))))
(t arg))))
nil
(byte-compile-docstring-length-warn form)
(setq form (copy-sequence form))
- (cond ((consp (nth 2 form))
- (setcar (cdr (cdr form))
- (byte-compile-top-level (nth 2 form) nil 'file)))
- ((symbolp (nth 2 form))
- (setcar (cddr form) (bare-symbol (nth 2 form))))
- (t (setcar (cddr form) (nth 2 form))))
- (setcar form (bare-symbol (car form)))
- (if (symbolp (nth 1 form))
- (setcar (cdr form) (bare-symbol (nth 1 form))))
+ (when (consp (nth 2 form))
+ (setcar (cdr (cdr form))
+ (byte-compile-top-level (nth 2 form) nil 'file)))
form))
(put 'define-abbrev-table 'byte-hunk-handler
(byte-compile-docstring-length-warn fun)
(byte-compile-check-lambda-list (nth 1 fun))
(let* ((arglist (nth 1 fun))
- (arglistvars (byte-compile-arglist-vars arglist))
+ (arglistvars (byte-run-strip-symbol-positions
+ (byte-compile-arglist-vars arglist)))
(byte-compile-bound-variables
(append (if (not lexical-binding) arglistvars)
byte-compile-bound-variables))
(cond
((not (consp form))
(cond ((or (not (symbolp form)) (macroexp--const-symbol-p form))
- (byte-compile-constant
- (if (symbolp form) (bare-symbol form) form)))
+ (byte-compile-constant form))
((and byte-compile--for-effect byte-compile-delete-errors)
(setq byte-compile--for-effect nil))
- (t
- (byte-compile-variable-ref (bare-symbol form)))))
+ (t (byte-compile-variable-ref form))))
((symbolp (car form))
(let* ((fn (car form))
(handler (get fn 'byte-compile))
(byte-compile-warn-obsolete var))))
(defsubst byte-compile-dynamic-variable-op (base-op var)
- (if (symbolp var) (setq var (bare-symbol var)))
(let ((tmp (assq var byte-compile-variables)))
(unless tmp
(setq tmp (list var))
(defun byte-compile-constant (const)
(if byte-compile--for-effect
(setq byte-compile--for-effect nil)
- (inline (byte-compile-push-constant
- (if (symbolp const) (bare-symbol const) const)))))
+ (inline (byte-compile-push-constant const))))
;; Use this for a constant that is not the value of its containing form.
;; This ignores byte-compile--for-effect.
(defun byte-compile-push-constant (const)
- (when (symbolp const)
- (setq const (bare-symbol const)))
(byte-compile-out
'byte-constant
(byte-compile-get-constant const)))
(- 1 operand))))
(defun byte-compile-out (op &optional operand)
+ (setq operand (byte-run-strip-symbol-positions operand))
(push (cons op operand) byte-compile-output)
(if (eq op 'byte-return)
;; This is actually an unnecessary case, because there should be no
static Lisp_Object
hashfn_eq (Lisp_Object key, struct Lisp_Hash_Table *h)
{
+ if (symbols_with_pos_enabled && SYMBOL_WITH_POS_P (key))
+ key = SYMBOL_WITH_POS_SYM (key);
return make_ufixnum (XHASH (key) ^ XTYPE (key));
}
ptrdiff_t start_of_bucket, i;
Lisp_Object hash_code;
- if (SYMBOL_WITH_POS_P (key))
- key = SYMBOL_WITH_POS_SYM (key);
hash_code = h->test.hashfn (key, h);
if (hash)
*hash = hash_code;
hash = sxhash_combine (hash, sxhash_obj (XOVERLAY (obj)->plist, depth));
return SXHASH_REDUCE (hash);
}
+ else if (symbols_with_pos_enabled && pvec_type == PVEC_SYMBOL_WITH_POS)
+ return sxhash_obj (XSYMBOL_WITH_POS (obj)->sym, depth + 1);
else
/* Others are 'equal' if they are 'eq', so take their
address as hash. */