From f897efa9f10bbafa6839274d8bbb739fc02ce562 Mon Sep 17 00:00:00 2001 From: Andy Wingo Date: Sat, 18 Apr 2020 22:16:31 +0200 Subject: [PATCH] bitvector-flip-all-bits! replaces bit-invert! * NEWS: Add entry. * doc/ref/api-data.texi (Bit Vectors): Update. * libguile/bitvectors.h: * libguile/bitvectors.c (scm_c_bitvector_flip_all_bits_x): New function. * libguile/deprecated.h: * libguile/deprecated.c (scm_bit_invert_x): Deprecate. * module/ice-9/sandbox.scm (mutable-bitvector-bindings): Replace bit-invert! with bitvector-flip-all-bits!. * module/system/vm/frame.scm (available-bindings): Use the new interface. * test-suite/tests/bitvectors.test: Update. --- NEWS | 8 +++++ doc/ref/api-data.texi | 11 +++---- libguile/bitvectors.c | 51 +++++++++++++------------------- libguile/bitvectors.h | 2 +- libguile/deprecated.c | 29 ++++++++++++++++++ libguile/deprecated.h | 1 + module/ice-9/sandbox.scm | 2 +- module/system/vm/frame.scm | 2 +- test-suite/tests/bitvectors.test | 4 +++ 9 files changed, 70 insertions(+), 40 deletions(-) diff --git a/NEWS b/NEWS index 386e5fd76..5a33dacbe 100644 --- a/NEWS +++ b/NEWS @@ -30,6 +30,10 @@ replacement above. These replace bitvector-fill!. +** New bitvector-flip-all-bits! procedure + +This replaces bit-invert!. + ** New bitvector-set-bits!, bitvector-clear-bits! procedures These replace the wonky "bit-set*!" procedure. See "Bit Vectors" in the @@ -54,6 +58,10 @@ Use 'bitvector-set-bit!' or 'bitvector-clear-bit!' instead. Use 'bitvector-set-all-bits!' or 'bitvector-clear-all-bits!' instead. +** 'bit-invert!' deprecated + +Use 'bitvector-flip-all-bits! instead. + ** 'bit-set*!' deprecated Use 'bitvector-set-bits!' or 'bitvector-clear-bits!' instead. diff --git a/doc/ref/api-data.texi b/doc/ref/api-data.texi index f9b14d13f..bb8f97a73 100644 --- a/doc/ref/api-data.texi +++ b/doc/ref/api-data.texi @@ -6600,12 +6600,14 @@ Set or clear the bit at index @var{idx} of the bitvector @var{vec}. @deffn {Scheme Procedure} bitvector-set-all-bits! vec @deffnx {Scheme Procedure} bitvector-clear-all-bits! vec -Set or clear all bits of @var{vec}. +@deffnx {Scheme Procedure} bitvector-flip-all-bits! vec +Set, clear, or flip all bits of @var{vec}. @end deffn @deftypefn {C Function} void scm_c_bitvector_set_all_bits_x (SCM vec) @deftypefnx {C Function} void scm_c_bitvector_clear_all_bits_x (SCM vec) -Set or clear all bits in the bitvector @var{vec}. +@deftypefnx {C Function} void scm_c_bitvector_flip_all_bits_x (SCM vec) +Set, clear, or flip all bits in the bitvector @var{vec}. @end deftypefn @deffn {Scheme Procedure} list->bitvector list @@ -6642,11 +6644,6 @@ entry between @var{start} and the end of @var{bitvector}, then return @end example @end deffn -@deffn {Scheme Procedure} bit-invert! bitvector -@deffnx {C Function} scm_bit_invert_x (bitvector) -Modify @var{bitvector} by replacing each element with its negation. -@end deffn - @deffn {Scheme Procedure} bitvector-set-bits! bitvector bits @deffnx {C Function} scm_bit_set_star_x (bitvector, bits) Set entries of @var{bitvector} to @code{#t}, with @var{bits} selecting diff --git a/libguile/bitvectors.c b/libguile/bitvectors.c index 077bc556c..69efd458f 100644 --- a/libguile/bitvectors.c +++ b/libguile/bitvectors.c @@ -767,40 +767,31 @@ SCM_DEFINE (scm_bit_count_star, "bit-count*", 3, 0, 0, } #undef FUNC_NAME -SCM_DEFINE (scm_bit_invert_x, "bit-invert!", 1, 0, 0, - (SCM v), - "Modify the bit vector @var{v} by replacing each element with\n" - "its negation.") -#define FUNC_NAME s_scm_bit_invert_x +void +scm_c_bitvector_flip_all_bits_x (SCM v) +#define FUNC_NAME "bitvector-flip-all-bits!" { - if (IS_MUTABLE_BITVECTOR (v)) - { - size_t len = BITVECTOR_LENGTH (v); - uint32_t *bits = BITVECTOR_BITS (v); - size_t word_len = (len + 31) / 32; - uint32_t last_mask = ((uint32_t)-1) >> (32*word_len - len); - size_t i; + VALIDATE_MUTABLE_BITVECTOR (1, v); - for (i = 0; i < word_len-1; i++) - bits[i] = ~bits[i]; - bits[i] = bits[i] ^ last_mask; - } - else - { - size_t off, len; - ssize_t inc; - scm_t_array_handle handle; + size_t len = BITVECTOR_LENGTH (v); + uint32_t *bits = BITVECTOR_BITS (v); + size_t word_len = (len + 31) / 32; + uint32_t last_mask = ((uint32_t)-1) >> (32*word_len - len); + size_t i; - scm_bitvector_writable_elements (v, &handle, &off, &len, &inc); - scm_c_issue_deprecation_warning - ("Using bit-invert! on arrays is deprecated. " - "Use scalar array accessors in a loop instead."); - for (size_t i = 0; i < len; i++) - scm_array_handle_set (&handle, i*inc, - scm_not (scm_array_handle_ref (&handle, i*inc))); - scm_array_handle_release (&handle); - } + for (i = 0; i < word_len-1; i++) + bits[i] = ~bits[i]; + bits[i] = bits[i] ^ last_mask; +} +#undef FUNC_NAME +SCM_DEFINE_STATIC (scm_bitvector_flip_all_bits_x, + "bitvector-flip-all-bits!", 1, 0, 0, (SCM v), + "Modify the bit vector @var{v} in place by setting all\n" + "clear bits and clearing all set bits.") +#define FUNC_NAME s_scm_bitvector_flip_all_bits_x +{ + scm_c_bitvector_flip_all_bits_x (v); return SCM_UNSPECIFIED; } #undef FUNC_NAME diff --git a/libguile/bitvectors.h b/libguile/bitvectors.h index ffeb5a894..3cf7697dd 100644 --- a/libguile/bitvectors.h +++ b/libguile/bitvectors.h @@ -45,7 +45,6 @@ SCM_API SCM scm_bitvector_set_bits_x (SCM v, SCM bits); SCM_API SCM scm_bitvector_clear_bits_x (SCM v, SCM bits); SCM_API SCM scm_bit_count_star (SCM v, SCM kv, SCM obj); -SCM_API SCM scm_bit_invert_x (SCM v); SCM_API int scm_is_bitvector (SCM obj); SCM_API SCM scm_c_make_bitvector (size_t len, SCM fill); @@ -56,6 +55,7 @@ SCM_API void scm_c_bitvector_set_bit_x (SCM vec, size_t idx); SCM_API void scm_c_bitvector_clear_bit_x (SCM vec, size_t idx); SCM_API void scm_c_bitvector_set_all_bits_x (SCM vec); SCM_API void scm_c_bitvector_clear_all_bits_x (SCM vec); +SCM_API void scm_c_bitvector_flip_all_bits_x (SCM vec); SCM_API const uint32_t *scm_array_handle_bit_elements (scm_t_array_handle *h); SCM_API uint32_t *scm_array_handle_bit_writable_elements (scm_t_array_handle *h); SCM_API size_t scm_array_handle_bit_elements_offset (scm_t_array_handle *h); diff --git a/libguile/deprecated.c b/libguile/deprecated.c index 3682a0c04..b48982b10 100644 --- a/libguile/deprecated.c +++ b/libguile/deprecated.c @@ -206,6 +206,35 @@ SCM_DEFINE (scm_bitvector_fill_x, "bitvector-fill!", 2, 0, 0, } #undef FUNC_NAME +SCM_DEFINE (scm_bit_invert_x, "bit-invert!", 1, 0, 0, + (SCM v), + "Modify the bit vector @var{v} by replacing each element with\n" + "its negation.") +#define FUNC_NAME s_scm_bit_invert_x +{ + scm_c_issue_deprecation_warning + ("bit-invert! is deprecated. Use bitvector-flip-all-bits!, or " + "scalar array accessors in a loop for generic arrays."); + + if (scm_is_bitvector (v)) + scm_c_bitvector_flip_all_bits_x (v); + else + { + size_t off, len; + ssize_t inc; + scm_t_array_handle handle; + + scm_bitvector_writable_elements (v, &handle, &off, &len, &inc); + for (size_t i = 0; i < len; i++) + scm_array_handle_set (&handle, i*inc, + scm_not (scm_array_handle_ref (&handle, i*inc))); + scm_array_handle_release (&handle); + } + + return SCM_UNSPECIFIED; +} +#undef FUNC_NAME + SCM_DEFINE (scm_bit_count, "bit-count", 2, 0, 0, (SCM b, SCM bitvector), "Return the number of occurrences of the boolean @var{b} in\n" diff --git a/libguile/deprecated.h b/libguile/deprecated.h index a0ccac75d..0a663eb0d 100644 --- a/libguile/deprecated.h +++ b/libguile/deprecated.h @@ -120,6 +120,7 @@ SCM_DEPRECATED SCM scm_bitvector_ref (SCM vec, SCM idx); SCM_DEPRECATED void scm_c_bitvector_set_x (SCM vec, size_t idx, SCM val); SCM_DEPRECATED SCM scm_bitvector_set_x (SCM vec, SCM idx, SCM val); SCM_DEPRECATED SCM scm_bitvector_fill_x (SCM vec, SCM val); +SCM_DEPRECATED SCM scm_bit_invert_x (SCM vec); SCM_DEPRECATED SCM scm_bit_count (SCM item, SCM seq); SCM_DEPRECATED SCM scm_bit_position (SCM item, SCM v, SCM k); SCM_DEPRECATED SCM scm_bit_set_star_x (SCM v, SCM kv, SCM obj); diff --git a/module/ice-9/sandbox.scm b/module/ice-9/sandbox.scm index 75c7f0dc3..799db250d 100644 --- a/module/ice-9/sandbox.scm +++ b/module/ice-9/sandbox.scm @@ -1092,11 +1092,11 @@ allocation limit is exceeded, an exception will be thrown to the ;; bitvector is exposed to the sandbox. (define mutating-bitvector-bindings '(((guile) - bit-invert! bitvector-clear-bit! bitvector-clear-bits! bitvector-set-all-bits! bitvector-clear-all-bits! + bitvector-flip-all-bits! bitvector-set-bit! bitvector-set-bits!))) diff --git a/module/system/vm/frame.scm b/module/system/vm/frame.scm index 18987d994..3be73e29c 100644 --- a/module/system/vm/frame.scm +++ b/module/system/vm/frame.scm @@ -228,7 +228,7 @@ (bitvector-set-bits! dst src)) (define (bitvector-meet! accum src) (bitvector-copy! tmp src) - (bit-invert! tmp) + (bitvector-flip-all-bits! tmp) (bitvector-clear-bits! accum tmp)) (let lp ((n 0)) diff --git a/test-suite/tests/bitvectors.test b/test-suite/tests/bitvectors.test index 9bbd6e2ac..070a15f6c 100644 --- a/test-suite/tests/bitvectors.test +++ b/test-suite/tests/bitvectors.test @@ -62,6 +62,10 @@ (bitvector-set-all-bits! bv) (pass-if-equal #*11111 bv) (bitvector-clear-all-bits! bv) + (pass-if-equal #*00000 bv) + (bitvector-flip-all-bits! bv) + (pass-if-equal #*11111 bv) + (bitvector-flip-all-bits! bv) (pass-if-equal #*00000 bv))) (with-test-prefix "bitvector-set-bits!"