mirror of
https://git.savannah.gnu.org/git/guile.git
synced 2025-05-09 07:00:23 +02:00
Add type and range checks to the complex generalized vector accessors.
* libguile/bytevectors.c (COMPLEX_ACCESSOR_PROLOGUE, COMPLEX_NATIVE_REF, COMPLEX_NATIVE_SET): New macros. (bytevector_ref_c32, bytevector_ref_c64): Defined in terms of `COMPLEX_NATIVE_REF'. (bytevector_set_c32, bytevector_set_c64): Defined in terms of `COMPLEX_NATIVE_SET'. (bytevector_ref_fns): Make `static'. * test-suite/tests/srfi-4.test ("c32 vectors")["generalized-vector-ref", "generalized-vector-set!", "generalized-vector-ref, out-of-range", "generalized-vector-set!, out-of-range"]: New tests. ("c64 vectors")["generalized-vector-ref", "generalized-vector-set!", "generalized-vector-ref, out-of-range", "generalized-vector-set!, out-of-range"]: New tests.
This commit is contained in:
parent
1e8f939229
commit
4bc95fccad
2 changed files with 105 additions and 50 deletions
|
@ -2092,36 +2092,56 @@ SCM_DEFINE (scm_utf32_to_string, "utf32->string",
|
||||||
|
|
||||||
/* Bytevectors as generalized vectors & arrays. */
|
/* Bytevectors as generalized vectors & arrays. */
|
||||||
|
|
||||||
|
#define COMPLEX_ACCESSOR_PROLOGUE(_type) \
|
||||||
|
size_t c_len, c_index; \
|
||||||
|
char *c_bv; \
|
||||||
|
\
|
||||||
|
SCM_VALIDATE_BYTEVECTOR (1, bv); \
|
||||||
|
c_index = scm_to_size_t (index); \
|
||||||
|
\
|
||||||
|
c_len = SCM_BYTEVECTOR_LENGTH (bv); \
|
||||||
|
c_bv = (char *) SCM_BYTEVECTOR_CONTENTS (bv); \
|
||||||
|
\
|
||||||
|
if (SCM_UNLIKELY (c_index + 2 * sizeof (_type) - 1 >= c_len)) \
|
||||||
|
scm_out_of_range (FUNC_NAME, index);
|
||||||
|
|
||||||
|
/* Template for native access to complex numbers of type TYPE. */
|
||||||
|
#define COMPLEX_NATIVE_REF(_type) \
|
||||||
|
SCM result; \
|
||||||
|
\
|
||||||
|
COMPLEX_ACCESSOR_PROLOGUE (_type); \
|
||||||
|
\
|
||||||
|
{ \
|
||||||
|
_type real, imag; \
|
||||||
|
\
|
||||||
|
memcpy (&real, &c_bv[c_index], sizeof (_type)); \
|
||||||
|
memcpy (&imag, &c_bv[c_index + sizeof (_type)], sizeof (_type)); \
|
||||||
|
\
|
||||||
|
result = scm_c_make_rectangular (real, imag); \
|
||||||
|
} \
|
||||||
|
\
|
||||||
|
return result;
|
||||||
|
|
||||||
static SCM
|
static SCM
|
||||||
bytevector_ref_c32 (SCM bv, SCM idx)
|
bytevector_ref_c32 (SCM bv, SCM index)
|
||||||
{ /* FIXME add some checks */
|
#define FUNC_NAME "bytevector_ref_c32"
|
||||||
float real, imag;
|
{
|
||||||
const char *contents = (char *) SCM_BYTEVECTOR_CONTENTS (bv);
|
COMPLEX_NATIVE_REF (float);
|
||||||
size_t i = scm_to_size_t (idx);
|
|
||||||
|
|
||||||
memcpy (&real, &contents[i], sizeof (float));
|
|
||||||
memcpy (&imag, &contents[i + sizeof (float)], sizeof (float));
|
|
||||||
|
|
||||||
return scm_c_make_rectangular (real, imag);
|
|
||||||
}
|
}
|
||||||
|
#undef FUNC_NAME
|
||||||
|
|
||||||
static SCM
|
static SCM
|
||||||
bytevector_ref_c64 (SCM bv, SCM idx)
|
bytevector_ref_c64 (SCM bv, SCM index)
|
||||||
{ /* FIXME add some checks */
|
#define FUNC_NAME "bytevector_ref_c64"
|
||||||
double real, imag;
|
{
|
||||||
const char *contents = (char *) SCM_BYTEVECTOR_CONTENTS (bv);
|
COMPLEX_NATIVE_REF (double);
|
||||||
size_t i = scm_to_size_t (idx);
|
|
||||||
|
|
||||||
memcpy (&real, &contents[i], sizeof (double));
|
|
||||||
memcpy (&imag, &contents[i + sizeof (double)], sizeof (double));
|
|
||||||
|
|
||||||
return scm_c_make_rectangular (real, imag);
|
|
||||||
}
|
}
|
||||||
|
#undef FUNC_NAME
|
||||||
|
|
||||||
typedef SCM (*scm_t_bytevector_ref_fn)(SCM, SCM);
|
typedef SCM (*scm_t_bytevector_ref_fn)(SCM, SCM);
|
||||||
|
|
||||||
const scm_t_bytevector_ref_fn bytevector_ref_fns[SCM_ARRAY_ELEMENT_TYPE_LAST + 1] =
|
static const scm_t_bytevector_ref_fn
|
||||||
|
bytevector_ref_fns[SCM_ARRAY_ELEMENT_TYPE_LAST + 1] =
|
||||||
{
|
{
|
||||||
NULL, /* SCM */
|
NULL, /* SCM */
|
||||||
NULL, /* CHAR */
|
NULL, /* CHAR */
|
||||||
|
@ -2153,38 +2173,36 @@ bv_handle_ref (scm_t_array_handle *h, size_t index)
|
||||||
return ref_fn (h->array, byte_index);
|
return ref_fn (h->array, byte_index);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* FIXME add checks!!! */
|
/* Template for native modification of complex numbers of type TYPE. */
|
||||||
static SCM
|
#define COMPLEX_NATIVE_SET(_type) \
|
||||||
bytevector_set_c32 (SCM bv, SCM idx, SCM val)
|
COMPLEX_ACCESSOR_PROLOGUE (_type); \
|
||||||
{
|
\
|
||||||
float imag, real;
|
{ \
|
||||||
char *contents = (char *) SCM_BYTEVECTOR_CONTENTS (bv);
|
_type real, imag; \
|
||||||
size_t i = scm_to_size_t (idx);
|
real = scm_c_real_part (value); \
|
||||||
|
imag = scm_c_imag_part (value); \
|
||||||
real = scm_c_real_part (val);
|
\
|
||||||
imag = scm_c_imag_part (val);
|
memcpy (&c_bv[c_index], &real, sizeof (_type)); \
|
||||||
|
memcpy (&c_bv[c_index + sizeof (_type)], &imag, sizeof (_type)); \
|
||||||
memcpy (&contents[i], &real, sizeof (float));
|
} \
|
||||||
memcpy (&contents[i + sizeof (float)], &imag, sizeof (float));
|
\
|
||||||
|
|
||||||
return SCM_UNSPECIFIED;
|
return SCM_UNSPECIFIED;
|
||||||
}
|
|
||||||
|
|
||||||
static SCM
|
static SCM
|
||||||
bytevector_set_c64 (SCM bv, SCM idx, SCM val)
|
bytevector_set_c32 (SCM bv, SCM index, SCM value)
|
||||||
|
#define FUNC_NAME "bytevector_set_c32"
|
||||||
{
|
{
|
||||||
double imag, real;
|
COMPLEX_NATIVE_SET (float);
|
||||||
char *contents = (char *) SCM_BYTEVECTOR_CONTENTS (bv);
|
|
||||||
size_t i = scm_to_size_t (idx);
|
|
||||||
|
|
||||||
real = scm_c_real_part (val);
|
|
||||||
imag = scm_c_imag_part (val);
|
|
||||||
|
|
||||||
memcpy (&contents[i], &real, sizeof (double));
|
|
||||||
memcpy (&contents[i + sizeof (double)], &imag, sizeof (double));
|
|
||||||
|
|
||||||
return SCM_UNSPECIFIED;
|
|
||||||
}
|
}
|
||||||
|
#undef FUNC_NAME
|
||||||
|
|
||||||
|
static SCM
|
||||||
|
bytevector_set_c64 (SCM bv, SCM index, SCM value)
|
||||||
|
#define FUNC_NAME "bytevector_set_c64"
|
||||||
|
{
|
||||||
|
COMPLEX_NATIVE_SET (double);
|
||||||
|
}
|
||||||
|
#undef FUNC_NAME
|
||||||
|
|
||||||
typedef SCM (*scm_t_bytevector_set_fn)(SCM, SCM, SCM);
|
typedef SCM (*scm_t_bytevector_set_fn)(SCM, SCM, SCM);
|
||||||
|
|
||||||
|
|
|
@ -436,7 +436,26 @@
|
||||||
(make-c32vector 4 7)))
|
(make-c32vector 4 7)))
|
||||||
|
|
||||||
(pass-if "+inf.0, -inf.0, +nan.0 in c32vector"
|
(pass-if "+inf.0, -inf.0, +nan.0 in c32vector"
|
||||||
(c32vector? #c32(+inf.0 -inf.0 +nan.0))))
|
(c32vector? #c32(+inf.0 -inf.0 +nan.0)))
|
||||||
|
|
||||||
|
(pass-if "generalized-vector-ref"
|
||||||
|
(let ((v (c32vector 1+1i)))
|
||||||
|
(= (c32vector-ref v 0)
|
||||||
|
(generalized-vector-ref v 0))))
|
||||||
|
|
||||||
|
(pass-if "generalized-vector-set!"
|
||||||
|
(let ((x 1+1i)
|
||||||
|
(v (c32vector 0)))
|
||||||
|
(generalized-vector-set! v 0 x)
|
||||||
|
(= x (generalized-vector-ref v 0))))
|
||||||
|
|
||||||
|
(pass-if-exception "generalized-vector-ref, out-of-range"
|
||||||
|
exception:out-of-range
|
||||||
|
(generalized-vector-ref (c32vector 1.0) 1))
|
||||||
|
|
||||||
|
(pass-if-exception "generalized-vector-set!, out-of-range"
|
||||||
|
exception:out-of-range
|
||||||
|
(generalized-vector-set! (c32vector 1.0) 1 2.0)))
|
||||||
|
|
||||||
(with-test-prefix "c64 vectors"
|
(with-test-prefix "c64 vectors"
|
||||||
|
|
||||||
|
@ -476,5 +495,23 @@
|
||||||
(make-c64vector 4 7)))
|
(make-c64vector 4 7)))
|
||||||
|
|
||||||
(pass-if "+inf.0, -inf.0, +nan.0 in c64vector"
|
(pass-if "+inf.0, -inf.0, +nan.0 in c64vector"
|
||||||
(c64vector? #c64(+inf.0 -inf.0 +nan.0))))
|
(c64vector? #c64(+inf.0 -inf.0 +nan.0)))
|
||||||
|
|
||||||
|
(pass-if "generalized-vector-ref"
|
||||||
|
(let ((v (c64vector 1+1i)))
|
||||||
|
(= (c64vector-ref v 0)
|
||||||
|
(generalized-vector-ref v 0))))
|
||||||
|
|
||||||
|
(pass-if "generalized-vector-set!"
|
||||||
|
(let ((x 1+1i)
|
||||||
|
(v (c64vector 0)))
|
||||||
|
(generalized-vector-set! v 0 x)
|
||||||
|
(= x (generalized-vector-ref v 0))))
|
||||||
|
|
||||||
|
(pass-if-exception "generalized-vector-ref, out-of-range"
|
||||||
|
exception:out-of-range
|
||||||
|
(generalized-vector-ref (c64vector 1.0) 1))
|
||||||
|
|
||||||
|
(pass-if-exception "generalized-vector-set!, out-of-range"
|
||||||
|
exception:out-of-range
|
||||||
|
(generalized-vector-set! (c64vector 1.0) 1 2.0)))
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue