2018-06-14 22:16:01 +02:00
|
|
|
|
/* Copyright (C) 2009-2015, 2018 Free Software Foundation, Inc.
|
2009-05-27 18:18:07 +02:00
|
|
|
|
*
|
|
|
|
|
|
* This library is free software; you can redistribute it and/or
|
2009-06-17 00:22:09 +01:00
|
|
|
|
* modify it under the terms of the GNU Lesser General Public License
|
|
|
|
|
|
* as published by the Free Software Foundation; either version 3 of
|
|
|
|
|
|
* the License, or (at your option) any later version.
|
2009-05-27 18:18:07 +02:00
|
|
|
|
*
|
2009-06-17 00:22:09 +01:00
|
|
|
|
* This library is distributed in the hope that it will be useful, but
|
|
|
|
|
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
2009-05-27 18:18:07 +02:00
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
|
|
* Lesser General Public License for more details.
|
|
|
|
|
|
*
|
|
|
|
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
|
|
|
|
* License along with this library; if not, write to the Free Software
|
2009-06-17 00:22:09 +01:00
|
|
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
|
|
|
|
|
* 02110-1301 USA
|
2009-05-27 18:18:07 +02:00
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#ifdef HAVE_CONFIG_H
|
|
|
|
|
|
# include <config.h>
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
2018-06-14 22:16:01 +02:00
|
|
|
|
#ifdef HAVE_LIMITS_H
|
|
|
|
|
|
# include <limits.h>
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
#include <byteswap.h>
|
2018-06-17 19:46:33 +02:00
|
|
|
|
#include <errno.h>
|
2018-06-14 22:16:01 +02:00
|
|
|
|
#include <striconveh.h>
|
|
|
|
|
|
#include <uniconv.h>
|
|
|
|
|
|
#include <unistr.h>
|
|
|
|
|
|
#include <string.h>
|
2009-05-27 18:18:07 +02:00
|
|
|
|
#include <alloca.h>
|
2009-09-17 13:52:09 +02:00
|
|
|
|
#include <assert.h>
|
2009-05-27 18:18:07 +02:00
|
|
|
|
|
|
|
|
|
|
#include <gmp.h>
|
|
|
|
|
|
|
|
|
|
|
|
#include "libguile/_scm.h"
|
2018-06-20 09:04:55 +02:00
|
|
|
|
#include "libguile/gsubr.h"
|
2018-06-14 22:16:01 +02:00
|
|
|
|
#include "libguile/dynwind.h"
|
2009-06-22 00:56:00 +02:00
|
|
|
|
#include "libguile/extensions.h"
|
2009-05-27 18:18:07 +02:00
|
|
|
|
#include "libguile/bytevectors.h"
|
2018-06-14 22:16:01 +02:00
|
|
|
|
#include "libguile/generalized-vectors.h"
|
2018-06-18 11:46:32 +02:00
|
|
|
|
#include "libguile/list.h"
|
2018-06-19 15:37:23 +02:00
|
|
|
|
#include "libguile/numbers.h"
|
2018-06-18 22:03:13 +02:00
|
|
|
|
#include "libguile/pairs.h"
|
2018-06-19 12:01:38 +02:00
|
|
|
|
#include "libguile/ports.h"
|
2009-05-27 18:18:07 +02:00
|
|
|
|
#include "libguile/strings.h"
|
2009-07-17 01:08:35 +02:00
|
|
|
|
#include "libguile/arrays.h"
|
2009-07-19 15:04:40 +02:00
|
|
|
|
#include "libguile/array-handle.h"
|
2009-07-18 12:18:15 +02:00
|
|
|
|
#include "libguile/uniform.h"
|
2009-06-05 16:31:38 +02:00
|
|
|
|
#include "libguile/srfi-4.h"
|
2009-05-27 18:18:07 +02:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Utilities. */
|
|
|
|
|
|
|
|
|
|
|
|
/* Convenience macros. These are used by the various templates (macros) that
|
|
|
|
|
|
are parameterized by integer signedness. */
|
|
|
|
|
|
#define INT8_T_signed scm_t_int8
|
|
|
|
|
|
#define INT8_T_unsigned scm_t_uint8
|
|
|
|
|
|
#define INT16_T_signed scm_t_int16
|
|
|
|
|
|
#define INT16_T_unsigned scm_t_uint16
|
|
|
|
|
|
#define INT32_T_signed scm_t_int32
|
|
|
|
|
|
#define INT32_T_unsigned scm_t_uint32
|
|
|
|
|
|
#define is_signed_int8(_x) (((_x) >= -128L) && ((_x) <= 127L))
|
|
|
|
|
|
#define is_unsigned_int8(_x) ((_x) <= 255UL)
|
|
|
|
|
|
#define is_signed_int16(_x) (((_x) >= -32768L) && ((_x) <= 32767L))
|
|
|
|
|
|
#define is_unsigned_int16(_x) ((_x) <= 65535UL)
|
|
|
|
|
|
#define is_signed_int32(_x) (((_x) >= -2147483648L) && ((_x) <= 2147483647L))
|
|
|
|
|
|
#define is_unsigned_int32(_x) ((_x) <= 4294967295UL)
|
|
|
|
|
|
#define SIGNEDNESS_signed 1
|
|
|
|
|
|
#define SIGNEDNESS_unsigned 0
|
|
|
|
|
|
|
|
|
|
|
|
#define INT_TYPE(_size, _sign) INT ## _size ## _T_ ## _sign
|
|
|
|
|
|
#define INT_SWAP(_size) bswap_ ## _size
|
|
|
|
|
|
#define INT_VALID_P(_size, _sign) is_ ## _sign ## _int ## _size
|
|
|
|
|
|
#define SIGNEDNESS(_sign) SIGNEDNESS_ ## _sign
|
|
|
|
|
|
|
|
|
|
|
|
|
All literal constants are read-only
* libguile/array-handle.c (initialize_vector_handle): Add mutable_p
argument. Unless the vector handle is mutable, null out its
writable_elements member.
(scm_array_get_handle): Adapt to determine mutability of the various
arrays.
(scm_array_handle_elements, scm_array_handle_writable_elements):
Reverse the sense: instead of implementing read-only in terms of
read-write, go the other way around, adding an assertion in the
read-write case that the array handle is mutable.
* libguile/array-map.c (racp): Assert that the destination is mutable.
* libguile/bitvectors.c (SCM_F_BITVECTOR_IMMUTABLE, IS_BITVECTOR):
(IS_MUTABLE_BITVECTOR): Add a flag to indicate immutability.
(scm_i_bitvector_bits): Fix indentation.
(scm_i_is_mutable_bitvector): New helper.
(scm_array_handle_bit_elements)
((scm_array_handle_bit_writable_elements): Build writable_elements in
terms of elements.
(scm_bitvector_elements, scm_bitvector_writable_elements): Likewise.
(scm_c_bitvector_set_x): Require a mutable bitvector for the
fast-path.
(scm_bitvector_to_list, scm_bit_count): Use read-only elements()
function.
* libguile/bitvectors.h (scm_i_is_mutable_bitvector): New decl.
* libguile/bytevectors.c (INTEGER_ACCESSOR_PROLOGUE):
(INTEGER_GETTER_PROLOGUE, INTEGER_SETTER_PROLOGUE):
(INTEGER_REF, INTEGER_NATIVE_REF, INTEGER_SET, INTEGER_NATIVE_SET):
(GENERIC_INTEGER_ACCESSOR_PROLOGUE):
(GENERIC_INTEGER_GETTER_PROLOGUE, GENERIC_INTEGER_SETTER_PROLOGUE):
(LARGE_INTEGER_NATIVE_REF, LARGE_INTEGER_NATIVE_SET):
(IEEE754_GETTER_PROLOGUE, IEEE754_SETTER_PROLOGUE):
(IEEE754_REF, IEEE754_NATIVE_REF, IEEE754_SET, IEEE754_NATIVE_SET):
Setters require a mutable bytevector.
(SCM_BYTEVECTOR_SET_FLAG): New helper.
(SCM_BYTEVECTOR_SET_CONTIGUOUS_P, SCM_BYTEVECTOR_SET_ELEMENT_TYPE):
Remove helpers.
(SCM_VALIDATE_MUTABLE_BYTEVECTOR): New helper.
(make_bytevector, make_bytevector_from_buffer): Use
SCM_SET_BYTEVECTOR_FLAGS.
(scm_c_bytevector_set_x, scm_bytevector_fill_x)
(scm_bytevector_copy_x): Require a mutable bytevector.
* libguile/bytevectors.h (SCM_F_BYTEVECTOR_CONTIGUOUS)
(SCM_F_BYTEVECTOR_IMMUTABLE, SCM_MUTABLE_BYTEVECTOR_P): New
definitions.
* libguile/bytevectors.h (SCM_BYTEVECTOR_CONTIGUOUS_P): Just access one
bit.
* libguile/srfi-4.c (DEFINE_SRFI_4_C_FUNCS): Implement
writable_elements() in terms of elements().
* libguile/strings.c (scm_i_string_is_mutable): New helper.
* libguile/uniform.c (scm_array_handle_uniform_elements):
(scm_array_handle_uniform_writable_elements): Implement
writable_elements in terms of elements.
* libguile/vectors.c (SCM_VALIDATE_MUTABLE_VECTOR): New helper.
(scm_vector_elements, scm_vector_writable_elements): Implement
writable_elements in terms of elements.
(scm_c_vector_set_x): Require a mutable vector.
* libguile/vectors.h (SCM_F_VECTOR_IMMUTABLE, SCM_I_IS_MUTABLE_VECTOR):
New definitions.
* libguile/vm-engine.c (VM_VALIDATE_MUTABLE_BYTEVECTOR):
(VM_VALIDATE_MUTABLE_VECTOR, vector-set!, vector-set!/immediate)
(BV_BOUNDED_SET, BV_SET): Require mutable bytevector/vector.
* libguile/vm.c (vm_error_not_a_mutable_bytevector):
(vm_error_not_a_mutable_vector): New definitions.
* module/system/vm/assembler.scm (link-data): Mark residualized vectors,
bytevectors, and bitvectors as being read-only.
2017-04-18 14:56:48 +02:00
|
|
|
|
#define INTEGER_ACCESSOR_PROLOGUE(validate, _len, _sign) \
|
2009-06-21 16:55:58 +02:00
|
|
|
|
size_t c_len, c_index; \
|
2009-05-27 18:18:07 +02:00
|
|
|
|
_sign char *c_bv; \
|
|
|
|
|
|
\
|
All literal constants are read-only
* libguile/array-handle.c (initialize_vector_handle): Add mutable_p
argument. Unless the vector handle is mutable, null out its
writable_elements member.
(scm_array_get_handle): Adapt to determine mutability of the various
arrays.
(scm_array_handle_elements, scm_array_handle_writable_elements):
Reverse the sense: instead of implementing read-only in terms of
read-write, go the other way around, adding an assertion in the
read-write case that the array handle is mutable.
* libguile/array-map.c (racp): Assert that the destination is mutable.
* libguile/bitvectors.c (SCM_F_BITVECTOR_IMMUTABLE, IS_BITVECTOR):
(IS_MUTABLE_BITVECTOR): Add a flag to indicate immutability.
(scm_i_bitvector_bits): Fix indentation.
(scm_i_is_mutable_bitvector): New helper.
(scm_array_handle_bit_elements)
((scm_array_handle_bit_writable_elements): Build writable_elements in
terms of elements.
(scm_bitvector_elements, scm_bitvector_writable_elements): Likewise.
(scm_c_bitvector_set_x): Require a mutable bitvector for the
fast-path.
(scm_bitvector_to_list, scm_bit_count): Use read-only elements()
function.
* libguile/bitvectors.h (scm_i_is_mutable_bitvector): New decl.
* libguile/bytevectors.c (INTEGER_ACCESSOR_PROLOGUE):
(INTEGER_GETTER_PROLOGUE, INTEGER_SETTER_PROLOGUE):
(INTEGER_REF, INTEGER_NATIVE_REF, INTEGER_SET, INTEGER_NATIVE_SET):
(GENERIC_INTEGER_ACCESSOR_PROLOGUE):
(GENERIC_INTEGER_GETTER_PROLOGUE, GENERIC_INTEGER_SETTER_PROLOGUE):
(LARGE_INTEGER_NATIVE_REF, LARGE_INTEGER_NATIVE_SET):
(IEEE754_GETTER_PROLOGUE, IEEE754_SETTER_PROLOGUE):
(IEEE754_REF, IEEE754_NATIVE_REF, IEEE754_SET, IEEE754_NATIVE_SET):
Setters require a mutable bytevector.
(SCM_BYTEVECTOR_SET_FLAG): New helper.
(SCM_BYTEVECTOR_SET_CONTIGUOUS_P, SCM_BYTEVECTOR_SET_ELEMENT_TYPE):
Remove helpers.
(SCM_VALIDATE_MUTABLE_BYTEVECTOR): New helper.
(make_bytevector, make_bytevector_from_buffer): Use
SCM_SET_BYTEVECTOR_FLAGS.
(scm_c_bytevector_set_x, scm_bytevector_fill_x)
(scm_bytevector_copy_x): Require a mutable bytevector.
* libguile/bytevectors.h (SCM_F_BYTEVECTOR_CONTIGUOUS)
(SCM_F_BYTEVECTOR_IMMUTABLE, SCM_MUTABLE_BYTEVECTOR_P): New
definitions.
* libguile/bytevectors.h (SCM_BYTEVECTOR_CONTIGUOUS_P): Just access one
bit.
* libguile/srfi-4.c (DEFINE_SRFI_4_C_FUNCS): Implement
writable_elements() in terms of elements().
* libguile/strings.c (scm_i_string_is_mutable): New helper.
* libguile/uniform.c (scm_array_handle_uniform_elements):
(scm_array_handle_uniform_writable_elements): Implement
writable_elements in terms of elements.
* libguile/vectors.c (SCM_VALIDATE_MUTABLE_VECTOR): New helper.
(scm_vector_elements, scm_vector_writable_elements): Implement
writable_elements in terms of elements.
(scm_c_vector_set_x): Require a mutable vector.
* libguile/vectors.h (SCM_F_VECTOR_IMMUTABLE, SCM_I_IS_MUTABLE_VECTOR):
New definitions.
* libguile/vm-engine.c (VM_VALIDATE_MUTABLE_BYTEVECTOR):
(VM_VALIDATE_MUTABLE_VECTOR, vector-set!, vector-set!/immediate)
(BV_BOUNDED_SET, BV_SET): Require mutable bytevector/vector.
* libguile/vm.c (vm_error_not_a_mutable_bytevector):
(vm_error_not_a_mutable_vector): New definitions.
* module/system/vm/assembler.scm (link-data): Mark residualized vectors,
bytevectors, and bitvectors as being read-only.
2017-04-18 14:56:48 +02:00
|
|
|
|
SCM_VALIDATE_##validate (1, bv); \
|
2009-05-27 18:18:07 +02:00
|
|
|
|
c_index = scm_to_uint (index); \
|
|
|
|
|
|
\
|
|
|
|
|
|
c_len = SCM_BYTEVECTOR_LENGTH (bv); \
|
|
|
|
|
|
c_bv = (_sign char *) SCM_BYTEVECTOR_CONTENTS (bv); \
|
|
|
|
|
|
\
|
|
|
|
|
|
if (SCM_UNLIKELY (c_index + ((_len) >> 3UL) - 1 >= c_len)) \
|
|
|
|
|
|
scm_out_of_range (FUNC_NAME, index);
|
|
|
|
|
|
|
All literal constants are read-only
* libguile/array-handle.c (initialize_vector_handle): Add mutable_p
argument. Unless the vector handle is mutable, null out its
writable_elements member.
(scm_array_get_handle): Adapt to determine mutability of the various
arrays.
(scm_array_handle_elements, scm_array_handle_writable_elements):
Reverse the sense: instead of implementing read-only in terms of
read-write, go the other way around, adding an assertion in the
read-write case that the array handle is mutable.
* libguile/array-map.c (racp): Assert that the destination is mutable.
* libguile/bitvectors.c (SCM_F_BITVECTOR_IMMUTABLE, IS_BITVECTOR):
(IS_MUTABLE_BITVECTOR): Add a flag to indicate immutability.
(scm_i_bitvector_bits): Fix indentation.
(scm_i_is_mutable_bitvector): New helper.
(scm_array_handle_bit_elements)
((scm_array_handle_bit_writable_elements): Build writable_elements in
terms of elements.
(scm_bitvector_elements, scm_bitvector_writable_elements): Likewise.
(scm_c_bitvector_set_x): Require a mutable bitvector for the
fast-path.
(scm_bitvector_to_list, scm_bit_count): Use read-only elements()
function.
* libguile/bitvectors.h (scm_i_is_mutable_bitvector): New decl.
* libguile/bytevectors.c (INTEGER_ACCESSOR_PROLOGUE):
(INTEGER_GETTER_PROLOGUE, INTEGER_SETTER_PROLOGUE):
(INTEGER_REF, INTEGER_NATIVE_REF, INTEGER_SET, INTEGER_NATIVE_SET):
(GENERIC_INTEGER_ACCESSOR_PROLOGUE):
(GENERIC_INTEGER_GETTER_PROLOGUE, GENERIC_INTEGER_SETTER_PROLOGUE):
(LARGE_INTEGER_NATIVE_REF, LARGE_INTEGER_NATIVE_SET):
(IEEE754_GETTER_PROLOGUE, IEEE754_SETTER_PROLOGUE):
(IEEE754_REF, IEEE754_NATIVE_REF, IEEE754_SET, IEEE754_NATIVE_SET):
Setters require a mutable bytevector.
(SCM_BYTEVECTOR_SET_FLAG): New helper.
(SCM_BYTEVECTOR_SET_CONTIGUOUS_P, SCM_BYTEVECTOR_SET_ELEMENT_TYPE):
Remove helpers.
(SCM_VALIDATE_MUTABLE_BYTEVECTOR): New helper.
(make_bytevector, make_bytevector_from_buffer): Use
SCM_SET_BYTEVECTOR_FLAGS.
(scm_c_bytevector_set_x, scm_bytevector_fill_x)
(scm_bytevector_copy_x): Require a mutable bytevector.
* libguile/bytevectors.h (SCM_F_BYTEVECTOR_CONTIGUOUS)
(SCM_F_BYTEVECTOR_IMMUTABLE, SCM_MUTABLE_BYTEVECTOR_P): New
definitions.
* libguile/bytevectors.h (SCM_BYTEVECTOR_CONTIGUOUS_P): Just access one
bit.
* libguile/srfi-4.c (DEFINE_SRFI_4_C_FUNCS): Implement
writable_elements() in terms of elements().
* libguile/strings.c (scm_i_string_is_mutable): New helper.
* libguile/uniform.c (scm_array_handle_uniform_elements):
(scm_array_handle_uniform_writable_elements): Implement
writable_elements in terms of elements.
* libguile/vectors.c (SCM_VALIDATE_MUTABLE_VECTOR): New helper.
(scm_vector_elements, scm_vector_writable_elements): Implement
writable_elements in terms of elements.
(scm_c_vector_set_x): Require a mutable vector.
* libguile/vectors.h (SCM_F_VECTOR_IMMUTABLE, SCM_I_IS_MUTABLE_VECTOR):
New definitions.
* libguile/vm-engine.c (VM_VALIDATE_MUTABLE_BYTEVECTOR):
(VM_VALIDATE_MUTABLE_VECTOR, vector-set!, vector-set!/immediate)
(BV_BOUNDED_SET, BV_SET): Require mutable bytevector/vector.
* libguile/vm.c (vm_error_not_a_mutable_bytevector):
(vm_error_not_a_mutable_vector): New definitions.
* module/system/vm/assembler.scm (link-data): Mark residualized vectors,
bytevectors, and bitvectors as being read-only.
2017-04-18 14:56:48 +02:00
|
|
|
|
#define INTEGER_GETTER_PROLOGUE(_len, _sign) \
|
|
|
|
|
|
INTEGER_ACCESSOR_PROLOGUE (BYTEVECTOR, _len, _sign)
|
|
|
|
|
|
|
|
|
|
|
|
#define INTEGER_SETTER_PROLOGUE(_len, _sign) \
|
|
|
|
|
|
INTEGER_ACCESSOR_PROLOGUE (MUTABLE_BYTEVECTOR, _len, _sign)
|
|
|
|
|
|
|
2009-05-27 18:18:07 +02:00
|
|
|
|
/* Template for fixed-size integer access (only 8, 16 or 32-bit). */
|
2009-06-24 23:46:42 +02:00
|
|
|
|
#define INTEGER_REF(_len, _sign) \
|
|
|
|
|
|
SCM result; \
|
|
|
|
|
|
\
|
All literal constants are read-only
* libguile/array-handle.c (initialize_vector_handle): Add mutable_p
argument. Unless the vector handle is mutable, null out its
writable_elements member.
(scm_array_get_handle): Adapt to determine mutability of the various
arrays.
(scm_array_handle_elements, scm_array_handle_writable_elements):
Reverse the sense: instead of implementing read-only in terms of
read-write, go the other way around, adding an assertion in the
read-write case that the array handle is mutable.
* libguile/array-map.c (racp): Assert that the destination is mutable.
* libguile/bitvectors.c (SCM_F_BITVECTOR_IMMUTABLE, IS_BITVECTOR):
(IS_MUTABLE_BITVECTOR): Add a flag to indicate immutability.
(scm_i_bitvector_bits): Fix indentation.
(scm_i_is_mutable_bitvector): New helper.
(scm_array_handle_bit_elements)
((scm_array_handle_bit_writable_elements): Build writable_elements in
terms of elements.
(scm_bitvector_elements, scm_bitvector_writable_elements): Likewise.
(scm_c_bitvector_set_x): Require a mutable bitvector for the
fast-path.
(scm_bitvector_to_list, scm_bit_count): Use read-only elements()
function.
* libguile/bitvectors.h (scm_i_is_mutable_bitvector): New decl.
* libguile/bytevectors.c (INTEGER_ACCESSOR_PROLOGUE):
(INTEGER_GETTER_PROLOGUE, INTEGER_SETTER_PROLOGUE):
(INTEGER_REF, INTEGER_NATIVE_REF, INTEGER_SET, INTEGER_NATIVE_SET):
(GENERIC_INTEGER_ACCESSOR_PROLOGUE):
(GENERIC_INTEGER_GETTER_PROLOGUE, GENERIC_INTEGER_SETTER_PROLOGUE):
(LARGE_INTEGER_NATIVE_REF, LARGE_INTEGER_NATIVE_SET):
(IEEE754_GETTER_PROLOGUE, IEEE754_SETTER_PROLOGUE):
(IEEE754_REF, IEEE754_NATIVE_REF, IEEE754_SET, IEEE754_NATIVE_SET):
Setters require a mutable bytevector.
(SCM_BYTEVECTOR_SET_FLAG): New helper.
(SCM_BYTEVECTOR_SET_CONTIGUOUS_P, SCM_BYTEVECTOR_SET_ELEMENT_TYPE):
Remove helpers.
(SCM_VALIDATE_MUTABLE_BYTEVECTOR): New helper.
(make_bytevector, make_bytevector_from_buffer): Use
SCM_SET_BYTEVECTOR_FLAGS.
(scm_c_bytevector_set_x, scm_bytevector_fill_x)
(scm_bytevector_copy_x): Require a mutable bytevector.
* libguile/bytevectors.h (SCM_F_BYTEVECTOR_CONTIGUOUS)
(SCM_F_BYTEVECTOR_IMMUTABLE, SCM_MUTABLE_BYTEVECTOR_P): New
definitions.
* libguile/bytevectors.h (SCM_BYTEVECTOR_CONTIGUOUS_P): Just access one
bit.
* libguile/srfi-4.c (DEFINE_SRFI_4_C_FUNCS): Implement
writable_elements() in terms of elements().
* libguile/strings.c (scm_i_string_is_mutable): New helper.
* libguile/uniform.c (scm_array_handle_uniform_elements):
(scm_array_handle_uniform_writable_elements): Implement
writable_elements in terms of elements.
* libguile/vectors.c (SCM_VALIDATE_MUTABLE_VECTOR): New helper.
(scm_vector_elements, scm_vector_writable_elements): Implement
writable_elements in terms of elements.
(scm_c_vector_set_x): Require a mutable vector.
* libguile/vectors.h (SCM_F_VECTOR_IMMUTABLE, SCM_I_IS_MUTABLE_VECTOR):
New definitions.
* libguile/vm-engine.c (VM_VALIDATE_MUTABLE_BYTEVECTOR):
(VM_VALIDATE_MUTABLE_VECTOR, vector-set!, vector-set!/immediate)
(BV_BOUNDED_SET, BV_SET): Require mutable bytevector/vector.
* libguile/vm.c (vm_error_not_a_mutable_bytevector):
(vm_error_not_a_mutable_vector): New definitions.
* module/system/vm/assembler.scm (link-data): Mark residualized vectors,
bytevectors, and bitvectors as being read-only.
2017-04-18 14:56:48 +02:00
|
|
|
|
INTEGER_GETTER_PROLOGUE (_len, _sign); \
|
2009-06-24 23:46:42 +02:00
|
|
|
|
SCM_VALIDATE_SYMBOL (3, endianness); \
|
|
|
|
|
|
\
|
|
|
|
|
|
{ \
|
|
|
|
|
|
INT_TYPE (_len, _sign) c_result; \
|
|
|
|
|
|
\
|
|
|
|
|
|
memcpy (&c_result, &c_bv[c_index], (_len) / 8); \
|
|
|
|
|
|
if (!scm_is_eq (endianness, scm_i_native_endianness)) \
|
|
|
|
|
|
c_result = INT_SWAP (_len) (c_result); \
|
|
|
|
|
|
\
|
|
|
|
|
|
result = SCM_I_MAKINUM (c_result); \
|
|
|
|
|
|
} \
|
|
|
|
|
|
\
|
2009-05-27 18:18:07 +02:00
|
|
|
|
return result;
|
|
|
|
|
|
|
|
|
|
|
|
/* Template for fixed-size integer access using the native endianness. */
|
|
|
|
|
|
#define INTEGER_NATIVE_REF(_len, _sign) \
|
|
|
|
|
|
SCM result; \
|
|
|
|
|
|
\
|
All literal constants are read-only
* libguile/array-handle.c (initialize_vector_handle): Add mutable_p
argument. Unless the vector handle is mutable, null out its
writable_elements member.
(scm_array_get_handle): Adapt to determine mutability of the various
arrays.
(scm_array_handle_elements, scm_array_handle_writable_elements):
Reverse the sense: instead of implementing read-only in terms of
read-write, go the other way around, adding an assertion in the
read-write case that the array handle is mutable.
* libguile/array-map.c (racp): Assert that the destination is mutable.
* libguile/bitvectors.c (SCM_F_BITVECTOR_IMMUTABLE, IS_BITVECTOR):
(IS_MUTABLE_BITVECTOR): Add a flag to indicate immutability.
(scm_i_bitvector_bits): Fix indentation.
(scm_i_is_mutable_bitvector): New helper.
(scm_array_handle_bit_elements)
((scm_array_handle_bit_writable_elements): Build writable_elements in
terms of elements.
(scm_bitvector_elements, scm_bitvector_writable_elements): Likewise.
(scm_c_bitvector_set_x): Require a mutable bitvector for the
fast-path.
(scm_bitvector_to_list, scm_bit_count): Use read-only elements()
function.
* libguile/bitvectors.h (scm_i_is_mutable_bitvector): New decl.
* libguile/bytevectors.c (INTEGER_ACCESSOR_PROLOGUE):
(INTEGER_GETTER_PROLOGUE, INTEGER_SETTER_PROLOGUE):
(INTEGER_REF, INTEGER_NATIVE_REF, INTEGER_SET, INTEGER_NATIVE_SET):
(GENERIC_INTEGER_ACCESSOR_PROLOGUE):
(GENERIC_INTEGER_GETTER_PROLOGUE, GENERIC_INTEGER_SETTER_PROLOGUE):
(LARGE_INTEGER_NATIVE_REF, LARGE_INTEGER_NATIVE_SET):
(IEEE754_GETTER_PROLOGUE, IEEE754_SETTER_PROLOGUE):
(IEEE754_REF, IEEE754_NATIVE_REF, IEEE754_SET, IEEE754_NATIVE_SET):
Setters require a mutable bytevector.
(SCM_BYTEVECTOR_SET_FLAG): New helper.
(SCM_BYTEVECTOR_SET_CONTIGUOUS_P, SCM_BYTEVECTOR_SET_ELEMENT_TYPE):
Remove helpers.
(SCM_VALIDATE_MUTABLE_BYTEVECTOR): New helper.
(make_bytevector, make_bytevector_from_buffer): Use
SCM_SET_BYTEVECTOR_FLAGS.
(scm_c_bytevector_set_x, scm_bytevector_fill_x)
(scm_bytevector_copy_x): Require a mutable bytevector.
* libguile/bytevectors.h (SCM_F_BYTEVECTOR_CONTIGUOUS)
(SCM_F_BYTEVECTOR_IMMUTABLE, SCM_MUTABLE_BYTEVECTOR_P): New
definitions.
* libguile/bytevectors.h (SCM_BYTEVECTOR_CONTIGUOUS_P): Just access one
bit.
* libguile/srfi-4.c (DEFINE_SRFI_4_C_FUNCS): Implement
writable_elements() in terms of elements().
* libguile/strings.c (scm_i_string_is_mutable): New helper.
* libguile/uniform.c (scm_array_handle_uniform_elements):
(scm_array_handle_uniform_writable_elements): Implement
writable_elements in terms of elements.
* libguile/vectors.c (SCM_VALIDATE_MUTABLE_VECTOR): New helper.
(scm_vector_elements, scm_vector_writable_elements): Implement
writable_elements in terms of elements.
(scm_c_vector_set_x): Require a mutable vector.
* libguile/vectors.h (SCM_F_VECTOR_IMMUTABLE, SCM_I_IS_MUTABLE_VECTOR):
New definitions.
* libguile/vm-engine.c (VM_VALIDATE_MUTABLE_BYTEVECTOR):
(VM_VALIDATE_MUTABLE_VECTOR, vector-set!, vector-set!/immediate)
(BV_BOUNDED_SET, BV_SET): Require mutable bytevector/vector.
* libguile/vm.c (vm_error_not_a_mutable_bytevector):
(vm_error_not_a_mutable_vector): New definitions.
* module/system/vm/assembler.scm (link-data): Mark residualized vectors,
bytevectors, and bitvectors as being read-only.
2017-04-18 14:56:48 +02:00
|
|
|
|
INTEGER_GETTER_PROLOGUE (_len, _sign); \
|
2009-05-27 18:18:07 +02:00
|
|
|
|
\
|
|
|
|
|
|
{ \
|
|
|
|
|
|
INT_TYPE (_len, _sign) c_result; \
|
|
|
|
|
|
\
|
|
|
|
|
|
memcpy (&c_result, &c_bv[c_index], (_len) / 8); \
|
|
|
|
|
|
result = SCM_I_MAKINUM (c_result); \
|
|
|
|
|
|
} \
|
|
|
|
|
|
\
|
|
|
|
|
|
return result;
|
|
|
|
|
|
|
|
|
|
|
|
/* Template for fixed-size integer modification (only 8, 16 or 32-bit). */
|
|
|
|
|
|
#define INTEGER_SET(_len, _sign) \
|
All literal constants are read-only
* libguile/array-handle.c (initialize_vector_handle): Add mutable_p
argument. Unless the vector handle is mutable, null out its
writable_elements member.
(scm_array_get_handle): Adapt to determine mutability of the various
arrays.
(scm_array_handle_elements, scm_array_handle_writable_elements):
Reverse the sense: instead of implementing read-only in terms of
read-write, go the other way around, adding an assertion in the
read-write case that the array handle is mutable.
* libguile/array-map.c (racp): Assert that the destination is mutable.
* libguile/bitvectors.c (SCM_F_BITVECTOR_IMMUTABLE, IS_BITVECTOR):
(IS_MUTABLE_BITVECTOR): Add a flag to indicate immutability.
(scm_i_bitvector_bits): Fix indentation.
(scm_i_is_mutable_bitvector): New helper.
(scm_array_handle_bit_elements)
((scm_array_handle_bit_writable_elements): Build writable_elements in
terms of elements.
(scm_bitvector_elements, scm_bitvector_writable_elements): Likewise.
(scm_c_bitvector_set_x): Require a mutable bitvector for the
fast-path.
(scm_bitvector_to_list, scm_bit_count): Use read-only elements()
function.
* libguile/bitvectors.h (scm_i_is_mutable_bitvector): New decl.
* libguile/bytevectors.c (INTEGER_ACCESSOR_PROLOGUE):
(INTEGER_GETTER_PROLOGUE, INTEGER_SETTER_PROLOGUE):
(INTEGER_REF, INTEGER_NATIVE_REF, INTEGER_SET, INTEGER_NATIVE_SET):
(GENERIC_INTEGER_ACCESSOR_PROLOGUE):
(GENERIC_INTEGER_GETTER_PROLOGUE, GENERIC_INTEGER_SETTER_PROLOGUE):
(LARGE_INTEGER_NATIVE_REF, LARGE_INTEGER_NATIVE_SET):
(IEEE754_GETTER_PROLOGUE, IEEE754_SETTER_PROLOGUE):
(IEEE754_REF, IEEE754_NATIVE_REF, IEEE754_SET, IEEE754_NATIVE_SET):
Setters require a mutable bytevector.
(SCM_BYTEVECTOR_SET_FLAG): New helper.
(SCM_BYTEVECTOR_SET_CONTIGUOUS_P, SCM_BYTEVECTOR_SET_ELEMENT_TYPE):
Remove helpers.
(SCM_VALIDATE_MUTABLE_BYTEVECTOR): New helper.
(make_bytevector, make_bytevector_from_buffer): Use
SCM_SET_BYTEVECTOR_FLAGS.
(scm_c_bytevector_set_x, scm_bytevector_fill_x)
(scm_bytevector_copy_x): Require a mutable bytevector.
* libguile/bytevectors.h (SCM_F_BYTEVECTOR_CONTIGUOUS)
(SCM_F_BYTEVECTOR_IMMUTABLE, SCM_MUTABLE_BYTEVECTOR_P): New
definitions.
* libguile/bytevectors.h (SCM_BYTEVECTOR_CONTIGUOUS_P): Just access one
bit.
* libguile/srfi-4.c (DEFINE_SRFI_4_C_FUNCS): Implement
writable_elements() in terms of elements().
* libguile/strings.c (scm_i_string_is_mutable): New helper.
* libguile/uniform.c (scm_array_handle_uniform_elements):
(scm_array_handle_uniform_writable_elements): Implement
writable_elements in terms of elements.
* libguile/vectors.c (SCM_VALIDATE_MUTABLE_VECTOR): New helper.
(scm_vector_elements, scm_vector_writable_elements): Implement
writable_elements in terms of elements.
(scm_c_vector_set_x): Require a mutable vector.
* libguile/vectors.h (SCM_F_VECTOR_IMMUTABLE, SCM_I_IS_MUTABLE_VECTOR):
New definitions.
* libguile/vm-engine.c (VM_VALIDATE_MUTABLE_BYTEVECTOR):
(VM_VALIDATE_MUTABLE_VECTOR, vector-set!, vector-set!/immediate)
(BV_BOUNDED_SET, BV_SET): Require mutable bytevector/vector.
* libguile/vm.c (vm_error_not_a_mutable_bytevector):
(vm_error_not_a_mutable_vector): New definitions.
* module/system/vm/assembler.scm (link-data): Mark residualized vectors,
bytevectors, and bitvectors as being read-only.
2017-04-18 14:56:48 +02:00
|
|
|
|
INTEGER_SETTER_PROLOGUE (_len, _sign); \
|
2009-05-27 18:18:07 +02:00
|
|
|
|
SCM_VALIDATE_SYMBOL (3, endianness); \
|
|
|
|
|
|
\
|
|
|
|
|
|
{ \
|
2010-11-19 11:29:26 +01:00
|
|
|
|
scm_t_signed_bits c_value; \
|
2009-05-27 18:18:07 +02:00
|
|
|
|
INT_TYPE (_len, _sign) c_value_short; \
|
|
|
|
|
|
\
|
|
|
|
|
|
if (SCM_UNLIKELY (!SCM_I_INUMP (value))) \
|
|
|
|
|
|
scm_wrong_type_arg (FUNC_NAME, 3, value); \
|
|
|
|
|
|
\
|
|
|
|
|
|
c_value = SCM_I_INUM (value); \
|
|
|
|
|
|
if (SCM_UNLIKELY (!INT_VALID_P (_len, _sign) (c_value))) \
|
|
|
|
|
|
scm_out_of_range (FUNC_NAME, value); \
|
|
|
|
|
|
\
|
|
|
|
|
|
c_value_short = (INT_TYPE (_len, _sign)) c_value; \
|
2009-06-24 23:46:42 +02:00
|
|
|
|
if (!scm_is_eq (endianness, scm_i_native_endianness)) \
|
2009-05-27 18:18:07 +02:00
|
|
|
|
c_value_short = INT_SWAP (_len) (c_value_short); \
|
|
|
|
|
|
\
|
|
|
|
|
|
memcpy (&c_bv[c_index], &c_value_short, (_len) / 8); \
|
|
|
|
|
|
} \
|
|
|
|
|
|
\
|
|
|
|
|
|
return SCM_UNSPECIFIED;
|
|
|
|
|
|
|
|
|
|
|
|
/* Template for fixed-size integer modification using the native
|
|
|
|
|
|
endianness. */
|
|
|
|
|
|
#define INTEGER_NATIVE_SET(_len, _sign) \
|
All literal constants are read-only
* libguile/array-handle.c (initialize_vector_handle): Add mutable_p
argument. Unless the vector handle is mutable, null out its
writable_elements member.
(scm_array_get_handle): Adapt to determine mutability of the various
arrays.
(scm_array_handle_elements, scm_array_handle_writable_elements):
Reverse the sense: instead of implementing read-only in terms of
read-write, go the other way around, adding an assertion in the
read-write case that the array handle is mutable.
* libguile/array-map.c (racp): Assert that the destination is mutable.
* libguile/bitvectors.c (SCM_F_BITVECTOR_IMMUTABLE, IS_BITVECTOR):
(IS_MUTABLE_BITVECTOR): Add a flag to indicate immutability.
(scm_i_bitvector_bits): Fix indentation.
(scm_i_is_mutable_bitvector): New helper.
(scm_array_handle_bit_elements)
((scm_array_handle_bit_writable_elements): Build writable_elements in
terms of elements.
(scm_bitvector_elements, scm_bitvector_writable_elements): Likewise.
(scm_c_bitvector_set_x): Require a mutable bitvector for the
fast-path.
(scm_bitvector_to_list, scm_bit_count): Use read-only elements()
function.
* libguile/bitvectors.h (scm_i_is_mutable_bitvector): New decl.
* libguile/bytevectors.c (INTEGER_ACCESSOR_PROLOGUE):
(INTEGER_GETTER_PROLOGUE, INTEGER_SETTER_PROLOGUE):
(INTEGER_REF, INTEGER_NATIVE_REF, INTEGER_SET, INTEGER_NATIVE_SET):
(GENERIC_INTEGER_ACCESSOR_PROLOGUE):
(GENERIC_INTEGER_GETTER_PROLOGUE, GENERIC_INTEGER_SETTER_PROLOGUE):
(LARGE_INTEGER_NATIVE_REF, LARGE_INTEGER_NATIVE_SET):
(IEEE754_GETTER_PROLOGUE, IEEE754_SETTER_PROLOGUE):
(IEEE754_REF, IEEE754_NATIVE_REF, IEEE754_SET, IEEE754_NATIVE_SET):
Setters require a mutable bytevector.
(SCM_BYTEVECTOR_SET_FLAG): New helper.
(SCM_BYTEVECTOR_SET_CONTIGUOUS_P, SCM_BYTEVECTOR_SET_ELEMENT_TYPE):
Remove helpers.
(SCM_VALIDATE_MUTABLE_BYTEVECTOR): New helper.
(make_bytevector, make_bytevector_from_buffer): Use
SCM_SET_BYTEVECTOR_FLAGS.
(scm_c_bytevector_set_x, scm_bytevector_fill_x)
(scm_bytevector_copy_x): Require a mutable bytevector.
* libguile/bytevectors.h (SCM_F_BYTEVECTOR_CONTIGUOUS)
(SCM_F_BYTEVECTOR_IMMUTABLE, SCM_MUTABLE_BYTEVECTOR_P): New
definitions.
* libguile/bytevectors.h (SCM_BYTEVECTOR_CONTIGUOUS_P): Just access one
bit.
* libguile/srfi-4.c (DEFINE_SRFI_4_C_FUNCS): Implement
writable_elements() in terms of elements().
* libguile/strings.c (scm_i_string_is_mutable): New helper.
* libguile/uniform.c (scm_array_handle_uniform_elements):
(scm_array_handle_uniform_writable_elements): Implement
writable_elements in terms of elements.
* libguile/vectors.c (SCM_VALIDATE_MUTABLE_VECTOR): New helper.
(scm_vector_elements, scm_vector_writable_elements): Implement
writable_elements in terms of elements.
(scm_c_vector_set_x): Require a mutable vector.
* libguile/vectors.h (SCM_F_VECTOR_IMMUTABLE, SCM_I_IS_MUTABLE_VECTOR):
New definitions.
* libguile/vm-engine.c (VM_VALIDATE_MUTABLE_BYTEVECTOR):
(VM_VALIDATE_MUTABLE_VECTOR, vector-set!, vector-set!/immediate)
(BV_BOUNDED_SET, BV_SET): Require mutable bytevector/vector.
* libguile/vm.c (vm_error_not_a_mutable_bytevector):
(vm_error_not_a_mutable_vector): New definitions.
* module/system/vm/assembler.scm (link-data): Mark residualized vectors,
bytevectors, and bitvectors as being read-only.
2017-04-18 14:56:48 +02:00
|
|
|
|
INTEGER_SETTER_PROLOGUE (_len, _sign); \
|
2009-05-27 18:18:07 +02:00
|
|
|
|
\
|
|
|
|
|
|
{ \
|
2010-11-19 11:29:26 +01:00
|
|
|
|
scm_t_signed_bits c_value; \
|
2009-05-27 18:18:07 +02:00
|
|
|
|
INT_TYPE (_len, _sign) c_value_short; \
|
|
|
|
|
|
\
|
|
|
|
|
|
if (SCM_UNLIKELY (!SCM_I_INUMP (value))) \
|
|
|
|
|
|
scm_wrong_type_arg (FUNC_NAME, 3, value); \
|
|
|
|
|
|
\
|
|
|
|
|
|
c_value = SCM_I_INUM (value); \
|
|
|
|
|
|
if (SCM_UNLIKELY (!INT_VALID_P (_len, _sign) (c_value))) \
|
|
|
|
|
|
scm_out_of_range (FUNC_NAME, value); \
|
|
|
|
|
|
\
|
|
|
|
|
|
c_value_short = (INT_TYPE (_len, _sign)) c_value; \
|
|
|
|
|
|
\
|
|
|
|
|
|
memcpy (&c_bv[c_index], &c_value_short, (_len) / 8); \
|
|
|
|
|
|
} \
|
|
|
|
|
|
\
|
|
|
|
|
|
return SCM_UNSPECIFIED;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Bytevector type. */
|
|
|
|
|
|
|
2009-08-31 01:07:30 +02:00
|
|
|
|
#define SCM_BYTEVECTOR_HEADER_BYTES \
|
2011-07-29 09:11:24 +02:00
|
|
|
|
(SCM_BYTEVECTOR_HEADER_SIZE * sizeof (scm_t_bits))
|
2009-08-31 01:07:30 +02:00
|
|
|
|
|
All literal constants are read-only
* libguile/array-handle.c (initialize_vector_handle): Add mutable_p
argument. Unless the vector handle is mutable, null out its
writable_elements member.
(scm_array_get_handle): Adapt to determine mutability of the various
arrays.
(scm_array_handle_elements, scm_array_handle_writable_elements):
Reverse the sense: instead of implementing read-only in terms of
read-write, go the other way around, adding an assertion in the
read-write case that the array handle is mutable.
* libguile/array-map.c (racp): Assert that the destination is mutable.
* libguile/bitvectors.c (SCM_F_BITVECTOR_IMMUTABLE, IS_BITVECTOR):
(IS_MUTABLE_BITVECTOR): Add a flag to indicate immutability.
(scm_i_bitvector_bits): Fix indentation.
(scm_i_is_mutable_bitvector): New helper.
(scm_array_handle_bit_elements)
((scm_array_handle_bit_writable_elements): Build writable_elements in
terms of elements.
(scm_bitvector_elements, scm_bitvector_writable_elements): Likewise.
(scm_c_bitvector_set_x): Require a mutable bitvector for the
fast-path.
(scm_bitvector_to_list, scm_bit_count): Use read-only elements()
function.
* libguile/bitvectors.h (scm_i_is_mutable_bitvector): New decl.
* libguile/bytevectors.c (INTEGER_ACCESSOR_PROLOGUE):
(INTEGER_GETTER_PROLOGUE, INTEGER_SETTER_PROLOGUE):
(INTEGER_REF, INTEGER_NATIVE_REF, INTEGER_SET, INTEGER_NATIVE_SET):
(GENERIC_INTEGER_ACCESSOR_PROLOGUE):
(GENERIC_INTEGER_GETTER_PROLOGUE, GENERIC_INTEGER_SETTER_PROLOGUE):
(LARGE_INTEGER_NATIVE_REF, LARGE_INTEGER_NATIVE_SET):
(IEEE754_GETTER_PROLOGUE, IEEE754_SETTER_PROLOGUE):
(IEEE754_REF, IEEE754_NATIVE_REF, IEEE754_SET, IEEE754_NATIVE_SET):
Setters require a mutable bytevector.
(SCM_BYTEVECTOR_SET_FLAG): New helper.
(SCM_BYTEVECTOR_SET_CONTIGUOUS_P, SCM_BYTEVECTOR_SET_ELEMENT_TYPE):
Remove helpers.
(SCM_VALIDATE_MUTABLE_BYTEVECTOR): New helper.
(make_bytevector, make_bytevector_from_buffer): Use
SCM_SET_BYTEVECTOR_FLAGS.
(scm_c_bytevector_set_x, scm_bytevector_fill_x)
(scm_bytevector_copy_x): Require a mutable bytevector.
* libguile/bytevectors.h (SCM_F_BYTEVECTOR_CONTIGUOUS)
(SCM_F_BYTEVECTOR_IMMUTABLE, SCM_MUTABLE_BYTEVECTOR_P): New
definitions.
* libguile/bytevectors.h (SCM_BYTEVECTOR_CONTIGUOUS_P): Just access one
bit.
* libguile/srfi-4.c (DEFINE_SRFI_4_C_FUNCS): Implement
writable_elements() in terms of elements().
* libguile/strings.c (scm_i_string_is_mutable): New helper.
* libguile/uniform.c (scm_array_handle_uniform_elements):
(scm_array_handle_uniform_writable_elements): Implement
writable_elements in terms of elements.
* libguile/vectors.c (SCM_VALIDATE_MUTABLE_VECTOR): New helper.
(scm_vector_elements, scm_vector_writable_elements): Implement
writable_elements in terms of elements.
(scm_c_vector_set_x): Require a mutable vector.
* libguile/vectors.h (SCM_F_VECTOR_IMMUTABLE, SCM_I_IS_MUTABLE_VECTOR):
New definitions.
* libguile/vm-engine.c (VM_VALIDATE_MUTABLE_BYTEVECTOR):
(VM_VALIDATE_MUTABLE_VECTOR, vector-set!, vector-set!/immediate)
(BV_BOUNDED_SET, BV_SET): Require mutable bytevector/vector.
* libguile/vm.c (vm_error_not_a_mutable_bytevector):
(vm_error_not_a_mutable_vector): New definitions.
* module/system/vm/assembler.scm (link-data): Mark residualized vectors,
bytevectors, and bitvectors as being read-only.
2017-04-18 14:56:48 +02:00
|
|
|
|
#define SCM_BYTEVECTOR_SET_FLAG(bv, flag) \
|
|
|
|
|
|
SCM_SET_BYTEVECTOR_FLAGS ((bv), SCM_BYTEVECTOR_FLAGS (bv) | flag)
|
2009-07-18 13:46:29 +02:00
|
|
|
|
#define SCM_BYTEVECTOR_SET_LENGTH(_bv, _len) \
|
Use a TC7 tag instead of a SMOB for bytevectors.
* libguile/bytevectors.c (scm_tc16_bytevector): Remove.
(SCM_BYTEVECTOR_SET_LENGTH, SCM_BYTEVECTOR_SET_CONTENTS,
SCM_BYTEVECTOR_SET_INLINE, SCM_BYTEVECTOR_SET_ELEMENT_TYPE,
make_bytevector_from_buffer, scm_is_bytevector,
scm_bootstrap_bytevectors): Adjust to the SMOB->tc7 change.
(scm_i_print_bytevector): New, formerly `print_bytevector ()'.
(bytevector_equal_p): Remove.
* libguile/bytevectors.h (SCM_BYTEVECTOR_LENGTH,
SCM_BYTEVECTOR_CONTENTS, SCM_BYTEVECTOR_P): Adjust to SMOB->tc7
change.
(SCM_BYTEVECTOR_FLAGS, SCM_SET_BYTEVECTOR_FLAGS): New macros.
(scm_tc16_bytevector): Remove declaration.
(scm_i_print_bytevector): New declaration.
* libguile/eq.c (scm_equal_p): Handle `scm_tc7_bytevector'.
* libguile/evalext.c (scm_self_evaluating_p): Likewise.
* libguile/print.c (iprin1): Likewise.
* libguile/tags.h (scm_tc7_bytevector): New.
(scm_tc7_unused_8): Remove.
* libguile/validate.h (SCM_VALIDATE_BYTEVECTOR): Adjust.
* test-suite/tests/bytevectors.test ("Datum
Syntax")["self-evaluating?"]: New test.
2009-08-30 20:12:09 +02:00
|
|
|
|
SCM_SET_CELL_WORD_1 ((_bv), (scm_t_bits) (_len))
|
2009-11-15 19:34:38 +01:00
|
|
|
|
#define SCM_BYTEVECTOR_SET_CONTENTS(_bv, _contents) \
|
|
|
|
|
|
SCM_SET_CELL_WORD_2 ((_bv), (scm_t_bits) (_contents))
|
2011-05-07 14:57:15 +02:00
|
|
|
|
#define SCM_BYTEVECTOR_SET_PARENT(_bv, _parent) \
|
|
|
|
|
|
SCM_SET_CELL_OBJECT_3 ((_bv), (_parent))
|
|
|
|
|
|
|
All literal constants are read-only
* libguile/array-handle.c (initialize_vector_handle): Add mutable_p
argument. Unless the vector handle is mutable, null out its
writable_elements member.
(scm_array_get_handle): Adapt to determine mutability of the various
arrays.
(scm_array_handle_elements, scm_array_handle_writable_elements):
Reverse the sense: instead of implementing read-only in terms of
read-write, go the other way around, adding an assertion in the
read-write case that the array handle is mutable.
* libguile/array-map.c (racp): Assert that the destination is mutable.
* libguile/bitvectors.c (SCM_F_BITVECTOR_IMMUTABLE, IS_BITVECTOR):
(IS_MUTABLE_BITVECTOR): Add a flag to indicate immutability.
(scm_i_bitvector_bits): Fix indentation.
(scm_i_is_mutable_bitvector): New helper.
(scm_array_handle_bit_elements)
((scm_array_handle_bit_writable_elements): Build writable_elements in
terms of elements.
(scm_bitvector_elements, scm_bitvector_writable_elements): Likewise.
(scm_c_bitvector_set_x): Require a mutable bitvector for the
fast-path.
(scm_bitvector_to_list, scm_bit_count): Use read-only elements()
function.
* libguile/bitvectors.h (scm_i_is_mutable_bitvector): New decl.
* libguile/bytevectors.c (INTEGER_ACCESSOR_PROLOGUE):
(INTEGER_GETTER_PROLOGUE, INTEGER_SETTER_PROLOGUE):
(INTEGER_REF, INTEGER_NATIVE_REF, INTEGER_SET, INTEGER_NATIVE_SET):
(GENERIC_INTEGER_ACCESSOR_PROLOGUE):
(GENERIC_INTEGER_GETTER_PROLOGUE, GENERIC_INTEGER_SETTER_PROLOGUE):
(LARGE_INTEGER_NATIVE_REF, LARGE_INTEGER_NATIVE_SET):
(IEEE754_GETTER_PROLOGUE, IEEE754_SETTER_PROLOGUE):
(IEEE754_REF, IEEE754_NATIVE_REF, IEEE754_SET, IEEE754_NATIVE_SET):
Setters require a mutable bytevector.
(SCM_BYTEVECTOR_SET_FLAG): New helper.
(SCM_BYTEVECTOR_SET_CONTIGUOUS_P, SCM_BYTEVECTOR_SET_ELEMENT_TYPE):
Remove helpers.
(SCM_VALIDATE_MUTABLE_BYTEVECTOR): New helper.
(make_bytevector, make_bytevector_from_buffer): Use
SCM_SET_BYTEVECTOR_FLAGS.
(scm_c_bytevector_set_x, scm_bytevector_fill_x)
(scm_bytevector_copy_x): Require a mutable bytevector.
* libguile/bytevectors.h (SCM_F_BYTEVECTOR_CONTIGUOUS)
(SCM_F_BYTEVECTOR_IMMUTABLE, SCM_MUTABLE_BYTEVECTOR_P): New
definitions.
* libguile/bytevectors.h (SCM_BYTEVECTOR_CONTIGUOUS_P): Just access one
bit.
* libguile/srfi-4.c (DEFINE_SRFI_4_C_FUNCS): Implement
writable_elements() in terms of elements().
* libguile/strings.c (scm_i_string_is_mutable): New helper.
* libguile/uniform.c (scm_array_handle_uniform_elements):
(scm_array_handle_uniform_writable_elements): Implement
writable_elements in terms of elements.
* libguile/vectors.c (SCM_VALIDATE_MUTABLE_VECTOR): New helper.
(scm_vector_elements, scm_vector_writable_elements): Implement
writable_elements in terms of elements.
(scm_c_vector_set_x): Require a mutable vector.
* libguile/vectors.h (SCM_F_VECTOR_IMMUTABLE, SCM_I_IS_MUTABLE_VECTOR):
New definitions.
* libguile/vm-engine.c (VM_VALIDATE_MUTABLE_BYTEVECTOR):
(VM_VALIDATE_MUTABLE_VECTOR, vector-set!, vector-set!/immediate)
(BV_BOUNDED_SET, BV_SET): Require mutable bytevector/vector.
* libguile/vm.c (vm_error_not_a_mutable_bytevector):
(vm_error_not_a_mutable_vector): New definitions.
* module/system/vm/assembler.scm (link-data): Mark residualized vectors,
bytevectors, and bitvectors as being read-only.
2017-04-18 14:56:48 +02:00
|
|
|
|
#define SCM_VALIDATE_MUTABLE_BYTEVECTOR(pos, v) \
|
|
|
|
|
|
SCM_MAKE_VALIDATE_MSG (pos, v, MUTABLE_BYTEVECTOR_P, "mutable bytevector")
|
|
|
|
|
|
|
|
|
|
|
|
|
2009-05-27 18:18:07 +02:00
|
|
|
|
/* The empty bytevector. */
|
|
|
|
|
|
SCM scm_null_bytevector = SCM_UNSPECIFIED;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static inline SCM
|
2009-08-31 01:07:30 +02:00
|
|
|
|
make_bytevector (size_t len, scm_t_array_element_type element_type)
|
2009-05-27 18:18:07 +02:00
|
|
|
|
{
|
2009-07-18 13:46:29 +02:00
|
|
|
|
SCM ret;
|
bytevectors have "element type" field, e.g. for generalized-vector-ref
Bytevectors have a very close relationship to other forms of uniform
vectors. Often you want to view a u64vector as a series of bytes, for
writing over a socket; or to process an incoming stream using the
convenient and less error-prone s16vector-ref API rather than
bytevector-s16-native-ref.
The essential needs of the representation of a bytevector and an
s64vector are the same, so we take advantage of that and extend the
bytevector implementation to have a "native type" field, which defaults
to VU8.
This commit doesn't actually expose any user-noticeable changes,
however.
* libguile/bytevectors.h (SCM_BYTEVECTOR_ELEMENT_TYPE): New internal
defines.
(scm_i_make_typed_bytevector, scm_c_take_typed_bytevector): New
internal functions.
* libguile/bytevectors.c (SCM_BYTEVECTOR_SET_ELEMENT_TYPE):
(SCM_BYTEVECTOR_TYPE_SIZE):
(SCM_BYTEVECTOR_TYPED_LENGTH): New internal macros.
(make_bytevector, make_bytevector_from_buffer): Take an extra
argument, the element type. The length argument is interpreted as
being the number of elements, which corresponds to the number of bytes
in the default VU8 case. Doing it this way eliminates a class of bugs
-- e.g. a u32vector of length 3 bytes doesn't make sense. We do have
to check for another class of bugs: overflow. The length stored on the
bytevector itself is still the byte length, though.
(scm_i_make_typed_bytevector):
(scm_c_take_typed_bytevector): New internal functions.
(scm_i_shrink_bytevector): Make sure the new size is valid for the
bytevector's type.
(scm_i_bytevector_generalized_set_x): Remove this function, the
array-handle infrastructure takes care of this for us.
(print_bytevector): Print the bytevector according to its type.
(scm_make_bytevector, scm_bytevector_copy)
(scm_uniform_array_to_bytevector)
(scm_u8_list_to_bytevector, scm_bytevector_to_uint_list): Adapt to
make_bytevector extra arg.
(bv_handle_ref, bv_handle_set_x): Adapt to ref and set based on the
type of the bytevector, e.g. f64 or u8.
(bytevector_get_handle): Set the typed length of the vector, not the
byte length.
Conflicts:
libguile/bytevectors.c
2009-07-19 15:11:53 +02:00
|
|
|
|
size_t c_len;
|
2009-08-31 01:07:30 +02:00
|
|
|
|
|
bytevectors have "element type" field, e.g. for generalized-vector-ref
Bytevectors have a very close relationship to other forms of uniform
vectors. Often you want to view a u64vector as a series of bytes, for
writing over a socket; or to process an incoming stream using the
convenient and less error-prone s16vector-ref API rather than
bytevector-s16-native-ref.
The essential needs of the representation of a bytevector and an
s64vector are the same, so we take advantage of that and extend the
bytevector implementation to have a "native type" field, which defaults
to VU8.
This commit doesn't actually expose any user-noticeable changes,
however.
* libguile/bytevectors.h (SCM_BYTEVECTOR_ELEMENT_TYPE): New internal
defines.
(scm_i_make_typed_bytevector, scm_c_take_typed_bytevector): New
internal functions.
* libguile/bytevectors.c (SCM_BYTEVECTOR_SET_ELEMENT_TYPE):
(SCM_BYTEVECTOR_TYPE_SIZE):
(SCM_BYTEVECTOR_TYPED_LENGTH): New internal macros.
(make_bytevector, make_bytevector_from_buffer): Take an extra
argument, the element type. The length argument is interpreted as
being the number of elements, which corresponds to the number of bytes
in the default VU8 case. Doing it this way eliminates a class of bugs
-- e.g. a u32vector of length 3 bytes doesn't make sense. We do have
to check for another class of bugs: overflow. The length stored on the
bytevector itself is still the byte length, though.
(scm_i_make_typed_bytevector):
(scm_c_take_typed_bytevector): New internal functions.
(scm_i_shrink_bytevector): Make sure the new size is valid for the
bytevector's type.
(scm_i_bytevector_generalized_set_x): Remove this function, the
array-handle infrastructure takes care of this for us.
(print_bytevector): Print the bytevector according to its type.
(scm_make_bytevector, scm_bytevector_copy)
(scm_uniform_array_to_bytevector)
(scm_u8_list_to_bytevector, scm_bytevector_to_uint_list): Adapt to
make_bytevector extra arg.
(bv_handle_ref, bv_handle_set_x): Adapt to ref and set based on the
type of the bytevector, e.g. f64 or u8.
(bytevector_get_handle): Set the typed length of the vector, not the
byte length.
Conflicts:
libguile/bytevectors.c
2009-07-19 15:11:53 +02:00
|
|
|
|
if (SCM_UNLIKELY (element_type > SCM_ARRAY_ELEMENT_TYPE_LAST
|
|
|
|
|
|
|| scm_i_array_element_type_sizes[element_type] < 8
|
2011-05-15 11:23:22 +02:00
|
|
|
|
|| len >= (((size_t) -1)
|
bytevectors have "element type" field, e.g. for generalized-vector-ref
Bytevectors have a very close relationship to other forms of uniform
vectors. Often you want to view a u64vector as a series of bytes, for
writing over a socket; or to process an incoming stream using the
convenient and less error-prone s16vector-ref API rather than
bytevector-s16-native-ref.
The essential needs of the representation of a bytevector and an
s64vector are the same, so we take advantage of that and extend the
bytevector implementation to have a "native type" field, which defaults
to VU8.
This commit doesn't actually expose any user-noticeable changes,
however.
* libguile/bytevectors.h (SCM_BYTEVECTOR_ELEMENT_TYPE): New internal
defines.
(scm_i_make_typed_bytevector, scm_c_take_typed_bytevector): New
internal functions.
* libguile/bytevectors.c (SCM_BYTEVECTOR_SET_ELEMENT_TYPE):
(SCM_BYTEVECTOR_TYPE_SIZE):
(SCM_BYTEVECTOR_TYPED_LENGTH): New internal macros.
(make_bytevector, make_bytevector_from_buffer): Take an extra
argument, the element type. The length argument is interpreted as
being the number of elements, which corresponds to the number of bytes
in the default VU8 case. Doing it this way eliminates a class of bugs
-- e.g. a u32vector of length 3 bytes doesn't make sense. We do have
to check for another class of bugs: overflow. The length stored on the
bytevector itself is still the byte length, though.
(scm_i_make_typed_bytevector):
(scm_c_take_typed_bytevector): New internal functions.
(scm_i_shrink_bytevector): Make sure the new size is valid for the
bytevector's type.
(scm_i_bytevector_generalized_set_x): Remove this function, the
array-handle infrastructure takes care of this for us.
(print_bytevector): Print the bytevector according to its type.
(scm_make_bytevector, scm_bytevector_copy)
(scm_uniform_array_to_bytevector)
(scm_u8_list_to_bytevector, scm_bytevector_to_uint_list): Adapt to
make_bytevector extra arg.
(bv_handle_ref, bv_handle_set_x): Adapt to ref and set based on the
type of the bytevector, e.g. f64 or u8.
(bytevector_get_handle): Set the typed length of the vector, not the
byte length.
Conflicts:
libguile/bytevectors.c
2009-07-19 15:11:53 +02:00
|
|
|
|
/ (scm_i_array_element_type_sizes[element_type]/8))))
|
|
|
|
|
|
/* This would be an internal Guile programming error */
|
|
|
|
|
|
abort ();
|
2009-08-31 01:07:30 +02:00
|
|
|
|
|
|
|
|
|
|
if (SCM_UNLIKELY (len == 0 && element_type == SCM_ARRAY_ELEMENT_TYPE_VU8
|
|
|
|
|
|
&& SCM_BYTEVECTOR_P (scm_null_bytevector)))
|
|
|
|
|
|
ret = scm_null_bytevector;
|
2009-07-18 13:46:29 +02:00
|
|
|
|
else
|
|
|
|
|
|
{
|
2009-11-15 19:34:38 +01:00
|
|
|
|
signed char *contents;
|
|
|
|
|
|
|
2009-08-31 01:07:30 +02:00
|
|
|
|
c_len = len * (scm_i_array_element_type_sizes[element_type] / 8);
|
|
|
|
|
|
|
2009-11-15 19:34:38 +01:00
|
|
|
|
contents = scm_gc_malloc_pointerless (SCM_BYTEVECTOR_HEADER_BYTES + c_len,
|
|
|
|
|
|
SCM_GC_BYTEVECTOR);
|
2011-10-24 17:58:22 +02:00
|
|
|
|
ret = SCM_PACK_POINTER (contents);
|
2009-11-15 19:34:38 +01:00
|
|
|
|
contents += SCM_BYTEVECTOR_HEADER_BYTES;
|
2009-08-31 01:07:30 +02:00
|
|
|
|
|
All literal constants are read-only
* libguile/array-handle.c (initialize_vector_handle): Add mutable_p
argument. Unless the vector handle is mutable, null out its
writable_elements member.
(scm_array_get_handle): Adapt to determine mutability of the various
arrays.
(scm_array_handle_elements, scm_array_handle_writable_elements):
Reverse the sense: instead of implementing read-only in terms of
read-write, go the other way around, adding an assertion in the
read-write case that the array handle is mutable.
* libguile/array-map.c (racp): Assert that the destination is mutable.
* libguile/bitvectors.c (SCM_F_BITVECTOR_IMMUTABLE, IS_BITVECTOR):
(IS_MUTABLE_BITVECTOR): Add a flag to indicate immutability.
(scm_i_bitvector_bits): Fix indentation.
(scm_i_is_mutable_bitvector): New helper.
(scm_array_handle_bit_elements)
((scm_array_handle_bit_writable_elements): Build writable_elements in
terms of elements.
(scm_bitvector_elements, scm_bitvector_writable_elements): Likewise.
(scm_c_bitvector_set_x): Require a mutable bitvector for the
fast-path.
(scm_bitvector_to_list, scm_bit_count): Use read-only elements()
function.
* libguile/bitvectors.h (scm_i_is_mutable_bitvector): New decl.
* libguile/bytevectors.c (INTEGER_ACCESSOR_PROLOGUE):
(INTEGER_GETTER_PROLOGUE, INTEGER_SETTER_PROLOGUE):
(INTEGER_REF, INTEGER_NATIVE_REF, INTEGER_SET, INTEGER_NATIVE_SET):
(GENERIC_INTEGER_ACCESSOR_PROLOGUE):
(GENERIC_INTEGER_GETTER_PROLOGUE, GENERIC_INTEGER_SETTER_PROLOGUE):
(LARGE_INTEGER_NATIVE_REF, LARGE_INTEGER_NATIVE_SET):
(IEEE754_GETTER_PROLOGUE, IEEE754_SETTER_PROLOGUE):
(IEEE754_REF, IEEE754_NATIVE_REF, IEEE754_SET, IEEE754_NATIVE_SET):
Setters require a mutable bytevector.
(SCM_BYTEVECTOR_SET_FLAG): New helper.
(SCM_BYTEVECTOR_SET_CONTIGUOUS_P, SCM_BYTEVECTOR_SET_ELEMENT_TYPE):
Remove helpers.
(SCM_VALIDATE_MUTABLE_BYTEVECTOR): New helper.
(make_bytevector, make_bytevector_from_buffer): Use
SCM_SET_BYTEVECTOR_FLAGS.
(scm_c_bytevector_set_x, scm_bytevector_fill_x)
(scm_bytevector_copy_x): Require a mutable bytevector.
* libguile/bytevectors.h (SCM_F_BYTEVECTOR_CONTIGUOUS)
(SCM_F_BYTEVECTOR_IMMUTABLE, SCM_MUTABLE_BYTEVECTOR_P): New
definitions.
* libguile/bytevectors.h (SCM_BYTEVECTOR_CONTIGUOUS_P): Just access one
bit.
* libguile/srfi-4.c (DEFINE_SRFI_4_C_FUNCS): Implement
writable_elements() in terms of elements().
* libguile/strings.c (scm_i_string_is_mutable): New helper.
* libguile/uniform.c (scm_array_handle_uniform_elements):
(scm_array_handle_uniform_writable_elements): Implement
writable_elements in terms of elements.
* libguile/vectors.c (SCM_VALIDATE_MUTABLE_VECTOR): New helper.
(scm_vector_elements, scm_vector_writable_elements): Implement
writable_elements in terms of elements.
(scm_c_vector_set_x): Require a mutable vector.
* libguile/vectors.h (SCM_F_VECTOR_IMMUTABLE, SCM_I_IS_MUTABLE_VECTOR):
New definitions.
* libguile/vm-engine.c (VM_VALIDATE_MUTABLE_BYTEVECTOR):
(VM_VALIDATE_MUTABLE_VECTOR, vector-set!, vector-set!/immediate)
(BV_BOUNDED_SET, BV_SET): Require mutable bytevector/vector.
* libguile/vm.c (vm_error_not_a_mutable_bytevector):
(vm_error_not_a_mutable_vector): New definitions.
* module/system/vm/assembler.scm (link-data): Mark residualized vectors,
bytevectors, and bitvectors as being read-only.
2017-04-18 14:56:48 +02:00
|
|
|
|
SCM_SET_BYTEVECTOR_FLAGS (ret,
|
|
|
|
|
|
element_type | SCM_F_BYTEVECTOR_CONTIGUOUS);
|
2009-08-31 01:07:30 +02:00
|
|
|
|
SCM_BYTEVECTOR_SET_LENGTH (ret, c_len);
|
2009-11-15 19:34:38 +01:00
|
|
|
|
SCM_BYTEVECTOR_SET_CONTENTS (ret, contents);
|
2011-05-07 14:57:15 +02:00
|
|
|
|
SCM_BYTEVECTOR_SET_PARENT (ret, SCM_BOOL_F);
|
2009-07-18 13:46:29 +02:00
|
|
|
|
}
|
2009-08-31 01:07:30 +02:00
|
|
|
|
|
2009-07-18 13:46:29 +02:00
|
|
|
|
return ret;
|
2009-05-27 18:18:07 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
2009-08-31 01:07:30 +02:00
|
|
|
|
/* Return a bytevector of LEN elements of type ELEMENT_TYPE, with element
|
2009-11-15 19:34:38 +01:00
|
|
|
|
values taken from CONTENTS. Assume that the storage for CONTENTS will be
|
|
|
|
|
|
automatically reclaimed when it becomes unreachable. */
|
2009-05-27 18:18:07 +02:00
|
|
|
|
static inline SCM
|
2009-08-31 01:07:30 +02:00
|
|
|
|
make_bytevector_from_buffer (size_t len, void *contents,
|
|
|
|
|
|
scm_t_array_element_type element_type)
|
2009-05-27 18:18:07 +02:00
|
|
|
|
{
|
2009-08-31 01:07:30 +02:00
|
|
|
|
SCM ret;
|
2009-05-27 18:18:07 +02:00
|
|
|
|
|
2009-11-15 19:34:38 +01:00
|
|
|
|
if (SCM_UNLIKELY (len == 0))
|
|
|
|
|
|
ret = make_bytevector (len, element_type);
|
|
|
|
|
|
else
|
2009-05-27 18:18:07 +02:00
|
|
|
|
{
|
2009-08-31 01:07:30 +02:00
|
|
|
|
size_t c_len;
|
|
|
|
|
|
|
2011-10-24 17:58:22 +02:00
|
|
|
|
ret = SCM_PACK_POINTER (scm_gc_malloc (SCM_BYTEVECTOR_HEADER_BYTES,
|
2009-11-15 19:34:38 +01:00
|
|
|
|
SCM_GC_BYTEVECTOR));
|
|
|
|
|
|
|
2009-08-31 01:07:30 +02:00
|
|
|
|
c_len = len * (scm_i_array_element_type_sizes[element_type] / 8);
|
|
|
|
|
|
|
All literal constants are read-only
* libguile/array-handle.c (initialize_vector_handle): Add mutable_p
argument. Unless the vector handle is mutable, null out its
writable_elements member.
(scm_array_get_handle): Adapt to determine mutability of the various
arrays.
(scm_array_handle_elements, scm_array_handle_writable_elements):
Reverse the sense: instead of implementing read-only in terms of
read-write, go the other way around, adding an assertion in the
read-write case that the array handle is mutable.
* libguile/array-map.c (racp): Assert that the destination is mutable.
* libguile/bitvectors.c (SCM_F_BITVECTOR_IMMUTABLE, IS_BITVECTOR):
(IS_MUTABLE_BITVECTOR): Add a flag to indicate immutability.
(scm_i_bitvector_bits): Fix indentation.
(scm_i_is_mutable_bitvector): New helper.
(scm_array_handle_bit_elements)
((scm_array_handle_bit_writable_elements): Build writable_elements in
terms of elements.
(scm_bitvector_elements, scm_bitvector_writable_elements): Likewise.
(scm_c_bitvector_set_x): Require a mutable bitvector for the
fast-path.
(scm_bitvector_to_list, scm_bit_count): Use read-only elements()
function.
* libguile/bitvectors.h (scm_i_is_mutable_bitvector): New decl.
* libguile/bytevectors.c (INTEGER_ACCESSOR_PROLOGUE):
(INTEGER_GETTER_PROLOGUE, INTEGER_SETTER_PROLOGUE):
(INTEGER_REF, INTEGER_NATIVE_REF, INTEGER_SET, INTEGER_NATIVE_SET):
(GENERIC_INTEGER_ACCESSOR_PROLOGUE):
(GENERIC_INTEGER_GETTER_PROLOGUE, GENERIC_INTEGER_SETTER_PROLOGUE):
(LARGE_INTEGER_NATIVE_REF, LARGE_INTEGER_NATIVE_SET):
(IEEE754_GETTER_PROLOGUE, IEEE754_SETTER_PROLOGUE):
(IEEE754_REF, IEEE754_NATIVE_REF, IEEE754_SET, IEEE754_NATIVE_SET):
Setters require a mutable bytevector.
(SCM_BYTEVECTOR_SET_FLAG): New helper.
(SCM_BYTEVECTOR_SET_CONTIGUOUS_P, SCM_BYTEVECTOR_SET_ELEMENT_TYPE):
Remove helpers.
(SCM_VALIDATE_MUTABLE_BYTEVECTOR): New helper.
(make_bytevector, make_bytevector_from_buffer): Use
SCM_SET_BYTEVECTOR_FLAGS.
(scm_c_bytevector_set_x, scm_bytevector_fill_x)
(scm_bytevector_copy_x): Require a mutable bytevector.
* libguile/bytevectors.h (SCM_F_BYTEVECTOR_CONTIGUOUS)
(SCM_F_BYTEVECTOR_IMMUTABLE, SCM_MUTABLE_BYTEVECTOR_P): New
definitions.
* libguile/bytevectors.h (SCM_BYTEVECTOR_CONTIGUOUS_P): Just access one
bit.
* libguile/srfi-4.c (DEFINE_SRFI_4_C_FUNCS): Implement
writable_elements() in terms of elements().
* libguile/strings.c (scm_i_string_is_mutable): New helper.
* libguile/uniform.c (scm_array_handle_uniform_elements):
(scm_array_handle_uniform_writable_elements): Implement
writable_elements in terms of elements.
* libguile/vectors.c (SCM_VALIDATE_MUTABLE_VECTOR): New helper.
(scm_vector_elements, scm_vector_writable_elements): Implement
writable_elements in terms of elements.
(scm_c_vector_set_x): Require a mutable vector.
* libguile/vectors.h (SCM_F_VECTOR_IMMUTABLE, SCM_I_IS_MUTABLE_VECTOR):
New definitions.
* libguile/vm-engine.c (VM_VALIDATE_MUTABLE_BYTEVECTOR):
(VM_VALIDATE_MUTABLE_VECTOR, vector-set!, vector-set!/immediate)
(BV_BOUNDED_SET, BV_SET): Require mutable bytevector/vector.
* libguile/vm.c (vm_error_not_a_mutable_bytevector):
(vm_error_not_a_mutable_vector): New definitions.
* module/system/vm/assembler.scm (link-data): Mark residualized vectors,
bytevectors, and bitvectors as being read-only.
2017-04-18 14:56:48 +02:00
|
|
|
|
SCM_SET_BYTEVECTOR_FLAGS (ret, element_type);
|
2009-11-15 19:34:38 +01:00
|
|
|
|
SCM_BYTEVECTOR_SET_LENGTH (ret, c_len);
|
|
|
|
|
|
SCM_BYTEVECTOR_SET_CONTENTS (ret, contents);
|
2011-05-07 14:57:15 +02:00
|
|
|
|
SCM_BYTEVECTOR_SET_PARENT (ret, SCM_BOOL_F);
|
2009-05-27 18:18:07 +02:00
|
|
|
|
}
|
2009-08-31 01:07:30 +02:00
|
|
|
|
|
|
|
|
|
|
return ret;
|
2009-05-27 18:18:07 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
2009-08-31 01:07:30 +02:00
|
|
|
|
|
2009-05-27 18:18:07 +02:00
|
|
|
|
/* Return a new bytevector of size LEN octets. */
|
|
|
|
|
|
SCM
|
2009-06-21 16:55:58 +02:00
|
|
|
|
scm_c_make_bytevector (size_t len)
|
2009-05-27 18:18:07 +02:00
|
|
|
|
{
|
bytevectors have "element type" field, e.g. for generalized-vector-ref
Bytevectors have a very close relationship to other forms of uniform
vectors. Often you want to view a u64vector as a series of bytes, for
writing over a socket; or to process an incoming stream using the
convenient and less error-prone s16vector-ref API rather than
bytevector-s16-native-ref.
The essential needs of the representation of a bytevector and an
s64vector are the same, so we take advantage of that and extend the
bytevector implementation to have a "native type" field, which defaults
to VU8.
This commit doesn't actually expose any user-noticeable changes,
however.
* libguile/bytevectors.h (SCM_BYTEVECTOR_ELEMENT_TYPE): New internal
defines.
(scm_i_make_typed_bytevector, scm_c_take_typed_bytevector): New
internal functions.
* libguile/bytevectors.c (SCM_BYTEVECTOR_SET_ELEMENT_TYPE):
(SCM_BYTEVECTOR_TYPE_SIZE):
(SCM_BYTEVECTOR_TYPED_LENGTH): New internal macros.
(make_bytevector, make_bytevector_from_buffer): Take an extra
argument, the element type. The length argument is interpreted as
being the number of elements, which corresponds to the number of bytes
in the default VU8 case. Doing it this way eliminates a class of bugs
-- e.g. a u32vector of length 3 bytes doesn't make sense. We do have
to check for another class of bugs: overflow. The length stored on the
bytevector itself is still the byte length, though.
(scm_i_make_typed_bytevector):
(scm_c_take_typed_bytevector): New internal functions.
(scm_i_shrink_bytevector): Make sure the new size is valid for the
bytevector's type.
(scm_i_bytevector_generalized_set_x): Remove this function, the
array-handle infrastructure takes care of this for us.
(print_bytevector): Print the bytevector according to its type.
(scm_make_bytevector, scm_bytevector_copy)
(scm_uniform_array_to_bytevector)
(scm_u8_list_to_bytevector, scm_bytevector_to_uint_list): Adapt to
make_bytevector extra arg.
(bv_handle_ref, bv_handle_set_x): Adapt to ref and set based on the
type of the bytevector, e.g. f64 or u8.
(bytevector_get_handle): Set the typed length of the vector, not the
byte length.
Conflicts:
libguile/bytevectors.c
2009-07-19 15:11:53 +02:00
|
|
|
|
return make_bytevector (len, SCM_ARRAY_ELEMENT_TYPE_VU8);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2010-01-05 17:25:53 +01:00
|
|
|
|
/* Return a new bytevector of size LEN elements. */
|
|
|
|
|
|
SCM
|
|
|
|
|
|
scm_i_make_typed_bytevector (size_t len, scm_t_array_element_type element_type)
|
|
|
|
|
|
{
|
|
|
|
|
|
return make_bytevector (len, element_type);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2011-05-07 14:57:15 +02:00
|
|
|
|
/* Return a bytevector of size LEN made up of CONTENTS. The area
|
|
|
|
|
|
pointed to by CONTENTS must be protected from GC somehow: either
|
|
|
|
|
|
because it was allocated using `scm_gc_malloc ()', or because it is
|
|
|
|
|
|
part of PARENT. */
|
2009-05-27 18:18:07 +02:00
|
|
|
|
SCM
|
2011-08-31 09:34:54 +02:00
|
|
|
|
scm_c_take_gc_bytevector (signed char *contents, size_t len, SCM parent)
|
2009-05-27 18:18:07 +02:00
|
|
|
|
{
|
2011-05-07 14:57:15 +02:00
|
|
|
|
SCM ret;
|
|
|
|
|
|
|
|
|
|
|
|
ret = make_bytevector_from_buffer (len, contents, SCM_ARRAY_ELEMENT_TYPE_VU8);
|
|
|
|
|
|
SCM_BYTEVECTOR_SET_PARENT (ret, parent);
|
|
|
|
|
|
|
|
|
|
|
|
return ret;
|
bytevectors have "element type" field, e.g. for generalized-vector-ref
Bytevectors have a very close relationship to other forms of uniform
vectors. Often you want to view a u64vector as a series of bytes, for
writing over a socket; or to process an incoming stream using the
convenient and less error-prone s16vector-ref API rather than
bytevector-s16-native-ref.
The essential needs of the representation of a bytevector and an
s64vector are the same, so we take advantage of that and extend the
bytevector implementation to have a "native type" field, which defaults
to VU8.
This commit doesn't actually expose any user-noticeable changes,
however.
* libguile/bytevectors.h (SCM_BYTEVECTOR_ELEMENT_TYPE): New internal
defines.
(scm_i_make_typed_bytevector, scm_c_take_typed_bytevector): New
internal functions.
* libguile/bytevectors.c (SCM_BYTEVECTOR_SET_ELEMENT_TYPE):
(SCM_BYTEVECTOR_TYPE_SIZE):
(SCM_BYTEVECTOR_TYPED_LENGTH): New internal macros.
(make_bytevector, make_bytevector_from_buffer): Take an extra
argument, the element type. The length argument is interpreted as
being the number of elements, which corresponds to the number of bytes
in the default VU8 case. Doing it this way eliminates a class of bugs
-- e.g. a u32vector of length 3 bytes doesn't make sense. We do have
to check for another class of bugs: overflow. The length stored on the
bytevector itself is still the byte length, though.
(scm_i_make_typed_bytevector):
(scm_c_take_typed_bytevector): New internal functions.
(scm_i_shrink_bytevector): Make sure the new size is valid for the
bytevector's type.
(scm_i_bytevector_generalized_set_x): Remove this function, the
array-handle infrastructure takes care of this for us.
(print_bytevector): Print the bytevector according to its type.
(scm_make_bytevector, scm_bytevector_copy)
(scm_uniform_array_to_bytevector)
(scm_u8_list_to_bytevector, scm_bytevector_to_uint_list): Adapt to
make_bytevector extra arg.
(bv_handle_ref, bv_handle_set_x): Adapt to ref and set based on the
type of the bytevector, e.g. f64 or u8.
(bytevector_get_handle): Set the typed length of the vector, not the
byte length.
Conflicts:
libguile/bytevectors.c
2009-07-19 15:11:53 +02:00
|
|
|
|
}
|
2009-05-27 18:18:07 +02:00
|
|
|
|
|
2010-01-05 17:25:53 +01:00
|
|
|
|
SCM
|
|
|
|
|
|
scm_c_take_typed_bytevector (signed char *contents, size_t len,
|
2011-05-07 14:57:15 +02:00
|
|
|
|
scm_t_array_element_type element_type, SCM parent)
|
2010-01-05 17:25:53 +01:00
|
|
|
|
{
|
2011-05-07 14:57:15 +02:00
|
|
|
|
SCM ret;
|
|
|
|
|
|
|
|
|
|
|
|
ret = make_bytevector_from_buffer (len, contents, element_type);
|
|
|
|
|
|
SCM_BYTEVECTOR_SET_PARENT (ret, parent);
|
|
|
|
|
|
|
|
|
|
|
|
return ret;
|
2010-01-05 17:25:53 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
2009-05-27 18:18:07 +02:00
|
|
|
|
/* Shrink BV to C_NEW_LEN (which is assumed to be smaller than its current
|
2009-08-31 01:07:30 +02:00
|
|
|
|
size) and return the new bytevector (possibly different from BV). */
|
2009-05-27 18:18:07 +02:00
|
|
|
|
SCM
|
2009-08-31 01:07:30 +02:00
|
|
|
|
scm_c_shrink_bytevector (SCM bv, size_t c_new_len)
|
2009-05-27 18:18:07 +02:00
|
|
|
|
{
|
2009-08-31 01:07:30 +02:00
|
|
|
|
SCM new_bv;
|
|
|
|
|
|
size_t c_len;
|
|
|
|
|
|
|
bytevectors have "element type" field, e.g. for generalized-vector-ref
Bytevectors have a very close relationship to other forms of uniform
vectors. Often you want to view a u64vector as a series of bytes, for
writing over a socket; or to process an incoming stream using the
convenient and less error-prone s16vector-ref API rather than
bytevector-s16-native-ref.
The essential needs of the representation of a bytevector and an
s64vector are the same, so we take advantage of that and extend the
bytevector implementation to have a "native type" field, which defaults
to VU8.
This commit doesn't actually expose any user-noticeable changes,
however.
* libguile/bytevectors.h (SCM_BYTEVECTOR_ELEMENT_TYPE): New internal
defines.
(scm_i_make_typed_bytevector, scm_c_take_typed_bytevector): New
internal functions.
* libguile/bytevectors.c (SCM_BYTEVECTOR_SET_ELEMENT_TYPE):
(SCM_BYTEVECTOR_TYPE_SIZE):
(SCM_BYTEVECTOR_TYPED_LENGTH): New internal macros.
(make_bytevector, make_bytevector_from_buffer): Take an extra
argument, the element type. The length argument is interpreted as
being the number of elements, which corresponds to the number of bytes
in the default VU8 case. Doing it this way eliminates a class of bugs
-- e.g. a u32vector of length 3 bytes doesn't make sense. We do have
to check for another class of bugs: overflow. The length stored on the
bytevector itself is still the byte length, though.
(scm_i_make_typed_bytevector):
(scm_c_take_typed_bytevector): New internal functions.
(scm_i_shrink_bytevector): Make sure the new size is valid for the
bytevector's type.
(scm_i_bytevector_generalized_set_x): Remove this function, the
array-handle infrastructure takes care of this for us.
(print_bytevector): Print the bytevector according to its type.
(scm_make_bytevector, scm_bytevector_copy)
(scm_uniform_array_to_bytevector)
(scm_u8_list_to_bytevector, scm_bytevector_to_uint_list): Adapt to
make_bytevector extra arg.
(bv_handle_ref, bv_handle_set_x): Adapt to ref and set based on the
type of the bytevector, e.g. f64 or u8.
(bytevector_get_handle): Set the typed length of the vector, not the
byte length.
Conflicts:
libguile/bytevectors.c
2009-07-19 15:11:53 +02:00
|
|
|
|
if (SCM_UNLIKELY (c_new_len % SCM_BYTEVECTOR_TYPE_SIZE (bv)))
|
|
|
|
|
|
/* This would be an internal Guile programming error */
|
|
|
|
|
|
abort ();
|
|
|
|
|
|
|
2009-08-31 01:07:30 +02:00
|
|
|
|
c_len = SCM_BYTEVECTOR_LENGTH (bv);
|
|
|
|
|
|
if (SCM_UNLIKELY (c_new_len > c_len))
|
|
|
|
|
|
abort ();
|
2009-05-27 18:18:07 +02:00
|
|
|
|
|
2009-08-31 01:07:30 +02:00
|
|
|
|
SCM_BYTEVECTOR_SET_LENGTH (bv, c_new_len);
|
2009-05-27 18:18:07 +02:00
|
|
|
|
|
2009-11-15 19:34:38 +01:00
|
|
|
|
if (SCM_BYTEVECTOR_CONTIGUOUS_P (bv))
|
2014-05-28 19:26:45 +02:00
|
|
|
|
{
|
|
|
|
|
|
signed char *c_bv;
|
|
|
|
|
|
|
|
|
|
|
|
c_bv = scm_gc_realloc (SCM2PTR (bv),
|
|
|
|
|
|
c_len + SCM_BYTEVECTOR_HEADER_BYTES,
|
|
|
|
|
|
c_new_len + SCM_BYTEVECTOR_HEADER_BYTES,
|
|
|
|
|
|
SCM_GC_BYTEVECTOR);
|
|
|
|
|
|
new_bv = PTR2SCM (c_bv);
|
|
|
|
|
|
SCM_BYTEVECTOR_SET_CONTENTS (new_bv, c_bv + SCM_BYTEVECTOR_HEADER_BYTES);
|
|
|
|
|
|
}
|
2009-11-15 19:34:38 +01:00
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
signed char *c_bv;
|
|
|
|
|
|
|
|
|
|
|
|
c_bv = scm_gc_realloc (SCM_BYTEVECTOR_CONTENTS (bv),
|
|
|
|
|
|
c_len, c_new_len, SCM_GC_BYTEVECTOR);
|
|
|
|
|
|
SCM_BYTEVECTOR_SET_CONTENTS (bv, c_bv);
|
|
|
|
|
|
|
|
|
|
|
|
new_bv = bv;
|
|
|
|
|
|
}
|
2009-05-27 18:18:07 +02:00
|
|
|
|
|
2009-08-31 01:07:30 +02:00
|
|
|
|
return new_bv;
|
2009-05-27 18:18:07 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
2009-06-21 23:16:57 +02:00
|
|
|
|
int
|
|
|
|
|
|
scm_is_bytevector (SCM obj)
|
|
|
|
|
|
{
|
Use a TC7 tag instead of a SMOB for bytevectors.
* libguile/bytevectors.c (scm_tc16_bytevector): Remove.
(SCM_BYTEVECTOR_SET_LENGTH, SCM_BYTEVECTOR_SET_CONTENTS,
SCM_BYTEVECTOR_SET_INLINE, SCM_BYTEVECTOR_SET_ELEMENT_TYPE,
make_bytevector_from_buffer, scm_is_bytevector,
scm_bootstrap_bytevectors): Adjust to the SMOB->tc7 change.
(scm_i_print_bytevector): New, formerly `print_bytevector ()'.
(bytevector_equal_p): Remove.
* libguile/bytevectors.h (SCM_BYTEVECTOR_LENGTH,
SCM_BYTEVECTOR_CONTENTS, SCM_BYTEVECTOR_P): Adjust to SMOB->tc7
change.
(SCM_BYTEVECTOR_FLAGS, SCM_SET_BYTEVECTOR_FLAGS): New macros.
(scm_tc16_bytevector): Remove declaration.
(scm_i_print_bytevector): New declaration.
* libguile/eq.c (scm_equal_p): Handle `scm_tc7_bytevector'.
* libguile/evalext.c (scm_self_evaluating_p): Likewise.
* libguile/print.c (iprin1): Likewise.
* libguile/tags.h (scm_tc7_bytevector): New.
(scm_tc7_unused_8): Remove.
* libguile/validate.h (SCM_VALIDATE_BYTEVECTOR): Adjust.
* test-suite/tests/bytevectors.test ("Datum
Syntax")["self-evaluating?"]: New test.
2009-08-30 20:12:09 +02:00
|
|
|
|
return SCM_BYTEVECTOR_P (obj);
|
2009-06-21 23:16:57 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
size_t
|
|
|
|
|
|
scm_c_bytevector_length (SCM bv)
|
|
|
|
|
|
#define FUNC_NAME "scm_c_bytevector_length"
|
|
|
|
|
|
{
|
|
|
|
|
|
SCM_VALIDATE_BYTEVECTOR (1, bv);
|
|
|
|
|
|
|
|
|
|
|
|
return SCM_BYTEVECTOR_LENGTH (bv);
|
|
|
|
|
|
}
|
|
|
|
|
|
#undef FUNC_NAME
|
|
|
|
|
|
|
|
|
|
|
|
scm_t_uint8
|
|
|
|
|
|
scm_c_bytevector_ref (SCM bv, size_t index)
|
|
|
|
|
|
#define FUNC_NAME "scm_c_bytevector_ref"
|
|
|
|
|
|
{
|
|
|
|
|
|
size_t c_len;
|
|
|
|
|
|
const scm_t_uint8 *c_bv;
|
|
|
|
|
|
|
|
|
|
|
|
SCM_VALIDATE_BYTEVECTOR (1, bv);
|
|
|
|
|
|
|
|
|
|
|
|
c_len = SCM_BYTEVECTOR_LENGTH (bv);
|
|
|
|
|
|
c_bv = (scm_t_uint8 *) SCM_BYTEVECTOR_CONTENTS (bv);
|
|
|
|
|
|
|
|
|
|
|
|
if (SCM_UNLIKELY (index >= c_len))
|
|
|
|
|
|
scm_out_of_range (FUNC_NAME, scm_from_size_t (index));
|
|
|
|
|
|
|
|
|
|
|
|
return c_bv[index];
|
|
|
|
|
|
}
|
|
|
|
|
|
#undef FUNC_NAME
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
|
scm_c_bytevector_set_x (SCM bv, size_t index, scm_t_uint8 value)
|
|
|
|
|
|
#define FUNC_NAME "scm_c_bytevector_set_x"
|
|
|
|
|
|
{
|
|
|
|
|
|
size_t c_len;
|
|
|
|
|
|
scm_t_uint8 *c_bv;
|
|
|
|
|
|
|
All literal constants are read-only
* libguile/array-handle.c (initialize_vector_handle): Add mutable_p
argument. Unless the vector handle is mutable, null out its
writable_elements member.
(scm_array_get_handle): Adapt to determine mutability of the various
arrays.
(scm_array_handle_elements, scm_array_handle_writable_elements):
Reverse the sense: instead of implementing read-only in terms of
read-write, go the other way around, adding an assertion in the
read-write case that the array handle is mutable.
* libguile/array-map.c (racp): Assert that the destination is mutable.
* libguile/bitvectors.c (SCM_F_BITVECTOR_IMMUTABLE, IS_BITVECTOR):
(IS_MUTABLE_BITVECTOR): Add a flag to indicate immutability.
(scm_i_bitvector_bits): Fix indentation.
(scm_i_is_mutable_bitvector): New helper.
(scm_array_handle_bit_elements)
((scm_array_handle_bit_writable_elements): Build writable_elements in
terms of elements.
(scm_bitvector_elements, scm_bitvector_writable_elements): Likewise.
(scm_c_bitvector_set_x): Require a mutable bitvector for the
fast-path.
(scm_bitvector_to_list, scm_bit_count): Use read-only elements()
function.
* libguile/bitvectors.h (scm_i_is_mutable_bitvector): New decl.
* libguile/bytevectors.c (INTEGER_ACCESSOR_PROLOGUE):
(INTEGER_GETTER_PROLOGUE, INTEGER_SETTER_PROLOGUE):
(INTEGER_REF, INTEGER_NATIVE_REF, INTEGER_SET, INTEGER_NATIVE_SET):
(GENERIC_INTEGER_ACCESSOR_PROLOGUE):
(GENERIC_INTEGER_GETTER_PROLOGUE, GENERIC_INTEGER_SETTER_PROLOGUE):
(LARGE_INTEGER_NATIVE_REF, LARGE_INTEGER_NATIVE_SET):
(IEEE754_GETTER_PROLOGUE, IEEE754_SETTER_PROLOGUE):
(IEEE754_REF, IEEE754_NATIVE_REF, IEEE754_SET, IEEE754_NATIVE_SET):
Setters require a mutable bytevector.
(SCM_BYTEVECTOR_SET_FLAG): New helper.
(SCM_BYTEVECTOR_SET_CONTIGUOUS_P, SCM_BYTEVECTOR_SET_ELEMENT_TYPE):
Remove helpers.
(SCM_VALIDATE_MUTABLE_BYTEVECTOR): New helper.
(make_bytevector, make_bytevector_from_buffer): Use
SCM_SET_BYTEVECTOR_FLAGS.
(scm_c_bytevector_set_x, scm_bytevector_fill_x)
(scm_bytevector_copy_x): Require a mutable bytevector.
* libguile/bytevectors.h (SCM_F_BYTEVECTOR_CONTIGUOUS)
(SCM_F_BYTEVECTOR_IMMUTABLE, SCM_MUTABLE_BYTEVECTOR_P): New
definitions.
* libguile/bytevectors.h (SCM_BYTEVECTOR_CONTIGUOUS_P): Just access one
bit.
* libguile/srfi-4.c (DEFINE_SRFI_4_C_FUNCS): Implement
writable_elements() in terms of elements().
* libguile/strings.c (scm_i_string_is_mutable): New helper.
* libguile/uniform.c (scm_array_handle_uniform_elements):
(scm_array_handle_uniform_writable_elements): Implement
writable_elements in terms of elements.
* libguile/vectors.c (SCM_VALIDATE_MUTABLE_VECTOR): New helper.
(scm_vector_elements, scm_vector_writable_elements): Implement
writable_elements in terms of elements.
(scm_c_vector_set_x): Require a mutable vector.
* libguile/vectors.h (SCM_F_VECTOR_IMMUTABLE, SCM_I_IS_MUTABLE_VECTOR):
New definitions.
* libguile/vm-engine.c (VM_VALIDATE_MUTABLE_BYTEVECTOR):
(VM_VALIDATE_MUTABLE_VECTOR, vector-set!, vector-set!/immediate)
(BV_BOUNDED_SET, BV_SET): Require mutable bytevector/vector.
* libguile/vm.c (vm_error_not_a_mutable_bytevector):
(vm_error_not_a_mutable_vector): New definitions.
* module/system/vm/assembler.scm (link-data): Mark residualized vectors,
bytevectors, and bitvectors as being read-only.
2017-04-18 14:56:48 +02:00
|
|
|
|
SCM_VALIDATE_MUTABLE_BYTEVECTOR (1, bv);
|
2009-06-21 23:16:57 +02:00
|
|
|
|
|
|
|
|
|
|
c_len = SCM_BYTEVECTOR_LENGTH (bv);
|
|
|
|
|
|
c_bv = (scm_t_uint8 *) SCM_BYTEVECTOR_CONTENTS (bv);
|
|
|
|
|
|
|
|
|
|
|
|
if (SCM_UNLIKELY (index >= c_len))
|
|
|
|
|
|
scm_out_of_range (FUNC_NAME, scm_from_size_t (index));
|
|
|
|
|
|
|
|
|
|
|
|
c_bv[index] = value;
|
|
|
|
|
|
}
|
|
|
|
|
|
#undef FUNC_NAME
|
|
|
|
|
|
|
bytevectors have "element type" field, e.g. for generalized-vector-ref
Bytevectors have a very close relationship to other forms of uniform
vectors. Often you want to view a u64vector as a series of bytes, for
writing over a socket; or to process an incoming stream using the
convenient and less error-prone s16vector-ref API rather than
bytevector-s16-native-ref.
The essential needs of the representation of a bytevector and an
s64vector are the same, so we take advantage of that and extend the
bytevector implementation to have a "native type" field, which defaults
to VU8.
This commit doesn't actually expose any user-noticeable changes,
however.
* libguile/bytevectors.h (SCM_BYTEVECTOR_ELEMENT_TYPE): New internal
defines.
(scm_i_make_typed_bytevector, scm_c_take_typed_bytevector): New
internal functions.
* libguile/bytevectors.c (SCM_BYTEVECTOR_SET_ELEMENT_TYPE):
(SCM_BYTEVECTOR_TYPE_SIZE):
(SCM_BYTEVECTOR_TYPED_LENGTH): New internal macros.
(make_bytevector, make_bytevector_from_buffer): Take an extra
argument, the element type. The length argument is interpreted as
being the number of elements, which corresponds to the number of bytes
in the default VU8 case. Doing it this way eliminates a class of bugs
-- e.g. a u32vector of length 3 bytes doesn't make sense. We do have
to check for another class of bugs: overflow. The length stored on the
bytevector itself is still the byte length, though.
(scm_i_make_typed_bytevector):
(scm_c_take_typed_bytevector): New internal functions.
(scm_i_shrink_bytevector): Make sure the new size is valid for the
bytevector's type.
(scm_i_bytevector_generalized_set_x): Remove this function, the
array-handle infrastructure takes care of this for us.
(print_bytevector): Print the bytevector according to its type.
(scm_make_bytevector, scm_bytevector_copy)
(scm_uniform_array_to_bytevector)
(scm_u8_list_to_bytevector, scm_bytevector_to_uint_list): Adapt to
make_bytevector extra arg.
(bv_handle_ref, bv_handle_set_x): Adapt to ref and set based on the
type of the bytevector, e.g. f64 or u8.
(bytevector_get_handle): Set the typed length of the vector, not the
byte length.
Conflicts:
libguile/bytevectors.c
2009-07-19 15:11:53 +02:00
|
|
|
|
|
|
|
|
|
|
|
Use a TC7 tag instead of a SMOB for bytevectors.
* libguile/bytevectors.c (scm_tc16_bytevector): Remove.
(SCM_BYTEVECTOR_SET_LENGTH, SCM_BYTEVECTOR_SET_CONTENTS,
SCM_BYTEVECTOR_SET_INLINE, SCM_BYTEVECTOR_SET_ELEMENT_TYPE,
make_bytevector_from_buffer, scm_is_bytevector,
scm_bootstrap_bytevectors): Adjust to the SMOB->tc7 change.
(scm_i_print_bytevector): New, formerly `print_bytevector ()'.
(bytevector_equal_p): Remove.
* libguile/bytevectors.h (SCM_BYTEVECTOR_LENGTH,
SCM_BYTEVECTOR_CONTENTS, SCM_BYTEVECTOR_P): Adjust to SMOB->tc7
change.
(SCM_BYTEVECTOR_FLAGS, SCM_SET_BYTEVECTOR_FLAGS): New macros.
(scm_tc16_bytevector): Remove declaration.
(scm_i_print_bytevector): New declaration.
* libguile/eq.c (scm_equal_p): Handle `scm_tc7_bytevector'.
* libguile/evalext.c (scm_self_evaluating_p): Likewise.
* libguile/print.c (iprin1): Likewise.
* libguile/tags.h (scm_tc7_bytevector): New.
(scm_tc7_unused_8): Remove.
* libguile/validate.h (SCM_VALIDATE_BYTEVECTOR): Adjust.
* test-suite/tests/bytevectors.test ("Datum
Syntax")["self-evaluating?"]: New test.
2009-08-30 20:12:09 +02:00
|
|
|
|
int
|
|
|
|
|
|
scm_i_print_bytevector (SCM bv, SCM port, scm_print_state *pstate SCM_UNUSED)
|
2009-05-27 18:18:07 +02:00
|
|
|
|
{
|
bytevectors have "element type" field, e.g. for generalized-vector-ref
Bytevectors have a very close relationship to other forms of uniform
vectors. Often you want to view a u64vector as a series of bytes, for
writing over a socket; or to process an incoming stream using the
convenient and less error-prone s16vector-ref API rather than
bytevector-s16-native-ref.
The essential needs of the representation of a bytevector and an
s64vector are the same, so we take advantage of that and extend the
bytevector implementation to have a "native type" field, which defaults
to VU8.
This commit doesn't actually expose any user-noticeable changes,
however.
* libguile/bytevectors.h (SCM_BYTEVECTOR_ELEMENT_TYPE): New internal
defines.
(scm_i_make_typed_bytevector, scm_c_take_typed_bytevector): New
internal functions.
* libguile/bytevectors.c (SCM_BYTEVECTOR_SET_ELEMENT_TYPE):
(SCM_BYTEVECTOR_TYPE_SIZE):
(SCM_BYTEVECTOR_TYPED_LENGTH): New internal macros.
(make_bytevector, make_bytevector_from_buffer): Take an extra
argument, the element type. The length argument is interpreted as
being the number of elements, which corresponds to the number of bytes
in the default VU8 case. Doing it this way eliminates a class of bugs
-- e.g. a u32vector of length 3 bytes doesn't make sense. We do have
to check for another class of bugs: overflow. The length stored on the
bytevector itself is still the byte length, though.
(scm_i_make_typed_bytevector):
(scm_c_take_typed_bytevector): New internal functions.
(scm_i_shrink_bytevector): Make sure the new size is valid for the
bytevector's type.
(scm_i_bytevector_generalized_set_x): Remove this function, the
array-handle infrastructure takes care of this for us.
(print_bytevector): Print the bytevector according to its type.
(scm_make_bytevector, scm_bytevector_copy)
(scm_uniform_array_to_bytevector)
(scm_u8_list_to_bytevector, scm_bytevector_to_uint_list): Adapt to
make_bytevector extra arg.
(bv_handle_ref, bv_handle_set_x): Adapt to ref and set based on the
type of the bytevector, e.g. f64 or u8.
(bytevector_get_handle): Set the typed length of the vector, not the
byte length.
Conflicts:
libguile/bytevectors.c
2009-07-19 15:11:53 +02:00
|
|
|
|
ssize_t ubnd, inc, i;
|
|
|
|
|
|
scm_t_array_handle h;
|
|
|
|
|
|
|
|
|
|
|
|
scm_array_get_handle (bv, &h);
|
2009-05-27 18:18:07 +02:00
|
|
|
|
|
2016-04-26 23:01:14 +02:00
|
|
|
|
scm_putc ('#', port);
|
bytevectors have "element type" field, e.g. for generalized-vector-ref
Bytevectors have a very close relationship to other forms of uniform
vectors. Often you want to view a u64vector as a series of bytes, for
writing over a socket; or to process an incoming stream using the
convenient and less error-prone s16vector-ref API rather than
bytevector-s16-native-ref.
The essential needs of the representation of a bytevector and an
s64vector are the same, so we take advantage of that and extend the
bytevector implementation to have a "native type" field, which defaults
to VU8.
This commit doesn't actually expose any user-noticeable changes,
however.
* libguile/bytevectors.h (SCM_BYTEVECTOR_ELEMENT_TYPE): New internal
defines.
(scm_i_make_typed_bytevector, scm_c_take_typed_bytevector): New
internal functions.
* libguile/bytevectors.c (SCM_BYTEVECTOR_SET_ELEMENT_TYPE):
(SCM_BYTEVECTOR_TYPE_SIZE):
(SCM_BYTEVECTOR_TYPED_LENGTH): New internal macros.
(make_bytevector, make_bytevector_from_buffer): Take an extra
argument, the element type. The length argument is interpreted as
being the number of elements, which corresponds to the number of bytes
in the default VU8 case. Doing it this way eliminates a class of bugs
-- e.g. a u32vector of length 3 bytes doesn't make sense. We do have
to check for another class of bugs: overflow. The length stored on the
bytevector itself is still the byte length, though.
(scm_i_make_typed_bytevector):
(scm_c_take_typed_bytevector): New internal functions.
(scm_i_shrink_bytevector): Make sure the new size is valid for the
bytevector's type.
(scm_i_bytevector_generalized_set_x): Remove this function, the
array-handle infrastructure takes care of this for us.
(print_bytevector): Print the bytevector according to its type.
(scm_make_bytevector, scm_bytevector_copy)
(scm_uniform_array_to_bytevector)
(scm_u8_list_to_bytevector, scm_bytevector_to_uint_list): Adapt to
make_bytevector extra arg.
(bv_handle_ref, bv_handle_set_x): Adapt to ref and set based on the
type of the bytevector, e.g. f64 or u8.
(bytevector_get_handle): Set the typed length of the vector, not the
byte length.
Conflicts:
libguile/bytevectors.c
2009-07-19 15:11:53 +02:00
|
|
|
|
scm_write (scm_array_handle_element_type (&h), port);
|
2016-04-26 23:01:14 +02:00
|
|
|
|
scm_putc ('(', port);
|
bytevectors have "element type" field, e.g. for generalized-vector-ref
Bytevectors have a very close relationship to other forms of uniform
vectors. Often you want to view a u64vector as a series of bytes, for
writing over a socket; or to process an incoming stream using the
convenient and less error-prone s16vector-ref API rather than
bytevector-s16-native-ref.
The essential needs of the representation of a bytevector and an
s64vector are the same, so we take advantage of that and extend the
bytevector implementation to have a "native type" field, which defaults
to VU8.
This commit doesn't actually expose any user-noticeable changes,
however.
* libguile/bytevectors.h (SCM_BYTEVECTOR_ELEMENT_TYPE): New internal
defines.
(scm_i_make_typed_bytevector, scm_c_take_typed_bytevector): New
internal functions.
* libguile/bytevectors.c (SCM_BYTEVECTOR_SET_ELEMENT_TYPE):
(SCM_BYTEVECTOR_TYPE_SIZE):
(SCM_BYTEVECTOR_TYPED_LENGTH): New internal macros.
(make_bytevector, make_bytevector_from_buffer): Take an extra
argument, the element type. The length argument is interpreted as
being the number of elements, which corresponds to the number of bytes
in the default VU8 case. Doing it this way eliminates a class of bugs
-- e.g. a u32vector of length 3 bytes doesn't make sense. We do have
to check for another class of bugs: overflow. The length stored on the
bytevector itself is still the byte length, though.
(scm_i_make_typed_bytevector):
(scm_c_take_typed_bytevector): New internal functions.
(scm_i_shrink_bytevector): Make sure the new size is valid for the
bytevector's type.
(scm_i_bytevector_generalized_set_x): Remove this function, the
array-handle infrastructure takes care of this for us.
(print_bytevector): Print the bytevector according to its type.
(scm_make_bytevector, scm_bytevector_copy)
(scm_uniform_array_to_bytevector)
(scm_u8_list_to_bytevector, scm_bytevector_to_uint_list): Adapt to
make_bytevector extra arg.
(bv_handle_ref, bv_handle_set_x): Adapt to ref and set based on the
type of the bytevector, e.g. f64 or u8.
(bytevector_get_handle): Set the typed length of the vector, not the
byte length.
Conflicts:
libguile/bytevectors.c
2009-07-19 15:11:53 +02:00
|
|
|
|
for (i = h.dims[0].lbnd, ubnd = h.dims[0].ubnd, inc = h.dims[0].inc;
|
|
|
|
|
|
i <= ubnd; i += inc)
|
2009-05-27 18:18:07 +02:00
|
|
|
|
{
|
|
|
|
|
|
if (i > 0)
|
2016-04-26 23:01:14 +02:00
|
|
|
|
scm_putc (' ', port);
|
bytevectors have "element type" field, e.g. for generalized-vector-ref
Bytevectors have a very close relationship to other forms of uniform
vectors. Often you want to view a u64vector as a series of bytes, for
writing over a socket; or to process an incoming stream using the
convenient and less error-prone s16vector-ref API rather than
bytevector-s16-native-ref.
The essential needs of the representation of a bytevector and an
s64vector are the same, so we take advantage of that and extend the
bytevector implementation to have a "native type" field, which defaults
to VU8.
This commit doesn't actually expose any user-noticeable changes,
however.
* libguile/bytevectors.h (SCM_BYTEVECTOR_ELEMENT_TYPE): New internal
defines.
(scm_i_make_typed_bytevector, scm_c_take_typed_bytevector): New
internal functions.
* libguile/bytevectors.c (SCM_BYTEVECTOR_SET_ELEMENT_TYPE):
(SCM_BYTEVECTOR_TYPE_SIZE):
(SCM_BYTEVECTOR_TYPED_LENGTH): New internal macros.
(make_bytevector, make_bytevector_from_buffer): Take an extra
argument, the element type. The length argument is interpreted as
being the number of elements, which corresponds to the number of bytes
in the default VU8 case. Doing it this way eliminates a class of bugs
-- e.g. a u32vector of length 3 bytes doesn't make sense. We do have
to check for another class of bugs: overflow. The length stored on the
bytevector itself is still the byte length, though.
(scm_i_make_typed_bytevector):
(scm_c_take_typed_bytevector): New internal functions.
(scm_i_shrink_bytevector): Make sure the new size is valid for the
bytevector's type.
(scm_i_bytevector_generalized_set_x): Remove this function, the
array-handle infrastructure takes care of this for us.
(print_bytevector): Print the bytevector according to its type.
(scm_make_bytevector, scm_bytevector_copy)
(scm_uniform_array_to_bytevector)
(scm_u8_list_to_bytevector, scm_bytevector_to_uint_list): Adapt to
make_bytevector extra arg.
(bv_handle_ref, bv_handle_set_x): Adapt to ref and set based on the
type of the bytevector, e.g. f64 or u8.
(bytevector_get_handle): Set the typed length of the vector, not the
byte length.
Conflicts:
libguile/bytevectors.c
2009-07-19 15:11:53 +02:00
|
|
|
|
scm_write (scm_array_handle_ref (&h, i), port);
|
2009-05-27 18:18:07 +02:00
|
|
|
|
}
|
2016-04-26 23:01:14 +02:00
|
|
|
|
scm_putc (')', port);
|
2009-05-27 18:18:07 +02:00
|
|
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* General operations. */
|
|
|
|
|
|
|
2016-06-23 18:31:55 +02:00
|
|
|
|
static SCM sym_big;
|
|
|
|
|
|
static SCM sym_little;
|
2009-05-27 18:18:07 +02:00
|
|
|
|
|
|
|
|
|
|
SCM scm_endianness_big, scm_endianness_little;
|
|
|
|
|
|
|
|
|
|
|
|
/* Host endianness (a symbol). */
|
2009-06-24 23:46:42 +02:00
|
|
|
|
SCM scm_i_native_endianness = SCM_UNSPECIFIED;
|
2009-05-27 18:18:07 +02:00
|
|
|
|
|
|
|
|
|
|
/* Byte-swapping. */
|
|
|
|
|
|
#ifndef bswap_24
|
|
|
|
|
|
# define bswap_24(_x) \
|
|
|
|
|
|
((((_x) & 0xff0000) >> 16) | \
|
|
|
|
|
|
(((_x) & 0x00ff00)) | \
|
|
|
|
|
|
(((_x) & 0x0000ff) << 16))
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
SCM_DEFINE (scm_native_endianness, "native-endianness", 0, 0, 0,
|
|
|
|
|
|
(void),
|
|
|
|
|
|
"Return a symbol denoting the machine's native endianness.")
|
|
|
|
|
|
#define FUNC_NAME s_scm_native_endianness
|
|
|
|
|
|
{
|
2009-06-24 23:46:42 +02:00
|
|
|
|
return scm_i_native_endianness;
|
2009-05-27 18:18:07 +02:00
|
|
|
|
}
|
|
|
|
|
|
#undef FUNC_NAME
|
|
|
|
|
|
|
|
|
|
|
|
SCM_DEFINE (scm_bytevector_p, "bytevector?", 1, 0, 0,
|
|
|
|
|
|
(SCM obj),
|
|
|
|
|
|
"Return true if @var{obj} is a bytevector.")
|
|
|
|
|
|
#define FUNC_NAME s_scm_bytevector_p
|
|
|
|
|
|
{
|
2009-06-21 23:16:57 +02:00
|
|
|
|
return scm_from_bool (scm_is_bytevector (obj));
|
2009-05-27 18:18:07 +02:00
|
|
|
|
}
|
|
|
|
|
|
#undef FUNC_NAME
|
|
|
|
|
|
|
|
|
|
|
|
SCM_DEFINE (scm_make_bytevector, "make-bytevector", 1, 1, 0,
|
|
|
|
|
|
(SCM len, SCM fill),
|
|
|
|
|
|
"Return a newly allocated bytevector of @var{len} bytes, "
|
|
|
|
|
|
"optionally filled with @var{fill}.")
|
|
|
|
|
|
#define FUNC_NAME s_scm_make_bytevector
|
|
|
|
|
|
{
|
|
|
|
|
|
SCM bv;
|
2014-11-12 00:35:34 -05:00
|
|
|
|
size_t c_len;
|
|
|
|
|
|
scm_t_uint8 c_fill = 0;
|
2009-05-27 18:18:07 +02:00
|
|
|
|
|
2014-11-12 00:35:34 -05:00
|
|
|
|
SCM_VALIDATE_SIZE_COPY (1, len, c_len);
|
scm_is_eq for SCM vals, not == or !=
* libguile/bytevectors.c (scm_make_bytevector, STRING_TO_UTF)
(UTF_TO_STRING):
* libguile/continuations.c (scm_i_check_continuation):
* libguile/expand.h (SCM_EXPANDED_P):
* libguile/fluids.c (scm_i_make_with_fluids):
* libguile/generalized-vectors.c (scm_make_generalized_vector):
* libguile/goops.c (SCM_GOOPS_UNBOUNDP, slot_definition_using_name):
(scm_c_extend_primitive_generic, more_specificp, scm_make)
* libguile/i18n.c (SCM_VALIDATE_OPTIONAL_LOCALE_COPY):
(scm_locale_string_to_integer)
* libguile/modules.c (resolve_duplicate_binding):
(scm_module_reverse_lookup)
* libguile/posix.c (scm_to_resource):
* libguile/r6rs-ports.c (scm_put_bytevector):
* libguile/socket.c (scm_connect, scm_bind, scm_sendto
* libguile/stacks.c (find_prompt):
* libguile/variable.c (scm_variable_ref, scm_variable_bound_p):
* libguile/vm-engine.h (ASSERT_BOUND_VARIABLE, ASSERT_BOUND)
* libguile/vm-i-system.c (VARIABLE_BOUNDP, local_bound)
(long_local_bound, fluid_ref): Use scm_is_eq to compare, not == / !=.
2011-05-13 12:42:01 +02:00
|
|
|
|
if (!scm_is_eq (fill, SCM_UNDEFINED))
|
2009-05-27 18:18:07 +02:00
|
|
|
|
{
|
|
|
|
|
|
int value;
|
|
|
|
|
|
|
|
|
|
|
|
value = scm_to_int (fill);
|
|
|
|
|
|
if (SCM_UNLIKELY ((value < -128) || (value > 255)))
|
|
|
|
|
|
scm_out_of_range (FUNC_NAME, fill);
|
2014-11-12 00:35:34 -05:00
|
|
|
|
c_fill = (scm_t_uint8) value;
|
2009-05-27 18:18:07 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
bytevectors have "element type" field, e.g. for generalized-vector-ref
Bytevectors have a very close relationship to other forms of uniform
vectors. Often you want to view a u64vector as a series of bytes, for
writing over a socket; or to process an incoming stream using the
convenient and less error-prone s16vector-ref API rather than
bytevector-s16-native-ref.
The essential needs of the representation of a bytevector and an
s64vector are the same, so we take advantage of that and extend the
bytevector implementation to have a "native type" field, which defaults
to VU8.
This commit doesn't actually expose any user-noticeable changes,
however.
* libguile/bytevectors.h (SCM_BYTEVECTOR_ELEMENT_TYPE): New internal
defines.
(scm_i_make_typed_bytevector, scm_c_take_typed_bytevector): New
internal functions.
* libguile/bytevectors.c (SCM_BYTEVECTOR_SET_ELEMENT_TYPE):
(SCM_BYTEVECTOR_TYPE_SIZE):
(SCM_BYTEVECTOR_TYPED_LENGTH): New internal macros.
(make_bytevector, make_bytevector_from_buffer): Take an extra
argument, the element type. The length argument is interpreted as
being the number of elements, which corresponds to the number of bytes
in the default VU8 case. Doing it this way eliminates a class of bugs
-- e.g. a u32vector of length 3 bytes doesn't make sense. We do have
to check for another class of bugs: overflow. The length stored on the
bytevector itself is still the byte length, though.
(scm_i_make_typed_bytevector):
(scm_c_take_typed_bytevector): New internal functions.
(scm_i_shrink_bytevector): Make sure the new size is valid for the
bytevector's type.
(scm_i_bytevector_generalized_set_x): Remove this function, the
array-handle infrastructure takes care of this for us.
(print_bytevector): Print the bytevector according to its type.
(scm_make_bytevector, scm_bytevector_copy)
(scm_uniform_array_to_bytevector)
(scm_u8_list_to_bytevector, scm_bytevector_to_uint_list): Adapt to
make_bytevector extra arg.
(bv_handle_ref, bv_handle_set_x): Adapt to ref and set based on the
type of the bytevector, e.g. f64 or u8.
(bytevector_get_handle): Set the typed length of the vector, not the
byte length.
Conflicts:
libguile/bytevectors.c
2009-07-19 15:11:53 +02:00
|
|
|
|
bv = make_bytevector (c_len, SCM_ARRAY_ELEMENT_TYPE_VU8);
|
scm_is_eq for SCM vals, not == or !=
* libguile/bytevectors.c (scm_make_bytevector, STRING_TO_UTF)
(UTF_TO_STRING):
* libguile/continuations.c (scm_i_check_continuation):
* libguile/expand.h (SCM_EXPANDED_P):
* libguile/fluids.c (scm_i_make_with_fluids):
* libguile/generalized-vectors.c (scm_make_generalized_vector):
* libguile/goops.c (SCM_GOOPS_UNBOUNDP, slot_definition_using_name):
(scm_c_extend_primitive_generic, more_specificp, scm_make)
* libguile/i18n.c (SCM_VALIDATE_OPTIONAL_LOCALE_COPY):
(scm_locale_string_to_integer)
* libguile/modules.c (resolve_duplicate_binding):
(scm_module_reverse_lookup)
* libguile/posix.c (scm_to_resource):
* libguile/r6rs-ports.c (scm_put_bytevector):
* libguile/socket.c (scm_connect, scm_bind, scm_sendto
* libguile/stacks.c (find_prompt):
* libguile/variable.c (scm_variable_ref, scm_variable_bound_p):
* libguile/vm-engine.h (ASSERT_BOUND_VARIABLE, ASSERT_BOUND)
* libguile/vm-i-system.c (VARIABLE_BOUNDP, local_bound)
(long_local_bound, fluid_ref): Use scm_is_eq to compare, not == / !=.
2011-05-13 12:42:01 +02:00
|
|
|
|
if (!scm_is_eq (fill, SCM_UNDEFINED))
|
2009-05-27 18:18:07 +02:00
|
|
|
|
{
|
2014-11-12 00:35:34 -05:00
|
|
|
|
size_t i;
|
|
|
|
|
|
scm_t_uint8 *contents;
|
2009-05-27 18:18:07 +02:00
|
|
|
|
|
2014-11-12 00:35:34 -05:00
|
|
|
|
contents = (scm_t_uint8 *) SCM_BYTEVECTOR_CONTENTS (bv);
|
2009-05-27 18:18:07 +02:00
|
|
|
|
for (i = 0; i < c_len; i++)
|
|
|
|
|
|
contents[i] = c_fill;
|
|
|
|
|
|
}
|
2010-12-04 19:31:20 +01:00
|
|
|
|
else
|
|
|
|
|
|
memset (SCM_BYTEVECTOR_CONTENTS (bv), 0, c_len);
|
2009-05-27 18:18:07 +02:00
|
|
|
|
|
|
|
|
|
|
return bv;
|
|
|
|
|
|
}
|
|
|
|
|
|
#undef FUNC_NAME
|
|
|
|
|
|
|
|
|
|
|
|
SCM_DEFINE (scm_bytevector_length, "bytevector-length", 1, 0, 0,
|
|
|
|
|
|
(SCM bv),
|
|
|
|
|
|
"Return the length (in bytes) of @var{bv}.")
|
|
|
|
|
|
#define FUNC_NAME s_scm_bytevector_length
|
|
|
|
|
|
{
|
2009-06-21 23:16:57 +02:00
|
|
|
|
return scm_from_uint (scm_c_bytevector_length (bv));
|
2009-05-27 18:18:07 +02:00
|
|
|
|
}
|
|
|
|
|
|
#undef FUNC_NAME
|
|
|
|
|
|
|
|
|
|
|
|
SCM_DEFINE (scm_bytevector_eq_p, "bytevector=?", 2, 0, 0,
|
|
|
|
|
|
(SCM bv1, SCM bv2),
|
|
|
|
|
|
"Return is @var{bv1} equals to @var{bv2}---i.e., if they "
|
|
|
|
|
|
"have the same length and contents.")
|
|
|
|
|
|
#define FUNC_NAME s_scm_bytevector_eq_p
|
|
|
|
|
|
{
|
|
|
|
|
|
SCM result = SCM_BOOL_F;
|
2014-11-12 00:35:34 -05:00
|
|
|
|
size_t c_len1, c_len2;
|
2009-05-27 18:18:07 +02:00
|
|
|
|
|
|
|
|
|
|
SCM_VALIDATE_BYTEVECTOR (1, bv1);
|
|
|
|
|
|
SCM_VALIDATE_BYTEVECTOR (2, bv2);
|
|
|
|
|
|
|
|
|
|
|
|
c_len1 = SCM_BYTEVECTOR_LENGTH (bv1);
|
|
|
|
|
|
c_len2 = SCM_BYTEVECTOR_LENGTH (bv2);
|
|
|
|
|
|
|
2010-04-01 00:18:44 +02:00
|
|
|
|
if (c_len1 == c_len2 && (SCM_BYTEVECTOR_ELEMENT_TYPE (bv1)
|
|
|
|
|
|
== SCM_BYTEVECTOR_ELEMENT_TYPE (bv2)))
|
2009-05-27 18:18:07 +02:00
|
|
|
|
{
|
|
|
|
|
|
signed char *c_bv1, *c_bv2;
|
|
|
|
|
|
|
|
|
|
|
|
c_bv1 = SCM_BYTEVECTOR_CONTENTS (bv1);
|
|
|
|
|
|
c_bv2 = SCM_BYTEVECTOR_CONTENTS (bv2);
|
|
|
|
|
|
|
|
|
|
|
|
result = scm_from_bool (!memcmp (c_bv1, c_bv2, c_len1));
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return result;
|
|
|
|
|
|
}
|
|
|
|
|
|
#undef FUNC_NAME
|
|
|
|
|
|
|
|
|
|
|
|
SCM_DEFINE (scm_bytevector_fill_x, "bytevector-fill!", 2, 0, 0,
|
|
|
|
|
|
(SCM bv, SCM fill),
|
|
|
|
|
|
"Fill bytevector @var{bv} with @var{fill}, a byte.")
|
|
|
|
|
|
#define FUNC_NAME s_scm_bytevector_fill_x
|
|
|
|
|
|
{
|
2014-11-12 00:35:34 -05:00
|
|
|
|
size_t c_len, i;
|
|
|
|
|
|
scm_t_uint8 *c_bv, c_fill;
|
2014-11-12 00:40:47 -05:00
|
|
|
|
int value;
|
2009-05-27 18:18:07 +02:00
|
|
|
|
|
All literal constants are read-only
* libguile/array-handle.c (initialize_vector_handle): Add mutable_p
argument. Unless the vector handle is mutable, null out its
writable_elements member.
(scm_array_get_handle): Adapt to determine mutability of the various
arrays.
(scm_array_handle_elements, scm_array_handle_writable_elements):
Reverse the sense: instead of implementing read-only in terms of
read-write, go the other way around, adding an assertion in the
read-write case that the array handle is mutable.
* libguile/array-map.c (racp): Assert that the destination is mutable.
* libguile/bitvectors.c (SCM_F_BITVECTOR_IMMUTABLE, IS_BITVECTOR):
(IS_MUTABLE_BITVECTOR): Add a flag to indicate immutability.
(scm_i_bitvector_bits): Fix indentation.
(scm_i_is_mutable_bitvector): New helper.
(scm_array_handle_bit_elements)
((scm_array_handle_bit_writable_elements): Build writable_elements in
terms of elements.
(scm_bitvector_elements, scm_bitvector_writable_elements): Likewise.
(scm_c_bitvector_set_x): Require a mutable bitvector for the
fast-path.
(scm_bitvector_to_list, scm_bit_count): Use read-only elements()
function.
* libguile/bitvectors.h (scm_i_is_mutable_bitvector): New decl.
* libguile/bytevectors.c (INTEGER_ACCESSOR_PROLOGUE):
(INTEGER_GETTER_PROLOGUE, INTEGER_SETTER_PROLOGUE):
(INTEGER_REF, INTEGER_NATIVE_REF, INTEGER_SET, INTEGER_NATIVE_SET):
(GENERIC_INTEGER_ACCESSOR_PROLOGUE):
(GENERIC_INTEGER_GETTER_PROLOGUE, GENERIC_INTEGER_SETTER_PROLOGUE):
(LARGE_INTEGER_NATIVE_REF, LARGE_INTEGER_NATIVE_SET):
(IEEE754_GETTER_PROLOGUE, IEEE754_SETTER_PROLOGUE):
(IEEE754_REF, IEEE754_NATIVE_REF, IEEE754_SET, IEEE754_NATIVE_SET):
Setters require a mutable bytevector.
(SCM_BYTEVECTOR_SET_FLAG): New helper.
(SCM_BYTEVECTOR_SET_CONTIGUOUS_P, SCM_BYTEVECTOR_SET_ELEMENT_TYPE):
Remove helpers.
(SCM_VALIDATE_MUTABLE_BYTEVECTOR): New helper.
(make_bytevector, make_bytevector_from_buffer): Use
SCM_SET_BYTEVECTOR_FLAGS.
(scm_c_bytevector_set_x, scm_bytevector_fill_x)
(scm_bytevector_copy_x): Require a mutable bytevector.
* libguile/bytevectors.h (SCM_F_BYTEVECTOR_CONTIGUOUS)
(SCM_F_BYTEVECTOR_IMMUTABLE, SCM_MUTABLE_BYTEVECTOR_P): New
definitions.
* libguile/bytevectors.h (SCM_BYTEVECTOR_CONTIGUOUS_P): Just access one
bit.
* libguile/srfi-4.c (DEFINE_SRFI_4_C_FUNCS): Implement
writable_elements() in terms of elements().
* libguile/strings.c (scm_i_string_is_mutable): New helper.
* libguile/uniform.c (scm_array_handle_uniform_elements):
(scm_array_handle_uniform_writable_elements): Implement
writable_elements in terms of elements.
* libguile/vectors.c (SCM_VALIDATE_MUTABLE_VECTOR): New helper.
(scm_vector_elements, scm_vector_writable_elements): Implement
writable_elements in terms of elements.
(scm_c_vector_set_x): Require a mutable vector.
* libguile/vectors.h (SCM_F_VECTOR_IMMUTABLE, SCM_I_IS_MUTABLE_VECTOR):
New definitions.
* libguile/vm-engine.c (VM_VALIDATE_MUTABLE_BYTEVECTOR):
(VM_VALIDATE_MUTABLE_VECTOR, vector-set!, vector-set!/immediate)
(BV_BOUNDED_SET, BV_SET): Require mutable bytevector/vector.
* libguile/vm.c (vm_error_not_a_mutable_bytevector):
(vm_error_not_a_mutable_vector): New definitions.
* module/system/vm/assembler.scm (link-data): Mark residualized vectors,
bytevectors, and bitvectors as being read-only.
2017-04-18 14:56:48 +02:00
|
|
|
|
SCM_VALIDATE_MUTABLE_BYTEVECTOR (1, bv);
|
2014-11-12 00:40:47 -05:00
|
|
|
|
|
|
|
|
|
|
value = scm_to_int (fill);
|
|
|
|
|
|
if (SCM_UNLIKELY ((value < -128) || (value > 255)))
|
|
|
|
|
|
scm_out_of_range (FUNC_NAME, fill);
|
|
|
|
|
|
c_fill = (scm_t_uint8) value;
|
2009-05-27 18:18:07 +02:00
|
|
|
|
|
|
|
|
|
|
c_len = SCM_BYTEVECTOR_LENGTH (bv);
|
2014-11-12 00:35:34 -05:00
|
|
|
|
c_bv = (scm_t_uint8 *) SCM_BYTEVECTOR_CONTENTS (bv);
|
2009-05-27 18:18:07 +02:00
|
|
|
|
|
|
|
|
|
|
for (i = 0; i < c_len; i++)
|
|
|
|
|
|
c_bv[i] = c_fill;
|
|
|
|
|
|
|
|
|
|
|
|
return SCM_UNSPECIFIED;
|
|
|
|
|
|
}
|
|
|
|
|
|
#undef FUNC_NAME
|
|
|
|
|
|
|
|
|
|
|
|
SCM_DEFINE (scm_bytevector_copy_x, "bytevector-copy!", 5, 0, 0,
|
|
|
|
|
|
(SCM source, SCM source_start, SCM target, SCM target_start,
|
|
|
|
|
|
SCM len),
|
|
|
|
|
|
"Copy @var{len} bytes from @var{source} into @var{target}, "
|
|
|
|
|
|
"starting reading from @var{source_start} (a positive index "
|
|
|
|
|
|
"within @var{source}) and start writing at "
|
|
|
|
|
|
"@var{target_start}.")
|
|
|
|
|
|
#define FUNC_NAME s_scm_bytevector_copy_x
|
|
|
|
|
|
{
|
2014-11-12 00:35:34 -05:00
|
|
|
|
size_t c_len, c_source_len, c_target_len;
|
|
|
|
|
|
size_t c_source_start, c_target_start;
|
2009-05-27 18:18:07 +02:00
|
|
|
|
signed char *c_source, *c_target;
|
|
|
|
|
|
|
|
|
|
|
|
SCM_VALIDATE_BYTEVECTOR (1, source);
|
All literal constants are read-only
* libguile/array-handle.c (initialize_vector_handle): Add mutable_p
argument. Unless the vector handle is mutable, null out its
writable_elements member.
(scm_array_get_handle): Adapt to determine mutability of the various
arrays.
(scm_array_handle_elements, scm_array_handle_writable_elements):
Reverse the sense: instead of implementing read-only in terms of
read-write, go the other way around, adding an assertion in the
read-write case that the array handle is mutable.
* libguile/array-map.c (racp): Assert that the destination is mutable.
* libguile/bitvectors.c (SCM_F_BITVECTOR_IMMUTABLE, IS_BITVECTOR):
(IS_MUTABLE_BITVECTOR): Add a flag to indicate immutability.
(scm_i_bitvector_bits): Fix indentation.
(scm_i_is_mutable_bitvector): New helper.
(scm_array_handle_bit_elements)
((scm_array_handle_bit_writable_elements): Build writable_elements in
terms of elements.
(scm_bitvector_elements, scm_bitvector_writable_elements): Likewise.
(scm_c_bitvector_set_x): Require a mutable bitvector for the
fast-path.
(scm_bitvector_to_list, scm_bit_count): Use read-only elements()
function.
* libguile/bitvectors.h (scm_i_is_mutable_bitvector): New decl.
* libguile/bytevectors.c (INTEGER_ACCESSOR_PROLOGUE):
(INTEGER_GETTER_PROLOGUE, INTEGER_SETTER_PROLOGUE):
(INTEGER_REF, INTEGER_NATIVE_REF, INTEGER_SET, INTEGER_NATIVE_SET):
(GENERIC_INTEGER_ACCESSOR_PROLOGUE):
(GENERIC_INTEGER_GETTER_PROLOGUE, GENERIC_INTEGER_SETTER_PROLOGUE):
(LARGE_INTEGER_NATIVE_REF, LARGE_INTEGER_NATIVE_SET):
(IEEE754_GETTER_PROLOGUE, IEEE754_SETTER_PROLOGUE):
(IEEE754_REF, IEEE754_NATIVE_REF, IEEE754_SET, IEEE754_NATIVE_SET):
Setters require a mutable bytevector.
(SCM_BYTEVECTOR_SET_FLAG): New helper.
(SCM_BYTEVECTOR_SET_CONTIGUOUS_P, SCM_BYTEVECTOR_SET_ELEMENT_TYPE):
Remove helpers.
(SCM_VALIDATE_MUTABLE_BYTEVECTOR): New helper.
(make_bytevector, make_bytevector_from_buffer): Use
SCM_SET_BYTEVECTOR_FLAGS.
(scm_c_bytevector_set_x, scm_bytevector_fill_x)
(scm_bytevector_copy_x): Require a mutable bytevector.
* libguile/bytevectors.h (SCM_F_BYTEVECTOR_CONTIGUOUS)
(SCM_F_BYTEVECTOR_IMMUTABLE, SCM_MUTABLE_BYTEVECTOR_P): New
definitions.
* libguile/bytevectors.h (SCM_BYTEVECTOR_CONTIGUOUS_P): Just access one
bit.
* libguile/srfi-4.c (DEFINE_SRFI_4_C_FUNCS): Implement
writable_elements() in terms of elements().
* libguile/strings.c (scm_i_string_is_mutable): New helper.
* libguile/uniform.c (scm_array_handle_uniform_elements):
(scm_array_handle_uniform_writable_elements): Implement
writable_elements in terms of elements.
* libguile/vectors.c (SCM_VALIDATE_MUTABLE_VECTOR): New helper.
(scm_vector_elements, scm_vector_writable_elements): Implement
writable_elements in terms of elements.
(scm_c_vector_set_x): Require a mutable vector.
* libguile/vectors.h (SCM_F_VECTOR_IMMUTABLE, SCM_I_IS_MUTABLE_VECTOR):
New definitions.
* libguile/vm-engine.c (VM_VALIDATE_MUTABLE_BYTEVECTOR):
(VM_VALIDATE_MUTABLE_VECTOR, vector-set!, vector-set!/immediate)
(BV_BOUNDED_SET, BV_SET): Require mutable bytevector/vector.
* libguile/vm.c (vm_error_not_a_mutable_bytevector):
(vm_error_not_a_mutable_vector): New definitions.
* module/system/vm/assembler.scm (link-data): Mark residualized vectors,
bytevectors, and bitvectors as being read-only.
2017-04-18 14:56:48 +02:00
|
|
|
|
SCM_VALIDATE_MUTABLE_BYTEVECTOR (3, target);
|
2009-05-27 18:18:07 +02:00
|
|
|
|
|
2014-11-12 00:35:34 -05:00
|
|
|
|
c_len = scm_to_size_t (len);
|
|
|
|
|
|
c_source_start = scm_to_size_t (source_start);
|
|
|
|
|
|
c_target_start = scm_to_size_t (target_start);
|
2009-05-27 18:18:07 +02:00
|
|
|
|
|
|
|
|
|
|
c_source = SCM_BYTEVECTOR_CONTENTS (source);
|
|
|
|
|
|
c_target = SCM_BYTEVECTOR_CONTENTS (target);
|
|
|
|
|
|
c_source_len = SCM_BYTEVECTOR_LENGTH (source);
|
|
|
|
|
|
c_target_len = SCM_BYTEVECTOR_LENGTH (target);
|
|
|
|
|
|
|
|
|
|
|
|
if (SCM_UNLIKELY (c_source_start + c_len > c_source_len))
|
|
|
|
|
|
scm_out_of_range (FUNC_NAME, source_start);
|
|
|
|
|
|
if (SCM_UNLIKELY (c_target_start + c_len > c_target_len))
|
|
|
|
|
|
scm_out_of_range (FUNC_NAME, target_start);
|
|
|
|
|
|
|
2011-11-20 01:10:58 +01:00
|
|
|
|
memmove (c_target + c_target_start,
|
|
|
|
|
|
c_source + c_source_start,
|
|
|
|
|
|
c_len);
|
2009-05-27 18:18:07 +02:00
|
|
|
|
|
|
|
|
|
|
return SCM_UNSPECIFIED;
|
|
|
|
|
|
}
|
|
|
|
|
|
#undef FUNC_NAME
|
|
|
|
|
|
|
|
|
|
|
|
SCM_DEFINE (scm_bytevector_copy, "bytevector-copy", 1, 0, 0,
|
|
|
|
|
|
(SCM bv),
|
|
|
|
|
|
"Return a newly allocated copy of @var{bv}.")
|
|
|
|
|
|
#define FUNC_NAME s_scm_bytevector_copy
|
|
|
|
|
|
{
|
|
|
|
|
|
SCM copy;
|
2014-11-12 00:35:34 -05:00
|
|
|
|
size_t c_len;
|
2009-05-27 18:18:07 +02:00
|
|
|
|
signed char *c_bv, *c_copy;
|
|
|
|
|
|
|
|
|
|
|
|
SCM_VALIDATE_BYTEVECTOR (1, bv);
|
|
|
|
|
|
|
|
|
|
|
|
c_len = SCM_BYTEVECTOR_LENGTH (bv);
|
|
|
|
|
|
c_bv = SCM_BYTEVECTOR_CONTENTS (bv);
|
|
|
|
|
|
|
2014-11-11 23:14:26 -05:00
|
|
|
|
copy = make_bytevector (c_len, SCM_ARRAY_ELEMENT_TYPE_VU8);
|
2009-05-27 18:18:07 +02:00
|
|
|
|
c_copy = SCM_BYTEVECTOR_CONTENTS (copy);
|
|
|
|
|
|
memcpy (c_copy, c_bv, c_len);
|
|
|
|
|
|
|
|
|
|
|
|
return copy;
|
|
|
|
|
|
}
|
|
|
|
|
|
#undef FUNC_NAME
|
|
|
|
|
|
|
2009-06-05 16:31:38 +02:00
|
|
|
|
SCM_DEFINE (scm_uniform_array_to_bytevector, "uniform-array->bytevector",
|
|
|
|
|
|
1, 0, 0, (SCM array),
|
|
|
|
|
|
"Return a newly allocated bytevector whose contents\n"
|
|
|
|
|
|
"will be copied from the uniform array @var{array}.")
|
|
|
|
|
|
#define FUNC_NAME s_scm_uniform_array_to_bytevector
|
|
|
|
|
|
{
|
|
|
|
|
|
SCM contents, ret;
|
2009-09-17 13:52:09 +02:00
|
|
|
|
size_t len, sz, byte_len;
|
2009-06-05 16:31:38 +02:00
|
|
|
|
scm_t_array_handle h;
|
2009-09-17 13:52:09 +02:00
|
|
|
|
const void *elts;
|
2009-06-05 16:31:38 +02:00
|
|
|
|
|
|
|
|
|
|
contents = scm_array_contents (array, SCM_BOOL_T);
|
|
|
|
|
|
if (scm_is_false (contents))
|
|
|
|
|
|
scm_wrong_type_arg_msg (FUNC_NAME, 0, array, "uniform contiguous array");
|
|
|
|
|
|
|
|
|
|
|
|
scm_array_get_handle (contents, &h);
|
2009-09-17 13:52:09 +02:00
|
|
|
|
assert (h.base == 0);
|
2009-06-05 16:31:38 +02:00
|
|
|
|
|
2009-09-17 13:52:09 +02:00
|
|
|
|
elts = h.elements;
|
2009-06-05 16:31:38 +02:00
|
|
|
|
len = h.dims->inc * (h.dims->ubnd - h.dims->lbnd + 1);
|
2009-09-17 13:52:09 +02:00
|
|
|
|
sz = scm_array_handle_uniform_element_bit_size (&h);
|
|
|
|
|
|
if (sz >= 8 && ((sz % 8) == 0))
|
|
|
|
|
|
byte_len = len * (sz / 8);
|
2009-10-16 11:59:30 +02:00
|
|
|
|
else if (sz < 8)
|
2013-11-03 21:45:34 +01:00
|
|
|
|
/* Elements of sub-byte size (bitvectors) are addressed in 32-bit
|
|
|
|
|
|
units. */
|
|
|
|
|
|
byte_len = ((len * sz + 31) / 32) * 4;
|
2009-10-16 11:59:30 +02:00
|
|
|
|
else
|
|
|
|
|
|
/* an internal guile error, really */
|
|
|
|
|
|
SCM_MISC_ERROR ("uniform elements larger than 8 bits must fill whole bytes", SCM_EOL);
|
2009-06-05 16:31:38 +02:00
|
|
|
|
|
2009-09-17 13:52:09 +02:00
|
|
|
|
ret = make_bytevector (byte_len, SCM_ARRAY_ELEMENT_TYPE_VU8);
|
|
|
|
|
|
memcpy (SCM_BYTEVECTOR_CONTENTS (ret), elts, byte_len);
|
2009-06-05 16:31:38 +02:00
|
|
|
|
|
|
|
|
|
|
scm_array_handle_release (&h);
|
|
|
|
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
|
|
}
|
|
|
|
|
|
#undef FUNC_NAME
|
|
|
|
|
|
|
2009-05-27 18:18:07 +02:00
|
|
|
|
|
|
|
|
|
|
/* Operations on bytes and octets. */
|
|
|
|
|
|
|
|
|
|
|
|
SCM_DEFINE (scm_bytevector_u8_ref, "bytevector-u8-ref", 2, 0, 0,
|
|
|
|
|
|
(SCM bv, SCM index),
|
|
|
|
|
|
"Return the octet located at @var{index} in @var{bv}.")
|
|
|
|
|
|
#define FUNC_NAME s_scm_bytevector_u8_ref
|
|
|
|
|
|
{
|
|
|
|
|
|
INTEGER_NATIVE_REF (8, unsigned);
|
|
|
|
|
|
}
|
|
|
|
|
|
#undef FUNC_NAME
|
|
|
|
|
|
|
|
|
|
|
|
SCM_DEFINE (scm_bytevector_s8_ref, "bytevector-s8-ref", 2, 0, 0,
|
|
|
|
|
|
(SCM bv, SCM index),
|
|
|
|
|
|
"Return the byte located at @var{index} in @var{bv}.")
|
|
|
|
|
|
#define FUNC_NAME s_scm_bytevector_s8_ref
|
|
|
|
|
|
{
|
|
|
|
|
|
INTEGER_NATIVE_REF (8, signed);
|
|
|
|
|
|
}
|
|
|
|
|
|
#undef FUNC_NAME
|
|
|
|
|
|
|
|
|
|
|
|
SCM_DEFINE (scm_bytevector_u8_set_x, "bytevector-u8-set!", 3, 0, 0,
|
|
|
|
|
|
(SCM bv, SCM index, SCM value),
|
|
|
|
|
|
"Return the octet located at @var{index} in @var{bv}.")
|
|
|
|
|
|
#define FUNC_NAME s_scm_bytevector_u8_set_x
|
|
|
|
|
|
{
|
|
|
|
|
|
INTEGER_NATIVE_SET (8, unsigned);
|
|
|
|
|
|
}
|
|
|
|
|
|
#undef FUNC_NAME
|
|
|
|
|
|
|
|
|
|
|
|
SCM_DEFINE (scm_bytevector_s8_set_x, "bytevector-s8-set!", 3, 0, 0,
|
|
|
|
|
|
(SCM bv, SCM index, SCM value),
|
|
|
|
|
|
"Return the octet located at @var{index} in @var{bv}.")
|
2009-06-05 22:54:45 +01:00
|
|
|
|
#define FUNC_NAME s_scm_bytevector_s8_set_x
|
2009-05-27 18:18:07 +02:00
|
|
|
|
{
|
|
|
|
|
|
INTEGER_NATIVE_SET (8, signed);
|
|
|
|
|
|
}
|
|
|
|
|
|
#undef FUNC_NAME
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
SCM_DEFINE (scm_bytevector_to_u8_list, "bytevector->u8-list", 1, 0, 0,
|
|
|
|
|
|
(SCM bv),
|
|
|
|
|
|
"Return a newly allocated list of octets containing the "
|
|
|
|
|
|
"contents of @var{bv}.")
|
|
|
|
|
|
#define FUNC_NAME s_scm_bytevector_to_u8_list
|
|
|
|
|
|
{
|
|
|
|
|
|
SCM lst, pair;
|
2014-11-12 00:35:34 -05:00
|
|
|
|
size_t c_len, i;
|
|
|
|
|
|
scm_t_uint8 *c_bv;
|
2009-05-27 18:18:07 +02:00
|
|
|
|
|
|
|
|
|
|
SCM_VALIDATE_BYTEVECTOR (1, bv);
|
|
|
|
|
|
|
|
|
|
|
|
c_len = SCM_BYTEVECTOR_LENGTH (bv);
|
2014-11-12 00:35:34 -05:00
|
|
|
|
c_bv = (scm_t_uint8 *) SCM_BYTEVECTOR_CONTENTS (bv);
|
2009-05-27 18:18:07 +02:00
|
|
|
|
|
2014-11-12 00:35:34 -05:00
|
|
|
|
lst = scm_make_list (scm_from_size_t (c_len), SCM_UNSPECIFIED);
|
2009-05-27 18:18:07 +02:00
|
|
|
|
for (i = 0, pair = lst;
|
|
|
|
|
|
i < c_len;
|
|
|
|
|
|
i++, pair = SCM_CDR (pair))
|
|
|
|
|
|
{
|
|
|
|
|
|
SCM_SETCAR (pair, SCM_I_MAKINUM (c_bv[i]));
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return lst;
|
|
|
|
|
|
}
|
|
|
|
|
|
#undef FUNC_NAME
|
|
|
|
|
|
|
|
|
|
|
|
SCM_DEFINE (scm_u8_list_to_bytevector, "u8-list->bytevector", 1, 0, 0,
|
|
|
|
|
|
(SCM lst),
|
|
|
|
|
|
"Turn @var{lst}, a list of octets, into a bytevector.")
|
|
|
|
|
|
#define FUNC_NAME s_scm_u8_list_to_bytevector
|
|
|
|
|
|
{
|
|
|
|
|
|
SCM bv, item;
|
2014-11-12 00:35:34 -05:00
|
|
|
|
size_t c_len, i;
|
|
|
|
|
|
scm_t_uint8 *c_bv;
|
2009-05-27 18:18:07 +02:00
|
|
|
|
|
|
|
|
|
|
SCM_VALIDATE_LIST_COPYLEN (1, lst, c_len);
|
|
|
|
|
|
|
bytevectors have "element type" field, e.g. for generalized-vector-ref
Bytevectors have a very close relationship to other forms of uniform
vectors. Often you want to view a u64vector as a series of bytes, for
writing over a socket; or to process an incoming stream using the
convenient and less error-prone s16vector-ref API rather than
bytevector-s16-native-ref.
The essential needs of the representation of a bytevector and an
s64vector are the same, so we take advantage of that and extend the
bytevector implementation to have a "native type" field, which defaults
to VU8.
This commit doesn't actually expose any user-noticeable changes,
however.
* libguile/bytevectors.h (SCM_BYTEVECTOR_ELEMENT_TYPE): New internal
defines.
(scm_i_make_typed_bytevector, scm_c_take_typed_bytevector): New
internal functions.
* libguile/bytevectors.c (SCM_BYTEVECTOR_SET_ELEMENT_TYPE):
(SCM_BYTEVECTOR_TYPE_SIZE):
(SCM_BYTEVECTOR_TYPED_LENGTH): New internal macros.
(make_bytevector, make_bytevector_from_buffer): Take an extra
argument, the element type. The length argument is interpreted as
being the number of elements, which corresponds to the number of bytes
in the default VU8 case. Doing it this way eliminates a class of bugs
-- e.g. a u32vector of length 3 bytes doesn't make sense. We do have
to check for another class of bugs: overflow. The length stored on the
bytevector itself is still the byte length, though.
(scm_i_make_typed_bytevector):
(scm_c_take_typed_bytevector): New internal functions.
(scm_i_shrink_bytevector): Make sure the new size is valid for the
bytevector's type.
(scm_i_bytevector_generalized_set_x): Remove this function, the
array-handle infrastructure takes care of this for us.
(print_bytevector): Print the bytevector according to its type.
(scm_make_bytevector, scm_bytevector_copy)
(scm_uniform_array_to_bytevector)
(scm_u8_list_to_bytevector, scm_bytevector_to_uint_list): Adapt to
make_bytevector extra arg.
(bv_handle_ref, bv_handle_set_x): Adapt to ref and set based on the
type of the bytevector, e.g. f64 or u8.
(bytevector_get_handle): Set the typed length of the vector, not the
byte length.
Conflicts:
libguile/bytevectors.c
2009-07-19 15:11:53 +02:00
|
|
|
|
bv = make_bytevector (c_len, SCM_ARRAY_ELEMENT_TYPE_VU8);
|
2014-11-12 00:35:34 -05:00
|
|
|
|
c_bv = (scm_t_uint8 *) SCM_BYTEVECTOR_CONTENTS (bv);
|
2009-05-27 18:18:07 +02:00
|
|
|
|
|
|
|
|
|
|
for (i = 0; i < c_len; lst = SCM_CDR (lst), i++)
|
|
|
|
|
|
{
|
|
|
|
|
|
item = SCM_CAR (lst);
|
|
|
|
|
|
|
|
|
|
|
|
if (SCM_LIKELY (SCM_I_INUMP (item)))
|
|
|
|
|
|
{
|
2010-11-19 11:29:26 +01:00
|
|
|
|
scm_t_signed_bits c_item;
|
2009-05-27 18:18:07 +02:00
|
|
|
|
|
|
|
|
|
|
c_item = SCM_I_INUM (item);
|
|
|
|
|
|
if (SCM_LIKELY ((c_item >= 0) && (c_item < 256)))
|
2014-11-12 00:35:34 -05:00
|
|
|
|
c_bv[i] = (scm_t_uint8) c_item;
|
2009-05-27 18:18:07 +02:00
|
|
|
|
else
|
|
|
|
|
|
goto type_error;
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
goto type_error;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return bv;
|
|
|
|
|
|
|
|
|
|
|
|
type_error:
|
|
|
|
|
|
scm_wrong_type_arg (FUNC_NAME, 1, item);
|
|
|
|
|
|
|
|
|
|
|
|
return SCM_BOOL_F;
|
|
|
|
|
|
}
|
|
|
|
|
|
#undef FUNC_NAME
|
|
|
|
|
|
|
|
|
|
|
|
/* Compute the two's complement of VALUE (a positive integer) on SIZE octets
|
|
|
|
|
|
using (2^(SIZE * 8) - VALUE). */
|
|
|
|
|
|
static inline void
|
|
|
|
|
|
twos_complement (mpz_t value, size_t size)
|
|
|
|
|
|
{
|
|
|
|
|
|
unsigned long bit_count;
|
|
|
|
|
|
|
|
|
|
|
|
/* We expect BIT_COUNT to fit in a unsigned long thanks to the range
|
|
|
|
|
|
checking on SIZE performed earlier. */
|
|
|
|
|
|
bit_count = (unsigned long) size << 3UL;
|
|
|
|
|
|
|
|
|
|
|
|
if (SCM_LIKELY (bit_count < sizeof (unsigned long)))
|
|
|
|
|
|
mpz_ui_sub (value, 1UL << bit_count, value);
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
mpz_t max;
|
|
|
|
|
|
|
|
|
|
|
|
mpz_init (max);
|
|
|
|
|
|
mpz_ui_pow_ui (max, 2, bit_count);
|
|
|
|
|
|
mpz_sub (value, max, value);
|
|
|
|
|
|
mpz_clear (max);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static inline SCM
|
|
|
|
|
|
bytevector_large_ref (const char *c_bv, size_t c_size, int signed_p,
|
|
|
|
|
|
SCM endianness)
|
|
|
|
|
|
{
|
|
|
|
|
|
SCM result;
|
|
|
|
|
|
mpz_t c_mpz;
|
|
|
|
|
|
int c_endianness, negative_p = 0;
|
|
|
|
|
|
|
|
|
|
|
|
if (signed_p)
|
|
|
|
|
|
{
|
2016-06-23 18:31:55 +02:00
|
|
|
|
if (scm_is_eq (endianness, sym_big))
|
2009-05-27 18:18:07 +02:00
|
|
|
|
negative_p = c_bv[0] & 0x80;
|
|
|
|
|
|
else
|
|
|
|
|
|
negative_p = c_bv[c_size - 1] & 0x80;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2016-06-23 18:31:55 +02:00
|
|
|
|
c_endianness = scm_is_eq (endianness, sym_big) ? 1 : -1;
|
2009-05-27 18:18:07 +02:00
|
|
|
|
|
|
|
|
|
|
mpz_init (c_mpz);
|
|
|
|
|
|
mpz_import (c_mpz, 1 /* 1 word */, 1 /* word order doesn't matter */,
|
|
|
|
|
|
c_size /* word is C_SIZE-byte long */,
|
|
|
|
|
|
c_endianness,
|
|
|
|
|
|
0 /* nails */, c_bv);
|
|
|
|
|
|
|
|
|
|
|
|
if (signed_p && negative_p)
|
|
|
|
|
|
{
|
|
|
|
|
|
twos_complement (c_mpz, c_size);
|
|
|
|
|
|
mpz_neg (c_mpz, c_mpz);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
result = scm_from_mpz (c_mpz);
|
|
|
|
|
|
mpz_clear (c_mpz); /* FIXME: Needed? */
|
|
|
|
|
|
|
|
|
|
|
|
return result;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static inline int
|
|
|
|
|
|
bytevector_large_set (char *c_bv, size_t c_size, int signed_p,
|
|
|
|
|
|
SCM value, SCM endianness)
|
|
|
|
|
|
{
|
|
|
|
|
|
mpz_t c_mpz;
|
|
|
|
|
|
int c_endianness, c_sign, err = 0;
|
|
|
|
|
|
|
2016-06-23 18:31:55 +02:00
|
|
|
|
c_endianness = scm_is_eq (endianness, sym_big) ? 1 : -1;
|
2009-05-27 18:18:07 +02:00
|
|
|
|
|
|
|
|
|
|
mpz_init (c_mpz);
|
|
|
|
|
|
scm_to_mpz (value, c_mpz);
|
|
|
|
|
|
|
|
|
|
|
|
c_sign = mpz_sgn (c_mpz);
|
|
|
|
|
|
if (c_sign < 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (SCM_LIKELY (signed_p))
|
|
|
|
|
|
{
|
|
|
|
|
|
mpz_neg (c_mpz, c_mpz);
|
|
|
|
|
|
twos_complement (c_mpz, c_size);
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
err = -1;
|
|
|
|
|
|
goto finish;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (c_sign == 0)
|
|
|
|
|
|
/* Zero. */
|
|
|
|
|
|
memset (c_bv, 0, c_size);
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
2016-06-20 17:11:59 +02:00
|
|
|
|
size_t word_count, value_words;
|
2009-05-27 18:18:07 +02:00
|
|
|
|
|
2016-06-20 17:11:59 +02:00
|
|
|
|
value_words = ((mpz_sizeinbase (c_mpz, 2) + (8 * c_size) - 1) /
|
|
|
|
|
|
(8 * c_size));
|
|
|
|
|
|
if (SCM_UNLIKELY (value_words > 1))
|
2009-05-27 18:18:07 +02:00
|
|
|
|
{
|
|
|
|
|
|
err = -2;
|
|
|
|
|
|
goto finish;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
mpz_export (c_bv, &word_count, 1 /* word order doesn't matter */,
|
|
|
|
|
|
c_size, c_endianness,
|
|
|
|
|
|
0 /* nails */, c_mpz);
|
|
|
|
|
|
if (SCM_UNLIKELY (word_count != 1))
|
|
|
|
|
|
/* Shouldn't happen since we already checked with VALUE_SIZE. */
|
|
|
|
|
|
abort ();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
finish:
|
|
|
|
|
|
mpz_clear (c_mpz);
|
|
|
|
|
|
|
|
|
|
|
|
return err;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
All literal constants are read-only
* libguile/array-handle.c (initialize_vector_handle): Add mutable_p
argument. Unless the vector handle is mutable, null out its
writable_elements member.
(scm_array_get_handle): Adapt to determine mutability of the various
arrays.
(scm_array_handle_elements, scm_array_handle_writable_elements):
Reverse the sense: instead of implementing read-only in terms of
read-write, go the other way around, adding an assertion in the
read-write case that the array handle is mutable.
* libguile/array-map.c (racp): Assert that the destination is mutable.
* libguile/bitvectors.c (SCM_F_BITVECTOR_IMMUTABLE, IS_BITVECTOR):
(IS_MUTABLE_BITVECTOR): Add a flag to indicate immutability.
(scm_i_bitvector_bits): Fix indentation.
(scm_i_is_mutable_bitvector): New helper.
(scm_array_handle_bit_elements)
((scm_array_handle_bit_writable_elements): Build writable_elements in
terms of elements.
(scm_bitvector_elements, scm_bitvector_writable_elements): Likewise.
(scm_c_bitvector_set_x): Require a mutable bitvector for the
fast-path.
(scm_bitvector_to_list, scm_bit_count): Use read-only elements()
function.
* libguile/bitvectors.h (scm_i_is_mutable_bitvector): New decl.
* libguile/bytevectors.c (INTEGER_ACCESSOR_PROLOGUE):
(INTEGER_GETTER_PROLOGUE, INTEGER_SETTER_PROLOGUE):
(INTEGER_REF, INTEGER_NATIVE_REF, INTEGER_SET, INTEGER_NATIVE_SET):
(GENERIC_INTEGER_ACCESSOR_PROLOGUE):
(GENERIC_INTEGER_GETTER_PROLOGUE, GENERIC_INTEGER_SETTER_PROLOGUE):
(LARGE_INTEGER_NATIVE_REF, LARGE_INTEGER_NATIVE_SET):
(IEEE754_GETTER_PROLOGUE, IEEE754_SETTER_PROLOGUE):
(IEEE754_REF, IEEE754_NATIVE_REF, IEEE754_SET, IEEE754_NATIVE_SET):
Setters require a mutable bytevector.
(SCM_BYTEVECTOR_SET_FLAG): New helper.
(SCM_BYTEVECTOR_SET_CONTIGUOUS_P, SCM_BYTEVECTOR_SET_ELEMENT_TYPE):
Remove helpers.
(SCM_VALIDATE_MUTABLE_BYTEVECTOR): New helper.
(make_bytevector, make_bytevector_from_buffer): Use
SCM_SET_BYTEVECTOR_FLAGS.
(scm_c_bytevector_set_x, scm_bytevector_fill_x)
(scm_bytevector_copy_x): Require a mutable bytevector.
* libguile/bytevectors.h (SCM_F_BYTEVECTOR_CONTIGUOUS)
(SCM_F_BYTEVECTOR_IMMUTABLE, SCM_MUTABLE_BYTEVECTOR_P): New
definitions.
* libguile/bytevectors.h (SCM_BYTEVECTOR_CONTIGUOUS_P): Just access one
bit.
* libguile/srfi-4.c (DEFINE_SRFI_4_C_FUNCS): Implement
writable_elements() in terms of elements().
* libguile/strings.c (scm_i_string_is_mutable): New helper.
* libguile/uniform.c (scm_array_handle_uniform_elements):
(scm_array_handle_uniform_writable_elements): Implement
writable_elements in terms of elements.
* libguile/vectors.c (SCM_VALIDATE_MUTABLE_VECTOR): New helper.
(scm_vector_elements, scm_vector_writable_elements): Implement
writable_elements in terms of elements.
(scm_c_vector_set_x): Require a mutable vector.
* libguile/vectors.h (SCM_F_VECTOR_IMMUTABLE, SCM_I_IS_MUTABLE_VECTOR):
New definitions.
* libguile/vm-engine.c (VM_VALIDATE_MUTABLE_BYTEVECTOR):
(VM_VALIDATE_MUTABLE_VECTOR, vector-set!, vector-set!/immediate)
(BV_BOUNDED_SET, BV_SET): Require mutable bytevector/vector.
* libguile/vm.c (vm_error_not_a_mutable_bytevector):
(vm_error_not_a_mutable_vector): New definitions.
* module/system/vm/assembler.scm (link-data): Mark residualized vectors,
bytevectors, and bitvectors as being read-only.
2017-04-18 14:56:48 +02:00
|
|
|
|
#define GENERIC_INTEGER_ACCESSOR_PROLOGUE(validate, _sign) \
|
2014-11-12 00:35:34 -05:00
|
|
|
|
size_t c_len, c_index, c_size; \
|
2009-05-27 18:18:07 +02:00
|
|
|
|
char *c_bv; \
|
|
|
|
|
|
\
|
All literal constants are read-only
* libguile/array-handle.c (initialize_vector_handle): Add mutable_p
argument. Unless the vector handle is mutable, null out its
writable_elements member.
(scm_array_get_handle): Adapt to determine mutability of the various
arrays.
(scm_array_handle_elements, scm_array_handle_writable_elements):
Reverse the sense: instead of implementing read-only in terms of
read-write, go the other way around, adding an assertion in the
read-write case that the array handle is mutable.
* libguile/array-map.c (racp): Assert that the destination is mutable.
* libguile/bitvectors.c (SCM_F_BITVECTOR_IMMUTABLE, IS_BITVECTOR):
(IS_MUTABLE_BITVECTOR): Add a flag to indicate immutability.
(scm_i_bitvector_bits): Fix indentation.
(scm_i_is_mutable_bitvector): New helper.
(scm_array_handle_bit_elements)
((scm_array_handle_bit_writable_elements): Build writable_elements in
terms of elements.
(scm_bitvector_elements, scm_bitvector_writable_elements): Likewise.
(scm_c_bitvector_set_x): Require a mutable bitvector for the
fast-path.
(scm_bitvector_to_list, scm_bit_count): Use read-only elements()
function.
* libguile/bitvectors.h (scm_i_is_mutable_bitvector): New decl.
* libguile/bytevectors.c (INTEGER_ACCESSOR_PROLOGUE):
(INTEGER_GETTER_PROLOGUE, INTEGER_SETTER_PROLOGUE):
(INTEGER_REF, INTEGER_NATIVE_REF, INTEGER_SET, INTEGER_NATIVE_SET):
(GENERIC_INTEGER_ACCESSOR_PROLOGUE):
(GENERIC_INTEGER_GETTER_PROLOGUE, GENERIC_INTEGER_SETTER_PROLOGUE):
(LARGE_INTEGER_NATIVE_REF, LARGE_INTEGER_NATIVE_SET):
(IEEE754_GETTER_PROLOGUE, IEEE754_SETTER_PROLOGUE):
(IEEE754_REF, IEEE754_NATIVE_REF, IEEE754_SET, IEEE754_NATIVE_SET):
Setters require a mutable bytevector.
(SCM_BYTEVECTOR_SET_FLAG): New helper.
(SCM_BYTEVECTOR_SET_CONTIGUOUS_P, SCM_BYTEVECTOR_SET_ELEMENT_TYPE):
Remove helpers.
(SCM_VALIDATE_MUTABLE_BYTEVECTOR): New helper.
(make_bytevector, make_bytevector_from_buffer): Use
SCM_SET_BYTEVECTOR_FLAGS.
(scm_c_bytevector_set_x, scm_bytevector_fill_x)
(scm_bytevector_copy_x): Require a mutable bytevector.
* libguile/bytevectors.h (SCM_F_BYTEVECTOR_CONTIGUOUS)
(SCM_F_BYTEVECTOR_IMMUTABLE, SCM_MUTABLE_BYTEVECTOR_P): New
definitions.
* libguile/bytevectors.h (SCM_BYTEVECTOR_CONTIGUOUS_P): Just access one
bit.
* libguile/srfi-4.c (DEFINE_SRFI_4_C_FUNCS): Implement
writable_elements() in terms of elements().
* libguile/strings.c (scm_i_string_is_mutable): New helper.
* libguile/uniform.c (scm_array_handle_uniform_elements):
(scm_array_handle_uniform_writable_elements): Implement
writable_elements in terms of elements.
* libguile/vectors.c (SCM_VALIDATE_MUTABLE_VECTOR): New helper.
(scm_vector_elements, scm_vector_writable_elements): Implement
writable_elements in terms of elements.
(scm_c_vector_set_x): Require a mutable vector.
* libguile/vectors.h (SCM_F_VECTOR_IMMUTABLE, SCM_I_IS_MUTABLE_VECTOR):
New definitions.
* libguile/vm-engine.c (VM_VALIDATE_MUTABLE_BYTEVECTOR):
(VM_VALIDATE_MUTABLE_VECTOR, vector-set!, vector-set!/immediate)
(BV_BOUNDED_SET, BV_SET): Require mutable bytevector/vector.
* libguile/vm.c (vm_error_not_a_mutable_bytevector):
(vm_error_not_a_mutable_vector): New definitions.
* module/system/vm/assembler.scm (link-data): Mark residualized vectors,
bytevectors, and bitvectors as being read-only.
2017-04-18 14:56:48 +02:00
|
|
|
|
SCM_VALIDATE_##validate (1, bv); \
|
2014-11-12 00:35:34 -05:00
|
|
|
|
c_index = scm_to_size_t (index); \
|
|
|
|
|
|
c_size = scm_to_size_t (size); \
|
2009-05-27 18:18:07 +02:00
|
|
|
|
\
|
|
|
|
|
|
c_len = SCM_BYTEVECTOR_LENGTH (bv); \
|
|
|
|
|
|
c_bv = (char *) SCM_BYTEVECTOR_CONTENTS (bv); \
|
|
|
|
|
|
\
|
|
|
|
|
|
/* C_SIZE must have its 3 higher bits set to zero so that \
|
2014-11-12 00:35:34 -05:00
|
|
|
|
multiplying it by 8 yields a number that fits in a \
|
|
|
|
|
|
size_t. */ \
|
2015-01-22 13:16:49 +01:00
|
|
|
|
if (SCM_UNLIKELY (c_size == 0 || c_size >= (SIZE_MAX >> 3))) \
|
2009-05-27 18:18:07 +02:00
|
|
|
|
scm_out_of_range (FUNC_NAME, size); \
|
|
|
|
|
|
if (SCM_UNLIKELY (c_index + c_size > c_len)) \
|
|
|
|
|
|
scm_out_of_range (FUNC_NAME, index);
|
|
|
|
|
|
|
All literal constants are read-only
* libguile/array-handle.c (initialize_vector_handle): Add mutable_p
argument. Unless the vector handle is mutable, null out its
writable_elements member.
(scm_array_get_handle): Adapt to determine mutability of the various
arrays.
(scm_array_handle_elements, scm_array_handle_writable_elements):
Reverse the sense: instead of implementing read-only in terms of
read-write, go the other way around, adding an assertion in the
read-write case that the array handle is mutable.
* libguile/array-map.c (racp): Assert that the destination is mutable.
* libguile/bitvectors.c (SCM_F_BITVECTOR_IMMUTABLE, IS_BITVECTOR):
(IS_MUTABLE_BITVECTOR): Add a flag to indicate immutability.
(scm_i_bitvector_bits): Fix indentation.
(scm_i_is_mutable_bitvector): New helper.
(scm_array_handle_bit_elements)
((scm_array_handle_bit_writable_elements): Build writable_elements in
terms of elements.
(scm_bitvector_elements, scm_bitvector_writable_elements): Likewise.
(scm_c_bitvector_set_x): Require a mutable bitvector for the
fast-path.
(scm_bitvector_to_list, scm_bit_count): Use read-only elements()
function.
* libguile/bitvectors.h (scm_i_is_mutable_bitvector): New decl.
* libguile/bytevectors.c (INTEGER_ACCESSOR_PROLOGUE):
(INTEGER_GETTER_PROLOGUE, INTEGER_SETTER_PROLOGUE):
(INTEGER_REF, INTEGER_NATIVE_REF, INTEGER_SET, INTEGER_NATIVE_SET):
(GENERIC_INTEGER_ACCESSOR_PROLOGUE):
(GENERIC_INTEGER_GETTER_PROLOGUE, GENERIC_INTEGER_SETTER_PROLOGUE):
(LARGE_INTEGER_NATIVE_REF, LARGE_INTEGER_NATIVE_SET):
(IEEE754_GETTER_PROLOGUE, IEEE754_SETTER_PROLOGUE):
(IEEE754_REF, IEEE754_NATIVE_REF, IEEE754_SET, IEEE754_NATIVE_SET):
Setters require a mutable bytevector.
(SCM_BYTEVECTOR_SET_FLAG): New helper.
(SCM_BYTEVECTOR_SET_CONTIGUOUS_P, SCM_BYTEVECTOR_SET_ELEMENT_TYPE):
Remove helpers.
(SCM_VALIDATE_MUTABLE_BYTEVECTOR): New helper.
(make_bytevector, make_bytevector_from_buffer): Use
SCM_SET_BYTEVECTOR_FLAGS.
(scm_c_bytevector_set_x, scm_bytevector_fill_x)
(scm_bytevector_copy_x): Require a mutable bytevector.
* libguile/bytevectors.h (SCM_F_BYTEVECTOR_CONTIGUOUS)
(SCM_F_BYTEVECTOR_IMMUTABLE, SCM_MUTABLE_BYTEVECTOR_P): New
definitions.
* libguile/bytevectors.h (SCM_BYTEVECTOR_CONTIGUOUS_P): Just access one
bit.
* libguile/srfi-4.c (DEFINE_SRFI_4_C_FUNCS): Implement
writable_elements() in terms of elements().
* libguile/strings.c (scm_i_string_is_mutable): New helper.
* libguile/uniform.c (scm_array_handle_uniform_elements):
(scm_array_handle_uniform_writable_elements): Implement
writable_elements in terms of elements.
* libguile/vectors.c (SCM_VALIDATE_MUTABLE_VECTOR): New helper.
(scm_vector_elements, scm_vector_writable_elements): Implement
writable_elements in terms of elements.
(scm_c_vector_set_x): Require a mutable vector.
* libguile/vectors.h (SCM_F_VECTOR_IMMUTABLE, SCM_I_IS_MUTABLE_VECTOR):
New definitions.
* libguile/vm-engine.c (VM_VALIDATE_MUTABLE_BYTEVECTOR):
(VM_VALIDATE_MUTABLE_VECTOR, vector-set!, vector-set!/immediate)
(BV_BOUNDED_SET, BV_SET): Require mutable bytevector/vector.
* libguile/vm.c (vm_error_not_a_mutable_bytevector):
(vm_error_not_a_mutable_vector): New definitions.
* module/system/vm/assembler.scm (link-data): Mark residualized vectors,
bytevectors, and bitvectors as being read-only.
2017-04-18 14:56:48 +02:00
|
|
|
|
#define GENERIC_INTEGER_GETTER_PROLOGUE(_sign) \
|
|
|
|
|
|
GENERIC_INTEGER_ACCESSOR_PROLOGUE (BYTEVECTOR, _sign)
|
|
|
|
|
|
#define GENERIC_INTEGER_SETTER_PROLOGUE(_sign) \
|
|
|
|
|
|
GENERIC_INTEGER_ACCESSOR_PROLOGUE (MUTABLE_BYTEVECTOR, _sign)
|
2009-05-27 18:18:07 +02:00
|
|
|
|
|
|
|
|
|
|
/* Template of an integer reference function. */
|
|
|
|
|
|
#define GENERIC_INTEGER_REF(_sign) \
|
|
|
|
|
|
SCM result; \
|
|
|
|
|
|
\
|
|
|
|
|
|
if (c_size < 3) \
|
|
|
|
|
|
{ \
|
|
|
|
|
|
int swap; \
|
|
|
|
|
|
_sign int value; \
|
|
|
|
|
|
\
|
2009-06-24 23:46:42 +02:00
|
|
|
|
swap = !scm_is_eq (endianness, scm_i_native_endianness); \
|
2009-05-27 18:18:07 +02:00
|
|
|
|
switch (c_size) \
|
|
|
|
|
|
{ \
|
|
|
|
|
|
case 1: \
|
|
|
|
|
|
{ \
|
|
|
|
|
|
_sign char c_value8; \
|
|
|
|
|
|
memcpy (&c_value8, c_bv, 1); \
|
|
|
|
|
|
value = c_value8; \
|
|
|
|
|
|
} \
|
|
|
|
|
|
break; \
|
|
|
|
|
|
case 2: \
|
|
|
|
|
|
{ \
|
|
|
|
|
|
INT_TYPE (16, _sign) c_value16; \
|
|
|
|
|
|
memcpy (&c_value16, c_bv, 2); \
|
|
|
|
|
|
if (swap) \
|
|
|
|
|
|
value = (INT_TYPE (16, _sign)) bswap_16 (c_value16); \
|
|
|
|
|
|
else \
|
|
|
|
|
|
value = c_value16; \
|
|
|
|
|
|
} \
|
|
|
|
|
|
break; \
|
|
|
|
|
|
default: \
|
|
|
|
|
|
abort (); \
|
|
|
|
|
|
} \
|
|
|
|
|
|
\
|
|
|
|
|
|
result = SCM_I_MAKINUM ((_sign int) value); \
|
|
|
|
|
|
} \
|
|
|
|
|
|
else \
|
|
|
|
|
|
result = bytevector_large_ref ((char *) c_bv, \
|
|
|
|
|
|
c_size, SIGNEDNESS (_sign), \
|
|
|
|
|
|
endianness); \
|
|
|
|
|
|
\
|
|
|
|
|
|
return result;
|
|
|
|
|
|
|
|
|
|
|
|
static inline SCM
|
|
|
|
|
|
bytevector_signed_ref (const char *c_bv, size_t c_size, SCM endianness)
|
|
|
|
|
|
{
|
|
|
|
|
|
GENERIC_INTEGER_REF (signed);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static inline SCM
|
|
|
|
|
|
bytevector_unsigned_ref (const char *c_bv, size_t c_size, SCM endianness)
|
|
|
|
|
|
{
|
|
|
|
|
|
GENERIC_INTEGER_REF (unsigned);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Template of an integer assignment function. */
|
|
|
|
|
|
#define GENERIC_INTEGER_SET(_sign) \
|
|
|
|
|
|
if (c_size < 3) \
|
|
|
|
|
|
{ \
|
2010-11-19 11:29:26 +01:00
|
|
|
|
scm_t_signed_bits c_value; \
|
2009-05-27 18:18:07 +02:00
|
|
|
|
\
|
|
|
|
|
|
if (SCM_UNLIKELY (!SCM_I_INUMP (value))) \
|
|
|
|
|
|
goto range_error; \
|
|
|
|
|
|
\
|
|
|
|
|
|
c_value = SCM_I_INUM (value); \
|
|
|
|
|
|
switch (c_size) \
|
|
|
|
|
|
{ \
|
|
|
|
|
|
case 1: \
|
|
|
|
|
|
if (SCM_LIKELY (INT_VALID_P (8, _sign) (c_value))) \
|
|
|
|
|
|
{ \
|
|
|
|
|
|
_sign char c_value8; \
|
|
|
|
|
|
c_value8 = (_sign char) c_value; \
|
|
|
|
|
|
memcpy (c_bv, &c_value8, 1); \
|
|
|
|
|
|
} \
|
|
|
|
|
|
else \
|
|
|
|
|
|
goto range_error; \
|
|
|
|
|
|
break; \
|
|
|
|
|
|
\
|
|
|
|
|
|
case 2: \
|
|
|
|
|
|
if (SCM_LIKELY (INT_VALID_P (16, _sign) (c_value))) \
|
|
|
|
|
|
{ \
|
|
|
|
|
|
int swap; \
|
|
|
|
|
|
INT_TYPE (16, _sign) c_value16; \
|
|
|
|
|
|
\
|
2009-06-24 23:46:42 +02:00
|
|
|
|
swap = !scm_is_eq (endianness, scm_i_native_endianness); \
|
2009-05-27 18:18:07 +02:00
|
|
|
|
\
|
|
|
|
|
|
if (swap) \
|
|
|
|
|
|
c_value16 = (INT_TYPE (16, _sign)) bswap_16 (c_value); \
|
|
|
|
|
|
else \
|
|
|
|
|
|
c_value16 = c_value; \
|
|
|
|
|
|
\
|
|
|
|
|
|
memcpy (c_bv, &c_value16, 2); \
|
|
|
|
|
|
} \
|
|
|
|
|
|
else \
|
|
|
|
|
|
goto range_error; \
|
|
|
|
|
|
break; \
|
|
|
|
|
|
\
|
|
|
|
|
|
default: \
|
|
|
|
|
|
abort (); \
|
|
|
|
|
|
} \
|
|
|
|
|
|
} \
|
|
|
|
|
|
else \
|
|
|
|
|
|
{ \
|
|
|
|
|
|
int err; \
|
|
|
|
|
|
\
|
|
|
|
|
|
err = bytevector_large_set (c_bv, c_size, \
|
|
|
|
|
|
SIGNEDNESS (_sign), \
|
|
|
|
|
|
value, endianness); \
|
|
|
|
|
|
if (err) \
|
|
|
|
|
|
goto range_error; \
|
|
|
|
|
|
} \
|
|
|
|
|
|
\
|
|
|
|
|
|
return; \
|
|
|
|
|
|
\
|
|
|
|
|
|
range_error: \
|
|
|
|
|
|
scm_out_of_range (FUNC_NAME, value); \
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
|
|
static inline void
|
|
|
|
|
|
bytevector_signed_set (char *c_bv, size_t c_size,
|
|
|
|
|
|
SCM value, SCM endianness,
|
|
|
|
|
|
const char *func_name)
|
|
|
|
|
|
#define FUNC_NAME func_name
|
|
|
|
|
|
{
|
|
|
|
|
|
GENERIC_INTEGER_SET (signed);
|
|
|
|
|
|
}
|
|
|
|
|
|
#undef FUNC_NAME
|
|
|
|
|
|
|
|
|
|
|
|
static inline void
|
|
|
|
|
|
bytevector_unsigned_set (char *c_bv, size_t c_size,
|
|
|
|
|
|
SCM value, SCM endianness,
|
|
|
|
|
|
const char *func_name)
|
|
|
|
|
|
#define FUNC_NAME func_name
|
|
|
|
|
|
{
|
|
|
|
|
|
GENERIC_INTEGER_SET (unsigned);
|
|
|
|
|
|
}
|
|
|
|
|
|
#undef FUNC_NAME
|
|
|
|
|
|
|
|
|
|
|
|
#undef GENERIC_INTEGER_SET
|
|
|
|
|
|
#undef GENERIC_INTEGER_REF
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
SCM_DEFINE (scm_bytevector_uint_ref, "bytevector-uint-ref", 4, 0, 0,
|
|
|
|
|
|
(SCM bv, SCM index, SCM endianness, SCM size),
|
|
|
|
|
|
"Return the @var{size}-octet long unsigned integer at index "
|
|
|
|
|
|
"@var{index} in @var{bv}.")
|
|
|
|
|
|
#define FUNC_NAME s_scm_bytevector_uint_ref
|
|
|
|
|
|
{
|
All literal constants are read-only
* libguile/array-handle.c (initialize_vector_handle): Add mutable_p
argument. Unless the vector handle is mutable, null out its
writable_elements member.
(scm_array_get_handle): Adapt to determine mutability of the various
arrays.
(scm_array_handle_elements, scm_array_handle_writable_elements):
Reverse the sense: instead of implementing read-only in terms of
read-write, go the other way around, adding an assertion in the
read-write case that the array handle is mutable.
* libguile/array-map.c (racp): Assert that the destination is mutable.
* libguile/bitvectors.c (SCM_F_BITVECTOR_IMMUTABLE, IS_BITVECTOR):
(IS_MUTABLE_BITVECTOR): Add a flag to indicate immutability.
(scm_i_bitvector_bits): Fix indentation.
(scm_i_is_mutable_bitvector): New helper.
(scm_array_handle_bit_elements)
((scm_array_handle_bit_writable_elements): Build writable_elements in
terms of elements.
(scm_bitvector_elements, scm_bitvector_writable_elements): Likewise.
(scm_c_bitvector_set_x): Require a mutable bitvector for the
fast-path.
(scm_bitvector_to_list, scm_bit_count): Use read-only elements()
function.
* libguile/bitvectors.h (scm_i_is_mutable_bitvector): New decl.
* libguile/bytevectors.c (INTEGER_ACCESSOR_PROLOGUE):
(INTEGER_GETTER_PROLOGUE, INTEGER_SETTER_PROLOGUE):
(INTEGER_REF, INTEGER_NATIVE_REF, INTEGER_SET, INTEGER_NATIVE_SET):
(GENERIC_INTEGER_ACCESSOR_PROLOGUE):
(GENERIC_INTEGER_GETTER_PROLOGUE, GENERIC_INTEGER_SETTER_PROLOGUE):
(LARGE_INTEGER_NATIVE_REF, LARGE_INTEGER_NATIVE_SET):
(IEEE754_GETTER_PROLOGUE, IEEE754_SETTER_PROLOGUE):
(IEEE754_REF, IEEE754_NATIVE_REF, IEEE754_SET, IEEE754_NATIVE_SET):
Setters require a mutable bytevector.
(SCM_BYTEVECTOR_SET_FLAG): New helper.
(SCM_BYTEVECTOR_SET_CONTIGUOUS_P, SCM_BYTEVECTOR_SET_ELEMENT_TYPE):
Remove helpers.
(SCM_VALIDATE_MUTABLE_BYTEVECTOR): New helper.
(make_bytevector, make_bytevector_from_buffer): Use
SCM_SET_BYTEVECTOR_FLAGS.
(scm_c_bytevector_set_x, scm_bytevector_fill_x)
(scm_bytevector_copy_x): Require a mutable bytevector.
* libguile/bytevectors.h (SCM_F_BYTEVECTOR_CONTIGUOUS)
(SCM_F_BYTEVECTOR_IMMUTABLE, SCM_MUTABLE_BYTEVECTOR_P): New
definitions.
* libguile/bytevectors.h (SCM_BYTEVECTOR_CONTIGUOUS_P): Just access one
bit.
* libguile/srfi-4.c (DEFINE_SRFI_4_C_FUNCS): Implement
writable_elements() in terms of elements().
* libguile/strings.c (scm_i_string_is_mutable): New helper.
* libguile/uniform.c (scm_array_handle_uniform_elements):
(scm_array_handle_uniform_writable_elements): Implement
writable_elements in terms of elements.
* libguile/vectors.c (SCM_VALIDATE_MUTABLE_VECTOR): New helper.
(scm_vector_elements, scm_vector_writable_elements): Implement
writable_elements in terms of elements.
(scm_c_vector_set_x): Require a mutable vector.
* libguile/vectors.h (SCM_F_VECTOR_IMMUTABLE, SCM_I_IS_MUTABLE_VECTOR):
New definitions.
* libguile/vm-engine.c (VM_VALIDATE_MUTABLE_BYTEVECTOR):
(VM_VALIDATE_MUTABLE_VECTOR, vector-set!, vector-set!/immediate)
(BV_BOUNDED_SET, BV_SET): Require mutable bytevector/vector.
* libguile/vm.c (vm_error_not_a_mutable_bytevector):
(vm_error_not_a_mutable_vector): New definitions.
* module/system/vm/assembler.scm (link-data): Mark residualized vectors,
bytevectors, and bitvectors as being read-only.
2017-04-18 14:56:48 +02:00
|
|
|
|
GENERIC_INTEGER_GETTER_PROLOGUE (unsigned);
|
2009-05-27 18:18:07 +02:00
|
|
|
|
|
|
|
|
|
|
return (bytevector_unsigned_ref (&c_bv[c_index], c_size, endianness));
|
|
|
|
|
|
}
|
|
|
|
|
|
#undef FUNC_NAME
|
|
|
|
|
|
|
|
|
|
|
|
SCM_DEFINE (scm_bytevector_sint_ref, "bytevector-sint-ref", 4, 0, 0,
|
|
|
|
|
|
(SCM bv, SCM index, SCM endianness, SCM size),
|
|
|
|
|
|
"Return the @var{size}-octet long unsigned integer at index "
|
|
|
|
|
|
"@var{index} in @var{bv}.")
|
|
|
|
|
|
#define FUNC_NAME s_scm_bytevector_sint_ref
|
|
|
|
|
|
{
|
All literal constants are read-only
* libguile/array-handle.c (initialize_vector_handle): Add mutable_p
argument. Unless the vector handle is mutable, null out its
writable_elements member.
(scm_array_get_handle): Adapt to determine mutability of the various
arrays.
(scm_array_handle_elements, scm_array_handle_writable_elements):
Reverse the sense: instead of implementing read-only in terms of
read-write, go the other way around, adding an assertion in the
read-write case that the array handle is mutable.
* libguile/array-map.c (racp): Assert that the destination is mutable.
* libguile/bitvectors.c (SCM_F_BITVECTOR_IMMUTABLE, IS_BITVECTOR):
(IS_MUTABLE_BITVECTOR): Add a flag to indicate immutability.
(scm_i_bitvector_bits): Fix indentation.
(scm_i_is_mutable_bitvector): New helper.
(scm_array_handle_bit_elements)
((scm_array_handle_bit_writable_elements): Build writable_elements in
terms of elements.
(scm_bitvector_elements, scm_bitvector_writable_elements): Likewise.
(scm_c_bitvector_set_x): Require a mutable bitvector for the
fast-path.
(scm_bitvector_to_list, scm_bit_count): Use read-only elements()
function.
* libguile/bitvectors.h (scm_i_is_mutable_bitvector): New decl.
* libguile/bytevectors.c (INTEGER_ACCESSOR_PROLOGUE):
(INTEGER_GETTER_PROLOGUE, INTEGER_SETTER_PROLOGUE):
(INTEGER_REF, INTEGER_NATIVE_REF, INTEGER_SET, INTEGER_NATIVE_SET):
(GENERIC_INTEGER_ACCESSOR_PROLOGUE):
(GENERIC_INTEGER_GETTER_PROLOGUE, GENERIC_INTEGER_SETTER_PROLOGUE):
(LARGE_INTEGER_NATIVE_REF, LARGE_INTEGER_NATIVE_SET):
(IEEE754_GETTER_PROLOGUE, IEEE754_SETTER_PROLOGUE):
(IEEE754_REF, IEEE754_NATIVE_REF, IEEE754_SET, IEEE754_NATIVE_SET):
Setters require a mutable bytevector.
(SCM_BYTEVECTOR_SET_FLAG): New helper.
(SCM_BYTEVECTOR_SET_CONTIGUOUS_P, SCM_BYTEVECTOR_SET_ELEMENT_TYPE):
Remove helpers.
(SCM_VALIDATE_MUTABLE_BYTEVECTOR): New helper.
(make_bytevector, make_bytevector_from_buffer): Use
SCM_SET_BYTEVECTOR_FLAGS.
(scm_c_bytevector_set_x, scm_bytevector_fill_x)
(scm_bytevector_copy_x): Require a mutable bytevector.
* libguile/bytevectors.h (SCM_F_BYTEVECTOR_CONTIGUOUS)
(SCM_F_BYTEVECTOR_IMMUTABLE, SCM_MUTABLE_BYTEVECTOR_P): New
definitions.
* libguile/bytevectors.h (SCM_BYTEVECTOR_CONTIGUOUS_P): Just access one
bit.
* libguile/srfi-4.c (DEFINE_SRFI_4_C_FUNCS): Implement
writable_elements() in terms of elements().
* libguile/strings.c (scm_i_string_is_mutable): New helper.
* libguile/uniform.c (scm_array_handle_uniform_elements):
(scm_array_handle_uniform_writable_elements): Implement
writable_elements in terms of elements.
* libguile/vectors.c (SCM_VALIDATE_MUTABLE_VECTOR): New helper.
(scm_vector_elements, scm_vector_writable_elements): Implement
writable_elements in terms of elements.
(scm_c_vector_set_x): Require a mutable vector.
* libguile/vectors.h (SCM_F_VECTOR_IMMUTABLE, SCM_I_IS_MUTABLE_VECTOR):
New definitions.
* libguile/vm-engine.c (VM_VALIDATE_MUTABLE_BYTEVECTOR):
(VM_VALIDATE_MUTABLE_VECTOR, vector-set!, vector-set!/immediate)
(BV_BOUNDED_SET, BV_SET): Require mutable bytevector/vector.
* libguile/vm.c (vm_error_not_a_mutable_bytevector):
(vm_error_not_a_mutable_vector): New definitions.
* module/system/vm/assembler.scm (link-data): Mark residualized vectors,
bytevectors, and bitvectors as being read-only.
2017-04-18 14:56:48 +02:00
|
|
|
|
GENERIC_INTEGER_GETTER_PROLOGUE (signed);
|
2009-05-27 18:18:07 +02:00
|
|
|
|
|
|
|
|
|
|
return (bytevector_signed_ref (&c_bv[c_index], c_size, endianness));
|
|
|
|
|
|
}
|
|
|
|
|
|
#undef FUNC_NAME
|
|
|
|
|
|
|
|
|
|
|
|
SCM_DEFINE (scm_bytevector_uint_set_x, "bytevector-uint-set!", 5, 0, 0,
|
|
|
|
|
|
(SCM bv, SCM index, SCM value, SCM endianness, SCM size),
|
|
|
|
|
|
"Set the @var{size}-octet long unsigned integer at @var{index} "
|
|
|
|
|
|
"to @var{value}.")
|
|
|
|
|
|
#define FUNC_NAME s_scm_bytevector_uint_set_x
|
|
|
|
|
|
{
|
All literal constants are read-only
* libguile/array-handle.c (initialize_vector_handle): Add mutable_p
argument. Unless the vector handle is mutable, null out its
writable_elements member.
(scm_array_get_handle): Adapt to determine mutability of the various
arrays.
(scm_array_handle_elements, scm_array_handle_writable_elements):
Reverse the sense: instead of implementing read-only in terms of
read-write, go the other way around, adding an assertion in the
read-write case that the array handle is mutable.
* libguile/array-map.c (racp): Assert that the destination is mutable.
* libguile/bitvectors.c (SCM_F_BITVECTOR_IMMUTABLE, IS_BITVECTOR):
(IS_MUTABLE_BITVECTOR): Add a flag to indicate immutability.
(scm_i_bitvector_bits): Fix indentation.
(scm_i_is_mutable_bitvector): New helper.
(scm_array_handle_bit_elements)
((scm_array_handle_bit_writable_elements): Build writable_elements in
terms of elements.
(scm_bitvector_elements, scm_bitvector_writable_elements): Likewise.
(scm_c_bitvector_set_x): Require a mutable bitvector for the
fast-path.
(scm_bitvector_to_list, scm_bit_count): Use read-only elements()
function.
* libguile/bitvectors.h (scm_i_is_mutable_bitvector): New decl.
* libguile/bytevectors.c (INTEGER_ACCESSOR_PROLOGUE):
(INTEGER_GETTER_PROLOGUE, INTEGER_SETTER_PROLOGUE):
(INTEGER_REF, INTEGER_NATIVE_REF, INTEGER_SET, INTEGER_NATIVE_SET):
(GENERIC_INTEGER_ACCESSOR_PROLOGUE):
(GENERIC_INTEGER_GETTER_PROLOGUE, GENERIC_INTEGER_SETTER_PROLOGUE):
(LARGE_INTEGER_NATIVE_REF, LARGE_INTEGER_NATIVE_SET):
(IEEE754_GETTER_PROLOGUE, IEEE754_SETTER_PROLOGUE):
(IEEE754_REF, IEEE754_NATIVE_REF, IEEE754_SET, IEEE754_NATIVE_SET):
Setters require a mutable bytevector.
(SCM_BYTEVECTOR_SET_FLAG): New helper.
(SCM_BYTEVECTOR_SET_CONTIGUOUS_P, SCM_BYTEVECTOR_SET_ELEMENT_TYPE):
Remove helpers.
(SCM_VALIDATE_MUTABLE_BYTEVECTOR): New helper.
(make_bytevector, make_bytevector_from_buffer): Use
SCM_SET_BYTEVECTOR_FLAGS.
(scm_c_bytevector_set_x, scm_bytevector_fill_x)
(scm_bytevector_copy_x): Require a mutable bytevector.
* libguile/bytevectors.h (SCM_F_BYTEVECTOR_CONTIGUOUS)
(SCM_F_BYTEVECTOR_IMMUTABLE, SCM_MUTABLE_BYTEVECTOR_P): New
definitions.
* libguile/bytevectors.h (SCM_BYTEVECTOR_CONTIGUOUS_P): Just access one
bit.
* libguile/srfi-4.c (DEFINE_SRFI_4_C_FUNCS): Implement
writable_elements() in terms of elements().
* libguile/strings.c (scm_i_string_is_mutable): New helper.
* libguile/uniform.c (scm_array_handle_uniform_elements):
(scm_array_handle_uniform_writable_elements): Implement
writable_elements in terms of elements.
* libguile/vectors.c (SCM_VALIDATE_MUTABLE_VECTOR): New helper.
(scm_vector_elements, scm_vector_writable_elements): Implement
writable_elements in terms of elements.
(scm_c_vector_set_x): Require a mutable vector.
* libguile/vectors.h (SCM_F_VECTOR_IMMUTABLE, SCM_I_IS_MUTABLE_VECTOR):
New definitions.
* libguile/vm-engine.c (VM_VALIDATE_MUTABLE_BYTEVECTOR):
(VM_VALIDATE_MUTABLE_VECTOR, vector-set!, vector-set!/immediate)
(BV_BOUNDED_SET, BV_SET): Require mutable bytevector/vector.
* libguile/vm.c (vm_error_not_a_mutable_bytevector):
(vm_error_not_a_mutable_vector): New definitions.
* module/system/vm/assembler.scm (link-data): Mark residualized vectors,
bytevectors, and bitvectors as being read-only.
2017-04-18 14:56:48 +02:00
|
|
|
|
GENERIC_INTEGER_SETTER_PROLOGUE (unsigned);
|
2009-05-27 18:18:07 +02:00
|
|
|
|
|
|
|
|
|
|
bytevector_unsigned_set (&c_bv[c_index], c_size, value, endianness,
|
|
|
|
|
|
FUNC_NAME);
|
|
|
|
|
|
|
|
|
|
|
|
return SCM_UNSPECIFIED;
|
|
|
|
|
|
}
|
|
|
|
|
|
#undef FUNC_NAME
|
|
|
|
|
|
|
|
|
|
|
|
SCM_DEFINE (scm_bytevector_sint_set_x, "bytevector-sint-set!", 5, 0, 0,
|
|
|
|
|
|
(SCM bv, SCM index, SCM value, SCM endianness, SCM size),
|
|
|
|
|
|
"Set the @var{size}-octet long signed integer at @var{index} "
|
|
|
|
|
|
"to @var{value}.")
|
|
|
|
|
|
#define FUNC_NAME s_scm_bytevector_sint_set_x
|
|
|
|
|
|
{
|
All literal constants are read-only
* libguile/array-handle.c (initialize_vector_handle): Add mutable_p
argument. Unless the vector handle is mutable, null out its
writable_elements member.
(scm_array_get_handle): Adapt to determine mutability of the various
arrays.
(scm_array_handle_elements, scm_array_handle_writable_elements):
Reverse the sense: instead of implementing read-only in terms of
read-write, go the other way around, adding an assertion in the
read-write case that the array handle is mutable.
* libguile/array-map.c (racp): Assert that the destination is mutable.
* libguile/bitvectors.c (SCM_F_BITVECTOR_IMMUTABLE, IS_BITVECTOR):
(IS_MUTABLE_BITVECTOR): Add a flag to indicate immutability.
(scm_i_bitvector_bits): Fix indentation.
(scm_i_is_mutable_bitvector): New helper.
(scm_array_handle_bit_elements)
((scm_array_handle_bit_writable_elements): Build writable_elements in
terms of elements.
(scm_bitvector_elements, scm_bitvector_writable_elements): Likewise.
(scm_c_bitvector_set_x): Require a mutable bitvector for the
fast-path.
(scm_bitvector_to_list, scm_bit_count): Use read-only elements()
function.
* libguile/bitvectors.h (scm_i_is_mutable_bitvector): New decl.
* libguile/bytevectors.c (INTEGER_ACCESSOR_PROLOGUE):
(INTEGER_GETTER_PROLOGUE, INTEGER_SETTER_PROLOGUE):
(INTEGER_REF, INTEGER_NATIVE_REF, INTEGER_SET, INTEGER_NATIVE_SET):
(GENERIC_INTEGER_ACCESSOR_PROLOGUE):
(GENERIC_INTEGER_GETTER_PROLOGUE, GENERIC_INTEGER_SETTER_PROLOGUE):
(LARGE_INTEGER_NATIVE_REF, LARGE_INTEGER_NATIVE_SET):
(IEEE754_GETTER_PROLOGUE, IEEE754_SETTER_PROLOGUE):
(IEEE754_REF, IEEE754_NATIVE_REF, IEEE754_SET, IEEE754_NATIVE_SET):
Setters require a mutable bytevector.
(SCM_BYTEVECTOR_SET_FLAG): New helper.
(SCM_BYTEVECTOR_SET_CONTIGUOUS_P, SCM_BYTEVECTOR_SET_ELEMENT_TYPE):
Remove helpers.
(SCM_VALIDATE_MUTABLE_BYTEVECTOR): New helper.
(make_bytevector, make_bytevector_from_buffer): Use
SCM_SET_BYTEVECTOR_FLAGS.
(scm_c_bytevector_set_x, scm_bytevector_fill_x)
(scm_bytevector_copy_x): Require a mutable bytevector.
* libguile/bytevectors.h (SCM_F_BYTEVECTOR_CONTIGUOUS)
(SCM_F_BYTEVECTOR_IMMUTABLE, SCM_MUTABLE_BYTEVECTOR_P): New
definitions.
* libguile/bytevectors.h (SCM_BYTEVECTOR_CONTIGUOUS_P): Just access one
bit.
* libguile/srfi-4.c (DEFINE_SRFI_4_C_FUNCS): Implement
writable_elements() in terms of elements().
* libguile/strings.c (scm_i_string_is_mutable): New helper.
* libguile/uniform.c (scm_array_handle_uniform_elements):
(scm_array_handle_uniform_writable_elements): Implement
writable_elements in terms of elements.
* libguile/vectors.c (SCM_VALIDATE_MUTABLE_VECTOR): New helper.
(scm_vector_elements, scm_vector_writable_elements): Implement
writable_elements in terms of elements.
(scm_c_vector_set_x): Require a mutable vector.
* libguile/vectors.h (SCM_F_VECTOR_IMMUTABLE, SCM_I_IS_MUTABLE_VECTOR):
New definitions.
* libguile/vm-engine.c (VM_VALIDATE_MUTABLE_BYTEVECTOR):
(VM_VALIDATE_MUTABLE_VECTOR, vector-set!, vector-set!/immediate)
(BV_BOUNDED_SET, BV_SET): Require mutable bytevector/vector.
* libguile/vm.c (vm_error_not_a_mutable_bytevector):
(vm_error_not_a_mutable_vector): New definitions.
* module/system/vm/assembler.scm (link-data): Mark residualized vectors,
bytevectors, and bitvectors as being read-only.
2017-04-18 14:56:48 +02:00
|
|
|
|
GENERIC_INTEGER_SETTER_PROLOGUE (signed);
|
2009-05-27 18:18:07 +02:00
|
|
|
|
|
|
|
|
|
|
bytevector_signed_set (&c_bv[c_index], c_size, value, endianness,
|
|
|
|
|
|
FUNC_NAME);
|
|
|
|
|
|
|
|
|
|
|
|
return SCM_UNSPECIFIED;
|
|
|
|
|
|
}
|
|
|
|
|
|
#undef FUNC_NAME
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Operations on integers of arbitrary size. */
|
|
|
|
|
|
|
|
|
|
|
|
#define INTEGERS_TO_LIST(_sign) \
|
|
|
|
|
|
SCM lst, pair; \
|
|
|
|
|
|
size_t i, c_len, c_size; \
|
|
|
|
|
|
\
|
|
|
|
|
|
SCM_VALIDATE_BYTEVECTOR (1, bv); \
|
|
|
|
|
|
SCM_VALIDATE_SYMBOL (2, endianness); \
|
2013-08-16 22:54:39 -04:00
|
|
|
|
c_size = scm_to_unsigned_integer (size, 1, (size_t) -1); \
|
2009-05-27 18:18:07 +02:00
|
|
|
|
\
|
|
|
|
|
|
c_len = SCM_BYTEVECTOR_LENGTH (bv); \
|
2013-08-16 23:10:14 -04:00
|
|
|
|
if (SCM_UNLIKELY (c_len % c_size != 0)) \
|
|
|
|
|
|
scm_wrong_type_arg_msg \
|
|
|
|
|
|
(FUNC_NAME, 0, size, \
|
|
|
|
|
|
"an exact positive integer that divides the bytevector length"); \
|
|
|
|
|
|
else if (SCM_UNLIKELY (c_len == 0)) \
|
2009-05-27 18:18:07 +02:00
|
|
|
|
lst = SCM_EOL; \
|
|
|
|
|
|
else \
|
|
|
|
|
|
{ \
|
|
|
|
|
|
const char *c_bv; \
|
|
|
|
|
|
\
|
|
|
|
|
|
c_bv = (char *) SCM_BYTEVECTOR_CONTENTS (bv); \
|
|
|
|
|
|
\
|
2013-08-16 22:54:39 -04:00
|
|
|
|
lst = scm_make_list (scm_from_size_t (c_len / c_size), \
|
2009-05-27 18:18:07 +02:00
|
|
|
|
SCM_UNSPECIFIED); \
|
|
|
|
|
|
for (i = 0, pair = lst; \
|
|
|
|
|
|
i <= c_len - c_size; \
|
|
|
|
|
|
i += c_size, c_bv += c_size, pair = SCM_CDR (pair)) \
|
|
|
|
|
|
{ \
|
|
|
|
|
|
SCM_SETCAR (pair, \
|
|
|
|
|
|
bytevector_ ## _sign ## _ref (c_bv, c_size, \
|
|
|
|
|
|
endianness)); \
|
|
|
|
|
|
} \
|
|
|
|
|
|
} \
|
|
|
|
|
|
\
|
|
|
|
|
|
return lst;
|
|
|
|
|
|
|
|
|
|
|
|
SCM_DEFINE (scm_bytevector_to_sint_list, "bytevector->sint-list",
|
|
|
|
|
|
3, 0, 0,
|
|
|
|
|
|
(SCM bv, SCM endianness, SCM size),
|
|
|
|
|
|
"Return a list of signed integers of @var{size} octets "
|
|
|
|
|
|
"representing the contents of @var{bv}.")
|
|
|
|
|
|
#define FUNC_NAME s_scm_bytevector_to_sint_list
|
|
|
|
|
|
{
|
|
|
|
|
|
INTEGERS_TO_LIST (signed);
|
|
|
|
|
|
}
|
|
|
|
|
|
#undef FUNC_NAME
|
|
|
|
|
|
|
|
|
|
|
|
SCM_DEFINE (scm_bytevector_to_uint_list, "bytevector->uint-list",
|
|
|
|
|
|
3, 0, 0,
|
|
|
|
|
|
(SCM bv, SCM endianness, SCM size),
|
|
|
|
|
|
"Return a list of unsigned integers of @var{size} octets "
|
|
|
|
|
|
"representing the contents of @var{bv}.")
|
|
|
|
|
|
#define FUNC_NAME s_scm_bytevector_to_uint_list
|
|
|
|
|
|
{
|
|
|
|
|
|
INTEGERS_TO_LIST (unsigned);
|
|
|
|
|
|
}
|
|
|
|
|
|
#undef FUNC_NAME
|
|
|
|
|
|
|
|
|
|
|
|
#undef INTEGER_TO_LIST
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#define INTEGER_LIST_TO_BYTEVECTOR(_sign) \
|
|
|
|
|
|
SCM bv; \
|
2014-11-12 00:35:34 -05:00
|
|
|
|
size_t c_len; \
|
2009-05-27 18:18:07 +02:00
|
|
|
|
size_t c_size; \
|
|
|
|
|
|
char *c_bv, *c_bv_ptr; \
|
|
|
|
|
|
\
|
|
|
|
|
|
SCM_VALIDATE_LIST_COPYLEN (1, lst, c_len); \
|
|
|
|
|
|
SCM_VALIDATE_SYMBOL (2, endianness); \
|
2014-11-12 00:35:34 -05:00
|
|
|
|
c_size = scm_to_size_t (size); \
|
2009-05-27 18:18:07 +02:00
|
|
|
|
\
|
2015-01-22 13:16:49 +01:00
|
|
|
|
if (SCM_UNLIKELY (c_size == 0 || c_size >= (SIZE_MAX >> 3))) \
|
2009-05-27 18:18:07 +02:00
|
|
|
|
scm_out_of_range (FUNC_NAME, size); \
|
|
|
|
|
|
\
|
2014-11-12 00:35:34 -05:00
|
|
|
|
bv = make_bytevector (c_len * c_size, SCM_ARRAY_ELEMENT_TYPE_VU8); \
|
2009-05-27 18:18:07 +02:00
|
|
|
|
c_bv = (char *) SCM_BYTEVECTOR_CONTENTS (bv); \
|
|
|
|
|
|
\
|
|
|
|
|
|
for (c_bv_ptr = c_bv; \
|
|
|
|
|
|
!scm_is_null (lst); \
|
|
|
|
|
|
lst = SCM_CDR (lst), c_bv_ptr += c_size) \
|
|
|
|
|
|
{ \
|
|
|
|
|
|
bytevector_ ## _sign ## _set (c_bv_ptr, c_size, \
|
|
|
|
|
|
SCM_CAR (lst), endianness, \
|
|
|
|
|
|
FUNC_NAME); \
|
|
|
|
|
|
} \
|
|
|
|
|
|
\
|
|
|
|
|
|
return bv;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
SCM_DEFINE (scm_uint_list_to_bytevector, "uint-list->bytevector",
|
|
|
|
|
|
3, 0, 0,
|
|
|
|
|
|
(SCM lst, SCM endianness, SCM size),
|
|
|
|
|
|
"Return a bytevector containing the unsigned integers "
|
|
|
|
|
|
"listed in @var{lst} and encoded on @var{size} octets "
|
|
|
|
|
|
"according to @var{endianness}.")
|
|
|
|
|
|
#define FUNC_NAME s_scm_uint_list_to_bytevector
|
|
|
|
|
|
{
|
|
|
|
|
|
INTEGER_LIST_TO_BYTEVECTOR (unsigned);
|
|
|
|
|
|
}
|
|
|
|
|
|
#undef FUNC_NAME
|
|
|
|
|
|
|
|
|
|
|
|
SCM_DEFINE (scm_sint_list_to_bytevector, "sint-list->bytevector",
|
|
|
|
|
|
3, 0, 0,
|
|
|
|
|
|
(SCM lst, SCM endianness, SCM size),
|
|
|
|
|
|
"Return a bytevector containing the signed integers "
|
|
|
|
|
|
"listed in @var{lst} and encoded on @var{size} octets "
|
|
|
|
|
|
"according to @var{endianness}.")
|
|
|
|
|
|
#define FUNC_NAME s_scm_sint_list_to_bytevector
|
|
|
|
|
|
{
|
|
|
|
|
|
INTEGER_LIST_TO_BYTEVECTOR (signed);
|
|
|
|
|
|
}
|
|
|
|
|
|
#undef FUNC_NAME
|
|
|
|
|
|
|
|
|
|
|
|
#undef INTEGER_LIST_TO_BYTEVECTOR
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Operations on 16-bit integers. */
|
|
|
|
|
|
|
|
|
|
|
|
SCM_DEFINE (scm_bytevector_u16_ref, "bytevector-u16-ref",
|
|
|
|
|
|
3, 0, 0,
|
|
|
|
|
|
(SCM bv, SCM index, SCM endianness),
|
|
|
|
|
|
"Return the unsigned 16-bit integer from @var{bv} at "
|
|
|
|
|
|
"@var{index}.")
|
|
|
|
|
|
#define FUNC_NAME s_scm_bytevector_u16_ref
|
|
|
|
|
|
{
|
|
|
|
|
|
INTEGER_REF (16, unsigned);
|
|
|
|
|
|
}
|
|
|
|
|
|
#undef FUNC_NAME
|
|
|
|
|
|
|
|
|
|
|
|
SCM_DEFINE (scm_bytevector_s16_ref, "bytevector-s16-ref",
|
|
|
|
|
|
3, 0, 0,
|
|
|
|
|
|
(SCM bv, SCM index, SCM endianness),
|
|
|
|
|
|
"Return the signed 16-bit integer from @var{bv} at "
|
|
|
|
|
|
"@var{index}.")
|
|
|
|
|
|
#define FUNC_NAME s_scm_bytevector_s16_ref
|
|
|
|
|
|
{
|
|
|
|
|
|
INTEGER_REF (16, signed);
|
|
|
|
|
|
}
|
|
|
|
|
|
#undef FUNC_NAME
|
|
|
|
|
|
|
|
|
|
|
|
SCM_DEFINE (scm_bytevector_u16_native_ref, "bytevector-u16-native-ref",
|
|
|
|
|
|
2, 0, 0,
|
|
|
|
|
|
(SCM bv, SCM index),
|
|
|
|
|
|
"Return the unsigned 16-bit integer from @var{bv} at "
|
|
|
|
|
|
"@var{index} using the native endianness.")
|
|
|
|
|
|
#define FUNC_NAME s_scm_bytevector_u16_native_ref
|
|
|
|
|
|
{
|
|
|
|
|
|
INTEGER_NATIVE_REF (16, unsigned);
|
|
|
|
|
|
}
|
|
|
|
|
|
#undef FUNC_NAME
|
|
|
|
|
|
|
|
|
|
|
|
SCM_DEFINE (scm_bytevector_s16_native_ref, "bytevector-s16-native-ref",
|
|
|
|
|
|
2, 0, 0,
|
|
|
|
|
|
(SCM bv, SCM index),
|
|
|
|
|
|
"Return the unsigned 16-bit integer from @var{bv} at "
|
|
|
|
|
|
"@var{index} using the native endianness.")
|
|
|
|
|
|
#define FUNC_NAME s_scm_bytevector_s16_native_ref
|
|
|
|
|
|
{
|
|
|
|
|
|
INTEGER_NATIVE_REF (16, signed);
|
|
|
|
|
|
}
|
|
|
|
|
|
#undef FUNC_NAME
|
|
|
|
|
|
|
|
|
|
|
|
SCM_DEFINE (scm_bytevector_u16_set_x, "bytevector-u16-set!",
|
|
|
|
|
|
4, 0, 0,
|
|
|
|
|
|
(SCM bv, SCM index, SCM value, SCM endianness),
|
|
|
|
|
|
"Store @var{value} in @var{bv} at @var{index} according to "
|
|
|
|
|
|
"@var{endianness}.")
|
|
|
|
|
|
#define FUNC_NAME s_scm_bytevector_u16_set_x
|
|
|
|
|
|
{
|
|
|
|
|
|
INTEGER_SET (16, unsigned);
|
|
|
|
|
|
}
|
|
|
|
|
|
#undef FUNC_NAME
|
|
|
|
|
|
|
|
|
|
|
|
SCM_DEFINE (scm_bytevector_s16_set_x, "bytevector-s16-set!",
|
|
|
|
|
|
4, 0, 0,
|
|
|
|
|
|
(SCM bv, SCM index, SCM value, SCM endianness),
|
|
|
|
|
|
"Store @var{value} in @var{bv} at @var{index} according to "
|
|
|
|
|
|
"@var{endianness}.")
|
|
|
|
|
|
#define FUNC_NAME s_scm_bytevector_s16_set_x
|
|
|
|
|
|
{
|
|
|
|
|
|
INTEGER_SET (16, signed);
|
|
|
|
|
|
}
|
|
|
|
|
|
#undef FUNC_NAME
|
|
|
|
|
|
|
|
|
|
|
|
SCM_DEFINE (scm_bytevector_u16_native_set_x, "bytevector-u16-native-set!",
|
|
|
|
|
|
3, 0, 0,
|
|
|
|
|
|
(SCM bv, SCM index, SCM value),
|
|
|
|
|
|
"Store the unsigned integer @var{value} at index @var{index} "
|
|
|
|
|
|
"of @var{bv} using the native endianness.")
|
|
|
|
|
|
#define FUNC_NAME s_scm_bytevector_u16_native_set_x
|
|
|
|
|
|
{
|
|
|
|
|
|
INTEGER_NATIVE_SET (16, unsigned);
|
|
|
|
|
|
}
|
|
|
|
|
|
#undef FUNC_NAME
|
|
|
|
|
|
|
|
|
|
|
|
SCM_DEFINE (scm_bytevector_s16_native_set_x, "bytevector-s16-native-set!",
|
|
|
|
|
|
3, 0, 0,
|
|
|
|
|
|
(SCM bv, SCM index, SCM value),
|
|
|
|
|
|
"Store the signed integer @var{value} at index @var{index} "
|
|
|
|
|
|
"of @var{bv} using the native endianness.")
|
|
|
|
|
|
#define FUNC_NAME s_scm_bytevector_s16_native_set_x
|
|
|
|
|
|
{
|
|
|
|
|
|
INTEGER_NATIVE_SET (16, signed);
|
|
|
|
|
|
}
|
|
|
|
|
|
#undef FUNC_NAME
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Operations on 32-bit integers. */
|
|
|
|
|
|
|
|
|
|
|
|
/* Unfortunately, on 32-bit machines `SCM' is not large enough to hold
|
|
|
|
|
|
arbitrary 32-bit integers. Thus we fall back to using the
|
|
|
|
|
|
`large_{ref,set}' variants on 32-bit machines. */
|
|
|
|
|
|
|
|
|
|
|
|
#define LARGE_INTEGER_REF(_len, _sign) \
|
All literal constants are read-only
* libguile/array-handle.c (initialize_vector_handle): Add mutable_p
argument. Unless the vector handle is mutable, null out its
writable_elements member.
(scm_array_get_handle): Adapt to determine mutability of the various
arrays.
(scm_array_handle_elements, scm_array_handle_writable_elements):
Reverse the sense: instead of implementing read-only in terms of
read-write, go the other way around, adding an assertion in the
read-write case that the array handle is mutable.
* libguile/array-map.c (racp): Assert that the destination is mutable.
* libguile/bitvectors.c (SCM_F_BITVECTOR_IMMUTABLE, IS_BITVECTOR):
(IS_MUTABLE_BITVECTOR): Add a flag to indicate immutability.
(scm_i_bitvector_bits): Fix indentation.
(scm_i_is_mutable_bitvector): New helper.
(scm_array_handle_bit_elements)
((scm_array_handle_bit_writable_elements): Build writable_elements in
terms of elements.
(scm_bitvector_elements, scm_bitvector_writable_elements): Likewise.
(scm_c_bitvector_set_x): Require a mutable bitvector for the
fast-path.
(scm_bitvector_to_list, scm_bit_count): Use read-only elements()
function.
* libguile/bitvectors.h (scm_i_is_mutable_bitvector): New decl.
* libguile/bytevectors.c (INTEGER_ACCESSOR_PROLOGUE):
(INTEGER_GETTER_PROLOGUE, INTEGER_SETTER_PROLOGUE):
(INTEGER_REF, INTEGER_NATIVE_REF, INTEGER_SET, INTEGER_NATIVE_SET):
(GENERIC_INTEGER_ACCESSOR_PROLOGUE):
(GENERIC_INTEGER_GETTER_PROLOGUE, GENERIC_INTEGER_SETTER_PROLOGUE):
(LARGE_INTEGER_NATIVE_REF, LARGE_INTEGER_NATIVE_SET):
(IEEE754_GETTER_PROLOGUE, IEEE754_SETTER_PROLOGUE):
(IEEE754_REF, IEEE754_NATIVE_REF, IEEE754_SET, IEEE754_NATIVE_SET):
Setters require a mutable bytevector.
(SCM_BYTEVECTOR_SET_FLAG): New helper.
(SCM_BYTEVECTOR_SET_CONTIGUOUS_P, SCM_BYTEVECTOR_SET_ELEMENT_TYPE):
Remove helpers.
(SCM_VALIDATE_MUTABLE_BYTEVECTOR): New helper.
(make_bytevector, make_bytevector_from_buffer): Use
SCM_SET_BYTEVECTOR_FLAGS.
(scm_c_bytevector_set_x, scm_bytevector_fill_x)
(scm_bytevector_copy_x): Require a mutable bytevector.
* libguile/bytevectors.h (SCM_F_BYTEVECTOR_CONTIGUOUS)
(SCM_F_BYTEVECTOR_IMMUTABLE, SCM_MUTABLE_BYTEVECTOR_P): New
definitions.
* libguile/bytevectors.h (SCM_BYTEVECTOR_CONTIGUOUS_P): Just access one
bit.
* libguile/srfi-4.c (DEFINE_SRFI_4_C_FUNCS): Implement
writable_elements() in terms of elements().
* libguile/strings.c (scm_i_string_is_mutable): New helper.
* libguile/uniform.c (scm_array_handle_uniform_elements):
(scm_array_handle_uniform_writable_elements): Implement
writable_elements in terms of elements.
* libguile/vectors.c (SCM_VALIDATE_MUTABLE_VECTOR): New helper.
(scm_vector_elements, scm_vector_writable_elements): Implement
writable_elements in terms of elements.
(scm_c_vector_set_x): Require a mutable vector.
* libguile/vectors.h (SCM_F_VECTOR_IMMUTABLE, SCM_I_IS_MUTABLE_VECTOR):
New definitions.
* libguile/vm-engine.c (VM_VALIDATE_MUTABLE_BYTEVECTOR):
(VM_VALIDATE_MUTABLE_VECTOR, vector-set!, vector-set!/immediate)
(BV_BOUNDED_SET, BV_SET): Require mutable bytevector/vector.
* libguile/vm.c (vm_error_not_a_mutable_bytevector):
(vm_error_not_a_mutable_vector): New definitions.
* module/system/vm/assembler.scm (link-data): Mark residualized vectors,
bytevectors, and bitvectors as being read-only.
2017-04-18 14:56:48 +02:00
|
|
|
|
INTEGER_GETTER_PROLOGUE(_len, _sign); \
|
2009-05-27 18:18:07 +02:00
|
|
|
|
SCM_VALIDATE_SYMBOL (3, endianness); \
|
|
|
|
|
|
\
|
|
|
|
|
|
return (bytevector_large_ref ((char *) c_bv + c_index, _len / 8, \
|
|
|
|
|
|
SIGNEDNESS (_sign), endianness));
|
|
|
|
|
|
|
|
|
|
|
|
#define LARGE_INTEGER_SET(_len, _sign) \
|
|
|
|
|
|
int err; \
|
All literal constants are read-only
* libguile/array-handle.c (initialize_vector_handle): Add mutable_p
argument. Unless the vector handle is mutable, null out its
writable_elements member.
(scm_array_get_handle): Adapt to determine mutability of the various
arrays.
(scm_array_handle_elements, scm_array_handle_writable_elements):
Reverse the sense: instead of implementing read-only in terms of
read-write, go the other way around, adding an assertion in the
read-write case that the array handle is mutable.
* libguile/array-map.c (racp): Assert that the destination is mutable.
* libguile/bitvectors.c (SCM_F_BITVECTOR_IMMUTABLE, IS_BITVECTOR):
(IS_MUTABLE_BITVECTOR): Add a flag to indicate immutability.
(scm_i_bitvector_bits): Fix indentation.
(scm_i_is_mutable_bitvector): New helper.
(scm_array_handle_bit_elements)
((scm_array_handle_bit_writable_elements): Build writable_elements in
terms of elements.
(scm_bitvector_elements, scm_bitvector_writable_elements): Likewise.
(scm_c_bitvector_set_x): Require a mutable bitvector for the
fast-path.
(scm_bitvector_to_list, scm_bit_count): Use read-only elements()
function.
* libguile/bitvectors.h (scm_i_is_mutable_bitvector): New decl.
* libguile/bytevectors.c (INTEGER_ACCESSOR_PROLOGUE):
(INTEGER_GETTER_PROLOGUE, INTEGER_SETTER_PROLOGUE):
(INTEGER_REF, INTEGER_NATIVE_REF, INTEGER_SET, INTEGER_NATIVE_SET):
(GENERIC_INTEGER_ACCESSOR_PROLOGUE):
(GENERIC_INTEGER_GETTER_PROLOGUE, GENERIC_INTEGER_SETTER_PROLOGUE):
(LARGE_INTEGER_NATIVE_REF, LARGE_INTEGER_NATIVE_SET):
(IEEE754_GETTER_PROLOGUE, IEEE754_SETTER_PROLOGUE):
(IEEE754_REF, IEEE754_NATIVE_REF, IEEE754_SET, IEEE754_NATIVE_SET):
Setters require a mutable bytevector.
(SCM_BYTEVECTOR_SET_FLAG): New helper.
(SCM_BYTEVECTOR_SET_CONTIGUOUS_P, SCM_BYTEVECTOR_SET_ELEMENT_TYPE):
Remove helpers.
(SCM_VALIDATE_MUTABLE_BYTEVECTOR): New helper.
(make_bytevector, make_bytevector_from_buffer): Use
SCM_SET_BYTEVECTOR_FLAGS.
(scm_c_bytevector_set_x, scm_bytevector_fill_x)
(scm_bytevector_copy_x): Require a mutable bytevector.
* libguile/bytevectors.h (SCM_F_BYTEVECTOR_CONTIGUOUS)
(SCM_F_BYTEVECTOR_IMMUTABLE, SCM_MUTABLE_BYTEVECTOR_P): New
definitions.
* libguile/bytevectors.h (SCM_BYTEVECTOR_CONTIGUOUS_P): Just access one
bit.
* libguile/srfi-4.c (DEFINE_SRFI_4_C_FUNCS): Implement
writable_elements() in terms of elements().
* libguile/strings.c (scm_i_string_is_mutable): New helper.
* libguile/uniform.c (scm_array_handle_uniform_elements):
(scm_array_handle_uniform_writable_elements): Implement
writable_elements in terms of elements.
* libguile/vectors.c (SCM_VALIDATE_MUTABLE_VECTOR): New helper.
(scm_vector_elements, scm_vector_writable_elements): Implement
writable_elements in terms of elements.
(scm_c_vector_set_x): Require a mutable vector.
* libguile/vectors.h (SCM_F_VECTOR_IMMUTABLE, SCM_I_IS_MUTABLE_VECTOR):
New definitions.
* libguile/vm-engine.c (VM_VALIDATE_MUTABLE_BYTEVECTOR):
(VM_VALIDATE_MUTABLE_VECTOR, vector-set!, vector-set!/immediate)
(BV_BOUNDED_SET, BV_SET): Require mutable bytevector/vector.
* libguile/vm.c (vm_error_not_a_mutable_bytevector):
(vm_error_not_a_mutable_vector): New definitions.
* module/system/vm/assembler.scm (link-data): Mark residualized vectors,
bytevectors, and bitvectors as being read-only.
2017-04-18 14:56:48 +02:00
|
|
|
|
INTEGER_SETTER_PROLOGUE (_len, _sign); \
|
2009-05-27 18:18:07 +02:00
|
|
|
|
SCM_VALIDATE_SYMBOL (4, endianness); \
|
|
|
|
|
|
\
|
|
|
|
|
|
err = bytevector_large_set ((char *) c_bv + c_index, _len / 8, \
|
|
|
|
|
|
SIGNEDNESS (_sign), value, endianness); \
|
|
|
|
|
|
if (SCM_UNLIKELY (err)) \
|
|
|
|
|
|
scm_out_of_range (FUNC_NAME, value); \
|
|
|
|
|
|
\
|
|
|
|
|
|
return SCM_UNSPECIFIED;
|
|
|
|
|
|
|
All literal constants are read-only
* libguile/array-handle.c (initialize_vector_handle): Add mutable_p
argument. Unless the vector handle is mutable, null out its
writable_elements member.
(scm_array_get_handle): Adapt to determine mutability of the various
arrays.
(scm_array_handle_elements, scm_array_handle_writable_elements):
Reverse the sense: instead of implementing read-only in terms of
read-write, go the other way around, adding an assertion in the
read-write case that the array handle is mutable.
* libguile/array-map.c (racp): Assert that the destination is mutable.
* libguile/bitvectors.c (SCM_F_BITVECTOR_IMMUTABLE, IS_BITVECTOR):
(IS_MUTABLE_BITVECTOR): Add a flag to indicate immutability.
(scm_i_bitvector_bits): Fix indentation.
(scm_i_is_mutable_bitvector): New helper.
(scm_array_handle_bit_elements)
((scm_array_handle_bit_writable_elements): Build writable_elements in
terms of elements.
(scm_bitvector_elements, scm_bitvector_writable_elements): Likewise.
(scm_c_bitvector_set_x): Require a mutable bitvector for the
fast-path.
(scm_bitvector_to_list, scm_bit_count): Use read-only elements()
function.
* libguile/bitvectors.h (scm_i_is_mutable_bitvector): New decl.
* libguile/bytevectors.c (INTEGER_ACCESSOR_PROLOGUE):
(INTEGER_GETTER_PROLOGUE, INTEGER_SETTER_PROLOGUE):
(INTEGER_REF, INTEGER_NATIVE_REF, INTEGER_SET, INTEGER_NATIVE_SET):
(GENERIC_INTEGER_ACCESSOR_PROLOGUE):
(GENERIC_INTEGER_GETTER_PROLOGUE, GENERIC_INTEGER_SETTER_PROLOGUE):
(LARGE_INTEGER_NATIVE_REF, LARGE_INTEGER_NATIVE_SET):
(IEEE754_GETTER_PROLOGUE, IEEE754_SETTER_PROLOGUE):
(IEEE754_REF, IEEE754_NATIVE_REF, IEEE754_SET, IEEE754_NATIVE_SET):
Setters require a mutable bytevector.
(SCM_BYTEVECTOR_SET_FLAG): New helper.
(SCM_BYTEVECTOR_SET_CONTIGUOUS_P, SCM_BYTEVECTOR_SET_ELEMENT_TYPE):
Remove helpers.
(SCM_VALIDATE_MUTABLE_BYTEVECTOR): New helper.
(make_bytevector, make_bytevector_from_buffer): Use
SCM_SET_BYTEVECTOR_FLAGS.
(scm_c_bytevector_set_x, scm_bytevector_fill_x)
(scm_bytevector_copy_x): Require a mutable bytevector.
* libguile/bytevectors.h (SCM_F_BYTEVECTOR_CONTIGUOUS)
(SCM_F_BYTEVECTOR_IMMUTABLE, SCM_MUTABLE_BYTEVECTOR_P): New
definitions.
* libguile/bytevectors.h (SCM_BYTEVECTOR_CONTIGUOUS_P): Just access one
bit.
* libguile/srfi-4.c (DEFINE_SRFI_4_C_FUNCS): Implement
writable_elements() in terms of elements().
* libguile/strings.c (scm_i_string_is_mutable): New helper.
* libguile/uniform.c (scm_array_handle_uniform_elements):
(scm_array_handle_uniform_writable_elements): Implement
writable_elements in terms of elements.
* libguile/vectors.c (SCM_VALIDATE_MUTABLE_VECTOR): New helper.
(scm_vector_elements, scm_vector_writable_elements): Implement
writable_elements in terms of elements.
(scm_c_vector_set_x): Require a mutable vector.
* libguile/vectors.h (SCM_F_VECTOR_IMMUTABLE, SCM_I_IS_MUTABLE_VECTOR):
New definitions.
* libguile/vm-engine.c (VM_VALIDATE_MUTABLE_BYTEVECTOR):
(VM_VALIDATE_MUTABLE_VECTOR, vector-set!, vector-set!/immediate)
(BV_BOUNDED_SET, BV_SET): Require mutable bytevector/vector.
* libguile/vm.c (vm_error_not_a_mutable_bytevector):
(vm_error_not_a_mutable_vector): New definitions.
* module/system/vm/assembler.scm (link-data): Mark residualized vectors,
bytevectors, and bitvectors as being read-only.
2017-04-18 14:56:48 +02:00
|
|
|
|
#define LARGE_INTEGER_NATIVE_REF(_len, _sign) \
|
|
|
|
|
|
INTEGER_GETTER_PROLOGUE(_len, _sign); \
|
|
|
|
|
|
return (bytevector_large_ref ((char *) c_bv + c_index, _len / 8, \
|
2009-06-24 23:46:42 +02:00
|
|
|
|
SIGNEDNESS (_sign), scm_i_native_endianness));
|
2009-05-27 18:18:07 +02:00
|
|
|
|
|
|
|
|
|
|
#define LARGE_INTEGER_NATIVE_SET(_len, _sign) \
|
|
|
|
|
|
int err; \
|
All literal constants are read-only
* libguile/array-handle.c (initialize_vector_handle): Add mutable_p
argument. Unless the vector handle is mutable, null out its
writable_elements member.
(scm_array_get_handle): Adapt to determine mutability of the various
arrays.
(scm_array_handle_elements, scm_array_handle_writable_elements):
Reverse the sense: instead of implementing read-only in terms of
read-write, go the other way around, adding an assertion in the
read-write case that the array handle is mutable.
* libguile/array-map.c (racp): Assert that the destination is mutable.
* libguile/bitvectors.c (SCM_F_BITVECTOR_IMMUTABLE, IS_BITVECTOR):
(IS_MUTABLE_BITVECTOR): Add a flag to indicate immutability.
(scm_i_bitvector_bits): Fix indentation.
(scm_i_is_mutable_bitvector): New helper.
(scm_array_handle_bit_elements)
((scm_array_handle_bit_writable_elements): Build writable_elements in
terms of elements.
(scm_bitvector_elements, scm_bitvector_writable_elements): Likewise.
(scm_c_bitvector_set_x): Require a mutable bitvector for the
fast-path.
(scm_bitvector_to_list, scm_bit_count): Use read-only elements()
function.
* libguile/bitvectors.h (scm_i_is_mutable_bitvector): New decl.
* libguile/bytevectors.c (INTEGER_ACCESSOR_PROLOGUE):
(INTEGER_GETTER_PROLOGUE, INTEGER_SETTER_PROLOGUE):
(INTEGER_REF, INTEGER_NATIVE_REF, INTEGER_SET, INTEGER_NATIVE_SET):
(GENERIC_INTEGER_ACCESSOR_PROLOGUE):
(GENERIC_INTEGER_GETTER_PROLOGUE, GENERIC_INTEGER_SETTER_PROLOGUE):
(LARGE_INTEGER_NATIVE_REF, LARGE_INTEGER_NATIVE_SET):
(IEEE754_GETTER_PROLOGUE, IEEE754_SETTER_PROLOGUE):
(IEEE754_REF, IEEE754_NATIVE_REF, IEEE754_SET, IEEE754_NATIVE_SET):
Setters require a mutable bytevector.
(SCM_BYTEVECTOR_SET_FLAG): New helper.
(SCM_BYTEVECTOR_SET_CONTIGUOUS_P, SCM_BYTEVECTOR_SET_ELEMENT_TYPE):
Remove helpers.
(SCM_VALIDATE_MUTABLE_BYTEVECTOR): New helper.
(make_bytevector, make_bytevector_from_buffer): Use
SCM_SET_BYTEVECTOR_FLAGS.
(scm_c_bytevector_set_x, scm_bytevector_fill_x)
(scm_bytevector_copy_x): Require a mutable bytevector.
* libguile/bytevectors.h (SCM_F_BYTEVECTOR_CONTIGUOUS)
(SCM_F_BYTEVECTOR_IMMUTABLE, SCM_MUTABLE_BYTEVECTOR_P): New
definitions.
* libguile/bytevectors.h (SCM_BYTEVECTOR_CONTIGUOUS_P): Just access one
bit.
* libguile/srfi-4.c (DEFINE_SRFI_4_C_FUNCS): Implement
writable_elements() in terms of elements().
* libguile/strings.c (scm_i_string_is_mutable): New helper.
* libguile/uniform.c (scm_array_handle_uniform_elements):
(scm_array_handle_uniform_writable_elements): Implement
writable_elements in terms of elements.
* libguile/vectors.c (SCM_VALIDATE_MUTABLE_VECTOR): New helper.
(scm_vector_elements, scm_vector_writable_elements): Implement
writable_elements in terms of elements.
(scm_c_vector_set_x): Require a mutable vector.
* libguile/vectors.h (SCM_F_VECTOR_IMMUTABLE, SCM_I_IS_MUTABLE_VECTOR):
New definitions.
* libguile/vm-engine.c (VM_VALIDATE_MUTABLE_BYTEVECTOR):
(VM_VALIDATE_MUTABLE_VECTOR, vector-set!, vector-set!/immediate)
(BV_BOUNDED_SET, BV_SET): Require mutable bytevector/vector.
* libguile/vm.c (vm_error_not_a_mutable_bytevector):
(vm_error_not_a_mutable_vector): New definitions.
* module/system/vm/assembler.scm (link-data): Mark residualized vectors,
bytevectors, and bitvectors as being read-only.
2017-04-18 14:56:48 +02:00
|
|
|
|
INTEGER_SETTER_PROLOGUE (_len, _sign); \
|
2009-05-27 18:18:07 +02:00
|
|
|
|
\
|
|
|
|
|
|
err = bytevector_large_set ((char *) c_bv + c_index, _len / 8, \
|
|
|
|
|
|
SIGNEDNESS (_sign), value, \
|
2009-06-24 23:46:42 +02:00
|
|
|
|
scm_i_native_endianness); \
|
2009-05-27 18:18:07 +02:00
|
|
|
|
if (SCM_UNLIKELY (err)) \
|
|
|
|
|
|
scm_out_of_range (FUNC_NAME, value); \
|
|
|
|
|
|
\
|
|
|
|
|
|
return SCM_UNSPECIFIED;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
SCM_DEFINE (scm_bytevector_u32_ref, "bytevector-u32-ref",
|
|
|
|
|
|
3, 0, 0,
|
|
|
|
|
|
(SCM bv, SCM index, SCM endianness),
|
|
|
|
|
|
"Return the unsigned 32-bit integer from @var{bv} at "
|
|
|
|
|
|
"@var{index}.")
|
|
|
|
|
|
#define FUNC_NAME s_scm_bytevector_u32_ref
|
|
|
|
|
|
{
|
|
|
|
|
|
#if SIZEOF_VOID_P > 4
|
|
|
|
|
|
INTEGER_REF (32, unsigned);
|
|
|
|
|
|
#else
|
|
|
|
|
|
LARGE_INTEGER_REF (32, unsigned);
|
|
|
|
|
|
#endif
|
|
|
|
|
|
}
|
|
|
|
|
|
#undef FUNC_NAME
|
|
|
|
|
|
|
|
|
|
|
|
SCM_DEFINE (scm_bytevector_s32_ref, "bytevector-s32-ref",
|
|
|
|
|
|
3, 0, 0,
|
|
|
|
|
|
(SCM bv, SCM index, SCM endianness),
|
|
|
|
|
|
"Return the signed 32-bit integer from @var{bv} at "
|
|
|
|
|
|
"@var{index}.")
|
|
|
|
|
|
#define FUNC_NAME s_scm_bytevector_s32_ref
|
|
|
|
|
|
{
|
|
|
|
|
|
#if SIZEOF_VOID_P > 4
|
|
|
|
|
|
INTEGER_REF (32, signed);
|
|
|
|
|
|
#else
|
|
|
|
|
|
LARGE_INTEGER_REF (32, signed);
|
|
|
|
|
|
#endif
|
|
|
|
|
|
}
|
|
|
|
|
|
#undef FUNC_NAME
|
|
|
|
|
|
|
|
|
|
|
|
SCM_DEFINE (scm_bytevector_u32_native_ref, "bytevector-u32-native-ref",
|
|
|
|
|
|
2, 0, 0,
|
|
|
|
|
|
(SCM bv, SCM index),
|
|
|
|
|
|
"Return the unsigned 32-bit integer from @var{bv} at "
|
|
|
|
|
|
"@var{index} using the native endianness.")
|
|
|
|
|
|
#define FUNC_NAME s_scm_bytevector_u32_native_ref
|
|
|
|
|
|
{
|
|
|
|
|
|
#if SIZEOF_VOID_P > 4
|
|
|
|
|
|
INTEGER_NATIVE_REF (32, unsigned);
|
|
|
|
|
|
#else
|
|
|
|
|
|
LARGE_INTEGER_NATIVE_REF (32, unsigned);
|
|
|
|
|
|
#endif
|
|
|
|
|
|
}
|
|
|
|
|
|
#undef FUNC_NAME
|
|
|
|
|
|
|
|
|
|
|
|
SCM_DEFINE (scm_bytevector_s32_native_ref, "bytevector-s32-native-ref",
|
|
|
|
|
|
2, 0, 0,
|
|
|
|
|
|
(SCM bv, SCM index),
|
|
|
|
|
|
"Return the unsigned 32-bit integer from @var{bv} at "
|
|
|
|
|
|
"@var{index} using the native endianness.")
|
|
|
|
|
|
#define FUNC_NAME s_scm_bytevector_s32_native_ref
|
|
|
|
|
|
{
|
|
|
|
|
|
#if SIZEOF_VOID_P > 4
|
|
|
|
|
|
INTEGER_NATIVE_REF (32, signed);
|
|
|
|
|
|
#else
|
|
|
|
|
|
LARGE_INTEGER_NATIVE_REF (32, signed);
|
|
|
|
|
|
#endif
|
|
|
|
|
|
}
|
|
|
|
|
|
#undef FUNC_NAME
|
|
|
|
|
|
|
|
|
|
|
|
SCM_DEFINE (scm_bytevector_u32_set_x, "bytevector-u32-set!",
|
|
|
|
|
|
4, 0, 0,
|
|
|
|
|
|
(SCM bv, SCM index, SCM value, SCM endianness),
|
|
|
|
|
|
"Store @var{value} in @var{bv} at @var{index} according to "
|
|
|
|
|
|
"@var{endianness}.")
|
|
|
|
|
|
#define FUNC_NAME s_scm_bytevector_u32_set_x
|
|
|
|
|
|
{
|
|
|
|
|
|
#if SIZEOF_VOID_P > 4
|
|
|
|
|
|
INTEGER_SET (32, unsigned);
|
|
|
|
|
|
#else
|
|
|
|
|
|
LARGE_INTEGER_SET (32, unsigned);
|
|
|
|
|
|
#endif
|
|
|
|
|
|
}
|
|
|
|
|
|
#undef FUNC_NAME
|
|
|
|
|
|
|
|
|
|
|
|
SCM_DEFINE (scm_bytevector_s32_set_x, "bytevector-s32-set!",
|
|
|
|
|
|
4, 0, 0,
|
|
|
|
|
|
(SCM bv, SCM index, SCM value, SCM endianness),
|
|
|
|
|
|
"Store @var{value} in @var{bv} at @var{index} according to "
|
|
|
|
|
|
"@var{endianness}.")
|
|
|
|
|
|
#define FUNC_NAME s_scm_bytevector_s32_set_x
|
|
|
|
|
|
{
|
|
|
|
|
|
#if SIZEOF_VOID_P > 4
|
|
|
|
|
|
INTEGER_SET (32, signed);
|
|
|
|
|
|
#else
|
|
|
|
|
|
LARGE_INTEGER_SET (32, signed);
|
|
|
|
|
|
#endif
|
|
|
|
|
|
}
|
|
|
|
|
|
#undef FUNC_NAME
|
|
|
|
|
|
|
|
|
|
|
|
SCM_DEFINE (scm_bytevector_u32_native_set_x, "bytevector-u32-native-set!",
|
|
|
|
|
|
3, 0, 0,
|
|
|
|
|
|
(SCM bv, SCM index, SCM value),
|
|
|
|
|
|
"Store the unsigned integer @var{value} at index @var{index} "
|
|
|
|
|
|
"of @var{bv} using the native endianness.")
|
|
|
|
|
|
#define FUNC_NAME s_scm_bytevector_u32_native_set_x
|
|
|
|
|
|
{
|
|
|
|
|
|
#if SIZEOF_VOID_P > 4
|
|
|
|
|
|
INTEGER_NATIVE_SET (32, unsigned);
|
|
|
|
|
|
#else
|
|
|
|
|
|
LARGE_INTEGER_NATIVE_SET (32, unsigned);
|
|
|
|
|
|
#endif
|
|
|
|
|
|
}
|
|
|
|
|
|
#undef FUNC_NAME
|
|
|
|
|
|
|
|
|
|
|
|
SCM_DEFINE (scm_bytevector_s32_native_set_x, "bytevector-s32-native-set!",
|
|
|
|
|
|
3, 0, 0,
|
|
|
|
|
|
(SCM bv, SCM index, SCM value),
|
|
|
|
|
|
"Store the signed integer @var{value} at index @var{index} "
|
|
|
|
|
|
"of @var{bv} using the native endianness.")
|
|
|
|
|
|
#define FUNC_NAME s_scm_bytevector_s32_native_set_x
|
|
|
|
|
|
{
|
|
|
|
|
|
#if SIZEOF_VOID_P > 4
|
|
|
|
|
|
INTEGER_NATIVE_SET (32, signed);
|
|
|
|
|
|
#else
|
|
|
|
|
|
LARGE_INTEGER_NATIVE_SET (32, signed);
|
|
|
|
|
|
#endif
|
|
|
|
|
|
}
|
|
|
|
|
|
#undef FUNC_NAME
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Operations on 64-bit integers. */
|
|
|
|
|
|
|
|
|
|
|
|
/* For 64-bit integers, we use only the `large_{ref,set}' variant. */
|
|
|
|
|
|
|
|
|
|
|
|
SCM_DEFINE (scm_bytevector_u64_ref, "bytevector-u64-ref",
|
|
|
|
|
|
3, 0, 0,
|
|
|
|
|
|
(SCM bv, SCM index, SCM endianness),
|
|
|
|
|
|
"Return the unsigned 64-bit integer from @var{bv} at "
|
|
|
|
|
|
"@var{index}.")
|
|
|
|
|
|
#define FUNC_NAME s_scm_bytevector_u64_ref
|
|
|
|
|
|
{
|
|
|
|
|
|
LARGE_INTEGER_REF (64, unsigned);
|
|
|
|
|
|
}
|
|
|
|
|
|
#undef FUNC_NAME
|
|
|
|
|
|
|
|
|
|
|
|
SCM_DEFINE (scm_bytevector_s64_ref, "bytevector-s64-ref",
|
|
|
|
|
|
3, 0, 0,
|
|
|
|
|
|
(SCM bv, SCM index, SCM endianness),
|
|
|
|
|
|
"Return the signed 64-bit integer from @var{bv} at "
|
|
|
|
|
|
"@var{index}.")
|
|
|
|
|
|
#define FUNC_NAME s_scm_bytevector_s64_ref
|
|
|
|
|
|
{
|
|
|
|
|
|
LARGE_INTEGER_REF (64, signed);
|
|
|
|
|
|
}
|
|
|
|
|
|
#undef FUNC_NAME
|
|
|
|
|
|
|
|
|
|
|
|
SCM_DEFINE (scm_bytevector_u64_native_ref, "bytevector-u64-native-ref",
|
|
|
|
|
|
2, 0, 0,
|
|
|
|
|
|
(SCM bv, SCM index),
|
|
|
|
|
|
"Return the unsigned 64-bit integer from @var{bv} at "
|
|
|
|
|
|
"@var{index} using the native endianness.")
|
|
|
|
|
|
#define FUNC_NAME s_scm_bytevector_u64_native_ref
|
|
|
|
|
|
{
|
|
|
|
|
|
LARGE_INTEGER_NATIVE_REF (64, unsigned);
|
|
|
|
|
|
}
|
|
|
|
|
|
#undef FUNC_NAME
|
|
|
|
|
|
|
|
|
|
|
|
SCM_DEFINE (scm_bytevector_s64_native_ref, "bytevector-s64-native-ref",
|
|
|
|
|
|
2, 0, 0,
|
|
|
|
|
|
(SCM bv, SCM index),
|
|
|
|
|
|
"Return the unsigned 64-bit integer from @var{bv} at "
|
|
|
|
|
|
"@var{index} using the native endianness.")
|
|
|
|
|
|
#define FUNC_NAME s_scm_bytevector_s64_native_ref
|
|
|
|
|
|
{
|
|
|
|
|
|
LARGE_INTEGER_NATIVE_REF (64, signed);
|
|
|
|
|
|
}
|
|
|
|
|
|
#undef FUNC_NAME
|
|
|
|
|
|
|
|
|
|
|
|
SCM_DEFINE (scm_bytevector_u64_set_x, "bytevector-u64-set!",
|
|
|
|
|
|
4, 0, 0,
|
|
|
|
|
|
(SCM bv, SCM index, SCM value, SCM endianness),
|
|
|
|
|
|
"Store @var{value} in @var{bv} at @var{index} according to "
|
|
|
|
|
|
"@var{endianness}.")
|
|
|
|
|
|
#define FUNC_NAME s_scm_bytevector_u64_set_x
|
|
|
|
|
|
{
|
|
|
|
|
|
LARGE_INTEGER_SET (64, unsigned);
|
|
|
|
|
|
}
|
|
|
|
|
|
#undef FUNC_NAME
|
|
|
|
|
|
|
|
|
|
|
|
SCM_DEFINE (scm_bytevector_s64_set_x, "bytevector-s64-set!",
|
|
|
|
|
|
4, 0, 0,
|
|
|
|
|
|
(SCM bv, SCM index, SCM value, SCM endianness),
|
|
|
|
|
|
"Store @var{value} in @var{bv} at @var{index} according to "
|
|
|
|
|
|
"@var{endianness}.")
|
|
|
|
|
|
#define FUNC_NAME s_scm_bytevector_s64_set_x
|
|
|
|
|
|
{
|
|
|
|
|
|
LARGE_INTEGER_SET (64, signed);
|
|
|
|
|
|
}
|
|
|
|
|
|
#undef FUNC_NAME
|
|
|
|
|
|
|
|
|
|
|
|
SCM_DEFINE (scm_bytevector_u64_native_set_x, "bytevector-u64-native-set!",
|
|
|
|
|
|
3, 0, 0,
|
|
|
|
|
|
(SCM bv, SCM index, SCM value),
|
|
|
|
|
|
"Store the unsigned integer @var{value} at index @var{index} "
|
|
|
|
|
|
"of @var{bv} using the native endianness.")
|
|
|
|
|
|
#define FUNC_NAME s_scm_bytevector_u64_native_set_x
|
|
|
|
|
|
{
|
|
|
|
|
|
LARGE_INTEGER_NATIVE_SET (64, unsigned);
|
|
|
|
|
|
}
|
|
|
|
|
|
#undef FUNC_NAME
|
|
|
|
|
|
|
|
|
|
|
|
SCM_DEFINE (scm_bytevector_s64_native_set_x, "bytevector-s64-native-set!",
|
|
|
|
|
|
3, 0, 0,
|
|
|
|
|
|
(SCM bv, SCM index, SCM value),
|
|
|
|
|
|
"Store the signed integer @var{value} at index @var{index} "
|
|
|
|
|
|
"of @var{bv} using the native endianness.")
|
|
|
|
|
|
#define FUNC_NAME s_scm_bytevector_s64_native_set_x
|
|
|
|
|
|
{
|
|
|
|
|
|
LARGE_INTEGER_NATIVE_SET (64, signed);
|
|
|
|
|
|
}
|
|
|
|
|
|
#undef FUNC_NAME
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Operations on IEEE-754 numbers. */
|
|
|
|
|
|
|
|
|
|
|
|
/* There are two possible word endians, visible in glibc's <ieee754.h>.
|
|
|
|
|
|
However, in R6RS, when the endianness is `little', little endian is
|
|
|
|
|
|
assumed for both the byte order and the word order. This is clear from
|
|
|
|
|
|
Section 2.1 of R6RS-lib (in response to
|
|
|
|
|
|
http://www.r6rs.org/formal-comments/comment-187.txt). */
|
|
|
|
|
|
|
bytevectors: Fix IEEE-754 endianness conversion.
Fixes <http://bugs.gnu.org/11310>.
Reported by Klaus Stehle <klaus.stehle@uni-tuebingen.de>.
* libguile/ieee-754.h: Remove.
* libguile/Makefile.am (noinst_HEADERS): Remove `ieee-754.h'.
* libguile/bytevectors.c (scm_ieee754_float, scm_ieee754_double): New
unions.
(float_to_foreign_endianness, float_from_foreign_endianness,
double_to_foreign_endianness, double_from_foreign_endianness): Rewrite
in terms of the new unions.
* test-suite/tests/bytevectors.test ("2.8 Operations on IEEE-754
Representations")["single, little endian", "single, big endian",
"double, little endian", "double, big endian"]: New tests.
2012-04-21 23:08:49 +02:00
|
|
|
|
union scm_ieee754_float
|
|
|
|
|
|
{
|
|
|
|
|
|
float f;
|
|
|
|
|
|
scm_t_uint32 i;
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
union scm_ieee754_double
|
|
|
|
|
|
{
|
|
|
|
|
|
double d;
|
|
|
|
|
|
scm_t_uint64 i;
|
|
|
|
|
|
};
|
|
|
|
|
|
|
2009-05-27 18:18:07 +02:00
|
|
|
|
|
|
|
|
|
|
/* Convert to/from a floating-point number with different endianness. This
|
|
|
|
|
|
method is probably not the most efficient but it should be portable. */
|
|
|
|
|
|
|
|
|
|
|
|
static inline void
|
|
|
|
|
|
float_to_foreign_endianness (union scm_ieee754_float *target,
|
|
|
|
|
|
float source)
|
|
|
|
|
|
{
|
bytevectors: Fix IEEE-754 endianness conversion.
Fixes <http://bugs.gnu.org/11310>.
Reported by Klaus Stehle <klaus.stehle@uni-tuebingen.de>.
* libguile/ieee-754.h: Remove.
* libguile/Makefile.am (noinst_HEADERS): Remove `ieee-754.h'.
* libguile/bytevectors.c (scm_ieee754_float, scm_ieee754_double): New
unions.
(float_to_foreign_endianness, float_from_foreign_endianness,
double_to_foreign_endianness, double_from_foreign_endianness): Rewrite
in terms of the new unions.
* test-suite/tests/bytevectors.test ("2.8 Operations on IEEE-754
Representations")["single, little endian", "single, big endian",
"double, little endian", "double, big endian"]: New tests.
2012-04-21 23:08:49 +02:00
|
|
|
|
union scm_ieee754_float input;
|
2009-05-27 18:18:07 +02:00
|
|
|
|
|
bytevectors: Fix IEEE-754 endianness conversion.
Fixes <http://bugs.gnu.org/11310>.
Reported by Klaus Stehle <klaus.stehle@uni-tuebingen.de>.
* libguile/ieee-754.h: Remove.
* libguile/Makefile.am (noinst_HEADERS): Remove `ieee-754.h'.
* libguile/bytevectors.c (scm_ieee754_float, scm_ieee754_double): New
unions.
(float_to_foreign_endianness, float_from_foreign_endianness,
double_to_foreign_endianness, double_from_foreign_endianness): Rewrite
in terms of the new unions.
* test-suite/tests/bytevectors.test ("2.8 Operations on IEEE-754
Representations")["single, little endian", "single, big endian",
"double, little endian", "double, big endian"]: New tests.
2012-04-21 23:08:49 +02:00
|
|
|
|
input.f = source;
|
|
|
|
|
|
target->i = bswap_32 (input.i);
|
2009-05-27 18:18:07 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static inline float
|
|
|
|
|
|
float_from_foreign_endianness (const union scm_ieee754_float *source)
|
|
|
|
|
|
{
|
|
|
|
|
|
union scm_ieee754_float result;
|
|
|
|
|
|
|
bytevectors: Fix IEEE-754 endianness conversion.
Fixes <http://bugs.gnu.org/11310>.
Reported by Klaus Stehle <klaus.stehle@uni-tuebingen.de>.
* libguile/ieee-754.h: Remove.
* libguile/Makefile.am (noinst_HEADERS): Remove `ieee-754.h'.
* libguile/bytevectors.c (scm_ieee754_float, scm_ieee754_double): New
unions.
(float_to_foreign_endianness, float_from_foreign_endianness,
double_to_foreign_endianness, double_from_foreign_endianness): Rewrite
in terms of the new unions.
* test-suite/tests/bytevectors.test ("2.8 Operations on IEEE-754
Representations")["single, little endian", "single, big endian",
"double, little endian", "double, big endian"]: New tests.
2012-04-21 23:08:49 +02:00
|
|
|
|
result.i = bswap_32 (source->i);
|
2009-05-27 18:18:07 +02:00
|
|
|
|
|
|
|
|
|
|
return (result.f);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static inline void
|
|
|
|
|
|
double_to_foreign_endianness (union scm_ieee754_double *target,
|
|
|
|
|
|
double source)
|
|
|
|
|
|
{
|
bytevectors: Fix IEEE-754 endianness conversion.
Fixes <http://bugs.gnu.org/11310>.
Reported by Klaus Stehle <klaus.stehle@uni-tuebingen.de>.
* libguile/ieee-754.h: Remove.
* libguile/Makefile.am (noinst_HEADERS): Remove `ieee-754.h'.
* libguile/bytevectors.c (scm_ieee754_float, scm_ieee754_double): New
unions.
(float_to_foreign_endianness, float_from_foreign_endianness,
double_to_foreign_endianness, double_from_foreign_endianness): Rewrite
in terms of the new unions.
* test-suite/tests/bytevectors.test ("2.8 Operations on IEEE-754
Representations")["single, little endian", "single, big endian",
"double, little endian", "double, big endian"]: New tests.
2012-04-21 23:08:49 +02:00
|
|
|
|
union scm_ieee754_double input;
|
2009-05-27 18:18:07 +02:00
|
|
|
|
|
bytevectors: Fix IEEE-754 endianness conversion.
Fixes <http://bugs.gnu.org/11310>.
Reported by Klaus Stehle <klaus.stehle@uni-tuebingen.de>.
* libguile/ieee-754.h: Remove.
* libguile/Makefile.am (noinst_HEADERS): Remove `ieee-754.h'.
* libguile/bytevectors.c (scm_ieee754_float, scm_ieee754_double): New
unions.
(float_to_foreign_endianness, float_from_foreign_endianness,
double_to_foreign_endianness, double_from_foreign_endianness): Rewrite
in terms of the new unions.
* test-suite/tests/bytevectors.test ("2.8 Operations on IEEE-754
Representations")["single, little endian", "single, big endian",
"double, little endian", "double, big endian"]: New tests.
2012-04-21 23:08:49 +02:00
|
|
|
|
input.d = source;
|
|
|
|
|
|
target->i = bswap_64 (input.i);
|
2009-05-27 18:18:07 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static inline double
|
|
|
|
|
|
double_from_foreign_endianness (const union scm_ieee754_double *source)
|
|
|
|
|
|
{
|
|
|
|
|
|
union scm_ieee754_double result;
|
|
|
|
|
|
|
bytevectors: Fix IEEE-754 endianness conversion.
Fixes <http://bugs.gnu.org/11310>.
Reported by Klaus Stehle <klaus.stehle@uni-tuebingen.de>.
* libguile/ieee-754.h: Remove.
* libguile/Makefile.am (noinst_HEADERS): Remove `ieee-754.h'.
* libguile/bytevectors.c (scm_ieee754_float, scm_ieee754_double): New
unions.
(float_to_foreign_endianness, float_from_foreign_endianness,
double_to_foreign_endianness, double_from_foreign_endianness): Rewrite
in terms of the new unions.
* test-suite/tests/bytevectors.test ("2.8 Operations on IEEE-754
Representations")["single, little endian", "single, big endian",
"double, little endian", "double, big endian"]: New tests.
2012-04-21 23:08:49 +02:00
|
|
|
|
result.i = bswap_64 (source->i);
|
2009-05-27 18:18:07 +02:00
|
|
|
|
|
|
|
|
|
|
return (result.d);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* Template macros to abstract over doubles and floats.
|
|
|
|
|
|
XXX: Guile can only convert to/from doubles. */
|
|
|
|
|
|
#define IEEE754_UNION(_c_type) union scm_ieee754_ ## _c_type
|
|
|
|
|
|
#define IEEE754_TO_SCM(_c_type) scm_from_double
|
|
|
|
|
|
#define IEEE754_FROM_SCM(_c_type) scm_to_double
|
|
|
|
|
|
#define IEEE754_FROM_FOREIGN_ENDIANNESS(_c_type) \
|
|
|
|
|
|
_c_type ## _from_foreign_endianness
|
|
|
|
|
|
#define IEEE754_TO_FOREIGN_ENDIANNESS(_c_type) \
|
|
|
|
|
|
_c_type ## _to_foreign_endianness
|
|
|
|
|
|
|
|
|
|
|
|
|
2009-07-18 19:03:28 +02:00
|
|
|
|
/* FIXME: SCM_VALIDATE_REAL rejects integers, etc. grrr */
|
|
|
|
|
|
#define VALIDATE_REAL(pos, v) \
|
|
|
|
|
|
do { \
|
2011-03-01 12:46:38 -05:00
|
|
|
|
SCM_ASSERT_TYPE (scm_is_real (v), v, pos, FUNC_NAME, "real"); \
|
2009-07-18 19:03:28 +02:00
|
|
|
|
} while (0)
|
|
|
|
|
|
|
2009-05-27 18:18:07 +02:00
|
|
|
|
/* Templace getters and setters. */
|
|
|
|
|
|
|
All literal constants are read-only
* libguile/array-handle.c (initialize_vector_handle): Add mutable_p
argument. Unless the vector handle is mutable, null out its
writable_elements member.
(scm_array_get_handle): Adapt to determine mutability of the various
arrays.
(scm_array_handle_elements, scm_array_handle_writable_elements):
Reverse the sense: instead of implementing read-only in terms of
read-write, go the other way around, adding an assertion in the
read-write case that the array handle is mutable.
* libguile/array-map.c (racp): Assert that the destination is mutable.
* libguile/bitvectors.c (SCM_F_BITVECTOR_IMMUTABLE, IS_BITVECTOR):
(IS_MUTABLE_BITVECTOR): Add a flag to indicate immutability.
(scm_i_bitvector_bits): Fix indentation.
(scm_i_is_mutable_bitvector): New helper.
(scm_array_handle_bit_elements)
((scm_array_handle_bit_writable_elements): Build writable_elements in
terms of elements.
(scm_bitvector_elements, scm_bitvector_writable_elements): Likewise.
(scm_c_bitvector_set_x): Require a mutable bitvector for the
fast-path.
(scm_bitvector_to_list, scm_bit_count): Use read-only elements()
function.
* libguile/bitvectors.h (scm_i_is_mutable_bitvector): New decl.
* libguile/bytevectors.c (INTEGER_ACCESSOR_PROLOGUE):
(INTEGER_GETTER_PROLOGUE, INTEGER_SETTER_PROLOGUE):
(INTEGER_REF, INTEGER_NATIVE_REF, INTEGER_SET, INTEGER_NATIVE_SET):
(GENERIC_INTEGER_ACCESSOR_PROLOGUE):
(GENERIC_INTEGER_GETTER_PROLOGUE, GENERIC_INTEGER_SETTER_PROLOGUE):
(LARGE_INTEGER_NATIVE_REF, LARGE_INTEGER_NATIVE_SET):
(IEEE754_GETTER_PROLOGUE, IEEE754_SETTER_PROLOGUE):
(IEEE754_REF, IEEE754_NATIVE_REF, IEEE754_SET, IEEE754_NATIVE_SET):
Setters require a mutable bytevector.
(SCM_BYTEVECTOR_SET_FLAG): New helper.
(SCM_BYTEVECTOR_SET_CONTIGUOUS_P, SCM_BYTEVECTOR_SET_ELEMENT_TYPE):
Remove helpers.
(SCM_VALIDATE_MUTABLE_BYTEVECTOR): New helper.
(make_bytevector, make_bytevector_from_buffer): Use
SCM_SET_BYTEVECTOR_FLAGS.
(scm_c_bytevector_set_x, scm_bytevector_fill_x)
(scm_bytevector_copy_x): Require a mutable bytevector.
* libguile/bytevectors.h (SCM_F_BYTEVECTOR_CONTIGUOUS)
(SCM_F_BYTEVECTOR_IMMUTABLE, SCM_MUTABLE_BYTEVECTOR_P): New
definitions.
* libguile/bytevectors.h (SCM_BYTEVECTOR_CONTIGUOUS_P): Just access one
bit.
* libguile/srfi-4.c (DEFINE_SRFI_4_C_FUNCS): Implement
writable_elements() in terms of elements().
* libguile/strings.c (scm_i_string_is_mutable): New helper.
* libguile/uniform.c (scm_array_handle_uniform_elements):
(scm_array_handle_uniform_writable_elements): Implement
writable_elements in terms of elements.
* libguile/vectors.c (SCM_VALIDATE_MUTABLE_VECTOR): New helper.
(scm_vector_elements, scm_vector_writable_elements): Implement
writable_elements in terms of elements.
(scm_c_vector_set_x): Require a mutable vector.
* libguile/vectors.h (SCM_F_VECTOR_IMMUTABLE, SCM_I_IS_MUTABLE_VECTOR):
New definitions.
* libguile/vm-engine.c (VM_VALIDATE_MUTABLE_BYTEVECTOR):
(VM_VALIDATE_MUTABLE_VECTOR, vector-set!, vector-set!/immediate)
(BV_BOUNDED_SET, BV_SET): Require mutable bytevector/vector.
* libguile/vm.c (vm_error_not_a_mutable_bytevector):
(vm_error_not_a_mutable_vector): New definitions.
* module/system/vm/assembler.scm (link-data): Mark residualized vectors,
bytevectors, and bitvectors as being read-only.
2017-04-18 14:56:48 +02:00
|
|
|
|
#define IEEE754_GETTER_PROLOGUE(_type) \
|
|
|
|
|
|
INTEGER_GETTER_PROLOGUE (sizeof (_type) << 3UL, signed);
|
|
|
|
|
|
|
|
|
|
|
|
#define IEEE754_SETTER_PROLOGUE(_type) \
|
|
|
|
|
|
INTEGER_SETTER_PROLOGUE (sizeof (_type) << 3UL, signed);
|
2009-05-27 18:18:07 +02:00
|
|
|
|
|
|
|
|
|
|
#define IEEE754_REF(_type) \
|
|
|
|
|
|
_type c_result; \
|
|
|
|
|
|
\
|
All literal constants are read-only
* libguile/array-handle.c (initialize_vector_handle): Add mutable_p
argument. Unless the vector handle is mutable, null out its
writable_elements member.
(scm_array_get_handle): Adapt to determine mutability of the various
arrays.
(scm_array_handle_elements, scm_array_handle_writable_elements):
Reverse the sense: instead of implementing read-only in terms of
read-write, go the other way around, adding an assertion in the
read-write case that the array handle is mutable.
* libguile/array-map.c (racp): Assert that the destination is mutable.
* libguile/bitvectors.c (SCM_F_BITVECTOR_IMMUTABLE, IS_BITVECTOR):
(IS_MUTABLE_BITVECTOR): Add a flag to indicate immutability.
(scm_i_bitvector_bits): Fix indentation.
(scm_i_is_mutable_bitvector): New helper.
(scm_array_handle_bit_elements)
((scm_array_handle_bit_writable_elements): Build writable_elements in
terms of elements.
(scm_bitvector_elements, scm_bitvector_writable_elements): Likewise.
(scm_c_bitvector_set_x): Require a mutable bitvector for the
fast-path.
(scm_bitvector_to_list, scm_bit_count): Use read-only elements()
function.
* libguile/bitvectors.h (scm_i_is_mutable_bitvector): New decl.
* libguile/bytevectors.c (INTEGER_ACCESSOR_PROLOGUE):
(INTEGER_GETTER_PROLOGUE, INTEGER_SETTER_PROLOGUE):
(INTEGER_REF, INTEGER_NATIVE_REF, INTEGER_SET, INTEGER_NATIVE_SET):
(GENERIC_INTEGER_ACCESSOR_PROLOGUE):
(GENERIC_INTEGER_GETTER_PROLOGUE, GENERIC_INTEGER_SETTER_PROLOGUE):
(LARGE_INTEGER_NATIVE_REF, LARGE_INTEGER_NATIVE_SET):
(IEEE754_GETTER_PROLOGUE, IEEE754_SETTER_PROLOGUE):
(IEEE754_REF, IEEE754_NATIVE_REF, IEEE754_SET, IEEE754_NATIVE_SET):
Setters require a mutable bytevector.
(SCM_BYTEVECTOR_SET_FLAG): New helper.
(SCM_BYTEVECTOR_SET_CONTIGUOUS_P, SCM_BYTEVECTOR_SET_ELEMENT_TYPE):
Remove helpers.
(SCM_VALIDATE_MUTABLE_BYTEVECTOR): New helper.
(make_bytevector, make_bytevector_from_buffer): Use
SCM_SET_BYTEVECTOR_FLAGS.
(scm_c_bytevector_set_x, scm_bytevector_fill_x)
(scm_bytevector_copy_x): Require a mutable bytevector.
* libguile/bytevectors.h (SCM_F_BYTEVECTOR_CONTIGUOUS)
(SCM_F_BYTEVECTOR_IMMUTABLE, SCM_MUTABLE_BYTEVECTOR_P): New
definitions.
* libguile/bytevectors.h (SCM_BYTEVECTOR_CONTIGUOUS_P): Just access one
bit.
* libguile/srfi-4.c (DEFINE_SRFI_4_C_FUNCS): Implement
writable_elements() in terms of elements().
* libguile/strings.c (scm_i_string_is_mutable): New helper.
* libguile/uniform.c (scm_array_handle_uniform_elements):
(scm_array_handle_uniform_writable_elements): Implement
writable_elements in terms of elements.
* libguile/vectors.c (SCM_VALIDATE_MUTABLE_VECTOR): New helper.
(scm_vector_elements, scm_vector_writable_elements): Implement
writable_elements in terms of elements.
(scm_c_vector_set_x): Require a mutable vector.
* libguile/vectors.h (SCM_F_VECTOR_IMMUTABLE, SCM_I_IS_MUTABLE_VECTOR):
New definitions.
* libguile/vm-engine.c (VM_VALIDATE_MUTABLE_BYTEVECTOR):
(VM_VALIDATE_MUTABLE_VECTOR, vector-set!, vector-set!/immediate)
(BV_BOUNDED_SET, BV_SET): Require mutable bytevector/vector.
* libguile/vm.c (vm_error_not_a_mutable_bytevector):
(vm_error_not_a_mutable_vector): New definitions.
* module/system/vm/assembler.scm (link-data): Mark residualized vectors,
bytevectors, and bitvectors as being read-only.
2017-04-18 14:56:48 +02:00
|
|
|
|
IEEE754_GETTER_PROLOGUE (_type); \
|
2009-05-27 18:18:07 +02:00
|
|
|
|
SCM_VALIDATE_SYMBOL (3, endianness); \
|
|
|
|
|
|
\
|
2009-06-24 23:46:42 +02:00
|
|
|
|
if (scm_is_eq (endianness, scm_i_native_endianness)) \
|
2009-05-27 18:18:07 +02:00
|
|
|
|
memcpy (&c_result, &c_bv[c_index], sizeof (c_result)); \
|
|
|
|
|
|
else \
|
|
|
|
|
|
{ \
|
|
|
|
|
|
IEEE754_UNION (_type) c_raw; \
|
|
|
|
|
|
\
|
|
|
|
|
|
memcpy (&c_raw, &c_bv[c_index], sizeof (c_raw)); \
|
|
|
|
|
|
c_result = \
|
|
|
|
|
|
IEEE754_FROM_FOREIGN_ENDIANNESS (_type) (&c_raw); \
|
|
|
|
|
|
} \
|
|
|
|
|
|
\
|
|
|
|
|
|
return (IEEE754_TO_SCM (_type) (c_result));
|
|
|
|
|
|
|
|
|
|
|
|
#define IEEE754_NATIVE_REF(_type) \
|
|
|
|
|
|
_type c_result; \
|
|
|
|
|
|
\
|
All literal constants are read-only
* libguile/array-handle.c (initialize_vector_handle): Add mutable_p
argument. Unless the vector handle is mutable, null out its
writable_elements member.
(scm_array_get_handle): Adapt to determine mutability of the various
arrays.
(scm_array_handle_elements, scm_array_handle_writable_elements):
Reverse the sense: instead of implementing read-only in terms of
read-write, go the other way around, adding an assertion in the
read-write case that the array handle is mutable.
* libguile/array-map.c (racp): Assert that the destination is mutable.
* libguile/bitvectors.c (SCM_F_BITVECTOR_IMMUTABLE, IS_BITVECTOR):
(IS_MUTABLE_BITVECTOR): Add a flag to indicate immutability.
(scm_i_bitvector_bits): Fix indentation.
(scm_i_is_mutable_bitvector): New helper.
(scm_array_handle_bit_elements)
((scm_array_handle_bit_writable_elements): Build writable_elements in
terms of elements.
(scm_bitvector_elements, scm_bitvector_writable_elements): Likewise.
(scm_c_bitvector_set_x): Require a mutable bitvector for the
fast-path.
(scm_bitvector_to_list, scm_bit_count): Use read-only elements()
function.
* libguile/bitvectors.h (scm_i_is_mutable_bitvector): New decl.
* libguile/bytevectors.c (INTEGER_ACCESSOR_PROLOGUE):
(INTEGER_GETTER_PROLOGUE, INTEGER_SETTER_PROLOGUE):
(INTEGER_REF, INTEGER_NATIVE_REF, INTEGER_SET, INTEGER_NATIVE_SET):
(GENERIC_INTEGER_ACCESSOR_PROLOGUE):
(GENERIC_INTEGER_GETTER_PROLOGUE, GENERIC_INTEGER_SETTER_PROLOGUE):
(LARGE_INTEGER_NATIVE_REF, LARGE_INTEGER_NATIVE_SET):
(IEEE754_GETTER_PROLOGUE, IEEE754_SETTER_PROLOGUE):
(IEEE754_REF, IEEE754_NATIVE_REF, IEEE754_SET, IEEE754_NATIVE_SET):
Setters require a mutable bytevector.
(SCM_BYTEVECTOR_SET_FLAG): New helper.
(SCM_BYTEVECTOR_SET_CONTIGUOUS_P, SCM_BYTEVECTOR_SET_ELEMENT_TYPE):
Remove helpers.
(SCM_VALIDATE_MUTABLE_BYTEVECTOR): New helper.
(make_bytevector, make_bytevector_from_buffer): Use
SCM_SET_BYTEVECTOR_FLAGS.
(scm_c_bytevector_set_x, scm_bytevector_fill_x)
(scm_bytevector_copy_x): Require a mutable bytevector.
* libguile/bytevectors.h (SCM_F_BYTEVECTOR_CONTIGUOUS)
(SCM_F_BYTEVECTOR_IMMUTABLE, SCM_MUTABLE_BYTEVECTOR_P): New
definitions.
* libguile/bytevectors.h (SCM_BYTEVECTOR_CONTIGUOUS_P): Just access one
bit.
* libguile/srfi-4.c (DEFINE_SRFI_4_C_FUNCS): Implement
writable_elements() in terms of elements().
* libguile/strings.c (scm_i_string_is_mutable): New helper.
* libguile/uniform.c (scm_array_handle_uniform_elements):
(scm_array_handle_uniform_writable_elements): Implement
writable_elements in terms of elements.
* libguile/vectors.c (SCM_VALIDATE_MUTABLE_VECTOR): New helper.
(scm_vector_elements, scm_vector_writable_elements): Implement
writable_elements in terms of elements.
(scm_c_vector_set_x): Require a mutable vector.
* libguile/vectors.h (SCM_F_VECTOR_IMMUTABLE, SCM_I_IS_MUTABLE_VECTOR):
New definitions.
* libguile/vm-engine.c (VM_VALIDATE_MUTABLE_BYTEVECTOR):
(VM_VALIDATE_MUTABLE_VECTOR, vector-set!, vector-set!/immediate)
(BV_BOUNDED_SET, BV_SET): Require mutable bytevector/vector.
* libguile/vm.c (vm_error_not_a_mutable_bytevector):
(vm_error_not_a_mutable_vector): New definitions.
* module/system/vm/assembler.scm (link-data): Mark residualized vectors,
bytevectors, and bitvectors as being read-only.
2017-04-18 14:56:48 +02:00
|
|
|
|
IEEE754_GETTER_PROLOGUE (_type); \
|
2009-05-27 18:18:07 +02:00
|
|
|
|
\
|
|
|
|
|
|
memcpy (&c_result, &c_bv[c_index], sizeof (c_result)); \
|
|
|
|
|
|
return (IEEE754_TO_SCM (_type) (c_result));
|
|
|
|
|
|
|
|
|
|
|
|
#define IEEE754_SET(_type) \
|
|
|
|
|
|
_type c_value; \
|
|
|
|
|
|
\
|
All literal constants are read-only
* libguile/array-handle.c (initialize_vector_handle): Add mutable_p
argument. Unless the vector handle is mutable, null out its
writable_elements member.
(scm_array_get_handle): Adapt to determine mutability of the various
arrays.
(scm_array_handle_elements, scm_array_handle_writable_elements):
Reverse the sense: instead of implementing read-only in terms of
read-write, go the other way around, adding an assertion in the
read-write case that the array handle is mutable.
* libguile/array-map.c (racp): Assert that the destination is mutable.
* libguile/bitvectors.c (SCM_F_BITVECTOR_IMMUTABLE, IS_BITVECTOR):
(IS_MUTABLE_BITVECTOR): Add a flag to indicate immutability.
(scm_i_bitvector_bits): Fix indentation.
(scm_i_is_mutable_bitvector): New helper.
(scm_array_handle_bit_elements)
((scm_array_handle_bit_writable_elements): Build writable_elements in
terms of elements.
(scm_bitvector_elements, scm_bitvector_writable_elements): Likewise.
(scm_c_bitvector_set_x): Require a mutable bitvector for the
fast-path.
(scm_bitvector_to_list, scm_bit_count): Use read-only elements()
function.
* libguile/bitvectors.h (scm_i_is_mutable_bitvector): New decl.
* libguile/bytevectors.c (INTEGER_ACCESSOR_PROLOGUE):
(INTEGER_GETTER_PROLOGUE, INTEGER_SETTER_PROLOGUE):
(INTEGER_REF, INTEGER_NATIVE_REF, INTEGER_SET, INTEGER_NATIVE_SET):
(GENERIC_INTEGER_ACCESSOR_PROLOGUE):
(GENERIC_INTEGER_GETTER_PROLOGUE, GENERIC_INTEGER_SETTER_PROLOGUE):
(LARGE_INTEGER_NATIVE_REF, LARGE_INTEGER_NATIVE_SET):
(IEEE754_GETTER_PROLOGUE, IEEE754_SETTER_PROLOGUE):
(IEEE754_REF, IEEE754_NATIVE_REF, IEEE754_SET, IEEE754_NATIVE_SET):
Setters require a mutable bytevector.
(SCM_BYTEVECTOR_SET_FLAG): New helper.
(SCM_BYTEVECTOR_SET_CONTIGUOUS_P, SCM_BYTEVECTOR_SET_ELEMENT_TYPE):
Remove helpers.
(SCM_VALIDATE_MUTABLE_BYTEVECTOR): New helper.
(make_bytevector, make_bytevector_from_buffer): Use
SCM_SET_BYTEVECTOR_FLAGS.
(scm_c_bytevector_set_x, scm_bytevector_fill_x)
(scm_bytevector_copy_x): Require a mutable bytevector.
* libguile/bytevectors.h (SCM_F_BYTEVECTOR_CONTIGUOUS)
(SCM_F_BYTEVECTOR_IMMUTABLE, SCM_MUTABLE_BYTEVECTOR_P): New
definitions.
* libguile/bytevectors.h (SCM_BYTEVECTOR_CONTIGUOUS_P): Just access one
bit.
* libguile/srfi-4.c (DEFINE_SRFI_4_C_FUNCS): Implement
writable_elements() in terms of elements().
* libguile/strings.c (scm_i_string_is_mutable): New helper.
* libguile/uniform.c (scm_array_handle_uniform_elements):
(scm_array_handle_uniform_writable_elements): Implement
writable_elements in terms of elements.
* libguile/vectors.c (SCM_VALIDATE_MUTABLE_VECTOR): New helper.
(scm_vector_elements, scm_vector_writable_elements): Implement
writable_elements in terms of elements.
(scm_c_vector_set_x): Require a mutable vector.
* libguile/vectors.h (SCM_F_VECTOR_IMMUTABLE, SCM_I_IS_MUTABLE_VECTOR):
New definitions.
* libguile/vm-engine.c (VM_VALIDATE_MUTABLE_BYTEVECTOR):
(VM_VALIDATE_MUTABLE_VECTOR, vector-set!, vector-set!/immediate)
(BV_BOUNDED_SET, BV_SET): Require mutable bytevector/vector.
* libguile/vm.c (vm_error_not_a_mutable_bytevector):
(vm_error_not_a_mutable_vector): New definitions.
* module/system/vm/assembler.scm (link-data): Mark residualized vectors,
bytevectors, and bitvectors as being read-only.
2017-04-18 14:56:48 +02:00
|
|
|
|
IEEE754_SETTER_PROLOGUE (_type); \
|
2009-07-18 19:03:28 +02:00
|
|
|
|
VALIDATE_REAL (3, value); \
|
2009-05-27 18:18:07 +02:00
|
|
|
|
SCM_VALIDATE_SYMBOL (4, endianness); \
|
|
|
|
|
|
c_value = IEEE754_FROM_SCM (_type) (value); \
|
|
|
|
|
|
\
|
2009-06-24 23:46:42 +02:00
|
|
|
|
if (scm_is_eq (endianness, scm_i_native_endianness)) \
|
2009-05-27 18:18:07 +02:00
|
|
|
|
memcpy (&c_bv[c_index], &c_value, sizeof (c_value)); \
|
|
|
|
|
|
else \
|
|
|
|
|
|
{ \
|
|
|
|
|
|
IEEE754_UNION (_type) c_raw; \
|
|
|
|
|
|
\
|
|
|
|
|
|
IEEE754_TO_FOREIGN_ENDIANNESS (_type) (&c_raw, c_value); \
|
|
|
|
|
|
memcpy (&c_bv[c_index], &c_raw, sizeof (c_raw)); \
|
|
|
|
|
|
} \
|
|
|
|
|
|
\
|
|
|
|
|
|
return SCM_UNSPECIFIED;
|
|
|
|
|
|
|
|
|
|
|
|
#define IEEE754_NATIVE_SET(_type) \
|
|
|
|
|
|
_type c_value; \
|
|
|
|
|
|
\
|
All literal constants are read-only
* libguile/array-handle.c (initialize_vector_handle): Add mutable_p
argument. Unless the vector handle is mutable, null out its
writable_elements member.
(scm_array_get_handle): Adapt to determine mutability of the various
arrays.
(scm_array_handle_elements, scm_array_handle_writable_elements):
Reverse the sense: instead of implementing read-only in terms of
read-write, go the other way around, adding an assertion in the
read-write case that the array handle is mutable.
* libguile/array-map.c (racp): Assert that the destination is mutable.
* libguile/bitvectors.c (SCM_F_BITVECTOR_IMMUTABLE, IS_BITVECTOR):
(IS_MUTABLE_BITVECTOR): Add a flag to indicate immutability.
(scm_i_bitvector_bits): Fix indentation.
(scm_i_is_mutable_bitvector): New helper.
(scm_array_handle_bit_elements)
((scm_array_handle_bit_writable_elements): Build writable_elements in
terms of elements.
(scm_bitvector_elements, scm_bitvector_writable_elements): Likewise.
(scm_c_bitvector_set_x): Require a mutable bitvector for the
fast-path.
(scm_bitvector_to_list, scm_bit_count): Use read-only elements()
function.
* libguile/bitvectors.h (scm_i_is_mutable_bitvector): New decl.
* libguile/bytevectors.c (INTEGER_ACCESSOR_PROLOGUE):
(INTEGER_GETTER_PROLOGUE, INTEGER_SETTER_PROLOGUE):
(INTEGER_REF, INTEGER_NATIVE_REF, INTEGER_SET, INTEGER_NATIVE_SET):
(GENERIC_INTEGER_ACCESSOR_PROLOGUE):
(GENERIC_INTEGER_GETTER_PROLOGUE, GENERIC_INTEGER_SETTER_PROLOGUE):
(LARGE_INTEGER_NATIVE_REF, LARGE_INTEGER_NATIVE_SET):
(IEEE754_GETTER_PROLOGUE, IEEE754_SETTER_PROLOGUE):
(IEEE754_REF, IEEE754_NATIVE_REF, IEEE754_SET, IEEE754_NATIVE_SET):
Setters require a mutable bytevector.
(SCM_BYTEVECTOR_SET_FLAG): New helper.
(SCM_BYTEVECTOR_SET_CONTIGUOUS_P, SCM_BYTEVECTOR_SET_ELEMENT_TYPE):
Remove helpers.
(SCM_VALIDATE_MUTABLE_BYTEVECTOR): New helper.
(make_bytevector, make_bytevector_from_buffer): Use
SCM_SET_BYTEVECTOR_FLAGS.
(scm_c_bytevector_set_x, scm_bytevector_fill_x)
(scm_bytevector_copy_x): Require a mutable bytevector.
* libguile/bytevectors.h (SCM_F_BYTEVECTOR_CONTIGUOUS)
(SCM_F_BYTEVECTOR_IMMUTABLE, SCM_MUTABLE_BYTEVECTOR_P): New
definitions.
* libguile/bytevectors.h (SCM_BYTEVECTOR_CONTIGUOUS_P): Just access one
bit.
* libguile/srfi-4.c (DEFINE_SRFI_4_C_FUNCS): Implement
writable_elements() in terms of elements().
* libguile/strings.c (scm_i_string_is_mutable): New helper.
* libguile/uniform.c (scm_array_handle_uniform_elements):
(scm_array_handle_uniform_writable_elements): Implement
writable_elements in terms of elements.
* libguile/vectors.c (SCM_VALIDATE_MUTABLE_VECTOR): New helper.
(scm_vector_elements, scm_vector_writable_elements): Implement
writable_elements in terms of elements.
(scm_c_vector_set_x): Require a mutable vector.
* libguile/vectors.h (SCM_F_VECTOR_IMMUTABLE, SCM_I_IS_MUTABLE_VECTOR):
New definitions.
* libguile/vm-engine.c (VM_VALIDATE_MUTABLE_BYTEVECTOR):
(VM_VALIDATE_MUTABLE_VECTOR, vector-set!, vector-set!/immediate)
(BV_BOUNDED_SET, BV_SET): Require mutable bytevector/vector.
* libguile/vm.c (vm_error_not_a_mutable_bytevector):
(vm_error_not_a_mutable_vector): New definitions.
* module/system/vm/assembler.scm (link-data): Mark residualized vectors,
bytevectors, and bitvectors as being read-only.
2017-04-18 14:56:48 +02:00
|
|
|
|
IEEE754_SETTER_PROLOGUE (_type); \
|
2009-07-18 19:03:28 +02:00
|
|
|
|
VALIDATE_REAL (3, value); \
|
2009-05-27 18:18:07 +02:00
|
|
|
|
c_value = IEEE754_FROM_SCM (_type) (value); \
|
|
|
|
|
|
\
|
|
|
|
|
|
memcpy (&c_bv[c_index], &c_value, sizeof (c_value)); \
|
|
|
|
|
|
return SCM_UNSPECIFIED;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Single precision. */
|
|
|
|
|
|
|
|
|
|
|
|
SCM_DEFINE (scm_bytevector_ieee_single_ref,
|
|
|
|
|
|
"bytevector-ieee-single-ref",
|
|
|
|
|
|
3, 0, 0,
|
|
|
|
|
|
(SCM bv, SCM index, SCM endianness),
|
|
|
|
|
|
"Return the IEEE-754 single from @var{bv} at "
|
|
|
|
|
|
"@var{index}.")
|
|
|
|
|
|
#define FUNC_NAME s_scm_bytevector_ieee_single_ref
|
|
|
|
|
|
{
|
|
|
|
|
|
IEEE754_REF (float);
|
|
|
|
|
|
}
|
|
|
|
|
|
#undef FUNC_NAME
|
|
|
|
|
|
|
|
|
|
|
|
SCM_DEFINE (scm_bytevector_ieee_single_native_ref,
|
|
|
|
|
|
"bytevector-ieee-single-native-ref",
|
|
|
|
|
|
2, 0, 0,
|
|
|
|
|
|
(SCM bv, SCM index),
|
|
|
|
|
|
"Return the IEEE-754 single from @var{bv} at "
|
|
|
|
|
|
"@var{index} using the native endianness.")
|
|
|
|
|
|
#define FUNC_NAME s_scm_bytevector_ieee_single_native_ref
|
|
|
|
|
|
{
|
|
|
|
|
|
IEEE754_NATIVE_REF (float);
|
|
|
|
|
|
}
|
|
|
|
|
|
#undef FUNC_NAME
|
|
|
|
|
|
|
|
|
|
|
|
SCM_DEFINE (scm_bytevector_ieee_single_set_x,
|
|
|
|
|
|
"bytevector-ieee-single-set!",
|
|
|
|
|
|
4, 0, 0,
|
|
|
|
|
|
(SCM bv, SCM index, SCM value, SCM endianness),
|
|
|
|
|
|
"Store real @var{value} in @var{bv} at @var{index} according to "
|
|
|
|
|
|
"@var{endianness}.")
|
|
|
|
|
|
#define FUNC_NAME s_scm_bytevector_ieee_single_set_x
|
|
|
|
|
|
{
|
|
|
|
|
|
IEEE754_SET (float);
|
|
|
|
|
|
}
|
|
|
|
|
|
#undef FUNC_NAME
|
|
|
|
|
|
|
|
|
|
|
|
SCM_DEFINE (scm_bytevector_ieee_single_native_set_x,
|
|
|
|
|
|
"bytevector-ieee-single-native-set!",
|
|
|
|
|
|
3, 0, 0,
|
|
|
|
|
|
(SCM bv, SCM index, SCM value),
|
|
|
|
|
|
"Store the real @var{value} at index @var{index} "
|
|
|
|
|
|
"of @var{bv} using the native endianness.")
|
|
|
|
|
|
#define FUNC_NAME s_scm_bytevector_ieee_single_native_set_x
|
|
|
|
|
|
{
|
|
|
|
|
|
IEEE754_NATIVE_SET (float);
|
|
|
|
|
|
}
|
|
|
|
|
|
#undef FUNC_NAME
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Double precision. */
|
|
|
|
|
|
|
|
|
|
|
|
SCM_DEFINE (scm_bytevector_ieee_double_ref,
|
|
|
|
|
|
"bytevector-ieee-double-ref",
|
|
|
|
|
|
3, 0, 0,
|
|
|
|
|
|
(SCM bv, SCM index, SCM endianness),
|
|
|
|
|
|
"Return the IEEE-754 double from @var{bv} at "
|
|
|
|
|
|
"@var{index}.")
|
|
|
|
|
|
#define FUNC_NAME s_scm_bytevector_ieee_double_ref
|
|
|
|
|
|
{
|
|
|
|
|
|
IEEE754_REF (double);
|
|
|
|
|
|
}
|
|
|
|
|
|
#undef FUNC_NAME
|
|
|
|
|
|
|
|
|
|
|
|
SCM_DEFINE (scm_bytevector_ieee_double_native_ref,
|
|
|
|
|
|
"bytevector-ieee-double-native-ref",
|
|
|
|
|
|
2, 0, 0,
|
|
|
|
|
|
(SCM bv, SCM index),
|
|
|
|
|
|
"Return the IEEE-754 double from @var{bv} at "
|
|
|
|
|
|
"@var{index} using the native endianness.")
|
|
|
|
|
|
#define FUNC_NAME s_scm_bytevector_ieee_double_native_ref
|
|
|
|
|
|
{
|
|
|
|
|
|
IEEE754_NATIVE_REF (double);
|
|
|
|
|
|
}
|
|
|
|
|
|
#undef FUNC_NAME
|
|
|
|
|
|
|
|
|
|
|
|
SCM_DEFINE (scm_bytevector_ieee_double_set_x,
|
|
|
|
|
|
"bytevector-ieee-double-set!",
|
|
|
|
|
|
4, 0, 0,
|
|
|
|
|
|
(SCM bv, SCM index, SCM value, SCM endianness),
|
|
|
|
|
|
"Store real @var{value} in @var{bv} at @var{index} according to "
|
|
|
|
|
|
"@var{endianness}.")
|
|
|
|
|
|
#define FUNC_NAME s_scm_bytevector_ieee_double_set_x
|
|
|
|
|
|
{
|
|
|
|
|
|
IEEE754_SET (double);
|
|
|
|
|
|
}
|
|
|
|
|
|
#undef FUNC_NAME
|
|
|
|
|
|
|
|
|
|
|
|
SCM_DEFINE (scm_bytevector_ieee_double_native_set_x,
|
|
|
|
|
|
"bytevector-ieee-double-native-set!",
|
|
|
|
|
|
3, 0, 0,
|
|
|
|
|
|
(SCM bv, SCM index, SCM value),
|
|
|
|
|
|
"Store the real @var{value} at index @var{index} "
|
|
|
|
|
|
"of @var{bv} using the native endianness.")
|
|
|
|
|
|
#define FUNC_NAME s_scm_bytevector_ieee_double_native_set_x
|
|
|
|
|
|
{
|
|
|
|
|
|
IEEE754_NATIVE_SET (double);
|
|
|
|
|
|
}
|
|
|
|
|
|
#undef FUNC_NAME
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#undef IEEE754_UNION
|
|
|
|
|
|
#undef IEEE754_TO_SCM
|
|
|
|
|
|
#undef IEEE754_FROM_SCM
|
|
|
|
|
|
#undef IEEE754_FROM_FOREIGN_ENDIANNESS
|
|
|
|
|
|
#undef IEEE754_TO_FOREIGN_ENDIANNESS
|
|
|
|
|
|
#undef IEEE754_REF
|
|
|
|
|
|
#undef IEEE754_NATIVE_REF
|
|
|
|
|
|
#undef IEEE754_SET
|
|
|
|
|
|
#undef IEEE754_NATIVE_SET
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Operations on strings. */
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Produce a function that returns the length of a UTF-encoded string. */
|
|
|
|
|
|
#define UTF_STRLEN_FUNCTION(_utf_width) \
|
|
|
|
|
|
static inline size_t \
|
|
|
|
|
|
utf ## _utf_width ## _strlen (const uint ## _utf_width ## _t *str) \
|
|
|
|
|
|
{ \
|
|
|
|
|
|
size_t len = 0; \
|
|
|
|
|
|
const uint ## _utf_width ## _t *ptr; \
|
|
|
|
|
|
for (ptr = str; \
|
|
|
|
|
|
*ptr != 0; \
|
|
|
|
|
|
ptr++) \
|
|
|
|
|
|
{ \
|
|
|
|
|
|
len++; \
|
|
|
|
|
|
} \
|
|
|
|
|
|
\
|
|
|
|
|
|
return (len * ((_utf_width) / 8)); \
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
UTF_STRLEN_FUNCTION (8)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Return the length (in bytes) of STR, a UTF-(UTF_WIDTH) encoded string. */
|
|
|
|
|
|
#define UTF_STRLEN(_utf_width, _str) \
|
|
|
|
|
|
utf ## _utf_width ## _strlen (_str)
|
|
|
|
|
|
|
|
|
|
|
|
/* Return the "portable" name of the UTF encoding of size UTF_WIDTH and
|
|
|
|
|
|
ENDIANNESS (Gnulib's `iconv_open' module guarantees the portability of the
|
|
|
|
|
|
encoding name). */
|
|
|
|
|
|
static inline void
|
|
|
|
|
|
utf_encoding_name (char *name, size_t utf_width, SCM endianness)
|
|
|
|
|
|
{
|
|
|
|
|
|
strcpy (name, "UTF-");
|
|
|
|
|
|
strcat (name, ((utf_width == 8)
|
|
|
|
|
|
? "8"
|
|
|
|
|
|
: ((utf_width == 16)
|
|
|
|
|
|
? "16"
|
|
|
|
|
|
: ((utf_width == 32)
|
|
|
|
|
|
? "32"
|
|
|
|
|
|
: "??"))));
|
|
|
|
|
|
strcat (name,
|
2016-06-23 18:31:55 +02:00
|
|
|
|
((scm_is_eq (endianness, sym_big))
|
2009-05-27 18:18:07 +02:00
|
|
|
|
? "BE"
|
2016-06-23 18:31:55 +02:00
|
|
|
|
: ((scm_is_eq (endianness, sym_little))
|
2009-05-27 18:18:07 +02:00
|
|
|
|
? "LE"
|
|
|
|
|
|
: "unknown")));
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* Maximum length of a UTF encoding name. */
|
|
|
|
|
|
#define MAX_UTF_ENCODING_NAME_LEN 16
|
|
|
|
|
|
|
|
|
|
|
|
/* Produce the body of a `string->utf' function. */
|
2009-10-28 06:24:23 -07:00
|
|
|
|
#define STRING_TO_UTF(_utf_width) \
|
|
|
|
|
|
SCM utf; \
|
|
|
|
|
|
int err; \
|
|
|
|
|
|
char c_utf_name[MAX_UTF_ENCODING_NAME_LEN]; \
|
|
|
|
|
|
char *c_utf = NULL; \
|
|
|
|
|
|
size_t c_strlen, c_utf_len = 0; \
|
|
|
|
|
|
\
|
|
|
|
|
|
SCM_VALIDATE_STRING (1, str); \
|
scm_is_eq for SCM vals, not == or !=
* libguile/bytevectors.c (scm_make_bytevector, STRING_TO_UTF)
(UTF_TO_STRING):
* libguile/continuations.c (scm_i_check_continuation):
* libguile/expand.h (SCM_EXPANDED_P):
* libguile/fluids.c (scm_i_make_with_fluids):
* libguile/generalized-vectors.c (scm_make_generalized_vector):
* libguile/goops.c (SCM_GOOPS_UNBOUNDP, slot_definition_using_name):
(scm_c_extend_primitive_generic, more_specificp, scm_make)
* libguile/i18n.c (SCM_VALIDATE_OPTIONAL_LOCALE_COPY):
(scm_locale_string_to_integer)
* libguile/modules.c (resolve_duplicate_binding):
(scm_module_reverse_lookup)
* libguile/posix.c (scm_to_resource):
* libguile/r6rs-ports.c (scm_put_bytevector):
* libguile/socket.c (scm_connect, scm_bind, scm_sendto
* libguile/stacks.c (find_prompt):
* libguile/variable.c (scm_variable_ref, scm_variable_bound_p):
* libguile/vm-engine.h (ASSERT_BOUND_VARIABLE, ASSERT_BOUND)
* libguile/vm-i-system.c (VARIABLE_BOUNDP, local_bound)
(long_local_bound, fluid_ref): Use scm_is_eq to compare, not == / !=.
2011-05-13 12:42:01 +02:00
|
|
|
|
if (scm_is_eq (endianness, SCM_UNDEFINED)) \
|
2016-06-23 18:31:55 +02:00
|
|
|
|
endianness = sym_big; \
|
2009-10-28 06:24:23 -07:00
|
|
|
|
else \
|
|
|
|
|
|
SCM_VALIDATE_SYMBOL (2, endianness); \
|
|
|
|
|
|
\
|
|
|
|
|
|
utf_encoding_name (c_utf_name, (_utf_width), endianness); \
|
|
|
|
|
|
\
|
|
|
|
|
|
c_strlen = scm_i_string_length (str); \
|
|
|
|
|
|
if (scm_i_is_narrow_string (str)) \
|
|
|
|
|
|
{ \
|
|
|
|
|
|
err = mem_iconveh (scm_i_string_chars (str), c_strlen, \
|
|
|
|
|
|
"ISO-8859-1", c_utf_name, \
|
|
|
|
|
|
iconveh_question_mark, NULL, \
|
|
|
|
|
|
&c_utf, &c_utf_len); \
|
|
|
|
|
|
if (SCM_UNLIKELY (err)) \
|
|
|
|
|
|
scm_syserror_msg (FUNC_NAME, "failed to convert string: ~A", \
|
|
|
|
|
|
scm_list_1 (str), err); \
|
|
|
|
|
|
} \
|
|
|
|
|
|
else \
|
|
|
|
|
|
{ \
|
|
|
|
|
|
const scm_t_wchar *wbuf = scm_i_string_wide_chars (str); \
|
|
|
|
|
|
c_utf = u32_conv_to_encoding (c_utf_name, \
|
|
|
|
|
|
iconveh_question_mark, \
|
|
|
|
|
|
(scm_t_uint32 *) wbuf, \
|
|
|
|
|
|
c_strlen, NULL, NULL, &c_utf_len); \
|
|
|
|
|
|
if (SCM_UNLIKELY (c_utf == NULL)) \
|
|
|
|
|
|
scm_syserror_msg (FUNC_NAME, "failed to convert string: ~A", \
|
|
|
|
|
|
scm_list_1 (str), errno); \
|
|
|
|
|
|
} \
|
|
|
|
|
|
scm_dynwind_begin (0); \
|
|
|
|
|
|
scm_dynwind_free (c_utf); \
|
|
|
|
|
|
utf = make_bytevector (c_utf_len, SCM_ARRAY_ELEMENT_TYPE_VU8); \
|
|
|
|
|
|
memcpy (SCM_BYTEVECTOR_CONTENTS (utf), c_utf, c_utf_len); \
|
|
|
|
|
|
scm_dynwind_end (); \
|
|
|
|
|
|
\
|
|
|
|
|
|
return (utf);
|
2009-05-27 18:18:07 +02:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
SCM_DEFINE (scm_string_to_utf8, "string->utf8",
|
|
|
|
|
|
1, 0, 0,
|
|
|
|
|
|
(SCM str),
|
|
|
|
|
|
"Return a newly allocated bytevector that contains the UTF-8 "
|
|
|
|
|
|
"encoding of @var{str}.")
|
|
|
|
|
|
#define FUNC_NAME s_scm_string_to_utf8
|
|
|
|
|
|
{
|
|
|
|
|
|
SCM utf;
|
2012-02-09 23:15:25 +01:00
|
|
|
|
scm_t_uint8 *c_utf;
|
|
|
|
|
|
size_t c_utf_len = 0;
|
2009-05-27 18:18:07 +02:00
|
|
|
|
|
|
|
|
|
|
SCM_VALIDATE_STRING (1, str);
|
|
|
|
|
|
|
2012-02-09 23:15:25 +01:00
|
|
|
|
c_utf = (scm_t_uint8 *) scm_to_utf8_stringn (str, &c_utf_len);
|
|
|
|
|
|
utf = make_bytevector (c_utf_len, SCM_ARRAY_ELEMENT_TYPE_VU8);
|
|
|
|
|
|
memcpy (SCM_BYTEVECTOR_CONTENTS (utf), c_utf, c_utf_len);
|
|
|
|
|
|
free (c_utf);
|
2009-05-27 18:18:07 +02:00
|
|
|
|
|
|
|
|
|
|
return (utf);
|
|
|
|
|
|
}
|
|
|
|
|
|
#undef FUNC_NAME
|
|
|
|
|
|
|
|
|
|
|
|
SCM_DEFINE (scm_string_to_utf16, "string->utf16",
|
|
|
|
|
|
1, 1, 0,
|
|
|
|
|
|
(SCM str, SCM endianness),
|
|
|
|
|
|
"Return a newly allocated bytevector that contains the UTF-16 "
|
|
|
|
|
|
"encoding of @var{str}.")
|
|
|
|
|
|
#define FUNC_NAME s_scm_string_to_utf16
|
|
|
|
|
|
{
|
|
|
|
|
|
STRING_TO_UTF (16);
|
|
|
|
|
|
}
|
|
|
|
|
|
#undef FUNC_NAME
|
|
|
|
|
|
|
2012-02-09 23:15:25 +01:00
|
|
|
|
static void
|
|
|
|
|
|
swap_u32 (scm_t_wchar *vals, size_t len)
|
|
|
|
|
|
{
|
|
|
|
|
|
size_t n;
|
|
|
|
|
|
for (n = 0; n < len; n++)
|
|
|
|
|
|
vals[n] = bswap_32 (vals[n]);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2009-05-27 18:18:07 +02:00
|
|
|
|
SCM_DEFINE (scm_string_to_utf32, "string->utf32",
|
|
|
|
|
|
1, 1, 0,
|
|
|
|
|
|
(SCM str, SCM endianness),
|
|
|
|
|
|
"Return a newly allocated bytevector that contains the UTF-32 "
|
|
|
|
|
|
"encoding of @var{str}.")
|
|
|
|
|
|
#define FUNC_NAME s_scm_string_to_utf32
|
|
|
|
|
|
{
|
2012-02-09 23:15:25 +01:00
|
|
|
|
SCM bv;
|
|
|
|
|
|
scm_t_wchar *wchars;
|
|
|
|
|
|
size_t wchar_len, bytes_len;
|
|
|
|
|
|
|
|
|
|
|
|
wchars = scm_to_utf32_stringn (str, &wchar_len);
|
|
|
|
|
|
bytes_len = wchar_len * sizeof (scm_t_wchar);
|
|
|
|
|
|
if (!scm_is_eq (SCM_UNBNDP (endianness) ? scm_endianness_big : endianness,
|
|
|
|
|
|
scm_i_native_endianness))
|
|
|
|
|
|
swap_u32 (wchars, wchar_len);
|
|
|
|
|
|
|
|
|
|
|
|
bv = make_bytevector (bytes_len, SCM_ARRAY_ELEMENT_TYPE_VU8);
|
|
|
|
|
|
memcpy (SCM_BYTEVECTOR_CONTENTS (bv), wchars, bytes_len);
|
|
|
|
|
|
free (wchars);
|
|
|
|
|
|
|
|
|
|
|
|
return bv;
|
2009-05-27 18:18:07 +02:00
|
|
|
|
}
|
|
|
|
|
|
#undef FUNC_NAME
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Produce the body of a function that converts a UTF-encoded bytevector to a
|
|
|
|
|
|
string. */
|
|
|
|
|
|
#define UTF_TO_STRING(_utf_width) \
|
|
|
|
|
|
SCM str = SCM_BOOL_F; \
|
|
|
|
|
|
int err; \
|
2009-10-28 06:24:23 -07:00
|
|
|
|
char *c_str = NULL; \
|
2009-05-27 18:18:07 +02:00
|
|
|
|
char c_utf_name[MAX_UTF_ENCODING_NAME_LEN]; \
|
2009-10-28 06:24:23 -07:00
|
|
|
|
char *c_utf; \
|
|
|
|
|
|
size_t c_strlen = 0, c_utf_len = 0; \
|
2009-05-27 18:18:07 +02:00
|
|
|
|
\
|
|
|
|
|
|
SCM_VALIDATE_BYTEVECTOR (1, utf); \
|
scm_is_eq for SCM vals, not == or !=
* libguile/bytevectors.c (scm_make_bytevector, STRING_TO_UTF)
(UTF_TO_STRING):
* libguile/continuations.c (scm_i_check_continuation):
* libguile/expand.h (SCM_EXPANDED_P):
* libguile/fluids.c (scm_i_make_with_fluids):
* libguile/generalized-vectors.c (scm_make_generalized_vector):
* libguile/goops.c (SCM_GOOPS_UNBOUNDP, slot_definition_using_name):
(scm_c_extend_primitive_generic, more_specificp, scm_make)
* libguile/i18n.c (SCM_VALIDATE_OPTIONAL_LOCALE_COPY):
(scm_locale_string_to_integer)
* libguile/modules.c (resolve_duplicate_binding):
(scm_module_reverse_lookup)
* libguile/posix.c (scm_to_resource):
* libguile/r6rs-ports.c (scm_put_bytevector):
* libguile/socket.c (scm_connect, scm_bind, scm_sendto
* libguile/stacks.c (find_prompt):
* libguile/variable.c (scm_variable_ref, scm_variable_bound_p):
* libguile/vm-engine.h (ASSERT_BOUND_VARIABLE, ASSERT_BOUND)
* libguile/vm-i-system.c (VARIABLE_BOUNDP, local_bound)
(long_local_bound, fluid_ref): Use scm_is_eq to compare, not == / !=.
2011-05-13 12:42:01 +02:00
|
|
|
|
if (scm_is_eq (endianness, SCM_UNDEFINED)) \
|
2016-06-23 18:31:55 +02:00
|
|
|
|
endianness = sym_big; \
|
2009-05-27 18:18:07 +02:00
|
|
|
|
else \
|
|
|
|
|
|
SCM_VALIDATE_SYMBOL (2, endianness); \
|
|
|
|
|
|
\
|
|
|
|
|
|
c_utf_len = SCM_BYTEVECTOR_LENGTH (utf); \
|
|
|
|
|
|
c_utf = (char *) SCM_BYTEVECTOR_CONTENTS (utf); \
|
|
|
|
|
|
utf_encoding_name (c_utf_name, (_utf_width), endianness); \
|
|
|
|
|
|
\
|
|
|
|
|
|
err = mem_iconveh (c_utf, c_utf_len, \
|
2009-10-28 06:24:23 -07:00
|
|
|
|
c_utf_name, "UTF-8", \
|
2009-05-27 18:18:07 +02:00
|
|
|
|
iconveh_question_mark, NULL, \
|
|
|
|
|
|
&c_str, &c_strlen); \
|
|
|
|
|
|
if (SCM_UNLIKELY (err)) \
|
|
|
|
|
|
scm_syserror_msg (FUNC_NAME, "failed to convert to string: ~A", \
|
|
|
|
|
|
scm_list_1 (utf), err); \
|
|
|
|
|
|
else \
|
2009-10-28 06:24:23 -07:00
|
|
|
|
{ \
|
2013-01-15 15:07:15 +01:00
|
|
|
|
str = scm_from_utf8_stringn (c_str, c_strlen); \
|
2009-10-28 06:24:23 -07:00
|
|
|
|
free (c_str); \
|
|
|
|
|
|
} \
|
2009-05-27 18:18:07 +02:00
|
|
|
|
return (str);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
SCM_DEFINE (scm_utf8_to_string, "utf8->string",
|
|
|
|
|
|
1, 0, 0,
|
|
|
|
|
|
(SCM utf),
|
|
|
|
|
|
"Return a newly allocate string that contains from the UTF-8-"
|
|
|
|
|
|
"encoded contents of bytevector @var{utf}.")
|
|
|
|
|
|
#define FUNC_NAME s_scm_utf8_to_string
|
|
|
|
|
|
{
|
|
|
|
|
|
SCM str;
|
|
|
|
|
|
const char *c_utf;
|
2009-10-28 06:24:23 -07:00
|
|
|
|
size_t c_utf_len = 0;
|
2009-05-27 18:18:07 +02:00
|
|
|
|
|
|
|
|
|
|
SCM_VALIDATE_BYTEVECTOR (1, utf);
|
|
|
|
|
|
|
|
|
|
|
|
c_utf_len = SCM_BYTEVECTOR_LENGTH (utf);
|
|
|
|
|
|
c_utf = (char *) SCM_BYTEVECTOR_CONTENTS (utf);
|
2013-01-15 11:01:10 +01:00
|
|
|
|
str = scm_from_utf8_stringn (c_utf, c_utf_len);
|
2009-05-27 18:18:07 +02:00
|
|
|
|
|
|
|
|
|
|
return (str);
|
|
|
|
|
|
}
|
|
|
|
|
|
#undef FUNC_NAME
|
|
|
|
|
|
|
|
|
|
|
|
SCM_DEFINE (scm_utf16_to_string, "utf16->string",
|
|
|
|
|
|
1, 1, 0,
|
|
|
|
|
|
(SCM utf, SCM endianness),
|
|
|
|
|
|
"Return a newly allocate string that contains from the UTF-16-"
|
|
|
|
|
|
"encoded contents of bytevector @var{utf}.")
|
|
|
|
|
|
#define FUNC_NAME s_scm_utf16_to_string
|
|
|
|
|
|
{
|
|
|
|
|
|
UTF_TO_STRING (16);
|
|
|
|
|
|
}
|
|
|
|
|
|
#undef FUNC_NAME
|
|
|
|
|
|
|
|
|
|
|
|
SCM_DEFINE (scm_utf32_to_string, "utf32->string",
|
|
|
|
|
|
1, 1, 0,
|
|
|
|
|
|
(SCM utf, SCM endianness),
|
|
|
|
|
|
"Return a newly allocate string that contains from the UTF-32-"
|
|
|
|
|
|
"encoded contents of bytevector @var{utf}.")
|
|
|
|
|
|
#define FUNC_NAME s_scm_utf32_to_string
|
|
|
|
|
|
{
|
|
|
|
|
|
UTF_TO_STRING (32);
|
|
|
|
|
|
}
|
|
|
|
|
|
#undef FUNC_NAME
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Initialization. */
|
|
|
|
|
|
|
2009-06-22 00:56:00 +02:00
|
|
|
|
void
|
|
|
|
|
|
scm_bootstrap_bytevectors (void)
|
|
|
|
|
|
{
|
Use a TC7 tag instead of a SMOB for bytevectors.
* libguile/bytevectors.c (scm_tc16_bytevector): Remove.
(SCM_BYTEVECTOR_SET_LENGTH, SCM_BYTEVECTOR_SET_CONTENTS,
SCM_BYTEVECTOR_SET_INLINE, SCM_BYTEVECTOR_SET_ELEMENT_TYPE,
make_bytevector_from_buffer, scm_is_bytevector,
scm_bootstrap_bytevectors): Adjust to the SMOB->tc7 change.
(scm_i_print_bytevector): New, formerly `print_bytevector ()'.
(bytevector_equal_p): Remove.
* libguile/bytevectors.h (SCM_BYTEVECTOR_LENGTH,
SCM_BYTEVECTOR_CONTENTS, SCM_BYTEVECTOR_P): Adjust to SMOB->tc7
change.
(SCM_BYTEVECTOR_FLAGS, SCM_SET_BYTEVECTOR_FLAGS): New macros.
(scm_tc16_bytevector): Remove declaration.
(scm_i_print_bytevector): New declaration.
* libguile/eq.c (scm_equal_p): Handle `scm_tc7_bytevector'.
* libguile/evalext.c (scm_self_evaluating_p): Likewise.
* libguile/print.c (iprin1): Likewise.
* libguile/tags.h (scm_tc7_bytevector): New.
(scm_tc7_unused_8): Remove.
* libguile/validate.h (SCM_VALIDATE_BYTEVECTOR): Adjust.
* test-suite/tests/bytevectors.test ("Datum
Syntax")["self-evaluating?"]: New test.
2009-08-30 20:12:09 +02:00
|
|
|
|
/* This must be instantiated here because the generalized-vector API may
|
2010-06-01 13:26:11 +02:00
|
|
|
|
want to access bytevectors even though `(rnrs bytevectors)' hasn't been
|
Use a TC7 tag instead of a SMOB for bytevectors.
* libguile/bytevectors.c (scm_tc16_bytevector): Remove.
(SCM_BYTEVECTOR_SET_LENGTH, SCM_BYTEVECTOR_SET_CONTENTS,
SCM_BYTEVECTOR_SET_INLINE, SCM_BYTEVECTOR_SET_ELEMENT_TYPE,
make_bytevector_from_buffer, scm_is_bytevector,
scm_bootstrap_bytevectors): Adjust to the SMOB->tc7 change.
(scm_i_print_bytevector): New, formerly `print_bytevector ()'.
(bytevector_equal_p): Remove.
* libguile/bytevectors.h (SCM_BYTEVECTOR_LENGTH,
SCM_BYTEVECTOR_CONTENTS, SCM_BYTEVECTOR_P): Adjust to SMOB->tc7
change.
(SCM_BYTEVECTOR_FLAGS, SCM_SET_BYTEVECTOR_FLAGS): New macros.
(scm_tc16_bytevector): Remove declaration.
(scm_i_print_bytevector): New declaration.
* libguile/eq.c (scm_equal_p): Handle `scm_tc7_bytevector'.
* libguile/evalext.c (scm_self_evaluating_p): Likewise.
* libguile/print.c (iprin1): Likewise.
* libguile/tags.h (scm_tc7_bytevector): New.
(scm_tc7_unused_8): Remove.
* libguile/validate.h (SCM_VALIDATE_BYTEVECTOR): Adjust.
* test-suite/tests/bytevectors.test ("Datum
Syntax")["self-evaluating?"]: New test.
2009-08-30 20:12:09 +02:00
|
|
|
|
loaded. */
|
2009-12-05 11:43:20 +01:00
|
|
|
|
scm_null_bytevector = make_bytevector (0, SCM_ARRAY_ELEMENT_TYPE_VU8);
|
2009-06-22 00:56:00 +02:00
|
|
|
|
|
2017-02-28 17:02:25 +01:00
|
|
|
|
|
|
|
|
|
|
scm_endianness_big = sym_big = scm_from_latin1_symbol ("big");
|
|
|
|
|
|
scm_endianness_little = sym_little = scm_from_latin1_symbol ("little");
|
|
|
|
|
|
|
2009-06-24 23:46:42 +02:00
|
|
|
|
#ifdef WORDS_BIGENDIAN
|
2017-02-28 17:02:25 +01:00
|
|
|
|
scm_i_native_endianness = sym_big;
|
2009-06-24 23:46:42 +02:00
|
|
|
|
#else
|
2017-02-28 17:02:25 +01:00
|
|
|
|
scm_i_native_endianness = sym_little;
|
2009-06-24 23:46:42 +02:00
|
|
|
|
#endif
|
|
|
|
|
|
|
2010-03-16 21:18:12 +01:00
|
|
|
|
scm_c_register_extension ("libguile-" SCM_EFFECTIVE_VERSION,
|
|
|
|
|
|
"scm_init_bytevectors",
|
2009-06-22 00:56:00 +02:00
|
|
|
|
(scm_t_extension_init_func) scm_init_bytevectors,
|
|
|
|
|
|
NULL);
|
2009-07-19 15:04:40 +02:00
|
|
|
|
|
Remove array impl. registry; instead, hard-code array handle creation
* libguile/array-handle.h (scm_t_vector_ref, scm_t_vector_set): Rename
from scm_t_array_ref, scm_t_array_set. These were named
scm_i_t_array_ref and scm_i_t_array_set in 1.8 and 2.0. Change to
take the vector directly, instead of the array handle. In this way,
generic array handles are layered on top of specific implementations
of backing stores.
Remove scm_t_array_implementation, introduced in 2.0 but never
documented. It was a failed attempt to layer the array implementation
that actually introduced too many layers, as it prevented the "vref"
and "vset" members of scm_t_array_handle (called "ref" and "set" in
1.8, not present in 2.0) from specializing on array backing stores.
(scm_i_register_array_implementation) (scm_i_array_implementation_for_obj):
Remove these internal interfaces.
(scm_t_array_handle): Adapt to scm_t_vector_ref / scm_t_vector_set
change.
(scm_array_handle_ref, scm_array_handle_set): Adapt to change in
vref/vset prototype.
* libguile/array-handle.c (scm_array_get_handle): Inline all the
necessary initializations here for all specific array types.
* libguile/array-map.c (rafill, racp, ramap, rafe, array_index_map_1):
* libguile/arrays.c: Remove array implementation code.
* libguile/bitvectors.h:
* libguile/bitvectors.c: Remove array implementation code.
(scm_i_bitvector_bits): New internal interface.
* libguile/bytevectors.c: Remove array implementation code.
* libguile/srfi-4.h: Remove declarations for internal procedures that
don't exist (!).
* libguile/strings.c: Remove array implementation code.
* libguile/vectors.c: Remove array implementation code.
2014-02-09 12:31:59 +01:00
|
|
|
|
scm_i_register_vector_constructor
|
|
|
|
|
|
(scm_i_array_element_types[SCM_ARRAY_ELEMENT_TYPE_VU8],
|
|
|
|
|
|
scm_make_bytevector);
|
2009-06-22 00:56:00 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
2009-05-27 18:18:07 +02:00
|
|
|
|
void
|
|
|
|
|
|
scm_init_bytevectors (void)
|
|
|
|
|
|
{
|
|
|
|
|
|
#include "libguile/bytevectors.x"
|
|
|
|
|
|
}
|