diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/alloc.c | 13 | ||||
| -rw-r--r-- | src/fns.c | 11 |
2 files changed, 16 insertions, 8 deletions
diff --git a/src/alloc.c b/src/alloc.c index 407ac725414..31e8da70161 100644 --- a/src/alloc.c +++ b/src/alloc.c | |||
| @@ -2774,6 +2774,19 @@ DEFUN ("cons", Fcons, Scons, 2, 2, 0, | |||
| 2774 | { | 2774 | { |
| 2775 | if (cons_block_index == CONS_BLOCK_SIZE) | 2775 | if (cons_block_index == CONS_BLOCK_SIZE) |
| 2776 | { | 2776 | { |
| 2777 | /* Maximum number of conses that should be active at any | ||
| 2778 | given time, so that list lengths fit into a ptrdiff_t and | ||
| 2779 | into a fixnum. */ | ||
| 2780 | ptrdiff_t max_conses = min (PTRDIFF_MAX, MOST_POSITIVE_FIXNUM); | ||
| 2781 | |||
| 2782 | /* This check is typically optimized away, as a runtime | ||
| 2783 | check is needed only on weird platforms where a count of | ||
| 2784 | distinct conses might not fit. */ | ||
| 2785 | if (max_conses < INTPTR_MAX / sizeof (struct Lisp_Cons) | ||
| 2786 | && (max_conses - CONS_BLOCK_SIZE | ||
| 2787 | < total_free_conses + total_conses)) | ||
| 2788 | memory_full (sizeof (struct cons_block)); | ||
| 2789 | |||
| 2777 | struct cons_block *new | 2790 | struct cons_block *new |
| 2778 | = lisp_align_malloc (sizeof *new, MEM_TYPE_CONS); | 2791 | = lisp_align_malloc (sizeof *new, MEM_TYPE_CONS); |
| 2779 | memset (new->gcmarkbits, 0, sizeof new->gcmarkbits); | 2792 | memset (new->gcmarkbits, 0, sizeof new->gcmarkbits); |
| @@ -101,9 +101,7 @@ list_length (Lisp_Object list) | |||
| 101 | FOR_EACH_TAIL (list) | 101 | FOR_EACH_TAIL (list) |
| 102 | i++; | 102 | i++; |
| 103 | CHECK_LIST_END (list, list); | 103 | CHECK_LIST_END (list, list); |
| 104 | if (i <= min (PTRDIFF_MAX, MOST_POSITIVE_FIXNUM)) | 104 | return i; |
| 105 | return i; | ||
| 106 | overflow_error (); | ||
| 107 | } | 105 | } |
| 108 | 106 | ||
| 109 | 107 | ||
| @@ -141,14 +139,13 @@ DEFUN ("safe-length", Fsafe_length, Ssafe_length, 1, 1, 0, | |||
| 141 | doc: /* Return the length of a list, but avoid error or infinite loop. | 139 | doc: /* Return the length of a list, but avoid error or infinite loop. |
| 142 | This function never gets an error. If LIST is not really a list, | 140 | This function never gets an error. If LIST is not really a list, |
| 143 | it returns 0. If LIST is circular, it returns an integer that is at | 141 | it returns 0. If LIST is circular, it returns an integer that is at |
| 144 | least the number of distinct elements. | 142 | least the number of distinct elements. */) |
| 145 | Value is a fixnum, if it's small enough, otherwise a bignum. */) | ||
| 146 | (Lisp_Object list) | 143 | (Lisp_Object list) |
| 147 | { | 144 | { |
| 148 | intptr_t len = 0; | 145 | intptr_t len = 0; |
| 149 | FOR_EACH_TAIL_SAFE (list) | 146 | FOR_EACH_TAIL_SAFE (list) |
| 150 | len++; | 147 | len++; |
| 151 | return INT_TO_INTEGER (len); | 148 | return make_fixnum (len); |
| 152 | } | 149 | } |
| 153 | 150 | ||
| 154 | DEFUN ("proper-list-p", Fproper_list_p, Sproper_list_p, 1, 1, 0, | 151 | DEFUN ("proper-list-p", Fproper_list_p, Sproper_list_p, 1, 1, 0, |
| @@ -168,8 +165,6 @@ A proper list is neither circular nor dotted (i.e., its last cdr is nil). */ | |||
| 168 | } | 165 | } |
| 169 | if (!NILP (last_tail)) | 166 | if (!NILP (last_tail)) |
| 170 | return Qnil; | 167 | return Qnil; |
| 171 | if (MOST_POSITIVE_FIXNUM < len) | ||
| 172 | overflow_error (); | ||
| 173 | return make_fixnum (len); | 168 | return make_fixnum (len); |
| 174 | } | 169 | } |
| 175 | 170 | ||