From eeff5e273f22aa28e81ab080e9ffdce85ac394b8 Mon Sep 17 00:00:00 2001 From: Bad Diode Date: Fri, 22 Oct 2021 09:59:31 +0200 Subject: Prepare skeleton for bytecode interpreter --- src/treewalk/darray.h | 78 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 78 insertions(+) create mode 100644 src/treewalk/darray.h (limited to 'src/treewalk/darray.h') diff --git a/src/treewalk/darray.h b/src/treewalk/darray.h new file mode 100644 index 0000000..db6234d --- /dev/null +++ b/src/treewalk/darray.h @@ -0,0 +1,78 @@ +#ifndef BDL_DARRAY_H +#define BDL_DARRAY_H + +#include + +typedef struct ArrayHeader { + size_t size; + size_t cap; +} ArrayHeader; + +// Header/Size/capacity accessors. +#define array_head(ARR) ((ArrayHeader *)((char *)(ARR) - sizeof(ArrayHeader))) +#define array_size(ARR) ((ARR) ? array_head(ARR)->size : 0) +#define array_cap(ARR) ((ARR) ? array_head(ARR)->cap : 0) + +// Initialize a dynamic array ARR with N elements. The initialization doesn't +// zero out the data, so thread carefully.. +#define array_init(ARR,N) ((ARR) = _array_reserve(N, sizeof(*(ARR)))) + +// Push a given element T to the dynamic array ARR. +#define array_push(ARR, T) \ + ((ARR) = _array_maybe_grow(ARR, sizeof(T)), \ + (ARR)[array_head(ARR)->size++] = (T)) + +// Return the last element of the array. Can be used to build stacks. +#define array_pop(ARR) (ARR)[--array_head(ARR)->size] + +// Insert N bytes from the SRC array into the ARR dynamic array. +#define array_insert(ARR, SRC, N) \ + ((ARR) = _array_insert(ARR, SRC, N, sizeof(*(ARR)))) + +// Free the memory from the original allocated position. +#define array_free(ARR) ((ARR) ? free(array_head(ARR)), (ARR) = NULL : 0) + +static inline void * +_array_reserve(size_t num_elem, size_t type_size) { + char *p = malloc(num_elem * type_size + sizeof(ArrayHeader)); + p += sizeof(ArrayHeader); + array_head(p)->size = 0; + array_head(p)->cap = num_elem; + return p; +} + +static inline void * +_array_maybe_grow(void *arr, size_t type_size) { + ArrayHeader *head = array_head(arr); + if (head->cap == head->size) { + if (head->cap == 0) { + head->cap++; + } else { + head->cap *= 2; + } + head = realloc(head, head->cap * type_size + sizeof(ArrayHeader)); + } + arr = (char *)head + sizeof(ArrayHeader); + return arr; +} + +static inline +char * _array_insert(char *arr, const char *src, size_t n_bytes, size_t type_size) { + ArrayHeader *head = array_head(arr); + size_t new_size = n_bytes + head->size; + if (new_size >= head->cap * type_size) { + if (head->cap == 0) { + head->cap = 1; + } + while (new_size >= head->cap * type_size) { + head->cap *= 2; + } + head = realloc(head, head->cap * type_size + sizeof(ArrayHeader)); + } + arr = (char *)head + sizeof(ArrayHeader); + memcpy((arr + head->size), src, n_bytes); + head->size = new_size; + return arr; +} + +#endif // BDL_DARRAY_H -- cgit v1.2.1