aboutsummaryrefslogtreecommitdiffstats
path: root/src/data.c
diff options
context:
space:
mode:
authorPaul Eggert2013-11-18 10:37:25 -0800
committerPaul Eggert2013-11-18 10:37:25 -0800
commit87d86601022feb7a330fc6344cc85ec65563c1b6 (patch)
treebd7b266fcaca082eb4f3854ef32344d98106a58d /src/data.c
parent37c790b38599cc80a16c6a76152abbf8160fe2a1 (diff)
downloademacs-87d86601022feb7a330fc6344cc85ec65563c1b6.tar.gz
emacs-87d86601022feb7a330fc6344cc85ec65563c1b6.zip
Always allocate at least one bits_word per bool vector.
See Daniel Colascione in: http://lists.gnu.org/archive/html/emacs-devel/2013-11/msg00518.html * alloc.c (make_uninit_bool_vector): Always allocate at least one word. * data.c (bool_vector_binop_driver): Rely on this. Tune. * lisp.h (struct Lisp_Bool_vector): Document this.
Diffstat (limited to 'src/data.c')
-rw-r--r--src/data.c88
1 files changed, 63 insertions, 25 deletions
diff --git a/src/data.c b/src/data.c
index d0171b5d758..b8b0f248dfa 100644
--- a/src/data.c
+++ b/src/data.c
@@ -3025,9 +3025,7 @@ bool_vector_binop_driver (Lisp_Object op1,
3025{ 3025{
3026 EMACS_INT nr_bits; 3026 EMACS_INT nr_bits;
3027 bits_word *adata, *bdata, *cdata; 3027 bits_word *adata, *bdata, *cdata;
3028 ptrdiff_t i; 3028 ptrdiff_t i = 0;
3029 bool changed = 0;
3030 bits_word mword;
3031 ptrdiff_t nr_words; 3029 ptrdiff_t nr_words;
3032 3030
3033 CHECK_BOOL_VECTOR (op1); 3031 CHECK_BOOL_VECTOR (op1);
@@ -3037,45 +3035,82 @@ bool_vector_binop_driver (Lisp_Object op1,
3037 if (bool_vector_size (op2) != nr_bits) 3035 if (bool_vector_size (op2) != nr_bits)
3038 wrong_length_argument (op1, op2, dest); 3036 wrong_length_argument (op1, op2, dest);
3039 3037
3038 nr_words = bool_vector_words (nr_bits);
3039 bdata = bool_vector_data (op1);
3040 cdata = bool_vector_data (op2);
3041
3040 if (NILP (dest)) 3042 if (NILP (dest))
3041 { 3043 {
3042 dest = make_uninit_bool_vector (nr_bits); 3044 dest = make_uninit_bool_vector (nr_bits);
3043 changed = 1; 3045 adata = bool_vector_data (dest);
3044 } 3046 }
3045 else 3047 else
3046 { 3048 {
3047 CHECK_BOOL_VECTOR (dest); 3049 CHECK_BOOL_VECTOR (dest);
3050 adata = bool_vector_data (dest);
3048 if (bool_vector_size (dest) != nr_bits) 3051 if (bool_vector_size (dest) != nr_bits)
3049 wrong_length_argument (op1, op2, dest); 3052 wrong_length_argument (op1, op2, dest);
3050 }
3051 3053
3052 nr_words = bool_vector_words (nr_bits); 3054 switch (op)
3055 {
3056 case bool_vector_exclusive_or:
3057 while (adata[i] == (bdata[i] ^ cdata[i]))
3058 if (! (++i < nr_words))
3059 return Qnil;
3060 break;
3053 3061
3054 adata = bool_vector_data (dest); 3062 case bool_vector_subsetp:
3055 bdata = bool_vector_data (op1); 3063 case bool_vector_union:
3056 cdata = bool_vector_data (op2); 3064 while (adata[i] == (bdata[i] | cdata[i]))
3065 if (! (++i < nr_words))
3066 return Qnil;
3067 break;
3068
3069 case bool_vector_intersection:
3070 while (adata[i] == (bdata[i] & cdata[i]))
3071 if (! (++i < nr_words))
3072 return Qnil;
3073 break;
3057 3074
3058 for (i = 0; i < nr_words; i++) 3075 case bool_vector_set_difference:
3076 while (adata[i] == (bdata[i] &~ cdata[i]))
3077 if (! (++i < nr_words))
3078 return Qnil;
3079 break;
3080 }
3081 }
3082
3083 switch (op)
3059 { 3084 {
3060 if (op == bool_vector_exclusive_or) 3085 case bool_vector_exclusive_or:
3061 mword = bdata[i] ^ cdata[i]; 3086 do
3062 else if (op == bool_vector_union || op == bool_vector_subsetp) 3087 adata[i] = bdata[i] ^ cdata[i];
3063 mword = bdata[i] | cdata[i]; 3088 while (++i < nr_words);
3064 else if (op == bool_vector_intersection) 3089 break;
3065 mword = bdata[i] & cdata[i]; 3090
3066 else if (op == bool_vector_set_difference) 3091 case bool_vector_subsetp:
3067 mword = bdata[i] &~ cdata[i]; 3092 break;
3068 else 3093
3069 abort (); 3094 case bool_vector_union:
3095 do
3096 adata[i] = bdata[i] | cdata[i];
3097 while (++i < nr_words);
3098 break;
3070 3099
3071 if (! changed) 3100 case bool_vector_intersection:
3072 changed = adata[i] != mword; 3101 do
3102 adata[i] = bdata[i] & cdata[i];
3103 while (++i < nr_words);
3104 break;
3073 3105
3074 if (op != bool_vector_subsetp) 3106 case bool_vector_set_difference:
3075 adata[i] = mword; 3107 do
3108 adata[i] = bdata[i] &~ cdata[i];
3109 while (++i < nr_words);
3110 break;
3076 } 3111 }
3077 3112
3078 return changed ? dest : Qnil; 3113 return dest;
3079} 3114}
3080 3115
3081/* PRECONDITION must be true. Return VALUE. This odd construction 3116/* PRECONDITION must be true. Return VALUE. This odd construction
@@ -3314,7 +3349,10 @@ index into the vector. */)
3314 mword = bits_word_to_host_endian (adata[pos]); 3349 mword = bits_word_to_host_endian (adata[pos]);
3315 mword ^= twiddle; 3350 mword ^= twiddle;
3316 mword >>= offset; 3351 mword >>= offset;
3352
3353 /* Do not count the pad bits. */
3317 mword |= (bits_word) 1 << (BITS_PER_BITS_WORD - offset); 3354 mword |= (bits_word) 1 << (BITS_PER_BITS_WORD - offset);
3355
3318 count = count_trailing_zero_bits (mword); 3356 count = count_trailing_zero_bits (mword);
3319 pos++; 3357 pos++;
3320 if (count + offset < BITS_PER_BITS_WORD) 3358 if (count + offset < BITS_PER_BITS_WORD)