From a0a7299fe03c74a2eb18f72744304593281b620a Mon Sep 17 00:00:00 2001 From: Gregory Lirent Date: Fri, 3 Jun 2022 11:56:01 +0300 Subject: [PATCH 1/2] Update base --- src/vnode.c | 157 ++++++++++++++---------------- src/vtype-extra.c | 92 ++++++++++++++++++ src/vtype.c | 241 ++++++++++------------------------------------ 3 files changed, 214 insertions(+), 276 deletions(-) create mode 100644 src/vtype-extra.c diff --git a/src/vnode.c b/src/vnode.c index c538fad..e8c2efd 100644 --- a/src/vnode.c +++ b/src/vnode.c @@ -7,96 +7,84 @@ /*#####################################################################################################################*/ -static vnode_t create_number(vtype xt, const void* v, vtype t) { - var_t _ = { .ptr = 0 }; +static vnode_t create_value(vtype xt, const void* v, vtype t) { + var_t _; - if (t == VTYPE_POINTER) t = (sizeof(void*) == 8) ? VTYPE_UINT64 : VTYPE_UINT32; - if (t == VTYPE_BOOLEAN) t = VTYPE_UINT8; + if (sizeof(void*) == 8) { + if (t == VTYPE_UINT8 || t == VTYPE_INT8 || t == VTYPE_BOOLEAN ) { + _.u64 = *(u8_t*)v; + } else if (t == VTYPE_UINT16 || t == VTYPE_INT16) { + _.u64 = *(u16_t*)v; + } else if (t == VTYPE_UINT32 || t == VTYPE_INT32 || (sizeof(void*) == 4 && t == VTYPE_POINTER)) { + _.u64 = *(u32_t*)v; + } else if (t == VTYPE_UINT64 || t == VTYPE_INT64 || (sizeof(void*) == 8 && t == VTYPE_POINTER)) { + _.u64 = *(u64_t*)v; + } - if (xt == VTYPE_POINTER) xt = (sizeof(void*) == 8) ? VTYPE_UINT64 : VTYPE_UINT32; - if (xt == VTYPE_BOOLEAN) xt = VTYPE_UINT8; + if (is_big_endian) { + if (xt == VTYPE_BOOLEAN) _.u8 = (_.u64 == 0) ? 0 : 1; + else if (xt == VTYPE_UINT8 || xt == VTYPE_INT8) { + _.u64 <<= 56; + } else if (xt == VTYPE_UINT16 || xt == VTYPE_INT16) { + _.u64 <<= 48; + } else if (xt == VTYPE_UINT32 || xt == VTYPE_INT32) { + _.u64 <<= 32; + } + } else if (xt == VTYPE_BOOLEAN) _.u64 = (_.u64 == 0) ? 0 : 1; - switch (xt) { default: default_: abort(); - case VTYPE_INT8: - case VTYPE_UINT8: switch (t) { default: goto default_; - case VTYPE_INT8: - case VTYPE_UINT8: _.u8 = *(u8_t*)v; break; - case VTYPE_INT16: - case VTYPE_UINT16: _.u8 = *(u16_t*)v; break; - case VTYPE_INT32: - case VTYPE_UINT32: _.u8 = *(u32_t*)v; break; - case VTYPE_INT64: - case VTYPE_UINT64: _.u8 = *(u64_t*)v; break; - } - break; + } else { + if (t == VTYPE_UINT8 || t == VTYPE_INT8 || t == VTYPE_BOOLEAN ) { + _.u64 = *(u8_t*)v; + } else if (t == VTYPE_UINT16 || t == VTYPE_INT16) { + _.u64 = *(u16_t*)v; + } else if (t == VTYPE_UINT32 || t == VTYPE_INT32 || (sizeof(void*) == 4 && t == VTYPE_POINTER)) { + _.u64 = *(u32_t*)v; + } else if (t == VTYPE_UINT64 || t == VTYPE_INT64 || (sizeof(void*) == 8 && t == VTYPE_POINTER)) { + _.u64 = *(u64_t*)v; + } - case VTYPE_INT16: - case VTYPE_UINT16: switch (t) { default: goto default_; - case VTYPE_INT8: - case VTYPE_UINT8: _.u16 = *(u8_t*)v; break; - case VTYPE_INT16: - case VTYPE_UINT16: _.u16 = *(u16_t*)v; break; - case VTYPE_INT32: - case VTYPE_UINT32: _.u16 = *(u32_t*)v; break; - case VTYPE_INT64: - case VTYPE_UINT64: _.u16 = *(u64_t*)v; break; - } - break; + if (xt == VTYPE_UINT64 || xt == VTYPE_UINT32) { + _.ptr = memndup(&_.u64, sizeof(_.u64)); + } else if (is_big_endian) { + _.u64 <<= 32; + if (xt == VTYPE_BOOLEAN) _.u8 = (_.u32 == 0) ? 0 : 1; + else if (xt == VTYPE_UINT8 || xt == VTYPE_INT8) { + _.u32 <<= 24; + } else if (xt == VTYPE_UINT16 || xt == VTYPE_INT16) { + _.u32 <<= 16; + } + } else if (xt == VTYPE_BOOLEAN) _.u32 = (_.u32 == 0) ? 0 : 1; + } - case VTYPE_INT32: - case VTYPE_UINT32: switch (t) { default: goto default_; - case VTYPE_INT8: - case VTYPE_UINT8: _.u32 = *(u8_t*)v; break; - case VTYPE_INT16: - case VTYPE_UINT16: _.u32 = *(u16_t*)v; break; - case VTYPE_INT32: - case VTYPE_UINT32: _.u32 = *(u32_t*)v; break; - case VTYPE_INT64: - case VTYPE_UINT64: _.u32 = *(u64_t*)v; break; - } - break; + return _.ptr; +} - case VTYPE_INT64: - case VTYPE_UINT64: switch (t) { default: goto default_; - case VTYPE_INT8: - case VTYPE_UINT8: _.u64 = *(u8_t*)v; goto u64_; - case VTYPE_INT16: - case VTYPE_UINT16: _.u64 = *(u16_t*)v; goto u64_; - case VTYPE_INT32: - case VTYPE_UINT32: _.u64 = *(u32_t*)v; goto u64_; - case VTYPE_INT64: - case VTYPE_UINT64: _.u64 = *(u64_t*)v; - u64_: if (!is_x64) _.ptr = memndup(&_.u64, sizeof(_.u64)); - break; - } - break; - case VTYPE_FLOAT: switch (t) { default: goto default_; - case VTYPE_DOUBLE: _.f = *(dbl_t*)v; goto f_; - case VTYPE_LDOUBLE: _.f = *(ldbl_t*)v; goto f_; - case VTYPE_FLOAT: _.f = *(fl_t*)v; - f_: if (!is_permissible(fl_t)) _.ptr = memndup(&_.f, sizeof(_.f)); - break; - } - break; +static vnode_t create_float(vtype xt, const void* v, vtype t) { + var_t _; - case VTYPE_DOUBLE: switch (t) { default: goto default_; - case VTYPE_FLOAT: _.d = *(fl_t*)v; goto d_; - case VTYPE_LDOUBLE: _.d = *(ldbl_t*)v; goto d_; - case VTYPE_DOUBLE: _.d = *(dbl_t*)v; - d_: if (!is_permissible(dbl_t)) _.ptr = memndup(&_.d, sizeof(_.d)); - break; - } - break; + if (t == VTYPE_FLOAT) { + _.ld = *(fl_t*)v; + } else if (t == VTYPE_DOUBLE) { + _.ld = *(dbl_t*)v; + } else { // (t == VTYPE_LDOUBLE) + _.ld = *(ldbl_t*)v; + } - case VTYPE_LDOUBLE: switch (t) { default: goto default_; - case VTYPE_FLOAT: _.ld = *(fl_t*)v; goto ld_; - case VTYPE_DOUBLE: _.ld = *(dbl_t*)v; goto ld_; - case VTYPE_LDOUBLE: _.ld = *(ldbl_t*)v; - ld_: if (!is_permissible(ldbl_t)) _.ptr = memndup(&_.ld, sizeof(_.ld)); - break; - } - break; + if (xt == VTYPE_FLOAT) { + _.f = _.ld; + if (!is_permissible(fl_t)) { + _.ptr = memndup(&_.f, sizeof(_.f)); + } + } else if (xt == VTYPE_DOUBLE) { + _.f = _.d; + if (!is_permissible(dbl_t)) { + _.ptr = memndup(&_.d, sizeof(_.d)); + } + } else { // (xt == VTYPE_LDOUBLE) + if (!is_permissible(ldbl_t)) { + _.ptr = memndup(&_.ld, sizeof(_.ld)); + } } return _.ptr; @@ -124,8 +112,7 @@ vnode_t libcdsb_vnode_create(const void* v, vtype t) { break; case VTYPE_INT64: - case VTYPE_UINT64: - u64_: if (is_x64) _.u64 = *(u64_t*)v; + case VTYPE_UINT64: if (is_x64) _.u64 = *(u64_t*)v; else _.ptr = memndup(v, sizeof(u64_t)); break; @@ -244,10 +231,10 @@ vnode_t libcdsb_vnode_create_target(vtype xt, const void* v, vtype t) { if (is_integer(xt)) { tvalue_assert(t); - return create_number(xt, v, t); + return create_value(xt, v, t); } else if (is_float(xt)) { tfloat_assert(t); - return create_number(xt, v, t); + return create_float(xt, v, t); } type_assert(xt, t); diff --git a/src/vtype-extra.c b/src/vtype-extra.c new file mode 100644 index 0000000..94d827d --- /dev/null +++ b/src/vtype-extra.c @@ -0,0 +1,92 @@ +/* This software is licensed by the MIT License, see LICENSE file */ +/* Copyright © 2022 Gregory Lirent */ + +#include +#include +#include "__internal/include.h" + +/*#####################################################################################################################*/ + +#define sh__(a) #a +#define s__(a) sh__(a) + +#define fstring(v) _Generic((v),\ + unsigned char: "%hhu", signed char: "%hhd",\ + unsigned short: "%hu", signed short: "%hd",\ + unsigned int: "%u", signed int: "%d",\ + unsigned long: "%lu", signed long: "%ld",\ + unsigned long long: "%llu", signed long long: "%lld",\ + float: "%."s__(FLT_DECIMAL_DIG)"g",\ + double: "%."s__(DBL_DIG)"lg",\ + long double: "%."s__(DBL_DECIMAL_DIG)"Lg") + +#define stringify(v) sprintf(STRINGIFY_BUFFER, fstring(v), (v)) + +static _Thread_local char STRINGIFY_BUFFER[64]; + +/*#####################################################################################################################*/ + + +const size_t LIBCDSB_VTYPE_SIZES[18] = { + sizeof(void*), sizeof(_Bool), + sizeof(u8_t), sizeof(u16_t), sizeof(u32_t), sizeof(u64_t), + sizeof(s8_t), sizeof(s16_t), sizeof(s32_t), sizeof(s64_t), + sizeof(fl_t), sizeof(dbl_t), sizeof(ldbl_t), + sizeof(str_t), sizeof(map_t), sizeof(arr_t), + sizeof(list_t), sizeof(set_t) +}; + + +/*#####################################################################################################################*/ + + +const char* libcdsb_vtype_name(vtype t) { + switch (t) { default: abort(); + case VTYPE_POINTER: return "VTYPE_POINTER"; + case VTYPE_BOOLEAN: return "VTYPE_BOOLEAN"; + case VTYPE_UINT8: return "VTYPE_UINT8"; + case VTYPE_UINT16: return "VTYPE_UINT16"; + case VTYPE_UINT32: return "VTYPE_UINT32"; + case VTYPE_UINT64: return "VTYPE_UINT64"; + case VTYPE_INT8: return "VTYPE_INT8"; + case VTYPE_INT16: return "VTYPE_INT16"; + case VTYPE_INT32: return "VTYPE_INT32"; + case VTYPE_INT64: return "VTYPE_INT64"; + case VTYPE_FLOAT: return "VTYPE_FLOAT"; + case VTYPE_DOUBLE: return "VTYPE_DOUBLE"; + case VTYPE_LDOUBLE: return "VTYPE_LDOUBLE"; + case VTYPE_STRING: return "VTYPE_STRING"; + case VTYPE_MAP: return "VTYPE_MAP"; + case VTYPE_ARRAY: return "VTYPE_ARRAY"; + case VTYPE_LIST: return "VTYPE_LIST"; + case VTYPE_SET: return "VTYPE_SET"; + } +} + + +const char* libcdsb_vtype_stringify(const void* v, vtype t) { + if (is_null(v) || (t == VTYPE_POINTER && is_null(*(void**)v))) return "null"; + if (t == VTYPE_BOOLEAN) return (*(vtype_bool*)v) ? "true" : "false"; + if (t == VTYPE_STRING) return *(char**)v; + + switch (t) { + case VTYPE_INT8: stringify(*( s8_t*)v); break; + case VTYPE_INT16: stringify(*( s16_t*)v); break; + case VTYPE_INT32: stringify(*( s32_t*)v); break; + case VTYPE_INT64: stringify(*( s64_t*)v); break; + case VTYPE_UINT8: stringify(*( u8_t*)v); break; + case VTYPE_UINT16: stringify(*( u16_t*)v); break; + case VTYPE_UINT32: stringify(*( u32_t*)v); break; + case VTYPE_UINT64: stringify(*( u64_t*)v); break; + case VTYPE_FLOAT: stringify(*( fl_t*)v); break; + case VTYPE_DOUBLE: stringify(*( dbl_t*)v); break; + case VTYPE_LDOUBLE: stringify(*(ldbl_t*)v); break; + + case VTYPE_POINTER: sprintf(STRINGIFY_BUFFER, (sizeof(void*) == 8) ? "0x%016lx" : "0x%08x", (uintptr_t)*(void**)v); break; + + default: sprintf(STRINGIFY_BUFFER, "<%s>", libcdsb_vtype_name(t)); + break; + } + + return STRINGIFY_BUFFER; +} diff --git a/src/vtype.c b/src/vtype.c index 9d5a605..d7b6a9f 100644 --- a/src/vtype.c +++ b/src/vtype.c @@ -1,6 +1,7 @@ /* This software is licensed by the MIT License, see LICENSE file */ /* Copyright © 2022 Gregory Lirent */ +#include "__internal/assert.h" #include "__internal/include.h" #define max_align _Alignof(max_align_t) @@ -8,212 +9,70 @@ /*#####################################################################################################################*/ -ainline(vtype expandu8(u32_t* v)) { - if (is_little_endian) { - *v &= 0x000000ff; - } else { - *v >>= 24; +static vtype normalize_value(u64_t* d, const void* v, vtype t) { + if (t == VTYPE_BOOLEAN || t == VTYPE_UINT8) { + *d = *(u8_t*)v; + t = VTYPE_UINT64; + } else if (t == VTYPE_UINT16) { + *d = *(u16_t*)v; + t = VTYPE_UINT64; + } else if (t == VTYPE_UINT32 || (sizeof(void*) == 4 && t == VTYPE_POINTER)) { + *d = *(u32_t*)v; + t = VTYPE_UINT64; + } else if (t == VTYPE_UINT64 || (sizeof(void*) == 8 && t == VTYPE_POINTER)) { + *d = *(u64_t*)v; + t = VTYPE_UINT64; + } else if (t == VTYPE_INT8) { + *d = *(s8_t*)v; + t = (*(s8_t*)v >= 0) ? VTYPE_UINT64 : VTYPE_INT64; + } else if (t == VTYPE_INT16) { + *d = *(s16_t*)v; + t = (*(s16_t*)v >= 0) ? VTYPE_UINT64 : VTYPE_INT64; + } else if (t == VTYPE_INT32) { + *d = *(s32_t*)v; + t = (*(s32_t*)v >= 0) ? VTYPE_UINT64 : VTYPE_INT64; + } else if (t == VTYPE_INT64) { + *d = *(s64_t*)v; + t = (*(s64_t*)v >= 0) ? VTYPE_UINT64 : VTYPE_INT64; } - return VTYPE_UINT32; + + return t; } -ainline(vtype expandu16(u32_t* v)) { - if (is_little_endian) { - *v &= 0x0000ffff; - } else { - *v >>= 16; - } - return VTYPE_UINT32; -} - -ainline(vtype expands8(u32_t* v)) { - if (is_big_endian) - *v >>= 24; - *v |= 0xffffff00; - - return VTYPE_INT32; -} - -ainline(vtype expands16(u32_t* v)) { - if (is_big_endian) - *v >>= 16; - *v |= 0xffff0000; - - return VTYPE_INT32; -} - - -/*#####################################################################################################################*/ - - -const size_t LIBCDSB_VTYPE_SIZES[18] = { - sizeof(void*), sizeof(_Bool), - sizeof(u8_t), sizeof(u16_t), sizeof(u32_t), sizeof(u64_t), - sizeof(s8_t), sizeof(s16_t), sizeof(s32_t), sizeof(s64_t), - sizeof(fl_t), sizeof(dbl_t), sizeof(ldbl_t), - sizeof(str_t), sizeof(map_t), sizeof(arr_t), - sizeof(list_t), sizeof(set_t) -}; - - -/*#####################################################################################################################*/ - - int libcdsb_vtype_compare_values(const void* s0, vtype t0, const void* s1, vtype t1) { + if (t0 == t1) return libcdsb_vtype_compare_values_eq(s0, s1, t0); - int c; - size_t _Alignas(max_align) v0[max_size/sizeof(size_t)]; - size_t _Alignas(max_align) v1[max_size/sizeof(size_t)]; + if (is_integer(t0) && is_integer(t1)) { + u64_t v0, v1; - c = t0 - t1; + t0 = normalize_value(&v0, s0, t0); + t1 = normalize_value(&v1, s1, t1); - if (t0 >= VTYPE_STRING || t1 >= VTYPE_STRING) { - static int(*compare[5])(const void*,const void*) = { - (void*)string_compare, - (void*) map_compare, - (void*) array_compare, - (void*) list_compare, - (void*) vset_compare - }; - - if (c) return c; - - t0 -= VTYPE_STRING; - return compare[t0](s0, s1); - } - - if (t0 == VTYPE_POINTER) t0 = (sizeof(void*) == 8) ? VTYPE_UINT64 : VTYPE_UINT32; - if (t1 == VTYPE_POINTER) t1 = (sizeof(void*) == 8) ? VTYPE_UINT64 : VTYPE_UINT32; - if (t0 == VTYPE_BOOLEAN) t0 = VTYPE_UINT8; - if (t1 == VTYPE_BOOLEAN) t1 = VTYPE_UINT8; - - if (!c) { - - if (s0 == s1) - return 0; - - if (t0 == VTYPE_LDOUBLE) { - *(ldbl_t*)v0 = *(ldbl_t*)s0 - *(ldbl_t*)s1; - - ldouble_: - if (!*(ldbl_t*)v0) - return 0; - return *(ldbl_t*)v0 < 0 ? -1 : 1; - } else if (t0 == VTYPE_DOUBLE) { - *(ldbl_t*)v0 = *(dbl_t*)s0 - *(dbl_t*)s1; - goto ldouble_; - } else if (t0 == VTYPE_FLOAT) { - *(ldbl_t*)v0 = *(fl_t*)s0 - *(fl_t*)s1; - goto ldouble_; + if (t0 == t1) { + if (t0 > VTYPE_UINT64) + return (s64_t)v0 - (s64_t)v1; + return v0 - v1; } - if (t0 == VTYPE_UINT8) - return *(u8_t*)s0 - *(u8_t*)s1; - if (t0 == VTYPE_UINT16) - return *(u16_t*)s0 - *(u16_t*)s1; - if (t0 == VTYPE_UINT32) - return *(u32_t*)s0 - *(u32_t*)s1; + return t1 - t0; - return *(u64_t*)s0 - *(u64_t*)s1; + } else if (is_float(t0) && is_float(t1)) { + ldbl_t v; - } else if (t0 >= VTYPE_FLOAT && t1 >= VTYPE_FLOAT) { - if (t0 == VTYPE_FLOAT) { - *(ldbl_t*)v0 = *(fl_t*)s0; - } else if (t0 == VTYPE_DOUBLE) { - *(ldbl_t*)v0 = *(dbl_t*)s0; - } else if (t0 == VTYPE_LDOUBLE) { - *(ldbl_t*)v0 = *(ldbl_t*)s0; - } + if (t0 == VTYPE_FLOAT) v = *(fl_t*)s0; + else if (t0 == VTYPE_DOUBLE) v = *(dbl_t*)s0; + else v = *(ldbl_t*)s0; - if (t1 == VTYPE_FLOAT) { - *(ldbl_t*)v0 -= *(fl_t*)s1; - } else if (t1 == VTYPE_DOUBLE) { - *(ldbl_t*)v0 -= *(dbl_t*)s1; - } else { - *(ldbl_t*)v0 -= *(ldbl_t*)s1; - } + if (t1 == VTYPE_FLOAT) v -= *(fl_t*)s1; + else if (t1 == VTYPE_DOUBLE) v -= *(dbl_t*)s1; + else v -= *(ldbl_t*)s1; - goto ldouble_; - } + if (v < 0) return -1; - memcpy(v0, s0, 8); - memcpy(v1, s1, 8); - - if (t0 <= VTYPE_UINT64 && t1 <= VTYPE_UINT64) { - - if (t0 == VTYPE_UINT8) { - t0 = expandu8((void*)v0); - } else if (t0 == VTYPE_UINT16) { - t0 = expandu16((void*)v0); - } else if (t0 == VTYPE_UINT64 && *(u64_t*)v0 <= UINT32_MAX) { - t0 = VTYPE_UINT32; - } - - if (t1 == VTYPE_UINT8) { - t1 = expandu8((void*)v1); - } else if (t1 == VTYPE_UINT16) { - t1 = expandu16((void*)v1); - } else if (t1 == VTYPE_UINT64 && *(u64_t*)v1 <= UINT32_MAX) { - t0 = VTYPE_UINT32; - } - - unsigned_: c = t0 - t1; - - if (!c) return *(u32_t*)v0 - *(u32_t*)v1; - - } else if (t0 <= VTYPE_INT64 && t1 <= VTYPE_INT64) { - - if (t0 == VTYPE_INT8) { - t0 = (*(u8_t*)v0 <= INT8_MAX) ? expandu8((void*)v0) : expands8((void*)v0); - - } else if (t0 == VTYPE_INT16) { - t0 = (*(u16_t*)v0 <= INT16_MAX) ? expandu16((void*)v0) : expands16((void*)v0); - - } else if (t0 == VTYPE_INT32) { - if (*(u32_t*)v0 <= INT32_MAX) { - t0 = VTYPE_UINT32; - } - } else if (t0 == VTYPE_INT64) { - if (*(u64_t*)v0 <= UINT32_MAX) { - t0 = VTYPE_UINT32; - } else if (*(u64_t*)v0 <= INT64_MAX) { - t0 = VTYPE_UINT64; - } - } - - if (t1 == VTYPE_INT8) { - t1 = (*(u8_t*)v1 <= INT8_MAX) ? expandu8((void*)v1) : expands8((void*)v1); - - } else if (t1 == VTYPE_INT16) { - t1 = (*(u16_t*)v1 <= INT16_MAX) ? expandu16((void*)v1) : expands16((void*)v1); - - } else if (t1 == VTYPE_INT32) { - if (*(u32_t*)v1 <= INT32_MAX) { - t1 = VTYPE_UINT32; - } - } else if (t1 == VTYPE_INT64) { - if (*(u64_t*)v1 <= UINT32_MAX) { - t1 = VTYPE_UINT32; - } else if (*(u64_t*)v1 <= INT64_MAX) { - t1 = VTYPE_UINT64; - } - } - - if (t0 <= VTYPE_UINT64 && t1 <= VTYPE_UINT64) - goto unsigned_; - - if (t0 <= VTYPE_UINT64) return 1; - if (t1 <= VTYPE_UINT64) return -1; - - c = t0 - t1; - - if (!c) return *(u32_t*)v1 - *(u32_t*)v0; - } - - return c; + return (v > 0) ? 1 : 0; + } else return t0 - t1; } - /*#####################################################################################################################*/ @@ -226,7 +85,7 @@ int libcdsb_vtype_compare_values_eq(const void* s0, const void* s1, vtype t) { switch (t) { default: abort(); - case VTYPE_INT8: return *(s8_t*)s0 - *(s8_t*)s1; + case VTYPE_INT8: return *(s8_t*)s0 - *(s8_t*)s1; case VTYPE_INT16: return *(s16_t*)s0 - *(s16_t*)s1; case VTYPE_INT32: return *(s32_t*)s0 - *(s32_t*)s1; case VTYPE_INT64: return *(s64_t*)s0 - *(s64_t*)s1; From 2e3dc282c76d4cdaaed514f95eae1f83b8a8aaad Mon Sep 17 00:00:00 2001 From: Gregory Lirent Date: Fri, 3 Jun 2022 11:58:02 +0300 Subject: [PATCH 2/2] Change the array's memory handling --- include/array.h | 1 + src/array/base-copy.c | 12 ++++----- src/array/extra.c | 58 ++++++++++++++++++++----------------------- src/array/get.c | 17 ++++++++----- src/array/include.h | 16 +----------- src/array/sort.c | 2 +- 6 files changed, 47 insertions(+), 59 deletions(-) diff --git a/include/array.h b/include/array.h index b438ba7..4582711 100644 --- a/include/array.h +++ b/include/array.h @@ -22,6 +22,7 @@ extern void array_reverse(vtype_array* x) LIBCDSB_nt__ LIBCDSB_nn1__; #define in_array(x, value) (array_indexof(x, value) >= 0) +extern void* array_at (const vtype_array* s, ssize_t index); extern ssize_t array_get(vtype_array* s, vtype_value* x, ssize_t index, _Bool cut); diff --git a/src/array/base-copy.c b/src/array/base-copy.c index a017b41..fe4dbcf 100644 --- a/src/array/base-copy.c +++ b/src/array/base-copy.c @@ -17,7 +17,7 @@ arr_t array_copy(const arr_t* s) { void *p, *v, *e; void (*init)(void*, const void*); - x.mem = p = malloc(array_allocated_nmemb(s)); + x.mem = p = malloc(x.size*vtype_size(x.type)); v = s->mem; e = array_end(&x); @@ -35,7 +35,7 @@ arr_t array_copy(const arr_t* s) { v += vtype_size(x.type); } while (p < e); - } else x.mem = memndup(s->mem, array_allocated_nmemb(s)); + } else x.mem = memndup(s->mem, x.size*vtype_size(x.type)); } return x; @@ -54,7 +54,7 @@ arr_t* array_duplicate(const arr_t* s) { void *p, *v, *e; void (*init)(void*, const void*); - x->mem = p = malloc(array_allocated_nmemb(s)); + x->mem = p = malloc(x->size*vtype_size(x->type)); v = s->mem; e = array_end(x); @@ -72,7 +72,7 @@ arr_t* array_duplicate(const arr_t* s) { v += vtype_size(x->type); } while (p < e); - } else x->mem = memndup(s->mem, array_allocated_nmemb(s)); + } else x->mem = memndup(s->mem, x->size*vtype_size(x->type)); } else memset(x, 0, sizeof(*x)); return x; @@ -89,7 +89,7 @@ void array_copy_init(arr_t* x, const arr_t* s) { void *p, *v, *e; void (*init)(void*, const void*); - x->mem = p = malloc(array_allocated_nmemb(s)); + x->mem = p = malloc(x->size*vtype_size(x->type)); v = s->mem; e = array_end(x); @@ -107,6 +107,6 @@ void array_copy_init(arr_t* x, const arr_t* s) { v += vtype_size(x->type); } while (p < e); - } else x->mem = memndup(s->mem, array_allocated_nmemb(s)); + } else x->mem = memndup(s->mem, x->size*vtype_size(x->type)); } else memset(x, 0, sizeof(*x)); } diff --git a/src/array/extra.c b/src/array/extra.c index c94e0d0..bfc662a 100644 --- a/src/array/extra.c +++ b/src/array/extra.c @@ -17,52 +17,48 @@ ssize_t array_find(const arr_t* x, const void* v, vtype vt) { index = -1; - if (x->size) { - void* p = x->mem; - void* e = array_end(x); + if (!x->size) + return index; - assert(!is_null(x->mem)); + void* p = x->mem; + void* e = array_end(x); - if (x->type != vt) { - do { - ++index; - c = vtype_compare(p, x->type, v, vt); + assert(!is_null(x->mem)); - if (c == 0) - return index; + if (x->type != vt) { + do { + ++index; + c = vtype_compare(p, x->type, v, vt); - p += vtype_size(x->type); - } while (p < e); - } else { - do { - ++index; - c = vtype_compare_eq(p, v, vt); + if (c == 0) + return index; - if (c == 0) - return index; + p += vtype_size(x->type); + } while (p < e); + } else { + do { + ++index; + c = vtype_compare_eq(p, v, vt); - p += vtype_size(x->type); - } while (p < e); - } + if (c == 0) + return index; + + p += vtype_size(x->type); + } while (p < e); } return -1; } ssize_t array_push(arr_t* x, const void* v, vtype vt) { - - void* p; - ssize_t i = x->size; + ssize_t i = x->size; vnode_t n = vnode_tcreate(x->type, v, vt); - if ((ssize_t)array_allocated_nmemb(x) - vtype_size(x->type) < 0) { - ++x->size; - x->mem = realloc(x->mem, array_allocated_nmemb(x)); - } else ++x->size; + x->mem = realloc(x->mem, ++x->size * vtype_size(x->type)); + memcpy(array_internal_at(x, i), vnode_peek(&n, x->type), vtype_size(x->type)); - memcpy(array_at(x, i), vnode_peek(&n, x->type), vtype_size(x->type)); - - if (x->type < VTYPE_STRING) vnode_free(&n, x->type); + if (vtype_size(x->type) > sizeof(void*) && x->type < VTYPE_STRING) + vnode_free(&n, x->type); return i; } diff --git a/src/array/get.c b/src/array/get.c index 3c8cdae..23a2323 100644 --- a/src/array/get.c +++ b/src/array/get.c @@ -5,6 +5,11 @@ #include "../__internal/assert.h" #include "../__internal/vnode.h" +void* array_at(const arr_t* x, ssize_t i) { + if (i < 0 && (i += x->size) < 0) i = 0; + return x->mem + i*vtype_size(x->type); +} + ssize_t array_get(arr_t* x, val_t* d, ssize_t i, _Bool cut) { if (i < 0 && (i += x->size) < 0) i = 0; @@ -14,12 +19,12 @@ ssize_t array_get(arr_t* x, val_t* d, ssize_t i, _Bool cut) { if (cut) { if (!is_null(d)) { - vnode_t n = vnode_create(array_at(x, i), x->type); + vnode_t n = vnode_create(array_internal_at(x, i), x->type); value_set(d, n, x->type, VF_WRITEABLE|VF_REMOVABLE); } array_cut(x, i, 1); - } else value_set(d, array_at(x, i), x->type, VF_WRITEABLE); + } else value_set(d, array_internal_at(x, i), x->type, VF_WRITEABLE); } else { i = -1; memset(d, 0, sizeof(*d)); @@ -41,15 +46,15 @@ _Bool array_slice(arr_t* x, arr_t* s, ssize_t i, size_t n, _Bool cut) { x->type = s->type; x->size = n; - x->mem = malloc(array_allocated_nmemb(x)); + x->mem = malloc(x->size*vtype_size(x->type)); if (!cut && s->type >= VTYPE_STRING) { void *p, *v, *e; void (*init)(void*, const void*); p = x->mem; - v = array_at(s, i); - e = array_at(x, n); + v = array_internal_at(s, i); + e = array_internal_at(x, n); switch (s->type) { default: abort(); case VTYPE_STRING: init = (void*)string_copy_init; break; @@ -64,7 +69,7 @@ _Bool array_slice(arr_t* x, arr_t* s, ssize_t i, size_t n, _Bool cut) { p += vtype_size(x->type); v += vtype_size(x->type); } while (p < e); - } else memcpy(x->mem, array_at(s, i), n*vtype_size(x->type)); + } else memcpy(x->mem, array_internal_at(s, i), n*vtype_size(x->type)); if (cut) array_cut(s, i, n); } else { diff --git a/src/array/include.h b/src/array/include.h index 06badcf..a9c17b8 100644 --- a/src/array/include.h +++ b/src/array/include.h @@ -8,20 +8,6 @@ #ifndef LIBCDSB_SRC_ARRAY_INCLUDE_H #define LIBCDSB_SRC_ARRAY_INCLUDE_H -#define ARRAY_MEM_BLOCK_SIZE 256 - -ainline(size_t array_nblocks(const arr_t* x)) { - size_t n = x->size*vtype_size(x->type); - - if (n%vtype_size(x->type)) { - return n / ARRAY_MEM_BLOCK_SIZE + 1; - } else return n / ARRAY_MEM_BLOCK_SIZE; -} - -ainline(size_t array_allocated_nmemb(const arr_t* x)) { - return array_nblocks(x) * ARRAY_MEM_BLOCK_SIZE; -} - ainline(void array_cut(arr_t* x, size_t i, size_t n)) { void* v = x->mem + i*vtype_size(x->type); void* e = v + n*vtype_size(x->type); @@ -34,7 +20,7 @@ ainline(void* array_end(const arr_t* x)) { return x->mem + x->size*vtype_size(x->type); } -ainline(void* array_at(const arr_t* x, size_t i)) { +ainline(void* array_internal_at(const arr_t* x, size_t i)) { return x->mem + i*vtype_size(x->type); } diff --git a/src/array/sort.c b/src/array/sort.c index 415f868..19622c2 100644 --- a/src/array/sort.c +++ b/src/array/sort.c @@ -81,7 +81,7 @@ void array_sort(arr_t* x) { void array_reverse(arr_t* x) { if (x->size >= 2) { void *l = x->mem; - void *r = array_at(x, x->size-1); + void *r = array_internal_at(x, x->size-1); char b[vtype_size(x->type)]; do {