diff --git a/include/deemon/alloc.h b/include/deemon/alloc.h index d3f4e746..404c4689 100644 --- a/include/deemon/alloc.h +++ b/include/deemon/alloc.h @@ -23,6 +23,7 @@ #include "api.h" #ifdef __CC__ +#include #include #include @@ -192,18 +193,115 @@ DFUNDEF void *(DCALL DeeDbg_UntrackAlloc)(void *ptr, char const *file, int line) #define Dee_UntrackAlloc(ptr) (ptr) #endif /* NDEBUG */ -#define Dee_Mallocc(elem_count, elem_size) Dee_Malloc((elem_count) * (elem_size)) -#define Dee_Callocc(elem_count, elem_size) Dee_Calloc((elem_count) * (elem_size)) -#define Dee_Reallocc(ptr, elem_count, elem_size) Dee_Realloc(ptr, (elem_count) * (elem_size)) -#define Dee_TryMallocc(elem_count, elem_size) Dee_TryMalloc((elem_count) * (elem_size)) -#define Dee_TryCallocc(elem_count, elem_size) Dee_TryCalloc((elem_count) * (elem_size)) -#define Dee_TryReallocc(ptr, elem_count, elem_size) Dee_TryRealloc(ptr, (elem_count) * (elem_size)) -#define DeeDbg_Mallocc(elem_count, elem_size, file, line) DeeDbg_Malloc((elem_count) * (elem_size), file, line) -#define DeeDbg_Callocc(elem_count, elem_size, file, line) DeeDbg_Calloc((elem_count) * (elem_size), file, line) -#define DeeDbg_Reallocc(ptr, elem_count, elem_size, file, line) DeeDbg_Realloc(ptr, (elem_count) * (elem_size), file, line) -#define DeeDbg_TryMallocc(elem_count, elem_size, file, line) DeeDbg_TryMalloc((elem_count) * (elem_size), file, line) -#define DeeDbg_TryCallocc(elem_count, elem_size, file, line) DeeDbg_TryCalloc((elem_count) * (elem_size), file, line) -#define DeeDbg_TryReallocc(ptr, elem_count, elem_size, file, line) DeeDbg_TryRealloc(ptr, (elem_count) * (elem_size), file, line) +/* Debug version of malloc buffer size calculation functions. + * These will trigger an assertion failure when an overflow *does* happen. + * As such, these functions should be used in debug builds to assert that + * no unexpected overflows happen. */ +DFUNDEF ATTR_CONST WUNUSED size_t (DCALL _Dee_MalloccBufsizeDbg)(size_t elem_count, size_t elem_size, char const *file, int line); +DFUNDEF ATTR_CONST WUNUSED size_t (DCALL _Dee_MallococBufsizeDbg)(size_t base_offset, size_t elem_count, size_t elem_size, char const *file, int line); + +/* Mallocc buffer size calculation (w/ and w/o overflow handling) */ +#if defined(NDEBUG) || defined(__INTELLISENSE__) +#define _Dee_MalloccBufsize(elem_count, elem_size) ((elem_count) * (elem_size)) +#define _Dee_MallococBufsize(base_offset, elem_count, elem_size) ((base_offset) + ((elem_count) * (elem_size))) +#define _Dee_MalloccBufsizeDbg(elem_count, elem_size, file, line) _Dee_MalloccBufsize(elem_count, elem_size) +#define _Dee_MallococBufsizeDbg(base_offset, elem_count, elem_size, file, line) _Dee_MallococBufsize(base_offset, elem_count, elem_size) +#else /* NDEBUG */ +#define _Dee_MalloccBufsize(elem_count, elem_size) \ + _Dee_MalloccBufsizeDbg(elem_count, elem_size, __FILE__, __LINE__) +#define _Dee_MallococBufsize(base_offset, elem_count, elem_size) \ + _Dee_MallococBufsizeDbg(base_offset, elem_count, elem_size, __FILE__, __LINE__) +#endif /* !NDEBUG */ + +FORCELOCAL ATTR_CONST WUNUSED size_t DCALL +_Dee_MalloccBufsizeSafe(size_t elem_count, size_t elem_size) { + size_t result; +#ifndef __NO_builtin_constant_p + if (__builtin_constant_p(elem_size) && (elem_size == 1)) + return elem_count; + if (__builtin_constant_p(elem_count) && (elem_count == 1)) + return elem_size; +#endif /* !__NO_builtin_constant_p */ + if (__hybrid_overflow_umul(elem_count, elem_size, &result)) + result = (size_t)-1; + return result; +} + +FORCELOCAL ATTR_CONST WUNUSED size_t DCALL +_Dee_MallococBufsizeSafe(size_t base_offset, size_t elem_count, size_t elem_size) { + size_t result; +#ifndef __NO_builtin_constant_p + if (__builtin_constant_p(base_offset) && (base_offset == 0)) + return _Dee_MalloccBufsizeSafe(elem_count, elem_size); + if (__builtin_constant_p(elem_size) && (elem_size == 1)) { + if (__hybrid_overflow_uadd(elem_count, base_offset, &result)) + result = (size_t)-1; + return result; + } + if (__builtin_constant_p(elem_count) && (elem_count == 1)) { + if (__hybrid_overflow_uadd(elem_size, base_offset, &result)) + result = (size_t)-1; + return result; + } +#endif /* !__NO_builtin_constant_p */ + if (__hybrid_overflow_umul(elem_count, elem_size, &result)) + result = (size_t)-1; + if (__hybrid_overflow_uadd(result, base_offset, &result)) + result = (size_t)-1; + return result; +} + +#define Dee_Mallocc(elem_count, elem_size) Dee_Malloc(_Dee_MalloccBufsize(elem_count, elem_size)) +#define Dee_Callocc(elem_count, elem_size) Dee_Calloc(_Dee_MalloccBufsize(elem_count, elem_size)) +#define Dee_Reallocc(ptr, elem_count, elem_size) Dee_Realloc(ptr, _Dee_MalloccBufsize(elem_count, elem_size)) +#define Dee_TryMallocc(elem_count, elem_size) Dee_TryMalloc(_Dee_MalloccBufsize(elem_count, elem_size)) +#define Dee_TryCallocc(elem_count, elem_size) Dee_TryCalloc(_Dee_MalloccBufsize(elem_count, elem_size)) +#define Dee_TryReallocc(ptr, elem_count, elem_size) Dee_TryRealloc(ptr, _Dee_MalloccBufsize(elem_count, elem_size)) +#define DeeDbg_Mallocc(elem_count, elem_size, file, line) DeeDbg_Malloc(_Dee_MalloccBufsize(elem_count, elem_size), file, line) +#define DeeDbg_Callocc(elem_count, elem_size, file, line) DeeDbg_Calloc(_Dee_MalloccBufsize(elem_count, elem_size), file, line) +#define DeeDbg_Reallocc(ptr, elem_count, elem_size, file, line) DeeDbg_Realloc(ptr, _Dee_MalloccBufsize(elem_count, elem_size), file, line) +#define DeeDbg_TryMallocc(elem_count, elem_size, file, line) DeeDbg_TryMalloc(_Dee_MalloccBufsize(elem_count, elem_size), file, line) +#define DeeDbg_TryCallocc(elem_count, elem_size, file, line) DeeDbg_TryCalloc(_Dee_MalloccBufsize(elem_count, elem_size), file, line) +#define DeeDbg_TryReallocc(ptr, elem_count, elem_size, file, line) DeeDbg_TryRealloc(ptr, _Dee_MalloccBufsize(elem_count, elem_size), file, line) + +#define Dee_MalloccSafe(elem_count, elem_size) Dee_Malloc(_Dee_MalloccBufsizeSafe(elem_count, elem_size)) +#define Dee_CalloccSafe(elem_count, elem_size) Dee_Calloc(_Dee_MalloccBufsizeSafe(elem_count, elem_size)) +#define Dee_RealloccSafe(ptr, elem_count, elem_size) Dee_Realloc(ptr, _Dee_MalloccBufsizeSafe(elem_count, elem_size)) +#define Dee_TryMalloccSafe(elem_count, elem_size) Dee_TryMalloc(_Dee_MalloccBufsizeSafe(elem_count, elem_size)) +#define Dee_TryCalloccSafe(elem_count, elem_size) Dee_TryCalloc(_Dee_MalloccBufsizeSafe(elem_count, elem_size)) +#define Dee_TryRealloccSafe(ptr, elem_count, elem_size) Dee_TryRealloc(ptr, _Dee_MalloccBufsizeSafe(elem_count, elem_size)) +#define DeeDbg_MalloccSafe(elem_count, elem_size, file, line) DeeDbg_Malloc(_Dee_MalloccBufsizeSafe(elem_count, elem_size), file, line) +#define DeeDbg_CalloccSafe(elem_count, elem_size, file, line) DeeDbg_Calloc(_Dee_MalloccBufsizeSafe(elem_count, elem_size), file, line) +#define DeeDbg_RealloccSafe(ptr, elem_count, elem_size, file, line) DeeDbg_Realloc(ptr, _Dee_MalloccBufsizeSafe(elem_count, elem_size), file, line) +#define DeeDbg_TryMalloccSafe(elem_count, elem_size, file, line) DeeDbg_TryMalloc(_Dee_MalloccBufsizeSafe(elem_count, elem_size), file, line) +#define DeeDbg_TryCalloccSafe(elem_count, elem_size, file, line) DeeDbg_TryCalloc(_Dee_MalloccBufsizeSafe(elem_count, elem_size), file, line) +#define DeeDbg_TryRealloccSafe(ptr, elem_count, elem_size, file, line) DeeDbg_TryRealloc(ptr, _Dee_MalloccBufsizeSafe(elem_count, elem_size), file, line) + +#define Dee_Mallococ(base_offset, elem_count, elem_size) Dee_Malloc(_Dee_MallococBufsize(base_offset, elem_count, elem_size)) +#define Dee_Callococ(base_offset, elem_count, elem_size) Dee_Calloc(_Dee_MallococBufsize(base_offset, elem_count, elem_size)) +#define Dee_Reallococ(ptr, base_offset, elem_count, elem_size) Dee_Realloc(ptr, _Dee_MallococBufsize(base_offset, elem_count, elem_size)) +#define Dee_TryMallococ(base_offset, elem_count, elem_size) Dee_TryMalloc(_Dee_MallococBufsize(base_offset, elem_count, elem_size)) +#define Dee_TryCallococ(base_offset, elem_count, elem_size) Dee_TryCalloc(_Dee_MallococBufsize(base_offset, elem_count, elem_size)) +#define Dee_TryReallococ(ptr, base_offset, elem_count, elem_size) Dee_TryRealloc(ptr, _Dee_MallococBufsize(base_offset, elem_count, elem_size)) +#define DeeDbg_Mallococ(base_offset, elem_count, elem_size, file, line) DeeDbg_Malloc(_Dee_MallococBufsizeDbg(base_offset, elem_count, elem_size, file, line), file, line) +#define DeeDbg_Callococ(base_offset, elem_count, elem_size, file, line) DeeDbg_Calloc(_Dee_MallococBufsizeDbg(base_offset, elem_count, elem_size, file, line), file, line) +#define DeeDbg_Reallococ(ptr, base_offset, elem_count, elem_size, file, line) DeeDbg_Realloc(ptr, _Dee_MallococBufsizeDbg(base_offset, elem_count, elem_size, file, line), file, line) +#define DeeDbg_TryMallococ(base_offset, elem_count, elem_size, file, line) DeeDbg_TryMalloc(_Dee_MallococBufsizeDbg(base_offset, elem_count, elem_size, file, line), file, line) +#define DeeDbg_TryCallococ(base_offset, elem_count, elem_size, file, line) DeeDbg_TryCalloc(_Dee_MallococBufsizeDbg(base_offset, elem_count, elem_size, file, line), file, line) +#define DeeDbg_TryReallococ(ptr, base_offset, elem_count, elem_size, file, line) DeeDbg_TryRealloc(ptr, _Dee_MallococBufsizeDbg(base_offset, elem_count, elem_size, file, line), file, line) + +#define Dee_MallococSafe(base_offset, elem_count, elem_size) Dee_Malloc(_Dee_MallococBufsizeSafe(base_offset, elem_count, elem_size)) +#define Dee_CallococSafe(base_offset, elem_count, elem_size) Dee_Calloc(_Dee_MallococBufsizeSafe(base_offset, elem_count, elem_size)) +#define Dee_ReallococSafe(ptr, base_offset, elem_count, elem_size) Dee_Realloc(ptr, _Dee_MallococBufsizeSafe(base_offset, elem_count, elem_size)) +#define Dee_TryMallococSafe(base_offset, elem_count, elem_size) Dee_TryMalloc(_Dee_MallococBufsizeSafe(base_offset, elem_count, elem_size)) +#define Dee_TryCallococSafe(base_offset, elem_count, elem_size) Dee_TryCalloc(_Dee_MallococBufsizeSafe(base_offset, elem_count, elem_size)) +#define Dee_TryReallococSafe(ptr, base_offset, elem_count, elem_size) Dee_TryRealloc(ptr, _Dee_MallococBufsizeSafe(base_offset, elem_count, elem_size)) +#define DeeDbg_MallococSafe(base_offset, elem_count, elem_size, file, line) DeeDbg_Malloc(_Dee_MallococBufsizeSafe(base_offset, elem_count, elem_size), file, line) +#define DeeDbg_CallococSafe(base_offset, elem_count, elem_size, file, line) DeeDbg_Calloc(_Dee_MallococBufsizeSafe(base_offset, elem_count, elem_size), file, line) +#define DeeDbg_ReallococSafe(ptr, base_offset, elem_count, elem_size, file, line) DeeDbg_Realloc(ptr, _Dee_MallococBufsizeSafe(base_offset, elem_count, elem_size), file, line) +#define DeeDbg_TryMallococSafe(base_offset, elem_count, elem_size, file, line) DeeDbg_TryMalloc(_Dee_MallococBufsizeSafe(base_offset, elem_count, elem_size), file, line) +#define DeeDbg_TryCallococSafe(base_offset, elem_count, elem_size, file, line) DeeDbg_TryCalloc(_Dee_MallococBufsizeSafe(base_offset, elem_count, elem_size), file, line) +#define DeeDbg_TryReallococSafe(ptr, base_offset, elem_count, elem_size, file, line) DeeDbg_TryRealloc(ptr, _Dee_MallococBufsizeSafe(base_offset, elem_count, elem_size), file, line) /* Reclaim free memory by going through internal pre-allocation caches, * freeing up to (but potentially exceeding by a bit) `max_collect' bytes of memory. @@ -219,7 +317,10 @@ DFUNDEF ATTR_COLD bool DCALL Dee_TryCollectMemory(size_t req_bytes); /* Same as `Dee_TryCollectMemory()', but raise an * `Error.NoMemory' if memory could not be collected. */ DFUNDEF WUNUSED ATTR_COLD bool DCALL Dee_CollectMemory(size_t req_bytes); -#define Dee_CollectMemoryc(elem_count, elem_size) Dee_CollectMemory((elem_count) * (elem_size)) +#define Dee_CollectMemoryc(elem_count, elem_size) \ + Dee_CollectMemory(_Dee_MalloccBufsize(elem_count, elem_size)) +#define Dee_CollectMemoryoc(base_offset, elem_count, elem_size) \ + Dee_CollectMemory(_Dee_MallococBufsize(base_offset, elem_count, elem_size)) /* Throw a bad-allocation error for `req_bytes' bytes. * @return: -1: Always returns -1. */ @@ -244,6 +345,32 @@ DFUNDEF ATTR_COLD int (DCALL Dee_BadAlloc)(size_t req_bytes); #define DeeDbgObject_TryCalloc DeeDbg_TryCalloc #define DeeDbgObject_TryRealloc DeeDbg_TryRealloc +#define DeeObject_Mallocc Dee_Mallococ +#define DeeObject_Callocc Dee_Callococ +#define DeeObject_Reallocc Dee_Reallococ +#define DeeObject_TryMallocc Dee_TryMallococ +#define DeeObject_TryCallocc Dee_TryCallococ +#define DeeObject_TryReallocc Dee_TryReallococ +#define DeeDbgObject_Mallocc DeeDbg_Mallococ +#define DeeDbgObject_Callocc DeeDbg_Callococ +#define DeeDbgObject_Reallocc DeeDbg_Reallococ +#define DeeDbgObject_TryMallocc DeeDbg_TryMallococ +#define DeeDbgObject_TryCallocc DeeDbg_TryCallococ +#define DeeDbgObject_TryReallocc DeeDbg_TryReallococ + +#define DeeObject_MalloccSafe Dee_MallococSafe +#define DeeObject_CalloccSafe Dee_CallococSafe +#define DeeObject_RealloccSafe Dee_ReallococSafe +#define DeeObject_TryMalloccSafe Dee_TryMallococSafe +#define DeeObject_TryCalloccSafe Dee_TryCallococSafe +#define DeeObject_TryRealloccSafe Dee_TryReallococSafe +#define DeeDbgObject_MalloccSafe DeeDbg_MallococSafe +#define DeeDbgObject_CalloccSafe DeeDbg_CallococSafe +#define DeeDbgObject_RealloccSafe DeeDbg_ReallococSafe +#define DeeDbgObject_TryMalloccSafe DeeDbg_TryMallococSafe +#define DeeDbgObject_TryCalloccSafe DeeDbg_TryCallococSafe +#define DeeDbgObject_TryRealloccSafe DeeDbg_TryReallococSafe + #ifdef __CC__ #ifndef CONFIG_NO_OBJECT_SLABS DFUNDEF void (DCALL DeeObject_Free)(void *ptr); @@ -702,18 +829,18 @@ DeeSlab_ENUMERATE(DEE_PRIVATE_DEFINE_SLAB_FUNCTIONS) #define DeeDbgSlab_FFree(ptr, size, file, line) DeeSlab_Invoke(DeeDbgSlab_Free, size, (ptr, file, line), DeeDbg_Free(ptr, file, line)) #define DeeDbgSlab_XFFree(ptr, size, file, line) ((ptr) ? DeeDbgSlab_FFree(ptr, size, file, line) : (void)0) -#define DeeSlab_Mallocc(elem_count, elem_size) DeeSlab_Malloc((elem_count) * (elem_size)) -#define DeeSlab_Callocc(elem_count, elem_size) DeeSlab_Calloc((elem_count) * (elem_size)) -#define DeeSlab_TryMallocc(elem_count, elem_size) DeeSlab_TryMalloc((elem_count) * (elem_size)) -#define DeeSlab_TryCallocc(elem_count, elem_size) DeeSlab_TryCalloc((elem_count) * (elem_size)) -#define DeeSlab_FFreec(ptr, elem_count, elem_size) DeeSlab_FFree(ptr, (elem_count) * (elem_size)) -#define DeeSlab_XFFreec(ptr, elem_count, elem_size) DeeSlab_XFFree(ptr, (elem_count) * (elem_size)) -#define DeeDbgSlab_Mallocc(elem_count, elem_size, file, line) DeeDbgSlab_Malloc((elem_count) * (elem_size), file, line) -#define DeeDbgSlab_Callocc(elem_count, elem_size, file, line) DeeDbgSlab_Calloc((elem_count) * (elem_size), file, line) -#define DeeDbgSlab_TryMallocc(elem_count, elem_size, file, line) DeeDbgSlab_TryMalloc((elem_count) * (elem_size), file, line) -#define DeeDbgSlab_TryCallocc(elem_count, elem_size, file, line) DeeDbgSlab_TryCalloc((elem_count) * (elem_size), file, line) -#define DeeDbgSlab_FFreec(ptr, elem_count, elem_size, file, line) DeeDbgSlab_FFree(ptr, (elem_count) * (elem_size), file, line) -#define DeeDbgSlab_XFFreec(ptr, elem_count, elem_size, file, line) DeeDbgSlab_XFFree(ptr, (elem_count) * (elem_size), file, line) +#define DeeSlab_Mallocc(elem_count, elem_size) DeeSlab_Malloc(_Dee_MalloccBufsize(elem_count, elem_size)) +#define DeeSlab_Callocc(elem_count, elem_size) DeeSlab_Calloc(_Dee_MalloccBufsize(elem_count, elem_size)) +#define DeeSlab_TryMallocc(elem_count, elem_size) DeeSlab_TryMalloc(_Dee_MalloccBufsize(elem_count, elem_size)) +#define DeeSlab_TryCallocc(elem_count, elem_size) DeeSlab_TryCalloc(_Dee_MalloccBufsize(elem_count, elem_size)) +#define DeeSlab_FFreec(ptr, elem_count, elem_size) DeeSlab_FFree(ptr, _Dee_MalloccBufsize(elem_count, elem_size)) +#define DeeSlab_XFFreec(ptr, elem_count, elem_size) DeeSlab_XFFree(ptr, _Dee_MalloccBufsize(elem_count, elem_size)) +#define DeeDbgSlab_Mallocc(elem_count, elem_size, file, line) DeeDbgSlab_Malloc(_Dee_MalloccBufsize(elem_count, elem_size), file, line) +#define DeeDbgSlab_Callocc(elem_count, elem_size, file, line) DeeDbgSlab_Calloc(_Dee_MalloccBufsize(elem_count, elem_size), file, line) +#define DeeDbgSlab_TryMallocc(elem_count, elem_size, file, line) DeeDbgSlab_TryMalloc(_Dee_MalloccBufsize(elem_count, elem_size), file, line) +#define DeeDbgSlab_TryCallocc(elem_count, elem_size, file, line) DeeDbgSlab_TryCalloc(_Dee_MalloccBufsize(elem_count, elem_size), file, line) +#define DeeDbgSlab_FFreec(ptr, elem_count, elem_size, file, line) DeeDbgSlab_FFree(ptr, _Dee_MalloccBufsize(elem_count, elem_size), file, line) +#define DeeDbgSlab_XFFreec(ptr, elem_count, elem_size, file, line) DeeDbgSlab_XFFree(ptr, _Dee_MalloccBufsize(elem_count, elem_size), file, line) #endif /* __CC__ */ /* Free any kind of pointer allocated by the general-purpose slab allocators. @@ -994,7 +1121,10 @@ FORCELOCAL WUNUSED void *DCALL DeeDbg_AllocaCleanup(void *ptr) { #endif /* !NO_DBG_ALIGNMENT */ #endif /* !Dee_Alloca && CONFIG_HAVE_alloca */ #if !defined(Dee_Allocac) && defined(Dee_Alloca) -#define Dee_Allocac(elem_count, elem_size) Dee_Alloca((elem_count) * (elem_size)) +#define Dee_Allocac(elem_count, elem_size) \ + Dee_Alloca(_Dee_MalloccBufsize(elem_count, elem_size)) +#define Dee_Allocaoc(base_offset, elem_count, elem_size) \ + Dee_Alloca(_Dee_MallococBufsize(base_offset, elem_count, elem_size)) #endif /* !Dee_Allocac && Dee_Alloca */ @@ -1387,12 +1517,17 @@ LOCAL void (DCALL Dee_XFreea)(void *p) { #endif /* Dee_Alloca && NO_DBG_ALIGNMENT */ #ifdef Dee_MallocaNoFail -#define Dee_MallocaNoFailc(p, elem_count, elem_size) Dee_MallocaNoFail(p, (elem_count) * (elem_size)) +#define Dee_MallocaNoFailc(p, elem_count, elem_size) Dee_MallocaNoFail(p, _Dee_MalloccBufsize(elem_count, elem_size)) +#define Dee_MallocaNoFailoc(p, base_offset, elem_count, elem_size) Dee_MallocaNoFail(p, _Dee_MallococBufsize(base_offset, elem_count, elem_size)) #endif /* Dee_MallocaNoFail */ -#define Dee_Mallocac(elem_count, elem_size) Dee_Malloca((elem_count) * (elem_size)) -#define Dee_Callocac(elem_count, elem_size) Dee_Calloca((elem_count) * (elem_size)) -#define Dee_TryMallocac(elem_count, elem_size) Dee_TryMalloca((elem_count) * (elem_size)) -#define Dee_TryCallocac(elem_count, elem_size) Dee_TryCalloca((elem_count) * (elem_size)) +#define Dee_Mallocac(elem_count, elem_size) Dee_Malloca(_Dee_MalloccBufsize(elem_count, elem_size)) +#define Dee_Callocac(elem_count, elem_size) Dee_Calloca(_Dee_MalloccBufsize(elem_count, elem_size)) +#define Dee_TryMallocac(elem_count, elem_size) Dee_TryMalloca(_Dee_MalloccBufsize(elem_count, elem_size)) +#define Dee_TryCallocac(elem_count, elem_size) Dee_TryCalloca(_Dee_MalloccBufsize(elem_count, elem_size)) +#define Dee_Mallocaoc(base_offset, elem_count, elem_size) Dee_Malloca(_Dee_MallococBufsize(base_offset, elem_count, elem_size)) +#define Dee_Callocaoc(base_offset, elem_count, elem_size) Dee_Calloca(_Dee_MallococBufsize(base_offset, elem_count, elem_size)) +#define Dee_TryMallocaoc(base_offset, elem_count, elem_size) Dee_TryMalloca(_Dee_MallococBufsize(base_offset, elem_count, elem_size)) +#define Dee_TryCallocaoc(base_offset, elem_count, elem_size) Dee_TryCalloca(_Dee_MallococBufsize(base_offset, elem_count, elem_size)) #endif /* __CC__ */ diff --git a/include/deemon/cell.h b/include/deemon/cell.h index 5b3c2036..ab2a0966 100644 --- a/include/deemon/cell.h +++ b/include/deemon/cell.h @@ -73,11 +73,11 @@ DeeCell_New(DeeObject *__restrict item); #define DeeCell_NewEmpty() DeeObject_NewDefault(&DeeCell_Type) /* Get/Del/Set the value associated with a given Cell. - * HINT: These are the getset callbacks used for `Cell.item' (or its deprecated name `Cell.value'). - * With that in mind, `DeeCell_Del()' and `DeeCell_Set()' - * always return `0' indicative of a successful callback. - * NOTE: `DeeCell_Get' will return `NULL' and throw an `AttributeError' if the `self' is - * empty, whereas `DeeCell_TryGet()' will do the same, but never throw any error. */ + * HINT: These are the getset callbacks used for `Cell.item' (or its deprecated name `Cell.value'). + * With that in mind, `DeeCell_Del()' and `DeeCell_Set()' + * always return `0' indicative of a successful callback. + * NOTE: `DeeCell_Get' will return `NULL' and throw an `UnboundAttribute' if the `self' is + * empty, whereas `DeeCell_TryGet()' will do the same, but never throw any error. */ DFUNDEF WUNUSED NONNULL((1)) DREF DeeObject *DCALL DeeCell_TryGet(DeeObject *__restrict self); DFUNDEF WUNUSED NONNULL((1)) DREF DeeObject *DCALL DeeCell_Get(DeeObject *__restrict self); DFUNDEF WUNUSED NONNULL((1)) int DCALL DeeCell_Del(DeeObject *__restrict self); diff --git a/include/deemon/gc.h b/include/deemon/gc.h index 5dfe358c..50ca397b 100644 --- a/include/deemon/gc.h +++ b/include/deemon/gc.h @@ -26,7 +26,16 @@ #ifndef __INTELLISENSE__ #include "alloc.h" -#endif /* !__INTELLISENSE__ */ +#else /* !__INTELLISENSE__ */ +DECL_BEGIN +#define _Dee_MalloccBufsize(elem_count, elem_size) ((elem_count) * (elem_size)) +#define _Dee_MallococBufsize(base_offset, elem_count, elem_size) ((base_offset) + ((elem_count) * (elem_size))) +#define _Dee_MalloccBufsizeDbg(elem_count, elem_size, file, line) _Dee_MalloccBufsize(elem_count, elem_size) +#define _Dee_MallococBufsizeDbg(base_offset, elem_count, elem_size, file, line) _Dee_MallococBufsize(base_offset, elem_count, elem_size) +LOCAL ATTR_CONST WUNUSED size_t DCALL _Dee_MalloccBufsizeSafe(size_t elem_count, size_t elem_size); +LOCAL ATTR_CONST WUNUSED size_t DCALL _Dee_MallococBufsizeSafe(size_t base_offset, size_t elem_count, size_t elem_size); +DECL_END +#endif /* __INTELLISENSE__ */ #include #include @@ -116,22 +125,95 @@ DFUNDEF ATTR_MALLOC WUNUSED void *(DCALL DeeDbgGCObject_TryCalloc)(size_t n_byte DFUNDEF WUNUSED void *(DCALL DeeDbgGCObject_TryRealloc)(void *p, size_t n_bytes, char const *file, int line); DFUNDEF void (DCALL DeeDbgGCObject_Free)(void *p, char const *file, int line); +#define DeeGCObject_Mallocc(base_offset, elem_count, elem_size) DeeGCObject_Malloc(_Dee_MallococBufsize(base_offset, elem_count, elem_size)) +#define DeeGCObject_Callocc(base_offset, elem_count, elem_size) DeeGCObject_Calloc(_Dee_MallococBufsize(base_offset, elem_count, elem_size)) +#define DeeGCObject_Reallocc(p, base_offset, elem_count, elem_size) DeeGCObject_Realloc(p, _Dee_MallococBufsize(base_offset, elem_count, elem_size)) +#define DeeGCObject_TryMallocc(base_offset, elem_count, elem_size) DeeGCObject_TryMalloc(_Dee_MallococBufsize(base_offset, elem_count, elem_size)) +#define DeeGCObject_TryCallocc(base_offset, elem_count, elem_size) DeeGCObject_TryCalloc(_Dee_MallococBufsize(base_offset, elem_count, elem_size)) +#define DeeGCObject_TryReallocc(p, base_offset, elem_count, elem_size) DeeGCObject_TryRealloc(p, _Dee_MallococBufsize(base_offset, elem_count, elem_size)) +#define DeeDbgGCObject_Mallocc(base_offset, elem_count, elem_size, file, line) DeeDbgGCObject_Malloc(_Dee_MallococBufsizeDbg(base_offset, elem_count, elem_size, file, line), file, line) +#define DeeDbgGCObject_Callocc(base_offset, elem_count, elem_size, file, line) DeeDbgGCObject_Calloc(_Dee_MallococBufsizeDbg(base_offset, elem_count, elem_size, file, line), file, line) +#define DeeDbgGCObject_Reallocc(p, base_offset, elem_count, elem_size, file, line) DeeDbgGCObject_Realloc(p, _Dee_MallococBufsizeDbg(base_offset, elem_count, elem_size, file, line), file, line) +#define DeeDbgGCObject_TryMallocc(base_offset, elem_count, elem_size, file, line) DeeDbgGCObject_TryMalloc(_Dee_MallococBufsizeDbg(base_offset, elem_count, elem_size, file, line), file, line) +#define DeeDbgGCObject_TryCallocc(base_offset, elem_count, elem_size, file, line) DeeDbgGCObject_TryCalloc(_Dee_MallococBufsizeDbg(base_offset, elem_count, elem_size, file, line), file, line) +#define DeeDbgGCObject_TryReallocc(p, base_offset, elem_count, elem_size, file, line) DeeDbgGCObject_TryRealloc(p, _Dee_MallococBufsizeDbg(base_offset, elem_count, elem_size, file, line), file, line) +#define DeeGCObject_MalloccSafe(base_offset, elem_count, elem_size) DeeGCObject_Malloc(_Dee_MallococBufsizeSafe(base_offset, elem_count, elem_size)) +#define DeeGCObject_CalloccSafe(base_offset, elem_count, elem_size) DeeGCObject_Calloc(_Dee_MallococBufsizeSafe(base_offset, elem_count, elem_size)) +#define DeeGCObject_RealloccSafe(p, base_offset, elem_count, elem_size) DeeGCObject_Realloc(p, _Dee_MallococBufsizeSafe(base_offset, elem_count, elem_size)) +#define DeeGCObject_TryMalloccSafe(base_offset, elem_count, elem_size) DeeGCObject_TryMalloc(_Dee_MallococBufsizeSafe(base_offset, elem_count, elem_size)) +#define DeeGCObject_TryCalloccSafe(base_offset, elem_count, elem_size) DeeGCObject_TryCalloc(_Dee_MallococBufsizeSafe(base_offset, elem_count, elem_size)) +#define DeeGCObject_TryRealloccSafe(p, base_offset, elem_count, elem_size) DeeGCObject_TryRealloc(p, _Dee_MallococBufsizeSafe(base_offset, elem_count, elem_size)) +#define DeeDbgGCObject_MalloccSafe(base_offset, elem_count, elem_size, file, line) DeeDbgGCObject_Malloc(_Dee_MallococBufsizeSafe(base_offset, elem_count, elem_size), file, line) +#define DeeDbgGCObject_CalloccSafe(base_offset, elem_count, elem_size, file, line) DeeDbgGCObject_Calloc(_Dee_MallococBufsizeSafe(base_offset, elem_count, elem_size), file, line) +#define DeeDbgGCObject_RealloccSafe(p, base_offset, elem_count, elem_size, file, line) DeeDbgGCObject_Realloc(p, _Dee_MallococBufsizeSafe(base_offset, elem_count, elem_size), file, line) +#define DeeDbgGCObject_TryMalloccSafe(base_offset, elem_count, elem_size, file, line) DeeDbgGCObject_TryMalloc(_Dee_MallococBufsizeSafe(base_offset, elem_count, elem_size), file, line) +#define DeeDbgGCObject_TryCalloccSafe(base_offset, elem_count, elem_size, file, line) DeeDbgGCObject_TryCalloc(_Dee_MallococBufsizeSafe(base_offset, elem_count, elem_size), file, line) +#define DeeDbgGCObject_TryRealloccSafe(p, base_offset, elem_count, elem_size, file, line) DeeDbgGCObject_TryRealloc(p, _Dee_MallococBufsizeSafe(base_offset, elem_count, elem_size), file, line) + #ifndef NDEBUG -#define DeeGCObject_Malloc(n_bytes) DeeDbgGCObject_Malloc(n_bytes, __FILE__, __LINE__) -#define DeeGCObject_Calloc(n_bytes) DeeDbgGCObject_Calloc(n_bytes, __FILE__, __LINE__) -#define DeeGCObject_Realloc(ptr, n_bytes) DeeDbgGCObject_Realloc(ptr, n_bytes, __FILE__, __LINE__) -#define DeeGCObject_TryMalloc(n_bytes) DeeDbgGCObject_TryMalloc(n_bytes, __FILE__, __LINE__) -#define DeeGCObject_TryCalloc(n_bytes) DeeDbgGCObject_TryCalloc(n_bytes, __FILE__, __LINE__) -#define DeeGCObject_TryRealloc(ptr, n_bytes) DeeDbgGCObject_TryRealloc(ptr, n_bytes, __FILE__, __LINE__) -#define DeeGCObject_Free(ptr) DeeDbgGCObject_Free(ptr, __FILE__, __LINE__) +#undef DeeGCObject_Mallocc +#undef DeeGCObject_Callocc +#undef DeeGCObject_Reallocc +#undef DeeGCObject_TryMallocc +#undef DeeGCObject_TryCallocc +#undef DeeGCObject_TryReallocc +#undef DeeGCObject_MalloccSafe +#undef DeeGCObject_CalloccSafe +#undef DeeGCObject_RealloccSafe +#undef DeeGCObject_TryMalloccSafe +#undef DeeGCObject_TryCalloccSafe +#undef DeeGCObject_TryRealloccSafe +#define DeeGCObject_Malloc(n_bytes) DeeDbgGCObject_Malloc(n_bytes, __FILE__, __LINE__) +#define DeeGCObject_Calloc(n_bytes) DeeDbgGCObject_Calloc(n_bytes, __FILE__, __LINE__) +#define DeeGCObject_Realloc(ptr, n_bytes) DeeDbgGCObject_Realloc(ptr, n_bytes, __FILE__, __LINE__) +#define DeeGCObject_TryMalloc(n_bytes) DeeDbgGCObject_TryMalloc(n_bytes, __FILE__, __LINE__) +#define DeeGCObject_TryCalloc(n_bytes) DeeDbgGCObject_TryCalloc(n_bytes, __FILE__, __LINE__) +#define DeeGCObject_TryRealloc(ptr, n_bytes) DeeDbgGCObject_TryRealloc(ptr, n_bytes, __FILE__, __LINE__) +#define DeeGCObject_Free(ptr) DeeDbgGCObject_Free(ptr, __FILE__, __LINE__) +#define DeeGCObject_Mallocc(base_offset, elem_count, elem_size) DeeDbgGCObject_Mallocc(base_offset, elem_count, elem_size, __FILE__, __LINE__) +#define DeeGCObject_Callocc(base_offset, elem_count, elem_size) DeeDbgGCObject_Callocc(base_offset, elem_count, elem_size, __FILE__, __LINE__) +#define DeeGCObject_Reallocc(ptr, base_offset, elem_count, elem_size) DeeDbgGCObject_Reallocc(ptr, base_offset, elem_count, elem_size, __FILE__, __LINE__) +#define DeeGCObject_TryMallocc(base_offset, elem_count, elem_size) DeeDbgGCObject_TryMallocc(base_offset, elem_count, elem_size, __FILE__, __LINE__) +#define DeeGCObject_TryCallocc(base_offset, elem_count, elem_size) DeeDbgGCObject_TryCallocc(base_offset, elem_count, elem_size, __FILE__, __LINE__) +#define DeeGCObject_TryReallocc(ptr, base_offset, elem_count, elem_size) DeeDbgGCObject_TryReallocc(ptr, base_offset, elem_count, elem_size, __FILE__, __LINE__) +#define DeeGCObject_MalloccSafe(base_offset, elem_count, elem_size) DeeDbgGCObject_MalloccSafe(base_offset, elem_count, elem_size, __FILE__, __LINE__) +#define DeeGCObject_CalloccSafe(base_offset, elem_count, elem_size) DeeDbgGCObject_CalloccSafe(base_offset, elem_count, elem_size, __FILE__, __LINE__) +#define DeeGCObject_RealloccSafe(ptr, base_offset, elem_count, elem_size) DeeDbgGCObject_RealloccSafe(ptr, base_offset, elem_count, elem_size, __FILE__, __LINE__) +#define DeeGCObject_TryMalloccSafe(base_offset, elem_count, elem_size) DeeDbgGCObject_TryMalloccSafe(base_offset, elem_count, elem_size, __FILE__, __LINE__) +#define DeeGCObject_TryCalloccSafe(base_offset, elem_count, elem_size) DeeDbgGCObject_TryCalloccSafe(base_offset, elem_count, elem_size, __FILE__, __LINE__) +#define DeeGCObject_TryRealloccSafe(ptr, base_offset, elem_count, elem_size) DeeDbgGCObject_TryRealloccSafe(ptr, base_offset, elem_count, elem_size, __FILE__, __LINE__) #else /* !NDEBUG */ -#define DeeDbgGCObject_Malloc(n_bytes, file, line) DeeGCObject_Malloc(n_bytes) -#define DeeDbgGCObject_Calloc(n_bytes, file, line) DeeGCObject_Calloc(n_bytes) -#define DeeDbgGCObject_Realloc(ptr, n_bytes, file, line) DeeGCObject_Realloc(ptr, n_bytes) -#define DeeDbgGCObject_TryMalloc(n_bytes, file, line) DeeGCObject_TryMalloc(n_bytes) -#define DeeDbgGCObject_TryCalloc(n_bytes, file, line) DeeGCObject_TryCalloc(n_bytes) -#define DeeDbgGCObject_TryRealloc(ptr, n_bytes, file, line) DeeGCObject_TryRealloc(ptr, n_bytes) -#define DeeDbgGCObject_Free(ptr, file, line) DeeGCObject_Free(ptr) +#undef DeeDbgGCObject_Mallocc +#undef DeeDbgGCObject_Callocc +#undef DeeDbgGCObject_Reallocc +#undef DeeDbgGCObject_TryMallocc +#undef DeeDbgGCObject_TryCallocc +#undef DeeDbgGCObject_TryReallocc +#undef DeeDbgGCObject_MalloccSafe +#undef DeeDbgGCObject_CalloccSafe +#undef DeeDbgGCObject_RealloccSafe +#undef DeeDbgGCObject_TryMalloccSafe +#undef DeeDbgGCObject_TryCalloccSafe +#undef DeeDbgGCObject_TryRealloccSafe +#define DeeDbgGCObject_Malloc(n_bytes, file, line) DeeGCObject_Malloc(n_bytes) +#define DeeDbgGCObject_Calloc(n_bytes, file, line) DeeGCObject_Calloc(n_bytes) +#define DeeDbgGCObject_Realloc(ptr, n_bytes, file, line) DeeGCObject_Realloc(ptr, n_bytes) +#define DeeDbgGCObject_TryMalloc(n_bytes, file, line) DeeGCObject_TryMalloc(n_bytes) +#define DeeDbgGCObject_TryCalloc(n_bytes, file, line) DeeGCObject_TryCalloc(n_bytes) +#define DeeDbgGCObject_TryRealloc(ptr, n_bytes, file, line) DeeGCObject_TryRealloc(ptr, n_bytes) +#define DeeDbgGCObject_Free(ptr, file, line) DeeGCObject_Free(ptr) +#define DeeDbgGCObject_Mallocc(base_offset, elem_count, elem_size, file, line) DeeGCObject_Mallocc(base_offset, elem_count, elem_size) +#define DeeDbgGCObject_Callocc(base_offset, elem_count, elem_size, file, line) DeeGCObject_Callocc(base_offset, elem_count, elem_size) +#define DeeDbgGCObject_Reallocc(ptr, base_offset, elem_count, elem_size, file, line) DeeGCObject_Reallocc(ptr, base_offset, elem_count, elem_size) +#define DeeDbgGCObject_TryMallocc(base_offset, elem_count, elem_size, file, line) DeeGCObject_TryMallocc(base_offset, elem_count, elem_size) +#define DeeDbgGCObject_TryCallocc(base_offset, elem_count, elem_size, file, line) DeeGCObject_TryCallocc(base_offset, elem_count, elem_size) +#define DeeDbgGCObject_TryReallocc(ptr, base_offset, elem_count, elem_size, file, line) DeeGCObject_TryReallocc(ptr, base_offset, elem_count, elem_size) +#define DeeDbgGCObject_MalloccSafe(base_offset, elem_count, elem_size, file, line) DeeGCObject_MalloccSafe(base_offset, elem_count, elem_size) +#define DeeDbgGCObject_CalloccSafe(base_offset, elem_count, elem_size, file, line) DeeGCObject_CalloccSafe(base_offset, elem_count, elem_size) +#define DeeDbgGCObject_RealloccSafe(ptr, base_offset, elem_count, elem_size, file, line) DeeGCObject_RealloccSafe(ptr, base_offset, elem_count, elem_size) +#define DeeDbgGCObject_TryMalloccSafe(base_offset, elem_count, elem_size, file, line) DeeGCObject_TryMalloccSafe(base_offset, elem_count, elem_size) +#define DeeDbgGCObject_TryCalloccSafe(base_offset, elem_count, elem_size, file, line) DeeGCObject_TryCalloccSafe(base_offset, elem_count, elem_size) +#define DeeDbgGCObject_TryRealloccSafe(ptr, base_offset, elem_count, elem_size, file, line) DeeGCObject_TryRealloccSafe(ptr, base_offset, elem_count, elem_size) #endif /* NDEBUG */ diff --git a/include/deemon/string.h b/include/deemon/string.h index 3abcd4fc..10a5afd6 100644 --- a/include/deemon/string.h +++ b/include/deemon/string.h @@ -1467,8 +1467,8 @@ LOCAL void (DCALL _DeeString_FreeBuffer)(void *buffer) { LOCAL ATTR_MALLOC WUNUSED uint8_t * (DCALL DeeString_New1ByteBuffer)(size_t num_chars) { DeeStringObject *result; - result = (DeeStringObject *)DeeObject_Malloc(COMPILER_OFFSETOF(DeeStringObject, s_str) + - (num_chars + 1) * sizeof(char)); + result = (DeeStringObject *)DeeObject_Mallocc(COMPILER_OFFSETOF(DeeStringObject, s_str), + num_chars + 1, sizeof(char)); if unlikely(!result) goto err; result->s_len = num_chars; @@ -1480,8 +1480,8 @@ LOCAL ATTR_MALLOC WUNUSED uint8_t * LOCAL ATTR_MALLOC WUNUSED uint8_t * (DCALL DeeString_TryNew1ByteBuffer)(size_t num_chars) { DeeStringObject *result; - result = (DeeStringObject *)DeeObject_TryMalloc(COMPILER_OFFSETOF(DeeStringObject, s_str) + - (num_chars + 1) * sizeof(char)); + result = (DeeStringObject *)DeeObject_TryMallocc(COMPILER_OFFSETOF(DeeStringObject, s_str), + num_chars + 1, sizeof(char)); if unlikely(!result) goto err; result->s_len = num_chars; @@ -1494,9 +1494,8 @@ LOCAL WUNUSED uint8_t * (DCALL DeeString_Resize1ByteBuffer)(uint8_t *buffer, size_t num_chars) { DeeStringObject *result; result = buffer ? COMPILER_CONTAINER_OF((char *)buffer, DeeStringObject, s_str) : NULL; - result = (DeeStringObject *)DeeObject_Realloc(result, - COMPILER_OFFSETOF(DeeStringObject, s_str) + - (num_chars + 1) * sizeof(char)); + result = (DeeStringObject *)DeeObject_Reallocc(result, COMPILER_OFFSETOF(DeeStringObject, s_str), + num_chars + 1, sizeof(char)); if unlikely(!result) goto err; result->s_len = num_chars; @@ -1509,9 +1508,8 @@ LOCAL WUNUSED uint8_t * (DCALL DeeString_TryResize1ByteBuffer)(uint8_t *buffer, size_t num_chars) { DeeStringObject *result; result = buffer ? COMPILER_CONTAINER_OF((char *)buffer, DeeStringObject, s_str) : NULL; - result = (DeeStringObject *)DeeObject_TryRealloc(result, - COMPILER_OFFSETOF(DeeStringObject, s_str) + - (num_chars + 1) * sizeof(char)); + result = (DeeStringObject *)DeeObject_TryReallocc(result, COMPILER_OFFSETOF(DeeStringObject, s_str), + num_chars + 1, sizeof(char)); if unlikely(!result) goto err; result->s_len = num_chars; @@ -1525,9 +1523,8 @@ LOCAL WUNUSED ATTR_RETNONNULL NONNULL((1)) uint8_t * DeeStringObject *result; result = COMPILER_CONTAINER_OF((char *)buffer, DeeStringObject, s_str); Dee_ASSERT(result->s_len >= num_chars); - result = (DeeStringObject *)DeeObject_TryRealloc(result, - COMPILER_OFFSETOF(DeeStringObject, s_str) + - (num_chars + 1) * sizeof(char)); + result = (DeeStringObject *)DeeObject_TryReallocc(result, COMPILER_OFFSETOF(DeeStringObject, s_str), + num_chars + 1, sizeof(char)); if unlikely(!result) result = COMPILER_CONTAINER_OF((char *)buffer, DeeStringObject, s_str); result->s_len = num_chars; @@ -1699,9 +1696,8 @@ LOCAL void (DCALL _DeeDbgString_FreeBuffer)(void *buffer, char const *file, int LOCAL ATTR_MALLOC WUNUSED uint8_t * (DCALL DeeDbgString_New1ByteBuffer)(size_t num_chars, char const *file, int line) { DeeStringObject *result; - result = (DeeStringObject *)DeeDbgObject_Malloc(COMPILER_OFFSETOF(DeeStringObject, s_str) + - (num_chars + 1) * sizeof(char), - file, line); + result = (DeeStringObject *)DeeDbgObject_Mallocc(COMPILER_OFFSETOF(DeeStringObject, s_str), + num_chars + 1, sizeof(char), file, line); if unlikely(!result) goto err; result->s_len = num_chars; @@ -1713,9 +1709,8 @@ LOCAL ATTR_MALLOC WUNUSED uint8_t * LOCAL ATTR_MALLOC WUNUSED uint8_t * (DCALL DeeDbgString_TryNew1ByteBuffer)(size_t num_chars, char const *file, int line) { DeeStringObject *result; - result = (DeeStringObject *)DeeDbgObject_TryMalloc(COMPILER_OFFSETOF(DeeStringObject, s_str) + - (num_chars + 1) * sizeof(char), - file, line); + result = (DeeStringObject *)DeeDbgObject_TryMallocc(COMPILER_OFFSETOF(DeeStringObject, s_str), + num_chars + 1, sizeof(char), file, line); if unlikely(!result) goto err; result->s_len = num_chars; @@ -1729,10 +1724,8 @@ LOCAL WUNUSED uint8_t * char const *file, int line) { DeeStringObject *result; result = buffer ? COMPILER_CONTAINER_OF((char *)buffer, DeeStringObject, s_str) : NULL; - result = (DeeStringObject *)DeeDbgObject_Realloc(result, - COMPILER_OFFSETOF(DeeStringObject, s_str) + - (num_chars + 1) * sizeof(char), - file, line); + result = (DeeStringObject *)DeeDbgObject_Reallocc(result, COMPILER_OFFSETOF(DeeStringObject, s_str), + num_chars + 1, sizeof(char), file, line); if unlikely(!result) goto err; result->s_len = num_chars; @@ -1746,10 +1739,8 @@ LOCAL WUNUSED uint8_t * char const *file, int line) { DeeStringObject *result; result = buffer ? COMPILER_CONTAINER_OF((char *)buffer, DeeStringObject, s_str) : NULL; - result = (DeeStringObject *)DeeDbgObject_TryRealloc(result, - COMPILER_OFFSETOF(DeeStringObject, s_str) + - (num_chars + 1) * sizeof(char), - file, line); + result = (DeeStringObject *)DeeDbgObject_TryReallocc(result, COMPILER_OFFSETOF(DeeStringObject, s_str), + num_chars + 1, sizeof(char), file, line); if unlikely(!result) goto err; result->s_len = num_chars; @@ -1764,10 +1755,8 @@ LOCAL WUNUSED ATTR_RETNONNULL NONNULL((1)) uint8_t * DeeStringObject *result; result = COMPILER_CONTAINER_OF((char *)buffer, DeeStringObject, s_str); Dee_ASSERT(result->s_len >= num_chars); - result = (DeeStringObject *)DeeDbgObject_TryRealloc(result, - COMPILER_OFFSETOF(DeeStringObject, s_str) + - (num_chars + 1) * sizeof(char), - file, line); + result = (DeeStringObject *)DeeDbgObject_TryReallocc(result, COMPILER_OFFSETOF(DeeStringObject, s_str), + num_chars + 1, sizeof(char), file, line); if unlikely(!result) result = COMPILER_CONTAINER_OF((char *)buffer, DeeStringObject, s_str); result->s_len = num_chars; @@ -1849,8 +1838,8 @@ LOCAL ATTR_MALLOC WUNUSED void * (DCALL DeeString_NewWidthBuffer)(size_t num_chars, unsigned int width) { if (width == Dee_STRING_WIDTH_1BYTE) { DeeStringObject *result; - result = (DeeStringObject *)DeeObject_Malloc(COMPILER_OFFSETOF(DeeStringObject, s_str) + - (num_chars + 1) * sizeof(char)); + result = (DeeStringObject *)DeeObject_Mallocc(COMPILER_OFFSETOF(DeeStringObject, s_str), + num_chars + 1, sizeof(char)); if unlikely(!result) goto err; result->s_len = num_chars; @@ -1870,8 +1859,8 @@ LOCAL ATTR_MALLOC WUNUSED void * LOCAL ATTR_MALLOC WUNUSED void *(DCALL DeeString_TryNewWidthBuffer)(size_t num_chars, unsigned int width) { if (width == Dee_STRING_WIDTH_1BYTE) { DeeStringObject *result; - result = (DeeStringObject *)DeeObject_TryMalloc(COMPILER_OFFSETOF(DeeStringObject, s_str) + - (num_chars + 1) * sizeof(char)); + result = (DeeStringObject *)DeeObject_TryMallocc(COMPILER_OFFSETOF(DeeStringObject, s_str), + num_chars + 1, sizeof(char)); if unlikely(!result) goto err; result->s_len = num_chars; @@ -1892,9 +1881,8 @@ LOCAL WUNUSED void *(DCALL DeeString_ResizeWidthBuffer)(void *buffer, size_t num if (width == Dee_STRING_WIDTH_1BYTE) { DeeStringObject *result; result = buffer ? COMPILER_CONTAINER_OF((char *)buffer, DeeStringObject, s_str) : NULL; - result = (DeeStringObject *)DeeObject_Realloc(result, - COMPILER_OFFSETOF(DeeStringObject, s_str) + - (num_chars + 1) * sizeof(char)); + result = (DeeStringObject *)DeeObject_Reallocc(result, COMPILER_OFFSETOF(DeeStringObject, s_str), + num_chars + 1, sizeof(char)); if unlikely(!result) goto err; result->s_len = num_chars; @@ -1916,9 +1904,8 @@ LOCAL WUNUSED void *(DCALL DeeString_TryResizeWidthBuffer)(void *buffer, size_t if (width == Dee_STRING_WIDTH_1BYTE) { DeeStringObject *result; result = buffer ? COMPILER_CONTAINER_OF((char *)buffer, DeeStringObject, s_str) : NULL; - result = (DeeStringObject *)DeeObject_TryRealloc(result, - COMPILER_OFFSETOF(DeeStringObject, s_str) + - (num_chars + 1) * sizeof(char)); + result = (DeeStringObject *)DeeObject_TryReallocc(result, COMPILER_OFFSETOF(DeeStringObject, s_str), + num_chars + 1, sizeof(char)); if unlikely(!result) goto err; result->s_len = num_chars; @@ -1941,9 +1928,9 @@ LOCAL WUNUSED ATTR_RETNONNULL NONNULL((1)) void * Dee_ASSERT(*((size_t *)buffer - 1) >= num_chars); if (width == Dee_STRING_WIDTH_1BYTE) { DeeStringObject *result; - result = (DeeStringObject *)DeeObject_TryRealloc(COMPILER_CONTAINER_OF((char *)buffer, DeeStringObject, s_str), - COMPILER_OFFSETOF(DeeStringObject, s_str) + - (num_chars + 1) * sizeof(char)); + result = (DeeStringObject *)DeeObject_TryReallocc(COMPILER_CONTAINER_OF((char *)buffer, DeeStringObject, s_str), + COMPILER_OFFSETOF(DeeStringObject, s_str), + num_chars + 1, sizeof(char)); if unlikely(!result) result = COMPILER_CONTAINER_OF((char *)buffer, DeeStringObject, s_str); result->s_len = num_chars; @@ -1987,9 +1974,8 @@ LOCAL ATTR_MALLOC WUNUSED void * (DCALL DeeDbgString_NewWidthBuffer)(size_t num_chars, unsigned int width, char const *file, int line) { if (width == Dee_STRING_WIDTH_1BYTE) { DeeStringObject *result; - result = (DeeStringObject *)DeeDbgObject_Malloc(COMPILER_OFFSETOF(DeeStringObject, s_str) + - (num_chars + 1) * sizeof(char), - file, line); + result = (DeeStringObject *)DeeDbgObject_Mallocc(COMPILER_OFFSETOF(DeeStringObject, s_str), + num_chars + 1, sizeof(char), file, line); if unlikely(!result) goto err; result->s_len = num_chars; @@ -2010,9 +1996,8 @@ LOCAL ATTR_MALLOC WUNUSED void * (DCALL DeeDbgString_TryNewWidthBuffer)(size_t num_chars, unsigned int width, char const *file, int line) { if (width == Dee_STRING_WIDTH_1BYTE) { DeeStringObject *result; - result = (DeeStringObject *)DeeDbgObject_TryMalloc(COMPILER_OFFSETOF(DeeStringObject, s_str) + - (num_chars + 1) * sizeof(char), - file, line); + result = (DeeStringObject *)DeeDbgObject_TryMallocc(COMPILER_OFFSETOF(DeeStringObject, s_str), + num_chars + 1, sizeof(char), file, line); if unlikely(!result) goto err; result->s_len = num_chars; @@ -2034,10 +2019,8 @@ LOCAL WUNUSED void * if (width == Dee_STRING_WIDTH_1BYTE) { DeeStringObject *result; result = buffer ? COMPILER_CONTAINER_OF((char *)buffer, DeeStringObject, s_str) : NULL; - result = (DeeStringObject *)DeeDbgObject_Realloc(result, - COMPILER_OFFSETOF(DeeStringObject, s_str) + - (num_chars + 1) * sizeof(char), - file, line); + result = (DeeStringObject *)DeeDbgObject_Reallocc(result, COMPILER_OFFSETOF(DeeStringObject, s_str), + num_chars + 1, sizeof(char), file, line); if unlikely(!result) goto err; result->s_len = num_chars; @@ -2060,10 +2043,8 @@ LOCAL WUNUSED void * if (width == Dee_STRING_WIDTH_1BYTE) { DeeStringObject *result; result = buffer ? COMPILER_CONTAINER_OF((char *)buffer, DeeStringObject, s_str) : NULL; - result = (DeeStringObject *)DeeDbgObject_TryRealloc(result, - COMPILER_OFFSETOF(DeeStringObject, s_str) + - (num_chars + 1) * sizeof(char), - file, line); + result = (DeeStringObject *)DeeDbgObject_TryReallocc(result, COMPILER_OFFSETOF(DeeStringObject, s_str), + num_chars + 1, sizeof(char), file, line); if unlikely(!result) goto err; result->s_len = num_chars; @@ -2087,10 +2068,9 @@ LOCAL WUNUSED ATTR_RETNONNULL NONNULL((1)) void * Dee_ASSERT(*((size_t *)buffer - 1) >= num_chars); if (width == Dee_STRING_WIDTH_1BYTE) { DeeStringObject *result; - result = (DeeStringObject *)DeeDbgObject_TryRealloc(COMPILER_CONTAINER_OF((char *)buffer, DeeStringObject, s_str), - COMPILER_OFFSETOF(DeeStringObject, s_str) + - (num_chars + 1) * sizeof(char), - file, line); + result = (DeeStringObject *)DeeDbgObject_TryReallocc(COMPILER_CONTAINER_OF((char *)buffer, DeeStringObject, s_str), + COMPILER_OFFSETOF(DeeStringObject, s_str), + num_chars + 1, sizeof(char), file, line); if unlikely(!result) result = COMPILER_CONTAINER_OF((char *)buffer, DeeStringObject, s_str); result->s_len = num_chars; diff --git a/include/deemon/tuple.h b/include/deemon/tuple.h index a8a8d18e..25a40b5e 100644 --- a/include/deemon/tuple.h +++ b/include/deemon/tuple.h @@ -46,25 +46,20 @@ struct Dee_tuple_object { COMPILER_FLEXIBLE_ARRAY(DREF DeeObject *, t_elem); /* [1..1][const][t_size] Tuple elements. */ }; -#define DeeTuple_SIZEOF(n_items) (COMPILER_OFFSETOF(DeeTupleObject, t_elem) + (n_items) * sizeof(DREF DeeObject *)) -#define DeeTuple_IsEmpty(ob) ((DeeObject *)Dee_REQUIRES_OBJECT(ob) == Dee_EmptyTuple) -#define DeeTuple_SIZE(ob) ((DeeTupleObject *)Dee_REQUIRES_OBJECT(ob))->t_size -#define DeeTuple_ELEM(ob) ((DeeTupleObject *)Dee_REQUIRES_OBJECT(ob))->t_elem -#define DeeTuple_END(ob) (((DeeTupleObject *)Dee_REQUIRES_OBJECT(ob))->t_elem + ((DeeTupleObject *)(ob))->t_size) -#define DeeTuple_GET(ob, i) ((DeeTupleObject *)Dee_REQUIRES_OBJECT(ob))->t_elem[i] -#define DeeTuple_SET(ob, i, v) (void)(((DeeTupleObject *)Dee_REQUIRES_OBJECT(ob))->t_elem[i] = (DeeObject *)Dee_REQUIRES_OBJECT(v)) +#define DeeTuple_SIZEOF(n_items) \ + _Dee_MallococBufsize(COMPILER_OFFSETOF(DeeTupleObject, t_elem), \ + n_items, sizeof(DREF DeeObject *)) +#define DeeTuple_IsEmpty(ob) ((DeeObject *)Dee_REQUIRES_OBJECT(ob) == Dee_EmptyTuple) +#define DeeTuple_SIZE(ob) ((DeeTupleObject *)Dee_REQUIRES_OBJECT(ob))->t_size +#define DeeTuple_ELEM(ob) ((DeeTupleObject *)Dee_REQUIRES_OBJECT(ob))->t_elem +#define DeeTuple_END(ob) (((DeeTupleObject *)Dee_REQUIRES_OBJECT(ob))->t_elem + ((DeeTupleObject *)(ob))->t_size) +#define DeeTuple_GET(ob, i) ((DeeTupleObject *)Dee_REQUIRES_OBJECT(ob))->t_elem[i] +#define DeeTuple_SET(ob, i, v) (void)(((DeeTupleObject *)Dee_REQUIRES_OBJECT(ob))->t_elem[i] = (DeeObject *)Dee_REQUIRES_OBJECT(v)) /* Same as `DeeTuple_SIZEOF()', but makes sure that no overflow takes place. */ -#define DeeTuple_SIZEOF_SAFE(n_items) DeeTuple_SIZEOF_SAFE(n_items) -LOCAL ATTR_CONST WUNUSED size_t -(DCALL DeeTuple_SIZEOF_SAFE)(size_t n_items) { - size_t result; - if unlikely(__hybrid_overflow_umul(n_items, sizeof(DREF DeeObject *), &result)) - result = (size_t)-1; - if unlikely(__hybrid_overflow_uadd(result, COMPILER_OFFSETOF(DeeTupleObject, t_elem), &result)) - result = (size_t)-1; - return result; -} +#define DeeTuple_SIZEOF_SAFE(n_items) \ + _Dee_MallococBufsizeSafe(COMPILER_OFFSETOF(DeeTupleObject, t_elem), \ + n_items, sizeof(DREF DeeObject *)) /* Define a statically allocated tuple: diff --git a/src/deemon/compiler/asm/assembler.c b/src/deemon/compiler/asm/assembler.c index 1217346f..405bbc50 100644 --- a/src/deemon/compiler/asm/assembler.c +++ b/src/deemon/compiler/asm/assembler.c @@ -1659,8 +1659,8 @@ INTERN WUNUSED instruction_t *(DFCALL asm_alloc)(size_t n_bytes) { new_size = min_size; goto realloc_instr; } - if (Dee_CollectMemory(offsetof(DeeCodeObject, co_code) + - new_size * sizeof(instruction_t))) + if (Dee_CollectMemoryoc(offsetof(DeeCodeObject, co_code), + new_size, sizeof(instruction_t))) goto realloc_instr; return NULL; } diff --git a/src/deemon/compiler/asm/userasm.c b/src/deemon/compiler/asm/userasm.c index a681c208..709017ab 100644 --- a/src/deemon/compiler/asm/userasm.c +++ b/src/deemon/compiler/asm/userasm.c @@ -2214,10 +2214,8 @@ assembly_formatter_format(struct assembly_formatter *__restrict self, } result->s_refcnt = 1; result->s_size = self->af_printer.ap_length; - result = (struct TPPString *)Dee_TryRealloc(result, - offsetof(struct TPPString, s_text) + - (self->af_printer.ap_length + 1) * - sizeof(char)); + result = (struct TPPString *)Dee_TryReallococ(result, offsetof(struct TPPString, s_text), + self->af_printer.ap_length + 1, sizeof(char)); if unlikely(!result) result = (struct TPPString *)self->af_printer.ap_string; self->af_printer.ap_string = NULL; diff --git a/src/deemon/compiler/ddi.c b/src/deemon/compiler/ddi.c index 8b528a5d..3d3ab259 100644 --- a/src/deemon/compiler/ddi.c +++ b/src/deemon/compiler/ddi.c @@ -299,12 +299,12 @@ INTERN WUNUSED DREF DeeDDIObject *DCALL ddi_compile(void) { result_size = (current_assembler.a_sect[0].sec_iter - current_assembler.a_sect[0].sec_begin) * 3; - result = (DeeDDIObject *)DeeObject_TryCalloc(offsetof(DeeDDIObject, d_ddi) + - 1 + result_size); + result = (DeeDDIObject *)DeeObject_TryCallocc(offsetof(DeeDDIObject, d_ddi), + result_size + 1, sizeof(uint8_t)); if unlikely(!result) { result_size = 0; - result = (DeeDDIObject *)DeeObject_Calloc(offsetof(DeeDDIObject, d_ddi) + - 1 + result_size); + result = (DeeDDIObject *)DeeObject_Callocc(offsetof(DeeDDIObject, d_ddi), + result_size + 1, sizeof(uint8_t)); if unlikely(!result) goto err; } @@ -506,14 +506,16 @@ INTERN WUNUSED DREF DeeDDIObject *DCALL ddi_compile(void) { ASSERT(old_alloc != 0); ASSERT(new_alloc != 0); ASSERT(old_alloc != new_alloc); - new_result = (DeeDDIObject *)DeeObject_TryRealloc(result, offsetof(DeeDDIObject, d_ddi) + 1 + new_alloc); + new_result = (DeeDDIObject *)DeeObject_TryReallocc(result, offsetof(DeeDDIObject, d_ddi), + new_alloc + 1, sizeof(uint8_t)); if unlikely(!new_result) { size_t min_alloc = bind_size + (size_t)(code_iter - result->d_ddi); if (new_alloc != min_alloc) { new_alloc = min_alloc; goto do_realloc_bind; } - if (Dee_CollectMemory(offsetof(DeeDDIObject, d_ddi) + 1 + new_alloc)) + if (Dee_CollectMemoryoc(offsetof(DeeDDIObject, d_ddi), + new_alloc + 1, sizeof(uint8_t))) goto do_realloc_bind; goto err_result_printer; } @@ -570,15 +572,16 @@ INTERN WUNUSED DREF DeeDDIObject *DCALL ddi_compile(void) { ASSERT(old_alloc != 0); ASSERT(new_alloc != 0); ASSERT(old_alloc != new_alloc); - new_result = (DeeDDIObject *)DeeObject_TryRealloc(result, - offsetof(DeeDDIObject, d_ddi) + 1 + new_alloc); + new_result = (DeeDDIObject *)DeeObject_TryReallocc(result, offsetof(DeeDDIObject, d_ddi), + new_alloc + 1, sizeof(uint8_t)); if unlikely(!new_result) { size_t min_alloc = text_size + (size_t)(code_iter - result->d_ddi); if (new_alloc != min_alloc) { new_alloc = min_alloc; goto do_realloc; } - if (Dee_CollectMemory(offsetof(DeeDDIObject, d_ddi) + 1 + new_alloc)) + if (Dee_CollectMemoryoc(offsetof(DeeDDIObject, d_ddi), + new_alloc + 1, sizeof(uint8_t))) goto do_realloc; goto err_result_printer; } diff --git a/src/deemon/compiler/lexer/asm.c b/src/deemon/compiler/lexer/asm.c index dd72ada7..05fe8e20 100644 --- a/src/deemon/compiler/lexer/asm.c +++ b/src/deemon/compiler/lexer/asm.c @@ -306,15 +306,15 @@ PRIVATE NONNULL((1)) ptrdiff_t while (alloc_size < bufsize) alloc_size *= 2; alloc_again: - string = (struct TPPString *)Dee_TryMalloc(offsetof(struct TPPString, s_text) + - (alloc_size + 1) * sizeof(char)); + string = (struct TPPString *)Dee_TryMallococ(offsetof(struct TPPString, s_text), + alloc_size + 1, sizeof(char)); if unlikely(!string) { if (alloc_size != bufsize) { alloc_size = bufsize; goto alloc_again; } - if (Dee_CollectMemory(offsetof(struct TPPString, s_text) + - (alloc_size + 1) * sizeof(char))) + if (Dee_CollectMemoryoc(offsetof(struct TPPString, s_text), + alloc_size + 1, sizeof(char))) goto alloc_again; return -1; } @@ -331,17 +331,16 @@ PRIVATE NONNULL((1)) ptrdiff_t size_t min_alloc = self->sp_length + bufsize; alloc_size = (min_alloc + 63) & ~63; realloc_again: - string = (struct TPPString *)Dee_TryRealloc(string, - offsetof(struct TPPString, s_text) + - (alloc_size + 1) * sizeof(char)); + string = (struct TPPString *)Dee_TryReallococ(string, offsetof(struct TPPString, s_text), + alloc_size + 1, sizeof(char)); if unlikely(!string) { string = self->sp_string; if (alloc_size != min_alloc) { alloc_size = min_alloc; goto realloc_again; } - if (Dee_CollectMemory(offsetof(struct TPPString, s_text) + - (alloc_size + 1) * sizeof(char))) + if (Dee_CollectMemoryoc(offsetof(struct TPPString, s_text), + alloc_size + 1, sizeof(char))) goto realloc_again; return -1; } @@ -374,9 +373,8 @@ PRIVATE /*REF*/ struct TPPString * /* Deallocate unused memory. */ if likely(self->sp_length != result->s_size) { DREF struct TPPString *reloc; - reloc = (DREF struct TPPString *)Dee_TryRealloc(result, - offsetof(struct TPPString, s_text) + - (self->sp_length + 1) * sizeof(char)); + reloc = (DREF struct TPPString *)Dee_TryReallococ(result, offsetof(struct TPPString, s_text), + self->sp_length + 1, sizeof(char)); if likely(reloc) result = reloc; result->s_size = self->sp_length; diff --git a/src/deemon/compiler/lexer/class.c b/src/deemon/compiler/lexer/class.c index 54beff13..e69b043c 100644 --- a/src/deemon/compiler/lexer/class.c +++ b/src/deemon/compiler/lexer/class.c @@ -217,8 +217,8 @@ rehash_instance_attributes(DREF DeeClassDescriptorObject *__restrict self) { if (new_mask <= 1) new_mask = 7; #endif - new_descr = (DeeClassDescriptorObject *)DeeObject_Calloc(offsetof(DeeClassDescriptorObject, cd_iattr_list) + - (new_mask + 1) * sizeof(struct class_attribute)); + new_descr = (DeeClassDescriptorObject *)DeeObject_Callocc(offsetof(DeeClassDescriptorObject, cd_iattr_list), + new_mask + 1, sizeof(struct class_attribute)); if unlikely(!new_descr) goto err; @@ -984,9 +984,9 @@ class_maker_pack(struct class_maker *__restrict self) { * we also don't have to both with relocating them! */ if (!self->cm_iattr_size) { DeeClassDescriptorObject *new_desc; - new_desc = (DeeClassDescriptorObject *)DeeObject_TryRealloc(self->cm_desc, - offsetof(DeeClassDescriptorObject, cd_iattr_list) + - 1 * sizeof(struct class_attribute)); + new_desc = (DeeClassDescriptorObject *)DeeObject_TryReallocc(self->cm_desc, + offsetof(DeeClassDescriptorObject, cd_iattr_list), + 1, sizeof(struct class_attribute)); if likely(new_desc) self->cm_desc = new_desc; self->cm_desc->cd_iattr_mask = 0; @@ -1462,8 +1462,8 @@ ast_parse_class_impl(uint16_t class_flags, struct TPPKeyword *name, unicode_printer_init(¤t_tags.at_doc); /* Allocate the initial descriptor for the class. */ - maker.cm_desc = (DREF DeeClassDescriptorObject *)DeeObject_Calloc(offsetof(DeeClassDescriptorObject, cd_iattr_list) + - (7 + 1) * sizeof(struct class_attribute)); + maker.cm_desc = (DREF DeeClassDescriptorObject *)DeeObject_Callocc(offsetof(DeeClassDescriptorObject, cd_iattr_list), + 7 + 1, sizeof(struct class_attribute)); if unlikely(!maker.cm_desc) goto err; DeeObject_Init(maker.cm_desc, &DeeClassDescriptor_Type); diff --git a/src/deemon/compiler/tpp.c b/src/deemon/compiler/tpp.c index 535322b9..02a1c2cd 100644 --- a/src/deemon/compiler/tpp.c +++ b/src/deemon/compiler/tpp.c @@ -663,8 +663,8 @@ tpp_unknown_file(int mode, char *__restrict filename, /* Try to pre-allocate a decently-sized buffer. */ buflen = 128 + filename_size; - buffer = (DeeStringObject *)DeeObject_TryMalloc(offsetof(DeeStringObject, s_str) + - (buflen + 1) * sizeof(char)); + buffer = (DeeStringObject *)DeeObject_TryMallocc(offsetof(DeeStringObject, s_str), + buflen + 1, sizeof(char)); if unlikely(!buffer) { buflen = 0; } else { @@ -689,8 +689,8 @@ tpp_unknown_file(int mode, char *__restrict filename, filename_size); /* baz.dee */ if unlikely(req_length > buflen) { /* Need a larger buffer. */ - new_buffer = (DeeStringObject *)DeeObject_Realloc(buffer, offsetof(DeeStringObject, s_str) + - (req_length + 1) * sizeof(char)); + new_buffer = (DeeStringObject *)DeeObject_Reallocc(buffer, offsetof(DeeStringObject, s_str), + req_length + 1, sizeof(char)); if unlikely(!new_buffer) goto err_path; if (!buffer) { @@ -760,8 +760,8 @@ tpp_unknown_file(int mode, char *__restrict filename, /* Try to truncate the used portion of the buffer. */ if (buffer->s_len != buflen) { - new_buffer = (DeeStringObject *)DeeObject_TryRealloc(buffer, offsetof(DeeStringObject, s_str) + - (buffer->s_len + 1) * sizeof(char)); + new_buffer = (DeeStringObject *)DeeObject_TryReallocc(buffer, offsetof(DeeStringObject, s_str), + buffer->s_len + 1, sizeof(char)); if likely(new_buffer) { buffer = new_buffer; buflen = buffer->s_len; diff --git a/src/deemon/execute/code-invoke-kw.c.inl b/src/deemon/execute/code-invoke-kw.c.inl index a2138159..6d4f5e56 100644 --- a/src/deemon/execute/code-invoke-kw.c.inl +++ b/src/deemon/execute/code-invoke-kw.c.inl @@ -137,11 +137,11 @@ PP_CAT2(LOCAL_DeeFunction_Call, IntellisenseInternal) * ones that are positional. */ #if CODE_FLAGS & (CODE_FYIELDING | CODE_FVARKWDS) #if defined(Dee_Alloca) && !(CODE_FLAGS & CODE_FYIELDING) - frame.cf_kw = (struct code_frame_kwds *)Dee_Alloca(offsetof(struct code_frame_kwds, fk_kargv) + - (ex_argc * sizeof(DeeObject *))); + frame.cf_kw = (struct code_frame_kwds *)Dee_Allocaoc(offsetof(struct code_frame_kwds, fk_kargv), + ex_argc, sizeof(DeeObject *)); #else /* Dee_Alloca && !(CODE_FLAGS & CODE_FYIELDING) */ - frame.cf_kw = (struct code_frame_kwds *)Dee_Malloc(offsetof(struct code_frame_kwds, fk_kargv) + - (ex_argc * sizeof(DeeObject *))); + frame.cf_kw = (struct code_frame_kwds *)Dee_Mallococ(offsetof(struct code_frame_kwds, fk_kargv), + ex_argc, sizeof(DeeObject *)); if unlikely(!frame.cf_kw) goto err; #endif /* !Dee_Alloca || (CODE_FLAGS & CODE_FYIELDING) != 0 */ diff --git a/src/deemon/execute/dec.c b/src/deemon/execute/dec.c index b3da2fa8..e3b81b52 100644 --- a/src/deemon/execute/dec.c +++ b/src/deemon/execute/dec.c @@ -1362,11 +1362,11 @@ DecFile_LoadObject(DecFile *__restrict self, refc = code->co_refc; ASSERT(code->co_refstaticc >= refc); if likely(code->co_refstaticc == refc) { - result = (DREF DeeObject *)DeeGCObject_Malloc(offsetof(DeeFunctionObject, fo_refv) + - (refc * sizeof(DREF DeeObject *))); + result = (DREF DeeObject *)DeeGCObject_Mallocc(offsetof(DeeFunctionObject, fo_refv), + refc, sizeof(DREF DeeObject *)); } else { - result = (DREF DeeObject *)DeeGCObject_Calloc(offsetof(DeeFunctionObject, fo_refv) + - (code->co_refstaticc * sizeof(DREF DeeObject *))); + result = (DREF DeeObject *)DeeGCObject_Callocc(offsetof(DeeFunctionObject, fo_refv), + code->co_refstaticc, sizeof(DREF DeeObject *)); } if unlikely(!result) { err_function_code: @@ -1495,8 +1495,8 @@ DecFile_LoadObject(DecFile *__restrict self, while (iattr_count > (iattr_mask / 3) * 2) iattr_mask = (iattr_mask << 1) | 1; } - result = (DREF DeeObject *)DeeObject_Calloc(offsetof(DeeClassDescriptorObject, cd_iattr_list) + - (iattr_mask + 1) * sizeof(struct class_attribute)); + result = (DREF DeeObject *)DeeObject_Callocc(offsetof(DeeClassDescriptorObject, cd_iattr_list), + iattr_mask + 1, sizeof(struct class_attribute)); if unlikely(!result) goto err; DeeObject_Init(result, &DeeClassDescriptor_Type); @@ -1873,8 +1873,8 @@ DecFile_LoadObject(DecFile *__restrict self, while (iattr_count > (iattr_mask / 3) * 2) iattr_mask = (iattr_mask << 1) | 1; } - result = (DREF DeeObject *)DeeObject_Calloc(offsetof(DeeClassDescriptorObject, cd_iattr_list) + - (iattr_mask + 1) * sizeof(struct class_attribute)); + result = (DREF DeeObject *)DeeObject_Callocc(offsetof(DeeClassDescriptorObject, cd_iattr_list), + iattr_mask + 1, sizeof(struct class_attribute)); if unlikely(!result) goto err; DeeObject_Init(result, &DeeClassDescriptor_Type); @@ -2266,8 +2266,9 @@ DecFile_LoadDDI(DecFile *__restrict self, ddi_ddisize != 0) { GOTO_CORRUPTED(reader, err_currupted); } - result = (DREF DeeDDIObject *)DeeObject_Calloc(offsetof(DeeDDIObject, d_ddi) + - ddi_ddisize + DDI_INSTRLEN_MAX); + result = (DREF DeeDDIObject *)DeeObject_Callocc(offsetof(DeeDDIObject, d_ddi), + ddi_ddisize + DDI_INSTRLEN_MAX, + sizeof(uint8_t)); if unlikely(!result) goto err; @@ -2311,8 +2312,8 @@ DecFile_LoadDDI(DecFile *__restrict self, GOTO_CORRUPTED(xdat, err_currupted_r_maps); if (xdat + xsiz >= self->df_base + self->df_size) GOTO_CORRUPTED(xdat, err_currupted_r_maps); - xres = (struct Dee_ddi_exdat *)Dee_Malloc(offsetof(struct Dee_ddi_exdat, dx_data) + - xsiz + DDI_EXDAT_MAXSIZE); + xres = (struct Dee_ddi_exdat *)Dee_MallococSafe(offsetof(struct Dee_ddi_exdat, dx_data), + xsiz, DDI_EXDAT_MAXSIZE); if unlikely(!xres) goto err_r_maps; xres->dx_size = xsiz; diff --git a/src/deemon/execute/function.c b/src/deemon/execute/function.c index 57fc2775..751279c4 100644 --- a/src/deemon/execute/function.c +++ b/src/deemon/execute/function.c @@ -294,11 +294,11 @@ DeeFunction_New(DeeObject *code_, size_t refc, DeeCode_NAME(code)); ASSERT(code->co_refstaticc >= refc); if likely(code->co_refstaticc == refc) { - result = (DREF Function *)DeeGCObject_Malloc(offsetof(Function, fo_refv) + - (refc * sizeof(DREF DeeObject *))); + result = (DREF Function *)DeeGCObject_Mallocc(offsetof(Function, fo_refv), + refc, sizeof(DREF DeeObject *)); } else { - result = (DREF Function *)DeeGCObject_Calloc(offsetof(Function, fo_refv) + - (code->co_refstaticc * sizeof(DREF DeeObject *))); + result = (DREF Function *)DeeGCObject_Callocc(offsetof(Function, fo_refv), + code->co_refstaticc, sizeof(DREF DeeObject *)); } if unlikely(!result) goto done; @@ -333,11 +333,11 @@ DeeFunction_NewInherited(DeeObject *code_, size_t refc, DeeCode_NAME(code)); ASSERT(code->co_refstaticc >= refc); if likely(code->co_refstaticc == refc) { - result = (DREF Function *)DeeGCObject_Malloc(offsetof(Function, fo_refv) + - (refc * sizeof(DREF DeeObject *))); + result = (DREF Function *)DeeGCObject_Mallocc(offsetof(Function, fo_refv), + refc, sizeof(DREF DeeObject *)); } else { - result = (DREF Function *)DeeGCObject_Calloc(offsetof(Function, fo_refv) + - (code->co_refstaticc * sizeof(DREF DeeObject *))); + result = (DREF Function *)DeeGCObject_Callocc(offsetof(Function, fo_refv), + code->co_refstaticc, sizeof(DREF DeeObject *)); } if unlikely(!result) goto done; @@ -366,8 +366,8 @@ DeeFunction_NewNoRefs(DeeObject *__restrict code_) { if likely(code->co_refstaticc == 0) { result = (DREF Function *)DeeGCObject_Malloc(offsetof(Function, fo_refv)); } else { - result = (DREF Function *)DeeGCObject_Calloc(offsetof(Function, fo_refv) + - (code->co_refstaticc * sizeof(DREF DeeObject *))); + result = (DREF Function *)DeeGCObject_Callocc(offsetof(Function, fo_refv), + code->co_refstaticc, sizeof(DREF DeeObject *)); } if unlikely(!result) goto done; @@ -398,11 +398,11 @@ function_init(size_t argc, DeeObject *const *argv) { goto err; ASSERT(code->co_refc <= code->co_refstaticc); if likely(code->co_refc == code->co_refstaticc) { - result = (DREF Function *)DeeGCObject_Malloc(offsetof(Function, fo_refv) + - (code->co_refc * sizeof(DREF DeeObject *))); + result = (DREF Function *)DeeGCObject_Mallocc(offsetof(Function, fo_refv), + code->co_refc, sizeof(DREF DeeObject *)); } else { - result = (DREF Function *)DeeGCObject_Calloc(offsetof(Function, fo_refv) + - (code->co_refstaticc * sizeof(DREF DeeObject *))); + result = (DREF Function *)DeeGCObject_Callocc(offsetof(Function, fo_refv), + code->co_refstaticc, sizeof(DREF DeeObject *)); } if unlikely(!result) goto err; @@ -1310,8 +1310,8 @@ yf_copy(YFunction *__restrict self) { size_t count; ASSERT(self->yf_func->fo_code->co_argc_max >= self->yf_pargc); count = (self->yf_func->fo_code->co_argc_max - self->yf_pargc); - kw = (struct code_frame_kwds *)Dee_Malloc(offsetof(struct code_frame_kwds, fk_kargv) + - (count * sizeof(DeeObject *))); + kw = (struct code_frame_kwds *)Dee_Mallococ(offsetof(struct code_frame_kwds, fk_kargv), + count, sizeof(DeeObject *)); if unlikely(!kw) goto err_r; result->yf_kw = kw; @@ -1361,8 +1361,8 @@ yf_deepcopy(YFunction *__restrict self) { DeeCodeObject *code; DeeObject *const *kw_argv; count = (self->yf_func->fo_code->co_argc_max - self->yf_pargc); - kw = (struct code_frame_kwds *)Dee_Malloc(offsetof(struct code_frame_kwds, fk_kargv) + - (count * sizeof(DeeObject *))); + kw = (struct code_frame_kwds *)Dee_Mallococ(offsetof(struct code_frame_kwds, fk_kargv), + count, sizeof(DeeObject *)); if unlikely(!kw) goto err_this_args_r; result->yf_kw = kw; diff --git a/src/deemon/execute/interactive-module.c b/src/deemon/execute/interactive-module.c index 41cf4c07..6cd2b853 100644 --- a/src/deemon/execute/interactive-module.c +++ b/src/deemon/execute/interactive-module.c @@ -1253,8 +1253,9 @@ imod_init(InteractiveModule *__restrict self, used_name = TPPString_New(DeeString_STR(self->im_options.co_filename), DeeString_SIZE(self->im_options.co_filename)); if unlikely(!used_name) { - if (Dee_CollectMemory(offsetof(struct TPPString, s_text) + - (DeeString_SIZE(self->im_options.co_filename) + 1) * sizeof(char))) + if (Dee_CollectMemoryoc(offsetof(struct TPPString, s_text), + DeeString_SIZE(self->im_options.co_filename) + 1, + sizeof(char))) goto do_create_used_name; goto err_basefile; } @@ -1273,8 +1274,9 @@ imod_init(InteractiveModule *__restrict self, module_base_scope->bs_name = TPPLexer_LookupKeyword(DeeString_STR(self->im_options.co_rootname), DeeString_SIZE(self->im_options.co_rootname), 1); if unlikely(!module_base_scope->bs_name) { - if (Dee_CollectMemory(offsetof(struct TPPKeyword, k_name) + - (DeeString_SIZE(self->im_options.co_rootname) + 1) * sizeof(char))) + if (Dee_CollectMemoryoc(offsetof(struct TPPKeyword, k_name), + DeeString_SIZE(self->im_options.co_rootname) + 1, + sizeof(char))) goto do_create_base_name; goto err_basefile; } diff --git a/src/deemon/execute/module.c b/src/deemon/execute/module.c index 8b60da12..c656e61e 100644 --- a/src/deemon/execute/module.c +++ b/src/deemon/execute/module.c @@ -151,8 +151,8 @@ DeeModule_GetRoot(DeeObject *__restrict self, if likely(code->co_refstaticc == 0) { result = (DREF DeeFunctionObject *)DeeGCObject_Malloc(offsetof(DeeFunctionObject, fo_refv)); } else { - result = (DREF DeeFunctionObject *)DeeGCObject_Calloc(offsetof(DeeFunctionObject, fo_refv) + - (code->co_refstaticc * sizeof(DREF DeeObject *))); + result = (DREF DeeFunctionObject *)DeeGCObject_Callocc(offsetof(DeeFunctionObject, fo_refv), + code->co_refstaticc, sizeof(DREF DeeObject *)); } if unlikely(!result) goto err; diff --git a/src/deemon/main.c b/src/deemon/main.c index 577ff3e9..31e838ea 100644 --- a/src/deemon/main.c +++ b/src/deemon/main.c @@ -2395,8 +2395,8 @@ dformat_source_files(char *filename, do_set_ddi_name: used_name = TPPString_New(ddi_filename, ddi_length); if unlikely(!used_name) { - if (Dee_CollectMemory(offsetof(struct TPPString, s_text) + - (ddi_length + 1) * sizeof(char))) + if (Dee_CollectMemoryoc(offsetof(struct TPPString, s_text), + ddi_length + 1, sizeof(char))) goto do_set_ddi_name; TPPFile_Decref(file); goto err_stream; diff --git a/src/deemon/objects/bytes.c b/src/deemon/objects/bytes.c index 3fe57750..f601d7b8 100644 --- a/src/deemon/objects/bytes.c +++ b/src/deemon/objects/bytes.c @@ -316,8 +316,7 @@ DeeBytes_FromSequence(DeeObject *__restrict seq) { if (bufsize != DEE_FASTSEQ_NOTFAST_DEPRECATED) { if (bufsize == 0) return_empty_bytes; - result = (DREF Bytes *)DeeObject_Malloc(offsetof(Bytes, b_data) + - bufsize); + result = (DREF Bytes *)DeeObject_Mallocc(offsetof(Bytes, b_data), bufsize, sizeof(byte_t)); if unlikely(!result) goto err; @@ -339,10 +338,10 @@ DeeBytes_FromSequence(DeeObject *__restrict seq) { /* Fallback: use an iterator. */ bufsize = 256; - result = (DREF Bytes *)DeeObject_TryMalloc(offsetof(Bytes, b_data) + bufsize); + result = (DREF Bytes *)DeeObject_TryMallocc(offsetof(Bytes, b_data), bufsize, sizeof(byte_t)); if unlikely(!bufsize) { bufsize = 1; - result = (DREF Bytes *)DeeObject_Malloc(offsetof(Bytes, b_data) + 1); + result = (DREF Bytes *)DeeObject_Mallocc(offsetof(Bytes, b_data), 1, sizeof(byte_t)); if unlikely(!result) goto err; } @@ -357,14 +356,12 @@ DeeBytes_FromSequence(DeeObject *__restrict seq) { size_t new_bufsize = bufsize * 2; /* Must allocate more memory. */ - new_result = (DREF Bytes *)DeeObject_TryRealloc(result, - offsetof(Bytes, b_data) + - new_bufsize); + new_result = (DREF Bytes *)DeeObject_TryReallocc(result, offsetof(Bytes, b_data), + new_bufsize, sizeof(byte_t)); if unlikely(!new_result) { new_bufsize = i + 1; - new_result = (DREF Bytes *)DeeObject_Realloc(result, - offsetof(Bytes, b_data) + - new_bufsize); + new_result = (DREF Bytes *)DeeObject_Reallocc(result, offsetof(Bytes, b_data), + new_bufsize, sizeof(byte_t)); if unlikely(!new_result) goto err_r_elem; } @@ -385,9 +382,8 @@ DeeBytes_FromSequence(DeeObject *__restrict seq) { /* Free unused buffer memory. */ if likely(i < bufsize) { DREF Bytes *new_result; - new_result = (DREF Bytes *)DeeObject_TryRealloc(result, - offsetof(Bytes, b_data) + - i); + new_result = (DREF Bytes *)DeeObject_TryReallocc(result, offsetof(Bytes, b_data), + i, sizeof(byte_t)); if likely(new_result) result = new_result; } @@ -481,8 +477,8 @@ DeeObject_TBytes(DeeTypeObject *tp_self, PUBLIC WUNUSED DREF DeeObject *DCALL DeeBytes_NewBuffer(size_t num_bytes, byte_t init) { DREF Bytes *result; - result = (DREF Bytes *)DeeObject_Malloc(offsetof(Bytes, b_data) + - num_bytes); + result = (DREF Bytes *)DeeObject_MalloccSafe(offsetof(Bytes, b_data), + num_bytes, sizeof(byte_t)); if unlikely(!result) goto done; memset(result->b_data, init, num_bytes); @@ -503,8 +499,8 @@ DeeBytes_NewBuffer(size_t num_bytes, byte_t init) { PUBLIC WUNUSED DREF DeeObject *DCALL DeeBytes_NewBufferUninitialized(size_t num_bytes) { DREF Bytes *result; - result = (DREF Bytes *)DeeObject_Malloc(offsetof(Bytes, b_data) + - num_bytes); + result = (DREF Bytes *)DeeObject_MalloccSafe(offsetof(Bytes, b_data), + num_bytes, sizeof(byte_t)); if unlikely(!result) goto done; result->b_base = result->b_data; @@ -524,8 +520,8 @@ DeeBytes_NewBufferUninitialized(size_t num_bytes) { PUBLIC WUNUSED NONNULL((1)) DREF DeeObject *DCALL DeeBytes_NewBufferData(void const *__restrict data, size_t num_bytes) { DREF Bytes *result; - result = (DREF Bytes *)DeeObject_Malloc(offsetof(Bytes, b_data) + - num_bytes); + result = (DREF Bytes *)DeeObject_Mallocc(offsetof(Bytes, b_data), + num_bytes, sizeof(byte_t)); if unlikely(!result) goto done; result->b_base = (byte_t *)memcpy(result->b_data, data, num_bytes); @@ -545,9 +541,12 @@ DeeBytes_NewBufferData(void const *__restrict data, size_t num_bytes) { PUBLIC WUNUSED NONNULL((1)) DREF DeeObject *DCALL DeeBytes_ResizeBuffer(/*inherit(on_success)*/ DREF DeeObject *__restrict self, size_t num_bytes) { + size_t total_bytes; DREF Bytes *result, *new_result; ASSERT_OBJECT_TYPE_EXACT(self, &DeeBytes_Type); ASSERT(!DeeObject_IsShared(self)); + if unlikely(OVERFLOW_UADD(offsetof(Bytes, b_data), num_bytes, &total_bytes)) + total_bytes = (size_t)-1; result = (DREF Bytes *)self; ASSERT(result->b_base == result->b_data); ASSERT(result->b_orig == (DREF DeeObject *)result); @@ -555,15 +554,13 @@ DeeBytes_ResizeBuffer(/*inherit(on_success)*/ DREF DeeObject *__restrict self, ASSERT(result->b_buffer.bb_base == result->b_data); ASSERT(result->b_buffer.bb_size == result->b_size); again: - new_result = (DREF Bytes *)DeeObject_TryRealloc(result, - offsetof(Bytes, b_data) + - num_bytes); + new_result = (DREF Bytes *)DeeObject_TryRealloc(result, total_bytes); if unlikely(!new_result) { if (num_bytes <= result->b_size) { result->b_size = result->b_buffer.bb_size = num_bytes; return (DREF DeeObject *)result; } - if (Dee_CollectMemory(offsetof(Bytes, b_data) + num_bytes)) + if (Dee_CollectMemory(total_bytes)) goto again; return NULL; } @@ -587,9 +584,8 @@ DeeBytes_TruncateBuffer(/*inherit(on_success)*/ DREF DeeObject *__restrict self, ASSERT(result->b_buffer.bb_size == result->b_size); ASSERT(num_bytes <= result->b_size); if (num_bytes != result->b_size) { - result = (DREF Bytes *)DeeObject_TryRealloc(result, - offsetof(Bytes, b_data) + - num_bytes); + result = (DREF Bytes *)DeeObject_TryReallocc(result, offsetof(Bytes, b_data), + num_bytes, sizeof(byte_t)); if unlikely(!result) { result = (DREF Bytes *)self; result->b_size = result->b_buffer.bb_size = num_bytes; @@ -2119,9 +2115,8 @@ Dee_bytes_printer_pack(/*inherit(always)*/ struct bytes_printer *__restrict self /* Deallocate unused memory. */ if likely(self->bp_length != result->b_size) { DREF Bytes *reloc; - reloc = (DREF Bytes *)DeeObject_TryRealloc(result, - offsetof(Bytes, b_data) + - self->bp_length); + reloc = (DREF Bytes *)DeeObject_TryReallocc(result, offsetof(Bytes, b_data), + self->bp_length, sizeof(byte_t)); if likely(reloc) result = reloc; result->b_size = self->bp_length; @@ -2163,13 +2158,14 @@ Dee_bytes_printer_append(struct bytes_printer *__restrict self, while (alloc_size < datalen) alloc_size *= 2; alloc_again: - bytes = (Bytes *)DeeObject_TryMalloc(offsetof(Bytes, b_data) + alloc_size); + bytes = (Bytes *)DeeObject_TryMallocc(offsetof(Bytes, b_data), + alloc_size, sizeof(byte_t)); if unlikely(!bytes) { if (alloc_size != datalen) { alloc_size = datalen; goto alloc_again; } - if (Dee_CollectMemory(offsetof(Bytes, b_data) + alloc_size)) + if (Dee_CollectMemoryoc(offsetof(Bytes, b_data), alloc_size, sizeof(byte_t))) goto alloc_again; return -1; } @@ -2186,14 +2182,15 @@ Dee_bytes_printer_append(struct bytes_printer *__restrict self, size_t min_alloc = self->bp_length + datalen; alloc_size = (min_alloc + 63) & ~63; realloc_again: - bytes = (Bytes *)DeeObject_TryRealloc(bytes, offsetof(Bytes, b_data) + alloc_size); + bytes = (Bytes *)DeeObject_TryReallocc(bytes, offsetof(Bytes, b_data), + alloc_size, sizeof(byte_t)); if unlikely(!bytes) { bytes = self->bp_bytes; if (alloc_size != min_alloc) { alloc_size = min_alloc; goto realloc_again; } - if (Dee_CollectMemory(offsetof(Bytes, b_data) + alloc_size)) + if (Dee_CollectMemoryoc(offsetof(Bytes, b_data), alloc_size, sizeof(byte_t))) goto realloc_again; return -1; } @@ -2267,15 +2264,15 @@ PUBLIC WUNUSED NONNULL((1)) byte_t * while (alloc_size < datalen) alloc_size *= 2; alloc_again: - bytes = (Bytes *)DeeObject_TryMalloc(offsetof(Bytes, b_data) + - (alloc_size + 1) * sizeof(char)); + bytes = (Bytes *)DeeObject_TryMallocc(offsetof(Bytes, b_data), + alloc_size + 1, sizeof(byte_t)); if unlikely(!bytes) { if (alloc_size != datalen) { alloc_size = datalen; goto alloc_again; } - if (Dee_CollectMemory(offsetof(Bytes, b_data) + - (alloc_size + 1) * sizeof(char))) + if (Dee_CollectMemoryoc(offsetof(Bytes, b_data), + alloc_size + 1, sizeof(byte_t))) goto alloc_again; return NULL; } @@ -2291,16 +2288,16 @@ PUBLIC WUNUSED NONNULL((1)) byte_t * size_t min_alloc = self->bp_length + datalen; alloc_size = (min_alloc + 63) & ~63; realloc_again: - bytes = (Bytes *)DeeObject_TryRealloc(bytes, offsetof(Bytes, b_data) + - (alloc_size + 1) * sizeof(char)); + bytes = (Bytes *)DeeObject_TryReallocc(bytes, offsetof(Bytes, b_data), + alloc_size + 1, sizeof(byte_t)); if unlikely(!bytes) { bytes = self->bp_bytes; if (alloc_size != min_alloc) { alloc_size = min_alloc; goto realloc_again; } - if (Dee_CollectMemory(offsetof(Bytes, b_data) + - (alloc_size + 1) * sizeof(char))) + if (Dee_CollectMemoryoc(offsetof(Bytes, b_data), + alloc_size + 1, sizeof(byte_t))) goto realloc_again; return NULL; } diff --git a/src/deemon/objects/cell.c b/src/deemon/objects/cell.c index 78e6104c..f5275a70 100644 --- a/src/deemon/objects/cell.c +++ b/src/deemon/objects/cell.c @@ -153,11 +153,11 @@ cell_deepload(Cell *__restrict self) { /* Get/Del/Set the value associated with a given Cell. - * HINT: These are the getset callbacks used for `Cell.item' (or its deprecated name `Cell.value'). - * With that in mind, `DeeCell_Del()' and `DeeCell_Set()' - * always return `0' indicative of a successful callback. - * NOTE: `DeeCell_Get' will return `NULL' and throw an `AttributeError' if the `self' is - * empty, whereas `DeeCell_TryGet()' will do the same, but never throw any error. */ + * HINT: These are the getset callbacks used for `Cell.item' (or its deprecated name `Cell.value'). + * With that in mind, `DeeCell_Del()' and `DeeCell_Set()' + * always return `0' indicative of a successful callback. + * NOTE: `DeeCell_Get' will return `NULL' and throw an `UnboundAttribute' if the `self' is + * empty, whereas `DeeCell_TryGet()' will do the same, but never throw any error. */ PUBLIC WUNUSED NONNULL((1)) DREF DeeObject *DCALL DeeCell_TryGet(DeeObject *__restrict self) { Cell *me = (Cell *)self; diff --git a/src/deemon/objects/class.c b/src/deemon/objects/class.c index 15cff63a..cff4a94c 100644 --- a/src/deemon/objects/class.c +++ b/src/deemon/objects/class.c @@ -5599,9 +5599,9 @@ DeeClass_New(DeeObject *bases, DeeObject *descriptor, result_class_offset &= ~(sizeof(void *) - 1); /* Allocate the resulting class object. */ - result = (DREF DeeTypeObject *)DeeGCObject_Calloc(result_class_offset + - offsetof(struct class_desc, cd_members) + - (desc->cd_cmemb_size * sizeof(DREF DeeObject *))); + result = (DREF DeeTypeObject *)DeeGCObject_Callocc(result_class_offset + + offsetof(struct class_desc, cd_members), + desc->cd_cmemb_size, sizeof(DREF DeeObject *)); if unlikely(!result) goto err_cbases; diff --git a/src/deemon/objects/class_desc.c b/src/deemon/objects/class_desc.c index e61e1477..6df92d24 100644 --- a/src/deemon/objects/class_desc.c +++ b/src/deemon/objects/class_desc.c @@ -1922,8 +1922,8 @@ cd_alloc_from_iattr(DeeObject *__restrict iattr, iterator = DeeObject_Iter(iattr); if unlikely(!iterator) goto err; - result = (ClassDescriptor *)DeeObject_Calloc(offsetof(ClassDescriptor, cd_iattr_list) + - (8 * sizeof(struct class_attribute))); + result = (ClassDescriptor *)DeeObject_Callocc(offsetof(ClassDescriptor, cd_iattr_list), + 8, sizeof(struct class_attribute)); if unlikely(!result) goto err_iter; while (ITER_ISOK(elem = DeeObject_IterNext(iterator))) { @@ -1933,8 +1933,8 @@ cd_alloc_from_iattr(DeeObject *__restrict iattr, ClassDescriptor *new_result; size_t i, new_mask; new_mask = (imask << 1) | 1; - new_result = (ClassDescriptor *)DeeObject_Calloc(offsetof(ClassDescriptor, cd_iattr_list) + - ((new_mask + 1) * sizeof(struct class_attribute))); + new_result = (ClassDescriptor *)DeeObject_Callocc(offsetof(ClassDescriptor, cd_iattr_list), + new_mask + 1, sizeof(struct class_attribute)); if unlikely(!new_result) goto err_iter_r_elem; /* Rehash the already existing instance attribute table. */ diff --git a/src/deemon/objects/dict.c b/src/deemon/objects/dict.c index b990b225..756f0a23 100644 --- a/src/deemon/objects/dict.c +++ b/src/deemon/objects/dict.c @@ -1204,8 +1204,8 @@ DeeDict_SetItemStringHash(DeeObject *self, first_dummy->di_key == dummy); /* Write to the first dummy item. */ - key_ob = (DREF DeeStringObject *)DeeObject_TryMalloc(offsetof(DeeStringObject, s_str) + - (key_len + 1) * sizeof(char)); + key_ob = (DREF DeeStringObject *)DeeObject_TryMallocc(offsetof(DeeStringObject, s_str), + key_len + 1, sizeof(char)); if unlikely(!key_ob) goto collect_memory; DeeObject_Init(key_ob, &DeeString_Type); @@ -1305,8 +1305,8 @@ DeeDict_SetItemStringLenHash(DeeObject *self, first_dummy->di_key == dummy); /* Write to the first dummy item. */ - key_ob = (DREF DeeStringObject *)DeeObject_TryMalloc(offsetof(DeeStringObject, s_str) + - (keylen + 1) * sizeof(char)); + key_ob = (DREF DeeStringObject *)DeeObject_TryMallocc(offsetof(DeeStringObject, s_str), + keylen + 1, sizeof(char)); if unlikely(!key_ob) goto collect_memory; DeeObject_Init(key_ob, &DeeString_Type); diff --git a/src/deemon/objects/filetypes.c b/src/deemon/objects/filetypes.c index e9322eb6..a79227b2 100644 --- a/src/deemon/objects/filetypes.c +++ b/src/deemon/objects/filetypes.c @@ -969,10 +969,8 @@ DeeFileWriter_GetString(DeeObject *__restrict self) { } result->s_hash = DEE_STRING_HASH_UNSET; result->s_len = me->w_printer.up_length; - result = (DREF DeeStringObject *)DeeObject_TryRealloc(result, - offsetof(DeeStringObject, s_str) + - (me->w_printer.up_length + 1) * - sizeof(char)); + result = (DREF DeeStringObject *)DeeObject_TryReallocc(result, offsetof(DeeStringObject, s_str), + me->w_printer.up_length + 1, sizeof(char)); if unlikely(!result) { result = COMPILER_CONTAINER_OF(me->w_printer.up_buffer, DeeStringObject, @@ -1183,12 +1181,12 @@ writer_tryappend8(Writer *__restrict self, DeeStringObject *init_buffer; if (init_size < UNICODE_PRINTER_INITIAL_BUFSIZE) init_size = UNICODE_PRINTER_INITIAL_BUFSIZE; - init_buffer = (DeeStringObject *)DeeObject_TryMalloc(offsetof(DeeStringObject, s_str) + - (init_size + 1) * sizeof(char)); + init_buffer = (DeeStringObject *)DeeObject_TryMallocc(offsetof(DeeStringObject, s_str), + init_size + 1, sizeof(char)); if unlikely(!init_buffer) { init_size = bufsize; - init_buffer = (DeeStringObject *)DeeObject_TryMalloc(offsetof(DeeStringObject, s_str) + - (init_size + 1) * sizeof(char)); + init_buffer = (DeeStringObject *)DeeObject_TryMallocc(offsetof(DeeStringObject, s_str), + init_size + 1, sizeof(char)); if unlikely(!init_buffer) goto err; } @@ -1214,18 +1212,12 @@ writer_tryappend8(Writer *__restrict self, do { new_size *= 2; } while (new_size < written + bufsize); - new_buffer = (DeeStringObject *)DeeObject_TryRealloc(COMPILER_CONTAINER_OF(self->w_printer.up_buffer, - DeeStringObject, - s_str), - offsetof(DeeStringObject, s_str) + - (new_size + 1) * sizeof(char)); + new_buffer = (DeeStringObject *)DeeObject_TryReallocc(COMPILER_CONTAINER_OF(self->w_printer.up_buffer, DeeStringObject, s_str), + offsetof(DeeStringObject, s_str), new_size + 1, sizeof(char)); if unlikely(!new_buffer) { new_size = written + bufsize; - new_buffer = (DeeStringObject *)DeeObject_TryRealloc(COMPILER_CONTAINER_OF(self->w_printer.up_buffer, - DeeStringObject, - s_str), - offsetof(DeeStringObject, s_str) + - (new_size + 1) * sizeof(char)); + new_buffer = (DeeStringObject *)DeeObject_TryReallocc(COMPILER_CONTAINER_OF(self->w_printer.up_buffer, DeeStringObject, s_str), + offsetof(DeeStringObject, s_str), new_size + 1, sizeof(char)); if unlikely(!new_buffer) goto err; } @@ -1300,12 +1292,12 @@ writer_tryappendch(Writer *__restrict self, uint32_t ch) { if (ch <= 0xff) { size_t init_size = UNICODE_PRINTER_INITIAL_BUFSIZE; DeeStringObject *init_buffer; - init_buffer = (DeeStringObject *)DeeObject_TryMalloc(offsetof(DeeStringObject, s_str) + - (init_size + 1) * sizeof(char)); + init_buffer = (DeeStringObject *)DeeObject_TryMallocc(offsetof(DeeStringObject, s_str), + init_size + 1, sizeof(char)); if unlikely(!init_buffer) { init_size = 1; - init_buffer = (DeeStringObject *)DeeObject_TryMalloc(offsetof(DeeStringObject, s_str) + - (init_size + 1) * sizeof(char)); + init_buffer = (DeeStringObject *)DeeObject_TryMallocc(offsetof(DeeStringObject, s_str), + init_size + 1, sizeof(char)); if unlikely(!init_buffer) goto err; } @@ -1362,18 +1354,12 @@ writer_tryappendch(Writer *__restrict self, uint32_t ch) { do { new_size *= 2; } while (new_size <= written); - new_buffer = (DeeStringObject *)DeeObject_TryRealloc(COMPILER_CONTAINER_OF(self->w_printer.up_buffer, - DeeStringObject, - s_str), - offsetof(DeeStringObject, s_str) + - (new_size + 1) * sizeof(char)); + new_buffer = (DeeStringObject *)DeeObject_TryReallocc(COMPILER_CONTAINER_OF(self->w_printer.up_buffer, DeeStringObject, s_str), + offsetof(DeeStringObject, s_str), new_size + 1, sizeof(char)); if unlikely(!new_buffer) { new_size = written + 1; - new_buffer = (DeeStringObject *)DeeObject_TryRealloc(COMPILER_CONTAINER_OF(self->w_printer.up_buffer, - DeeStringObject, - s_str), - offsetof(DeeStringObject, s_str) + - (new_size + 1) * sizeof(char)); + new_buffer = (DeeStringObject *)DeeObject_TryReallocc(COMPILER_CONTAINER_OF(self->w_printer.up_buffer, DeeStringObject, s_str), + offsetof(DeeStringObject, s_str), new_size + 1, sizeof(char)); if unlikely(!new_buffer) goto err; } @@ -1581,12 +1567,14 @@ writer_write(Writer *__restrict self, DeeStringObject *buffer_copy; size_t buffer_length = self->w_printer.up_length; ASSERT(buffer_length == DeeString_SIZE(written_buffer)); - buffer_copy = (DeeStringObject *)DeeObject_TryMalloc(offsetof(DeeStringObject, s_str) + - (buffer_length + bufsize + 1) * sizeof(char)); + buffer_copy = (DeeStringObject *)DeeObject_TryMallocc(offsetof(DeeStringObject, s_str), + buffer_length + bufsize + 1, + sizeof(char)); if unlikely(!buffer_copy) { DeeFileWriter_LockEndWrite(self); - if (Dee_CollectMemory(offsetof(DeeStringObject, s_str) + - (buffer_length + bufsize + 1) * sizeof(char))) + if (Dee_CollectMemoryoc(offsetof(DeeStringObject, s_str), + buffer_length + bufsize + 1, + sizeof(char))) goto again; goto err; } diff --git a/src/deemon/objects/gc_inspect.c b/src/deemon/objects/gc_inspect.c index f3b1ca32..f15c80b7 100644 --- a/src/deemon/objects/gc_inspect.c +++ b/src/deemon/objects/gc_inspect.c @@ -415,8 +415,8 @@ GCSetMaker_Rehash(GCSetMaker *__restrict self) { } else { new_mask = 31; } - new_set = (GCSet *)DeeObject_TryCalloc(offsetof(GCSet, gs_elem) + - (new_mask + 1) * sizeof(DREF DeeObject *)); + new_set = (GCSet *)DeeObject_TryCallocc(offsetof(GCSet, gs_elem), + new_mask + 1, sizeof(DREF DeeObject *)); if unlikely(!new_set) return false; new_set->gs_mask = new_mask; @@ -484,9 +484,9 @@ GCSetMaker_RemoveNonGC(GCSetMaker *__restrict self) { old_set = self->gs_set; if (!old_set) return 0; - new_set = (GCSet *)DeeObject_TryCalloc(offsetof(GCSet, gs_elem) + - (old_set->gs_mask + 1) * - sizeof(DREF DeeObject *)); + new_set = (GCSet *)DeeObject_TryCallocc(offsetof(GCSet, gs_elem), + old_set->gs_mask + 1, + sizeof(DREF DeeObject *)); if unlikely(!new_set) return false; new_set->gs_mask = old_set->gs_mask; diff --git a/src/deemon/objects/hashset.c b/src/deemon/objects/hashset.c index 46522c31..da008cd5 100644 --- a/src/deemon/objects/hashset.c +++ b/src/deemon/objects/hashset.c @@ -1014,11 +1014,12 @@ DeeHashSet_UnifyString(DeeObject *__restrict self, } if likely(!result) { /* Create the actual string that's going to get stored. */ - result = (DREF DeeStringObject *)DeeObject_TryMalloc(offsetof(DeeStringObject, s_str) + - (search_item_length + 1) * sizeof(char)); + result = (DREF DeeStringObject *)DeeObject_TryMallocc(offsetof(DeeStringObject, s_str), + search_item_length + 1, sizeof(char)); if unlikely(!result) { DeeHashSet_LockEndRead(me); - if (Dee_CollectMemory(offsetof(DeeStringObject, s_str) + (search_item_length + 1) * sizeof(char))) + if (Dee_CollectMemoryoc(offsetof(DeeStringObject, s_str), + search_item_length + 1, sizeof(char))) goto again_lock; return NULL; } @@ -1108,11 +1109,12 @@ DeeHashSet_InsertString(DeeObject *__restrict self, } if likely(!new_item) { /* Create the actual string that's going to get stored. */ - new_item = (DREF DeeStringObject *)DeeObject_TryMalloc(offsetof(DeeStringObject, s_str) + - (search_item_length + 1) * sizeof(char)); + new_item = (DREF DeeStringObject *)DeeObject_TryMallocc(offsetof(DeeStringObject, s_str), + search_item_length + 1, sizeof(char)); if unlikely(!new_item) { DeeHashSet_LockEndRead(me); - if (Dee_CollectMemory(offsetof(DeeStringObject, s_str) + (search_item_length + 1) * sizeof(char))) + if (Dee_CollectMemoryoc(offsetof(DeeStringObject, s_str), + search_item_length + 1, sizeof(char))) goto again_lock; return -1; } diff --git a/src/deemon/objects/int.c b/src/deemon/objects/int.c index c045605f..cc100c6b 100644 --- a/src/deemon/objects/int.c +++ b/src/deemon/objects/int.c @@ -176,8 +176,7 @@ Dee_intcache_clearall(size_t max_clear) { SCHED_YIELD(); } #endif /* !CONFIG_NO_THREADS */ - total_free = set->fis_size * (offsetof(DeeIntObject, ob_digit) + - i * sizeof(digit)); + total_free = set->fis_size * _Dee_MallococBufsize(offsetof(DeeIntObject, ob_digit), i, sizeof(digit)); chain = set->fis_head; if (max_clear >= result + total_free) { result += total_free; @@ -185,7 +184,7 @@ Dee_intcache_clearall(size_t max_clear) { set->fis_head = NULL; } else { size_t single_item; - single_item = offsetof(DeeIntObject, ob_digit) + i * sizeof(digit); + single_item = _Dee_MallococBufsize(offsetof(DeeIntObject, ob_digit), i, sizeof(digit)); total_free = max_clear - result; total_free += single_item - 1; total_free /= single_item; @@ -283,13 +282,11 @@ DeeInt_Alloc_dbg(size_t n_digits, char const *file, int line) do_alloc: #endif /* !CONFIG_NO_THREADS */ #ifdef NDEBUG - result = (DREF DeeIntObject *)DeeObject_Malloc(offsetof(DeeIntObject, ob_digit) + - n_digits * sizeof(digit)); + result = (DREF DeeIntObject *)DeeObject_Mallocc(offsetof(DeeIntObject, ob_digit), + n_digits, sizeof(digit)); #else /* NDEBUG */ - result = (DREF DeeIntObject *)DeeDbgObject_Malloc(offsetof(DeeIntObject, ob_digit) + - n_digits * sizeof(digit), - file, - line); + result = (DREF DeeIntObject *)DeeDbgObject_Mallocc(offsetof(DeeIntObject, ob_digit), + n_digits, sizeof(digit), file, line); #endif /* !NDEBUG */ if unlikely(!result) goto done; @@ -317,13 +314,11 @@ DeeInt_Alloc_dbg(size_t n_digits, char const *file, int line) { DREF DeeIntObject *result; #ifdef NDEBUG - result = (DREF DeeIntObject *)DeeObject_Malloc(offsetof(DeeIntObject, ob_digit) + - n_digits * sizeof(digit)); + result = (DREF DeeIntObject *)DeeObject_Mallocc(offsetof(DeeIntObject, ob_digit), + n_digits, sizeof(digit)); #else /* NDEBUG */ - result = (DREF DeeIntObject *)DeeDbgObject_Malloc(offsetof(DeeIntObject, ob_digit) + - n_digits * sizeof(digit), - file, - line); + result = (DREF DeeIntObject *)DeeDbgObject_Mallocc(offsetof(DeeIntObject, ob_digit), + n_digits, sizeof(digit), file, line); #endif /* !NDEBUG */ if (result) { DeeObject_Init(result, &DeeInt_Type); @@ -4435,12 +4430,13 @@ PRIVATE struct type_method tpconst int_class_methods[] = { PRIVATE WUNUSED NONNULL((1)) DREF DeeObject *DCALL int_sizeof(DeeIntObject *__restrict self) { - size_t int_size; + size_t int_size, result; int_size = (size_t)self->ob_size; if ((Dee_ssize_t)int_size < 0) int_size = (size_t)(-(Dee_ssize_t)int_size); - return DeeInt_NewSize(offsetof(DeeIntObject, ob_digit) + - (int_size * sizeof(digit))); + result = _Dee_MallococBufsize(offsetof(DeeIntObject, ob_digit), + int_size, sizeof(digit)); + return DeeInt_NewSize(result); } PRIVATE WUNUSED NONNULL((1)) DREF DeeIntObject *DCALL diff --git a/src/deemon/objects/list.c b/src/deemon/objects/list.c index 85d75c0e..2c7e9410 100644 --- a/src/deemon/objects/list.c +++ b/src/deemon/objects/list.c @@ -231,7 +231,7 @@ DeeList_NewWithHint(size_t n_prealloc) { weakref_support_init(result); Dee_atomic_rwlock_init(&result->l_lock); if likely(n_prealloc) { - result->l_list.ol_elemv = (DREF DeeObject **)Dee_TryMallocc(n_prealloc, sizeof(DREF DeeObject *)); + result->l_list.ol_elemv = (DREF DeeObject **)Dee_TryMalloccSafe(n_prealloc, sizeof(DREF DeeObject *)); if unlikely(!result->l_list.ol_elemv) _DeeList_SetAlloc(result, 0); } else { @@ -248,7 +248,7 @@ DeeList_NewUninitialized(size_t n_elem) { result = DeeGCObject_MALLOC(List); if unlikely(!result) goto done; - result->l_list.ol_elemv = (DREF DeeObject **)Dee_Mallocc(n_elem, sizeof(DREF DeeObject *)); + result->l_list.ol_elemv = (DREF DeeObject **)Dee_MalloccSafe(n_elem, sizeof(DREF DeeObject *)); if unlikely(!result->l_list.ol_elemv) goto err_r; DeeObject_Init(result, &DeeList_Type); @@ -511,7 +511,7 @@ DeeList_ExtendInherited(/*inherit(on_success)*/ DREF DeeObject *self, size_t arg list_size = DeeList_SIZE_ATOMIC(me); allocate_new_vector: new_elemv = (DREF DeeObject **)Dee_Mallocc(list_size + argc, - sizeof(DREF DeeObject *)); + sizeof(DREF DeeObject *)); if unlikely(!new_elemv) goto err; DeeList_LockRead(me); @@ -1098,8 +1098,8 @@ list_init(List *__restrict self, } else { if (filler == NULL) filler = Dee_None; - self->l_list.ol_elemv = (DREF DeeObject **)Dee_Mallocc(list_size, - sizeof(DREF DeeObject *)); + self->l_list.ol_elemv = (DREF DeeObject **)Dee_MalloccSafe(list_size, + sizeof(DREF DeeObject *)); if unlikely(!self->l_list.ol_elemv) goto err; Dee_Setrefv(self->l_list.ol_elemv, filler, list_size); diff --git a/src/deemon/objects/rodict.c b/src/deemon/objects/rodict.c index b9aec613..213d2fce 100644 --- a/src/deemon/objects/rodict.c +++ b/src/deemon/objects/rodict.c @@ -283,7 +283,7 @@ INTERN DeeTypeObject RoDictIterator_Type = { #define RODICT_ALLOC(mask) ((DREF RoDict *)DeeObject_Calloc(SIZEOF_RODICT(mask))) -#define SIZEOF_RODICT(mask) (offsetof(RoDict, rd_elem) + (((mask) + 1) * sizeof(struct rodict_item))) +#define SIZEOF_RODICT(mask) _Dee_MallococBufsize(offsetof(RoDict, rd_elem), (mask) + 1, sizeof(struct rodict_item)) #define RODICT_INITIAL_MASK 0x03 PRIVATE WUNUSED NONNULL((1)) DREF RoDict *DCALL @@ -1064,9 +1064,11 @@ rodict_get(RoDict *self, size_t argc, DeeObject *const *argv) { PRIVATE WUNUSED NONNULL((1)) DREF DeeObject *DCALL rodict_sizeof(RoDict *self) { - return DeeInt_NewSize(offsetof(RoDict, rd_elem) + - ((self->rd_mask + 1) * - sizeof(struct rodict_item))); + size_t result; + result = _Dee_MallococBufsize(offsetof(RoDict, rd_elem), + self->rd_mask + 1, + sizeof(struct rodict_item)); + return DeeInt_NewSize(result); } PRIVATE WUNUSED NONNULL((1)) DREF DeeObject *DCALL diff --git a/src/deemon/objects/roset.c b/src/deemon/objects/roset.c index 22957e40..fa5805d8 100644 --- a/src/deemon/objects/roset.c +++ b/src/deemon/objects/roset.c @@ -222,7 +222,7 @@ INTERN DeeTypeObject RoSetIterator_Type = { #define ROSET_ALLOC(mask) ((DREF RoSet *)DeeObject_Calloc(SIZEOF_ROSET(mask))) -#define SIZEOF_ROSET(mask) (offsetof(RoSet, rs_elem) + (((mask) + 1) * sizeof(struct roset_item))) +#define SIZEOF_ROSET(mask) _Dee_MallococBufsize(offsetof(RoSet, rs_elem), (mask) + 1, sizeof(struct roset_item)) #define ROSET_INITIAL_MASK 0x03 PRIVATE WUNUSED NONNULL((1)) DREF RoSet *DCALL @@ -568,9 +568,11 @@ PRIVATE struct type_seq roset_seq = { PRIVATE WUNUSED NONNULL((1)) DREF DeeObject *DCALL roset_sizeof(RoSet *self) { - return DeeInt_NewSize(offsetof(RoSet, rs_elem) + - ((self->rs_mask + 1) * - sizeof(struct roset_item))); + size_t result; + result = _Dee_MallococBufsize(offsetof(RoSet, rs_elem), + self->rs_mask + 1, + sizeof(struct roset_item)); + return DeeInt_NewSize(result); } PRIVATE struct type_method tpconst roset_methods[] = { diff --git a/src/deemon/objects/seq/each-fastpass.c.inl b/src/deemon/objects/seq/each-fastpass.c.inl index 1bf5bcc6..53f85b0d 100644 --- a/src/deemon/objects/seq/each-fastpass.c.inl +++ b/src/deemon/objects/seq/each-fastpass.c.inl @@ -958,8 +958,8 @@ done: PRIVATE WUNUSED DREF STRUCT_TYPE *DCALL F(copy)(STRUCT_TYPE *__restrict other) { DREF STRUCT_TYPE *result; - result = (DREF STRUCT_TYPE *)DeeObject_Malloc(offsetof(STRUCT_TYPE, sg_argv) + - (other->sg_argc * sizeof(DREF DeeObject *))); + result = (DREF STRUCT_TYPE *)DeeObject_Mallocc(offsetof(STRUCT_TYPE, sg_argv), + other->sg_argc, sizeof(DREF DeeObject *)); if unlikely(!result) goto done; result->se_seq = other->se_seq; @@ -981,8 +981,8 @@ PRIVATE WUNUSED DREF STRUCT_TYPE *DCALL F(deep)(STRUCT_TYPE *__restrict other) { DREF STRUCT_TYPE *result; size_t i; - result = (DREF STRUCT_TYPE *)DeeObject_Malloc(offsetof(STRUCT_TYPE, sg_argv) + - (other->sg_argc * sizeof(DREF DeeObject *))); + result = (DREF STRUCT_TYPE *)DeeObject_Mallocc(offsetof(STRUCT_TYPE, sg_argv), + other->sg_argc, sizeof(DREF DeeObject *)); if unlikely(!result) goto done; result->se_seq = DeeObject_DeepCopy(other->se_seq); @@ -1037,8 +1037,8 @@ F(init)(size_t argc, DeeObject *const *argv) { goto err; if (DeeObject_AssertTypeExact(args, &DeeTuple_Type)) goto err; - result = (DREF STRUCT_TYPE *)DeeObject_Malloc(offsetof(STRUCT_TYPE, sg_argv) + - (DeeTuple_SIZE(args) * sizeof(DREF DeeObject *))); + result = (DREF STRUCT_TYPE *)DeeObject_Mallocc(offsetof(STRUCT_TYPE, sg_argv), + DeeTuple_SIZE(args), sizeof(DREF DeeObject *)); if unlikely(!result) goto err; result->sg_argc = DeeTuple_SIZE(args); diff --git a/src/deemon/objects/seq/each.c b/src/deemon/objects/seq/each.c index a67db7bd..03d3c80a 100644 --- a/src/deemon/objects/seq/each.c +++ b/src/deemon/objects/seq/each.c @@ -2728,8 +2728,8 @@ DeeSeqEach_CallAttr(DeeObject *__restrict self, size_t argc, DeeObject *const *argv) { DREF SeqEachCallAttr *result; - result = (DREF SeqEachCallAttr *)DeeObject_Malloc(offsetof(SeqEachCallAttr, sg_argv) + - (argc * sizeof(DREF DeeObject *))); + result = (DREF SeqEachCallAttr *)DeeObject_Mallocc(offsetof(SeqEachCallAttr, sg_argv), + argc, sizeof(DREF DeeObject *)); if unlikely(!result) goto done; result->se_seq = self; @@ -2752,8 +2752,8 @@ DeeSeqEach_CallAttrKw(DeeObject *__restrict self, DREF SeqEachCallAttrKw *result; if (!kw) return DeeSeqEach_CallAttr(self, attr, argc, argv); - result = (DREF SeqEachCallAttrKw *)DeeObject_Malloc(offsetof(SeqEachCallAttrKw, sg_argv) + - (argc * sizeof(DREF DeeObject *))); + result = (DREF SeqEachCallAttrKw *)DeeObject_Mallocc(offsetof(SeqEachCallAttrKw, sg_argv), + argc, sizeof(DREF DeeObject *)); if unlikely(!result) goto done; result->se_seq = self; diff --git a/src/deemon/objects/seq/fastseq.c b/src/deemon/objects/seq/fastseq.c index 6ea6bfdf..d5597c0e 100644 --- a/src/deemon/objects/seq/fastseq.c +++ b/src/deemon/objects/seq/fastseq.c @@ -965,6 +965,7 @@ PUBLIC WUNUSED ATTR_OUTS(3, 2) NONNULL((1)) int (DCALL DeeObject_UnpackWithUnbound)(DeeObject *__restrict self, size_t objc, /*out*/ DREF DeeObject **__restrict objv) { size_t i, size; + /* TODO: Try to use `DeeObject_EnumerateIndex()'; if that isn't available, use `DeeObject_Unpack()' */ size = DeeFastSeq_GetSize_deprecated(self); if (size != DEE_FASTSEQ_NOTFAST_DEPRECATED) { if (size != objc) diff --git a/src/deemon/objects/seq/smap.h b/src/deemon/objects/seq/smap.h index 442d0bb7..570bd52a 100644 --- a/src/deemon/objects/seq/smap.h +++ b/src/deemon/objects/seq/smap.h @@ -71,7 +71,7 @@ typedef struct { #define SharedMap_LockEndRead(self) Dee_atomic_rwlock_endread(&(self)->sm_lock) #define SharedMap_LockEnd(self) Dee_atomic_rwlock_end(&(self)->sm_lock) -#define SHAREDMAP_SIZEOF(mask) (offsetof(SharedMap, sm_map) + ((mask) + 1) * sizeof(SharedItemEx)) +#define SHAREDMAP_SIZEOF(mask) _Dee_MallococBufsize(offsetof(SharedMap, sm_map), (mask) + 1, sizeof(SharedItemEx)) diff --git a/src/deemon/objects/string.c b/src/deemon/objects/string.c index bbcc198f..e3aeba46 100644 --- a/src/deemon/objects/string.c +++ b/src/deemon/objects/string.c @@ -93,15 +93,15 @@ PUBLIC WUNUSED NONNULL((1)) char * while (alloc_size < datalen) alloc_size *= 2; alloc_again: - string = (String *)DeeObject_TryMalloc(offsetof(String, s_str) + - (alloc_size + 1) * sizeof(char)); + string = (String *)DeeObject_TryMallocc(offsetof(String, s_str), + alloc_size + 1, sizeof(char)); if unlikely(!string) { if (alloc_size != datalen) { alloc_size = datalen; goto alloc_again; } - if (Dee_CollectMemory(offsetof(String, s_str) + - (alloc_size + 1) * sizeof(char))) + if (Dee_CollectMemoryoc(offsetof(String, s_str), + alloc_size + 1, sizeof(char))) goto alloc_again; return NULL; } @@ -117,17 +117,15 @@ PUBLIC WUNUSED NONNULL((1)) char * size_t min_alloc = self->ap_length + datalen; alloc_size = (min_alloc + 63) & ~63; realloc_again: - string = (String *)DeeObject_TryRealloc(string, - offsetof(String, s_str) + - (alloc_size + 1) * sizeof(char)); + string = (String *)DeeObject_TryReallocc(string, offsetof(String, s_str), + alloc_size + 1, sizeof(char)); if unlikely(!string) { string = self->ap_string; if (alloc_size != min_alloc) { alloc_size = min_alloc; goto realloc_again; } - if (Dee_CollectMemory(offsetof(String, s_str) + - (alloc_size + 1) * sizeof(char))) + if (Dee_CollectMemoryoc(offsetof(String, s_str), alloc_size + 1, sizeof(char))) goto realloc_again; return NULL; } @@ -178,15 +176,15 @@ PUBLIC WUNUSED NONNULL((1)) Dee_ssize_t while (alloc_size < datalen) alloc_size *= 2; alloc_again: - string = (String *)DeeObject_TryMalloc(offsetof(String, s_str) + - (alloc_size + 1) * sizeof(char)); + string = (String *)DeeObject_TryMallocc(offsetof(String, s_str), + alloc_size + 1, sizeof(char)); if unlikely(!string) { if (alloc_size != datalen) { alloc_size = datalen; goto alloc_again; } - if (Dee_CollectMemory(offsetof(String, s_str) + - (alloc_size + 1) * sizeof(char))) + if (Dee_CollectMemoryoc(offsetof(String, s_str), + alloc_size + 1, sizeof(char))) goto alloc_again; return -1; } @@ -204,17 +202,16 @@ PUBLIC WUNUSED NONNULL((1)) Dee_ssize_t size_t min_alloc = me->ap_length + datalen; alloc_size = (min_alloc + 63) & ~63; realloc_again: - string = (String *)DeeObject_TryRealloc(string, - offsetof(String, s_str) + - (alloc_size + 1) * sizeof(char)); + string = (String *)DeeObject_TryReallocc(string, offsetof(String, s_str), + alloc_size + 1, sizeof(char)); if unlikely(!string) { string = me->ap_string; if (alloc_size != min_alloc) { alloc_size = min_alloc; goto realloc_again; } - if (Dee_CollectMemory(offsetof(String, s_str) + - (alloc_size + 1) * sizeof(char))) + if (Dee_CollectMemoryoc(offsetof(String, s_str), + alloc_size + 1, sizeof(char))) goto realloc_again; return -1; } @@ -240,9 +237,8 @@ PUBLIC WUNUSED NONNULL((1)) DREF DeeObject * /* Deallocate unused memory. */ if likely(self->ap_length != result->s_len) { DREF String *reloc; - reloc = (DREF String *)DeeObject_TryRealloc(result, - offsetof(String, s_str) + - (self->ap_length + 1) * sizeof(char)); + reloc = (DREF String *)DeeObject_TryReallocc(result, offsetof(String, s_str), + self->ap_length + 1, sizeof(char)); if likely(reloc) result = reloc; result->s_len = self->ap_length; @@ -317,9 +313,8 @@ DeeString_ResizeBuffer(DREF DeeObject *self, size_t num_bytes) { } /* Re-allocate the buffer. */ - result = (DREF String *)DeeObject_Realloc(self, - offsetof(String, s_str) + - (num_bytes + 1) * sizeof(char)); + result = (DREF String *)DeeObject_Reallocc(self, offsetof(String, s_str), + num_bytes + 1, sizeof(char)); if likely(result) { if (!self) { /* Do the initial init when `self' was `NULL'. */ @@ -327,7 +322,7 @@ DeeString_ResizeBuffer(DREF DeeObject *self, size_t num_bytes) { result->s_data = NULL; result->s_hash = (dhash_t)-1; } - result->s_len = num_bytes; + result->s_len = num_bytes; result->s_str[num_bytes] = '\0'; } return (DREF DeeObject *)result; @@ -350,9 +345,8 @@ DeeString_TryResizeBuffer(DREF DeeObject *self, size_t num_bytes) { } /* Re-allocate the buffer. */ - result = (DREF String *)DeeObject_TryRealloc(self, - offsetof(String, s_str) + - (num_bytes + 1) * sizeof(char)); + result = (DREF String *)DeeObject_TryReallocc(self, offsetof(String, s_str), + num_bytes + 1, sizeof(char)); if likely(result) { if (!self) { /* Do the initial init when `self' was `NULL'. */ @@ -382,12 +376,12 @@ PUBLIC WUNUSED DREF DeeObject * return Dee_EmptyString; } #ifdef NDEBUG - result = (DREF String *)DeeObject_Malloc(offsetof(String, s_str) + - (num_bytes + 1) * sizeof(char)); + result = (DREF String *)DeeObject_Mallocc(offsetof(String, s_str), + num_bytes + 1, sizeof(char)); #else /* NDEBUG */ - result = (DREF String *)DeeDbgObject_Malloc(offsetof(String, s_str) + - (num_bytes + 1) * sizeof(char), - file, line); + result = (DREF String *)DeeDbgObject_Mallocc(offsetof(String, s_str), + num_bytes + 1, sizeof(char), + file, line); #endif /* !NDEBUG */ if likely(result) { DeeObject_Init(result, &DeeString_Type); diff --git a/src/deemon/objects/traceback.c b/src/deemon/objects/traceback.c index 6bb2c18d..ea2fbea9 100644 --- a/src/deemon/objects/traceback.c +++ b/src/deemon/objects/traceback.c @@ -80,8 +80,8 @@ DeeTraceback_New(struct thread_object *__restrict thread) { struct code_frame *dst, *src; DREF DeeTracebackObject *result; ASSERTF(thread == DeeThread_Self(), "Traceback for other threads must be created using `DeeThread_Trace()'"); - result = (DREF DeeTracebackObject *)DeeGCObject_TryMalloc(offsetof(DeeTracebackObject, tb_frames) + - thread->t_execsz * sizeof(struct code_frame)); + result = (DREF DeeTracebackObject *)DeeGCObject_TryMallocc(offsetof(DeeTracebackObject, tb_frames), + thread->t_execsz, sizeof(struct code_frame)); if unlikely(!result) goto err; @@ -741,8 +741,9 @@ PRIVATE WUNUSED NONNULL((1)) DREF DeeObject *DCALL traceback_sizeof(DeeTracebackObject *self) { size_t result; uint16_t i; - result = offsetof(DeeTracebackObject, tb_frames) + - (self->tb_numframes * sizeof(struct code_frame)); + result = _Dee_MallococBufsize(offsetof(DeeTracebackObject, tb_frames), + self->tb_numframes, + sizeof(struct code_frame)); for (i = 0; i < self->tb_numframes; ++i) { if (self->tb_frames[i].cf_frame) result += self->tb_frames[i].cf_func->fo_code->co_framesize; diff --git a/src/deemon/objects/tuple.c b/src/deemon/objects/tuple.c index 44895957..2f018444 100644 --- a/src/deemon/objects/tuple.c +++ b/src/deemon/objects/tuple.c @@ -126,8 +126,9 @@ Dee_tuplecache_clearall(size_t max_clear) { SLIST_REMOVE_HEAD(&iter->tuc_list, tci_link); ASSERT(iter->tuc_count != 0); --iter->tuc_count; - result += (offsetof(Tuple, t_elem) + - ((size_t)(iter - cache + 1) * sizeof(DeeObject *))); + result += _Dee_MallococBufsize(offsetof(Tuple, t_elem), + (size_t)(iter - cache + 1), + sizeof(DeeObject *)); DeeObject_Free(elem); } ASSERT(!!SLIST_EMPTY(&iter->tuc_list) == (iter->tuc_count == 0)); diff --git a/src/deemon/objects/unicode/regroups.h b/src/deemon/objects/unicode/regroups.h index e7c90a83..81acf27e 100644 --- a/src/deemon/objects/unicode/regroups.h +++ b/src/deemon/objects/unicode/regroups.h @@ -43,9 +43,8 @@ typedef struct { (self)->rm_eo)) INTDEF DeeTypeObject ReGroups_Type; -#define ReGroups_Malloc(ngroups) \ - ((ReGroups *)DeeObject_Malloc(offsetof(ReGroups, rg_groups) + \ - (ngroups) * sizeof(struct DeeRegexMatch))) +#define ReGroups_Malloc(ngroups) \ + ((ReGroups *)DeeObject_Mallocc(offsetof(ReGroups, rg_groups), ngroups, sizeof(struct DeeRegexMatch))) #define ReGroups_Free(self) DeeObject_Free(self) #define ReGroups_Init(self, ngroups) \ (void)(DeeObject_Init(self, &ReGroups_Type), \ @@ -77,9 +76,8 @@ typedef struct { INTDEF DeeTypeObject ReSubStrings_Type; INTDEF DeeTypeObject ReSubBytes_Type; -#define ReSubStrings_Malloc(ngroups) \ - ((ReSubStrings *)DeeObject_Malloc(offsetof(ReSubStrings, rss_groups) + \ - (ngroups) * sizeof(struct DeeRegexMatch))) +#define ReSubStrings_Malloc(ngroups) \ + ((ReSubStrings *)DeeObject_Mallocc(offsetof(ReSubStrings, rss_groups), ngroups, sizeof(struct DeeRegexMatch))) #define ReSubStrings_Free(self) DeeObject_Free(self) #define ReSubStrings_Init(self, baseown, baseptr, ngroups) \ (void)(DeeObject_Init(self, &ReSubStrings_Type), \ diff --git a/src/deemon/objects/unicode/string_functions.c b/src/deemon/objects/unicode/string_functions.c index 37130bf8..88ff54aa 100644 --- a/src/deemon/objects/unicode/string_functions.c +++ b/src/deemon/objects/unicode/string_functions.c @@ -11447,8 +11447,8 @@ string_cat(String *__restrict self, DeeObject *__restrict other) { /* Most likely case: both strings use 1-byte characters, * so we don't even need to use a multi-byte buffer! */ - result = (DREF String *)DeeObject_Malloc(offsetof(String, s_str) + - (total_length + 1) * sizeof(char)); + result = (DREF String *)DeeObject_Mallocc(offsetof(String, s_str), + total_length + 1, sizeof(char)); if unlikely(!result) goto err; result->s_len = total_length; @@ -11482,8 +11482,8 @@ string_cat(String *__restrict self, DeeObject *__restrict other) { /* Most likely case: both strings use 1-byte characters, * so we don't even need to use a multi-byte buffer! */ - result = (DREF String *)DeeObject_Malloc(offsetof(String, s_str) + - (total_length + 1) * sizeof(char)); + result = (DREF String *)DeeObject_Mallocc(offsetof(String, s_str), + total_length + 1, sizeof(char)); if unlikely(!result) goto err; result_utf = Dee_string_utf_alloc(); diff --git a/src/deemon/objects/unicode/unicode.c b/src/deemon/objects/unicode/unicode.c index e1e887d5..c32d37bb 100644 --- a/src/deemon/objects/unicode/unicode.c +++ b/src/deemon/objects/unicode/unicode.c @@ -1442,8 +1442,8 @@ DeeString_Pack2ByteBuffer(/*inherit(always)*/ uint16_t *__restrict text) { } } ASSERT(utf8_length >= length); - result = (DREF String *)DeeObject_Malloc(offsetof(String, s_str) + - (utf8_length + 1) * sizeof(char)); + result = (DREF String *)DeeObject_Mallocc(offsetof(String, s_str), + utf8_length + 1, sizeof(char)); if unlikely(!result) goto err; result->s_len = utf8_length; @@ -1496,8 +1496,8 @@ DeeString_TryPack2ByteBuffer(/*inherit(on_success)*/ uint16_t *__restrict text) } } ASSERT(utf8_length >= length); - result = (DREF String *)DeeObject_TryMalloc(offsetof(String, s_str) + - (utf8_length + 1) * sizeof(char)); + result = (DREF String *)DeeObject_TryMallocc(offsetof(String, s_str), + utf8_length + 1, sizeof(char)); if unlikely(!result) goto err; result->s_len = utf8_length; @@ -1625,8 +1625,8 @@ DeeString_PackUtf16Buffer(/*inherit(always)*/ uint16_t *__restrict text, } ASSERT(((size_t *)text)[-1] == length); ASSERT(utf8_length >= length); - result = (DREF String *)DeeObject_Malloc(offsetof(String, s_str) + - (utf8_length + 1) * sizeof(char)); + result = (DREF String *)DeeObject_Mallocc(offsetof(String, s_str), + utf8_length + 1, sizeof(char)); if unlikely(!result) goto err; result->s_len = utf8_length; @@ -1781,8 +1781,8 @@ DeeString_TryPackUtf16Buffer(/*inherit(on_success)*/ uint16_t *__restrict text) } ASSERT(((size_t *)text)[-1] == length); ASSERT(utf8_length >= length); - result = (DREF String *)DeeObject_TryMalloc(offsetof(String, s_str) + - (utf8_length + 1) * sizeof(char)); + result = (DREF String *)DeeObject_TryMallocc(offsetof(String, s_str), + utf8_length + 1, sizeof(char)); if unlikely(!result) goto err; result->s_len = utf8_length; @@ -1913,8 +1913,8 @@ DeeString_PackUtf32Buffer(/*inherit(always)*/ uint32_t *__restrict text, } } ASSERT(utf8_length >= length); - result = (DREF String *)DeeObject_Malloc(offsetof(String, s_str) + - (utf8_length + 1) * sizeof(char)); + result = (DREF String *)DeeObject_Mallocc(offsetof(String, s_str), + utf8_length + 1, sizeof(char)); if unlikely(!result) goto err; result->s_len = utf8_length; @@ -1976,8 +1976,8 @@ DeeString_TryPackUtf32Buffer(/*inherit(on_success)*/ uint32_t *__restrict text) } } ASSERT(utf8_length >= length); - result = (DREF String *)DeeObject_TryMalloc(offsetof(String, s_str) + - (utf8_length + 1) * sizeof(char)); + result = (DREF String *)DeeObject_TryMallocc(offsetof(String, s_str), + utf8_length + 1, sizeof(char)); if unlikely(!result) goto err; result->s_len = utf8_length; @@ -2144,8 +2144,8 @@ PUBLIC WUNUSED DREF DeeObject * uint32_t *buffer32, *dst32; size_t i, simple_length, utf_length; #ifdef NDEBUG - result = (DREF String *)DeeObject_Malloc(offsetof(String, s_str) + - (length + 1) * sizeof(char)); + result = (DREF String *)DeeObject_Mallocc(offsetof(String, s_str), + length + 1, sizeof(char)); #else /* NDEBUG */ result = (DREF String *)DeeDbgObject_Malloc(offsetof(String, s_str) + (length + 1) * sizeof(char), @@ -3315,11 +3315,8 @@ Dee_unicode_printer_allocate(struct unicode_printer *__restrict self, CASE_WIDTH_1BYTE: if (width == STRING_WIDTH_1BYTE) { DeeStringObject *new_string; - new_string = (DeeStringObject *)DeeObject_TryRealloc(COMPILER_CONTAINER_OF(buffer.ptr, - DeeStringObject, - s_str), - offsetof(DeeStringObject, s_str) + - (required + 1) * sizeof(char)); + new_string = (DeeStringObject *)DeeObject_TryReallocc(COMPILER_CONTAINER_OF(buffer.ptr, DeeStringObject, s_str), + offsetof(DeeStringObject, s_str), required + 1, sizeof(char)); if unlikely(!new_string) goto err; new_string->s_len = required; @@ -3552,13 +3549,14 @@ LOCAL WUNUSED NONNULL((1)) int DeeStringObject *buffer; allocate_initial_normally: ASSERT((self->up_flags & UNICODE_PRINTER_FWIDTH) == STRING_WIDTH_1BYTE); - buffer = (DeeStringObject *)DeeObject_TryMalloc(offsetof(DeeStringObject, s_str) + - (UNICODE_PRINTER_INITIAL_BUFSIZE + 1) * sizeof(char)); + buffer = (DeeStringObject *)DeeObject_TryMallocc(offsetof(DeeStringObject, s_str), + UNICODE_PRINTER_INITIAL_BUFSIZE + 1, + sizeof(char)); if likely(buffer) { buffer->s_len = UNICODE_PRINTER_INITIAL_BUFSIZE; } else { - buffer = (DeeStringObject *)DeeObject_Malloc(offsetof(DeeStringObject, s_str) + - (1 + 1) * sizeof(char)); + buffer = (DeeStringObject *)DeeObject_Mallocc(offsetof(DeeStringObject, s_str), + 1 + 1, sizeof(char)); if unlikely(!buffer) goto err; buffer->s_len = 1; @@ -3572,13 +3570,14 @@ LOCAL WUNUSED NONNULL((1)) int DeeStringObject *buffer; ASSERT(!self->up_length); ASSERT((self->up_flags & UNICODE_PRINTER_FWIDTH) == STRING_WIDTH_1BYTE); - buffer = (DeeStringObject *)DeeObject_TryMalloc(offsetof(DeeStringObject, s_str) + - (UNICODE_PRINTER_INITIAL_BUFSIZE + 1) * sizeof(char)); + buffer = (DeeStringObject *)DeeObject_TryMallocc(offsetof(DeeStringObject, s_str), + UNICODE_PRINTER_INITIAL_BUFSIZE + 1, + sizeof(char)); if likely(buffer) { buffer->s_len = UNICODE_PRINTER_INITIAL_BUFSIZE; } else { - buffer = (DeeStringObject *)DeeObject_Malloc(offsetof(DeeStringObject, s_str) + - (1 + 1) * sizeof(char)); + buffer = (DeeStringObject *)DeeObject_Mallocc(offsetof(DeeStringObject, s_str), + 1 + 1, sizeof(char)); if unlikely(!buffer) goto err; buffer->s_len = 1; @@ -4062,12 +4061,12 @@ Dee_unicode_printer_print8(struct unicode_printer *__restrict self, self->up_flags |= STRING_WIDTH_1BYTE; #endif /* STRING_WIDTH_1BYTE != 0 */ #endif /* !CONFIG_UNICODE_PRINTER_LAZY_PREALLOCATION */ - base_string = (String *)DeeObject_TryMalloc(offsetof(String, s_str) + - (initial_alloc + 1) * sizeof(char)); + base_string = (String *)DeeObject_TryMallocc(offsetof(String, s_str), + initial_alloc + 1, sizeof(char)); if unlikely(!base_string) { initial_alloc = textlen; - base_string = (String *)DeeObject_Malloc(offsetof(String, s_str) + - (initial_alloc + 1) * sizeof(char)); + base_string = (String *)DeeObject_Mallocc(offsetof(String, s_str), + initial_alloc + 1, sizeof(char)); if unlikely(!base_string) goto err; } @@ -4089,14 +4088,12 @@ Dee_unicode_printer_print8(struct unicode_printer *__restrict self, do { new_alloc *= 2; } while (new_alloc < self->up_length + textlen); - new_string = (String *)DeeObject_TryRealloc(COMPILER_CONTAINER_OF((char *)string, String, s_str), - offsetof(String, s_str) + - (new_alloc + 1) * sizeof(char)); + new_string = (String *)DeeObject_TryReallocc(COMPILER_CONTAINER_OF((char *)string, String, s_str), + offsetof(String, s_str), new_alloc + 1, sizeof(char)); if unlikely(!new_string) { new_alloc = self->up_length + textlen; - new_string = (String *)DeeObject_Realloc(COMPILER_CONTAINER_OF((char *)string, String, s_str), - offsetof(String, s_str) + - (new_alloc + 1) * sizeof(char)); + new_string = (String *)DeeObject_Reallocc(COMPILER_CONTAINER_OF((char *)string, String, s_str), + offsetof(String, s_str), new_alloc + 1, sizeof(char)); if unlikely(!new_string) goto err; } @@ -4190,12 +4187,12 @@ Dee_unicode_printer_repeatascii(struct unicode_printer *__restrict self, self->up_flags |= STRING_WIDTH_1BYTE; #endif /* STRING_WIDTH_1BYTE != 0 */ #endif /* CONFIG_UNICODE_PRINTER_LAZY_PREALLOCATION */ - base_string = (String *)DeeObject_TryMalloc(offsetof(String, s_str) + - (initial_alloc + 1) * sizeof(char)); + base_string = (String *)DeeObject_TryMallocc(offsetof(String, s_str), + initial_alloc + 1, sizeof(char)); if unlikely(!base_string) { initial_alloc = num_chars; - base_string = (String *)DeeObject_Malloc(offsetof(String, s_str) + - (initial_alloc + 1) * sizeof(char)); + base_string = (String *)DeeObject_Mallocc(offsetof(String, s_str), + initial_alloc + 1, sizeof(char)); if unlikely(!base_string) goto err; } @@ -4218,14 +4215,12 @@ Dee_unicode_printer_repeatascii(struct unicode_printer *__restrict self, do { new_alloc *= 2; } while (new_alloc < self->up_length + num_chars); - new_string = (String *)DeeObject_TryRealloc(COMPILER_CONTAINER_OF((char *)string, String, s_str), - offsetof(String, s_str) + - (new_alloc + 1) * sizeof(char)); + new_string = (String *)DeeObject_TryReallocc(COMPILER_CONTAINER_OF((char *)string, String, s_str), + offsetof(String, s_str), new_alloc + 1, sizeof(char)); if unlikely(!new_string) { new_alloc = self->up_length + num_chars; - new_string = (String *)DeeObject_Realloc(COMPILER_CONTAINER_OF((char *)string, String, s_str), - offsetof(String, s_str) + - (new_alloc + 1) * sizeof(char)); + new_string = (String *)DeeObject_Reallocc(COMPILER_CONTAINER_OF((char *)string, String, s_str), + offsetof(String, s_str), new_alloc + 1, sizeof(char)); if unlikely(!new_string) goto err; } @@ -4686,12 +4681,12 @@ Dee_unicode_printer_reserve(struct unicode_printer *__restrict self, self->up_flags |= STRING_WIDTH_1BYTE; #endif /* STRING_WIDTH_1BYTE != 0 */ #endif /* CONFIG_UNICODE_PRINTER_LAZY_PREALLOCATION */ - init_buffer = (String *)DeeObject_TryMalloc(offsetof(String, s_str) + - (initial_alloc + 1) * sizeof(char)); + init_buffer = (String *)DeeObject_TryMallocc(offsetof(String, s_str), + initial_alloc + 1, sizeof(char)); if unlikely(!init_buffer) { initial_alloc = num_chars; - init_buffer = (String *)DeeObject_Malloc(offsetof(String, s_str) + - (initial_alloc + 1) * sizeof(char)); + init_buffer = (String *)DeeObject_Mallocc(offsetof(String, s_str), + initial_alloc + 1, sizeof(char)); if unlikely(!init_buffer) goto err; } @@ -4832,12 +4827,12 @@ Dee_unicode_printer_tryalloc_utf8(struct unicode_printer *__restrict self, self->up_flags |= STRING_WIDTH_1BYTE; #endif /* STRING_WIDTH_1BYTE != 0 */ #endif /* CONFIG_UNICODE_PRINTER_LAZY_PREALLOCATION */ - base_string = (String *)DeeObject_TryMalloc(offsetof(String, s_str) + - (initial_alloc + 1) * sizeof(char)); + base_string = (String *)DeeObject_TryMallocc(offsetof(String, s_str), + initial_alloc + 1, sizeof(char)); if unlikely(!base_string) { initial_alloc = length; - base_string = (String *)DeeObject_TryMalloc(offsetof(String, s_str) + - (initial_alloc + 1) * sizeof(char)); + base_string = (String *)DeeObject_Mallocc(offsetof(String, s_str), + initial_alloc + 1, sizeof(char)); if unlikely(!base_string) goto err; } @@ -4864,14 +4859,12 @@ Dee_unicode_printer_tryalloc_utf8(struct unicode_printer *__restrict self, do { new_alloc *= 2; } while (new_alloc < self->up_length + length); - new_string = (String *)DeeObject_TryRealloc(COMPILER_CONTAINER_OF((char *)string, String, s_str), - offsetof(String, s_str) + - (new_alloc + 1) * sizeof(char)); + new_string = (String *)DeeObject_TryReallocc(COMPILER_CONTAINER_OF((char *)string, String, s_str), + offsetof(String, s_str), new_alloc + 1, sizeof(char)); if unlikely(!new_string) { new_alloc = self->up_length + length; - new_string = (String *)DeeObject_TryRealloc(COMPILER_CONTAINER_OF((char *)string, String, s_str), - offsetof(String, s_str) + - (new_alloc + 1) * sizeof(char)); + new_string = (String *)DeeObject_TryReallocc(COMPILER_CONTAINER_OF((char *)string, String, s_str), + offsetof(String, s_str), new_alloc + 1, sizeof(char)); if unlikely(!new_string) goto err; } diff --git a/src/deemon/runtime/gc.c b/src/deemon/runtime/gc.c index cae14cd6..ebbfd7c8 100644 --- a/src/deemon/runtime/gc.c +++ b/src/deemon/runtime/gc.c @@ -38,6 +38,8 @@ #include #include +#include + #ifndef CONFIG_NO_DEX #include #endif /* !CONFIG_NO_DEX */ @@ -1271,48 +1273,64 @@ LOCAL void *gc_initob(void *ptr) { * includes some storage at negative offsets to hold a `struct gc_head', * as is required for objects that should later be tracked by the GC. */ PUBLIC ATTR_MALLOC WUNUSED void *(DCALL DeeGCObject_Malloc)(size_t n_bytes) { - return gc_initob((DeeObject_Malloc)(DEE_GC_HEAD_SIZE + n_bytes)); + size_t whole_size; + if unlikely(OVERFLOW_UADD(DEE_GC_HEAD_SIZE, n_bytes, &whole_size)) + whole_size = (size_t)-1; + return gc_initob((DeeObject_Malloc)(whole_size)); } PUBLIC ATTR_MALLOC WUNUSED void *(DCALL DeeGCObject_Calloc)(size_t n_bytes) { - return gc_initob((DeeObject_Calloc)(DEE_GC_HEAD_SIZE + n_bytes)); + size_t whole_size; + if unlikely(OVERFLOW_UADD(DEE_GC_HEAD_SIZE, n_bytes, &whole_size)) + whole_size = (size_t)-1; + return gc_initob((DeeObject_Calloc)(whole_size)); } PUBLIC WUNUSED void *(DCALL DeeGCObject_Realloc)(void *p, size_t n_bytes) { + size_t whole_size; + if unlikely(OVERFLOW_UADD(DEE_GC_HEAD_SIZE, n_bytes, &whole_size)) + whole_size = (size_t)-1; if (p) { #ifdef GCHEAD_ISTRACKED ASSERTF(!GCHEAD_ISTRACKED(DeeGC_Head((DeeObject *)p)), "Object at %p was still being tracked", p); #endif /* GCHEAD_ISTRACKED */ - p = (DeeObject_Realloc)(DeeGC_Head((DeeObject *)p), - DEE_GC_HEAD_SIZE + n_bytes); + p = (DeeObject_Realloc)(DeeGC_Head((DeeObject *)p), whole_size); } else { - p = (DeeObject_Malloc)(DEE_GC_HEAD_SIZE + n_bytes); + p = (DeeObject_Malloc)(whole_size); } return gc_initob(p); } PUBLIC ATTR_MALLOC WUNUSED void * (DCALL DeeGCObject_TryMalloc)(size_t n_bytes) { - return gc_initob((DeeObject_TryMalloc)(DEE_GC_HEAD_SIZE + n_bytes)); + size_t whole_size; + if unlikely(OVERFLOW_UADD(DEE_GC_HEAD_SIZE, n_bytes, &whole_size)) + whole_size = (size_t)-1; + return gc_initob((DeeObject_TryMalloc)(whole_size)); } PUBLIC ATTR_MALLOC WUNUSED void * (DCALL DeeGCObject_TryCalloc)(size_t n_bytes) { - return gc_initob((DeeObject_TryCalloc)(DEE_GC_HEAD_SIZE + n_bytes)); + size_t whole_size; + if unlikely(OVERFLOW_UADD(DEE_GC_HEAD_SIZE, n_bytes, &whole_size)) + whole_size = (size_t)-1; + return gc_initob((DeeObject_TryCalloc)(whole_size)); } PUBLIC WUNUSED void * (DCALL DeeGCObject_TryRealloc)(void *p, size_t n_bytes) { + size_t whole_size; + if unlikely(OVERFLOW_UADD(DEE_GC_HEAD_SIZE, n_bytes, &whole_size)) + whole_size = (size_t)-1; if (p) { #ifdef GCHEAD_ISTRACKED ASSERTF(!GCHEAD_ISTRACKED(DeeGC_Head((DeeObject *)p)), "Object at %p was still being tracked", p); #endif /* GCHEAD_ISTRACKED */ - p = (DeeObject_TryRealloc)(DeeGC_Head((DeeObject *)p), - DEE_GC_HEAD_SIZE + n_bytes); + p = (DeeObject_TryRealloc)(DeeGC_Head((DeeObject *)p), whole_size); } else { - p = (DeeObject_TryMalloc)(DEE_GC_HEAD_SIZE + n_bytes); + p = (DeeObject_TryMalloc)(whole_size); } return gc_initob(p); } @@ -1335,16 +1353,25 @@ PUBLIC void DFUNDEF ATTR_MALLOC WUNUSED void * (DCALL DeeDbgGCObject_Malloc)(size_t n_bytes, char const *file, int line) { - return gc_initob((DeeDbgObject_Malloc)(DEE_GC_HEAD_SIZE + n_bytes, file, line)); + size_t whole_size; + if unlikely(OVERFLOW_UADD(DEE_GC_HEAD_SIZE, n_bytes, &whole_size)) + whole_size = (size_t)-1; + return gc_initob((DeeDbgObject_Malloc)(whole_size, file, line)); } DFUNDEF ATTR_MALLOC WUNUSED void * (DCALL DeeDbgGCObject_Calloc)(size_t n_bytes, char const *file, int line) { - return gc_initob((DeeDbgObject_Calloc)(DEE_GC_HEAD_SIZE + n_bytes, file, line)); + size_t whole_size; + if unlikely(OVERFLOW_UADD(DEE_GC_HEAD_SIZE, n_bytes, &whole_size)) + whole_size = (size_t)-1; + return gc_initob((DeeDbgObject_Calloc)(whole_size, file, line)); } DFUNDEF WUNUSED void * (DCALL DeeDbgGCObject_Realloc)(void *p, size_t n_bytes, char const *file, int line) { + size_t whole_size; + if unlikely(OVERFLOW_UADD(DEE_GC_HEAD_SIZE, n_bytes, &whole_size)) + whole_size = (size_t)-1; if (p) { #if defined(GCHEAD_ISTRACKED) && !defined(NDEBUG) if (GCHEAD_ISTRACKED(DeeGC_Head((DeeObject *)p))) { @@ -1352,27 +1379,34 @@ DFUNDEF WUNUSED void * "Object at %p was still being tracked", p); } #endif /* GCHEAD_ISTRACKED && !NDEBUG */ - p = (DeeDbgObject_Realloc)(DeeGC_Head((DeeObject *)p), - DEE_GC_HEAD_SIZE + n_bytes, - file, line); + p = (DeeDbgObject_Realloc)(DeeGC_Head((DeeObject *)p), whole_size, file, line); } else { - p = (DeeDbgObject_Malloc)(DEE_GC_HEAD_SIZE + n_bytes, file, line); + p = (DeeDbgObject_Malloc)(whole_size, file, line); } return gc_initob(p); } DFUNDEF ATTR_MALLOC WUNUSED void * (DCALL DeeDbgGCObject_TryMalloc)(size_t n_bytes, char const *file, int line) { - return gc_initob((DeeDbgObject_TryMalloc)(DEE_GC_HEAD_SIZE + n_bytes, file, line)); + size_t whole_size; + if unlikely(OVERFLOW_UADD(DEE_GC_HEAD_SIZE, n_bytes, &whole_size)) + whole_size = (size_t)-1; + return gc_initob((DeeDbgObject_TryMalloc)(whole_size, file, line)); } DFUNDEF ATTR_MALLOC WUNUSED void * (DCALL DeeDbgGCObject_TryCalloc)(size_t n_bytes, char const *file, int line) { - return gc_initob((DeeDbgObject_TryCalloc)(DEE_GC_HEAD_SIZE + n_bytes, file, line)); + size_t whole_size; + if unlikely(OVERFLOW_UADD(DEE_GC_HEAD_SIZE, n_bytes, &whole_size)) + whole_size = (size_t)-1; + return gc_initob((DeeDbgObject_TryCalloc)(whole_size, file, line)); } DFUNDEF WUNUSED void * (DCALL DeeDbgGCObject_TryRealloc)(void *p, size_t n_bytes, char const *file, int line) { + size_t whole_size; + if unlikely(OVERFLOW_UADD(DEE_GC_HEAD_SIZE, n_bytes, &whole_size)) + whole_size = (size_t)-1; if (p) { #if defined(GCHEAD_ISTRACKED) && !defined(NDEBUG) if (GCHEAD_ISTRACKED(DeeGC_Head((DeeObject *)p))) { @@ -1380,11 +1414,9 @@ DFUNDEF WUNUSED void * "Object at %p was still being tracked", p); } #endif /* GCHEAD_ISTRACKED && !NDEBUG */ - p = (DeeDbgObject_TryRealloc)(DeeGC_Head((DeeObject *)p), - DEE_GC_HEAD_SIZE + n_bytes, - file, line); + p = (DeeDbgObject_TryRealloc)(DeeGC_Head((DeeObject *)p), whole_size, file, line); } else { - p = (DeeDbgObject_TryMalloc)(DEE_GC_HEAD_SIZE + n_bytes, file, line); + p = (DeeDbgObject_TryMalloc)(whole_size, file, line); } return gc_initob(p); } diff --git a/src/deemon/runtime/kwds-wrappers.c b/src/deemon/runtime/kwds-wrappers.c index c7e6e35e..182b8b56 100644 --- a/src/deemon/runtime/kwds-wrappers.c +++ b/src/deemon/runtime/kwds-wrappers.c @@ -897,8 +897,9 @@ blv_copy(DeeBlackListKwdsObject *__restrict self) { size_t count = self->blkd_kwds->kw_size; size_t sizeof_blkd_blck = ((self->blkd_mask + 1) * sizeof(DeeBlackListKwdsEntry)); DREF DeeBlackListKwdsObject *result; - result = (DREF DeeBlackListKwdsObject *)DeeObject_Malloc(offsetof(DeeBlackListKwdsObject, blkd_blck) + - sizeof_blkd_blck + (count * sizeof(DREF DeeObject *))); + result = (DREF DeeBlackListKwdsObject *)DeeObject_Mallocc(offsetof(DeeBlackListKwdsObject, blkd_blck) + + sizeof_blkd_blck, + count, sizeof(DREF DeeObject *)); if unlikely(!result) goto done; result->blkd_argv = (DREF DeeObject **)((byte_t *)result->blkd_blck + sizeof_blkd_blck); @@ -928,8 +929,9 @@ blv_deep(DeeBlackListKwdsObject *__restrict self) { size_t count = self->blkd_kwds->kw_size; size_t sizeof_blkd_blck = ((self->blkd_mask + 1) * sizeof(DeeBlackListKwdsEntry)); DREF DeeBlackListKwdsObject *result; - result = (DREF DeeBlackListKwdsObject *)DeeObject_Malloc(offsetof(DeeBlackListKwdsObject, blkd_blck) + - sizeof_blkd_blck + (count * sizeof(DREF DeeObject *))); + result = (DREF DeeBlackListKwdsObject *)DeeObject_Mallocc(offsetof(DeeBlackListKwdsObject, blkd_blck) + + sizeof_blkd_blck, + count, sizeof(DREF DeeObject *)); if unlikely(!result) goto done; result->blkd_argv = (DREF DeeObject **)((byte_t *)result->blkd_blck + sizeof_blkd_blck); @@ -1050,9 +1052,9 @@ DeeBlackListKwds_New(struct code_object *__restrict code, /* Calculate an appropriate mask for the blacklist hash-set. */ for (mask = 3; mask <= argc; mask = (mask << 1) | 1) ; - result = (DREF DeeBlackListKwdsObject *)DeeObject_Calloc(offsetof(DeeBlackListKwdsObject, blkd_blck) + - ((mask + 1) * sizeof(DeeBlackListKwdsEntry)) + - (kwds->kw_size * sizeof(DREF DeeObject *))); + result = (DREF DeeBlackListKwdsObject *)DeeObject_Callocc(offsetof(DeeBlackListKwdsObject, blkd_blck) + + ((mask + 1) * sizeof(DeeBlackListKwdsEntry)), + kwds->kw_size, sizeof(DREF DeeObject *)); if unlikely(!result) goto done; Dee_atomic_rwlock_cinit(&result->blkd_lock); @@ -1873,9 +1875,8 @@ blkw_copy(DeeBlackListKwObject *__restrict self) { return_reference_(self); } - result = (DREF DeeBlackListKwObject *)DeeObject_Malloc(offsetof(DeeBlackListKwObject, blkw_blck) + - (self->blkw_mask + 1) * - sizeof(DeeBlackListKwdsEntry)); + result = (DREF DeeBlackListKwObject *)DeeObject_Mallocc(offsetof(DeeBlackListKwObject, blkw_blck), + self->blkw_mask + 1, sizeof(DeeBlackListKwdsEntry)); if unlikely(!result) goto err_result_kw; result->blkw_kw = result_kw; /* Inherit reference */ @@ -1903,9 +1904,8 @@ blkw_copy(DeeBlackListKwObject *__restrict self) { PRIVATE WUNUSED NONNULL((1)) DREF DeeBlackListKwObject *DCALL blkw_deep(DeeBlackListKwObject *__restrict self) { DREF DeeBlackListKwObject *result; - result = (DREF DeeBlackListKwObject *)DeeObject_Malloc(offsetof(DeeBlackListKwObject, blkw_blck) + - (self->blkw_mask + 1) * - sizeof(DeeBlackListKwdsEntry)); + result = (DREF DeeBlackListKwObject *)DeeObject_Mallocc(offsetof(DeeBlackListKwObject, blkw_blck), + self->blkw_mask + 1, sizeof(DeeBlackListKwdsEntry)); if unlikely(!result) goto done; result->blkw_kw = DeeObject_DeepCopy(self->blkw_kw); @@ -1945,9 +1945,8 @@ blkw_get_frozen(DeeBlackListKwObject *__restrict self) { return_reference_(self); } - result = (DREF DeeBlackListKwObject *)DeeObject_Malloc(offsetof(DeeBlackListKwObject, blkw_blck) + - (self->blkw_mask + 1) * - sizeof(DeeBlackListKwdsEntry)); + result = (DREF DeeBlackListKwObject *)DeeObject_Mallocc(offsetof(DeeBlackListKwObject, blkw_blck), + self->blkw_mask + 1, sizeof(DeeBlackListKwdsEntry)); if unlikely(!result) goto err_frozen_kw; @@ -2070,8 +2069,8 @@ DeeBlackListKw_New(struct code_object *__restrict code, /* Calculate an appropriate mask for the blacklist hash-set. */ for (mask = 3; mask <= argc; mask = (mask << 1) | 1) ; - result = (DREF DeeBlackListKwObject *)DeeObject_Calloc(offsetof(DeeBlackListKwObject, blkw_blck) + - (mask + 1) * sizeof(DeeBlackListKwdsEntry)); + result = (DREF DeeBlackListKwObject *)DeeObject_Callocc(offsetof(DeeBlackListKwObject, blkw_blck), + mask + 1, sizeof(DeeBlackListKwdsEntry)); if unlikely(!result) goto done; Dee_atomic_rwlock_cinit(&result->blkw_lock); diff --git a/src/deemon/runtime/kwds.c b/src/deemon/runtime/kwds.c index 455feaa8..3b1a7303 100644 --- a/src/deemon/runtime/kwds.c +++ b/src/deemon/runtime/kwds.c @@ -279,8 +279,9 @@ DeeKwds_NewWithHint(size_t num_items) { size_t init_mask = 1; while (init_mask <= num_items) init_mask = (init_mask << 1) | 1; - result = (DREF Kwds *)DeeObject_Calloc(offsetof(Kwds, kw_map) + - (init_mask + 1) * sizeof(struct kwds_entry)); + result = (DREF Kwds *)DeeObject_Callocc(offsetof(Kwds, kw_map), + init_mask + 1, + sizeof(struct kwds_entry)); if unlikely(!result) goto done; result->kw_mask = init_mask; @@ -294,8 +295,9 @@ kwds_rehash(DREF Kwds *__restrict self) { DREF Kwds *result; size_t i, j, perturb; size_t new_mask = (self->kw_mask << 1) | 1; - result = (DREF Kwds *)DeeObject_Calloc(offsetof(Kwds, kw_map) + - (new_mask + 1) * sizeof(struct kwds_entry)); + result = (DREF Kwds *)DeeObject_Callocc(offsetof(Kwds, kw_map), + new_mask + 1, + sizeof(struct kwds_entry)); if unlikely(!result) goto done; result->kw_mask = new_mask; @@ -409,8 +411,8 @@ DeeKwds_GetByIndex(DeeObject *__restrict self, size_t keyword_index) { PRIVATE WUNUSED DREF Kwds *DCALL kwds_ctor(void) { DREF Kwds *result; - result = (DREF Kwds *)DeeObject_Malloc(offsetof(Kwds, kw_map) + - (2 * sizeof(struct kwds_entry))); + result = (DREF Kwds *)DeeObject_Mallocc(offsetof(Kwds, kw_map), + 2, sizeof(struct kwds_entry)); if unlikely(!result) goto done; result->kw_map[0].ke_name = NULL; @@ -1083,8 +1085,8 @@ kmap_copy(KwdsMapping *__restrict self) { DREF KwdsMapping *result; size_t argc; argc = DeeKwds_SIZE(self->kmo_kwds); - result = (DREF KwdsMapping *)DeeObject_Malloc(offsetof(KwdsMapping, kmo_args) + - (argc * sizeof(DREF DeeObject *))); + result = (DREF KwdsMapping *)DeeObject_Mallocc(offsetof(KwdsMapping, kmo_args), + argc, sizeof(DREF DeeObject *)); if unlikely(!result) goto done; DeeKwdsMapping_LockRead(self); @@ -1104,8 +1106,8 @@ kmap_deep(KwdsMapping *__restrict self) { DREF KwdsMapping *result; size_t argc; argc = DeeKwds_SIZE(self->kmo_kwds); - result = (DREF KwdsMapping *)DeeObject_Malloc(offsetof(KwdsMapping, kmo_args) + - (argc * sizeof(DREF DeeObject *))); + result = (DREF KwdsMapping *)DeeObject_Mallocc(offsetof(KwdsMapping, kmo_args), + argc, sizeof(DREF DeeObject *)); if unlikely(!result) goto done; DeeKwdsMapping_LockRead(self); @@ -1144,8 +1146,8 @@ kmap_init(size_t argc, DeeObject *const *argv) { err_keywords_bad_for_argc(DeeTuple_SIZE(args), kw_argc); goto err; } - result = (DREF KwdsMapping *)DeeObject_Malloc(offsetof(KwdsMapping, kmo_args) + - (kw_argc * sizeof(DREF DeeObject *))); + result = (DREF KwdsMapping *)DeeObject_Mallocc(offsetof(KwdsMapping, kmo_args), + kw_argc, sizeof(DREF DeeObject *)); if unlikely(!result) goto err; result->kmo_argv = Dee_Movrefv(result->kmo_args, DeeTuple_ELEM(args), kw_argc); @@ -1606,8 +1608,8 @@ DeeKwdsMapping_New(/*Kwds*/ DeeObject *kwds, size_t argc; ASSERT_OBJECT_TYPE_EXACT(kwds, &DeeKwds_Type); argc = DeeKwds_SIZE(kwds); - result = (DREF KwdsMapping *)DeeObject_Malloc(offsetof(KwdsMapping, kmo_args) + - (argc * sizeof(DREF DeeObject *))); + result = (DREF KwdsMapping *)DeeObject_Mallocc(offsetof(KwdsMapping, kmo_args), + argc, sizeof(DREF DeeObject *)); if unlikely(!result) goto done; Dee_atomic_rwlock_init(&result->kmo_lock); diff --git a/src/deemon/runtime/misc.c b/src/deemon/runtime/misc.c index 5ab7c82c..443c2edb 100644 --- a/src/deemon/runtime/misc.c +++ b/src/deemon/runtime/misc.c @@ -2154,6 +2154,68 @@ PUBLIC ATTR_NORETURN void _DeeAssert_XFailf(expr, file, line, NULL); } +#if __SIZEOF_SIZE_T__ == 4 +#define PRFxSIZ_FULLWIDTH ".8" PRFxSIZ +#elif __SIZEOF_SIZE_T__ == 8 +#define PRFxSIZ_FULLWIDTH ".16" PRFxSIZ +#elif __SIZEOF_SIZE_T__ == 2 +#define PRFxSIZ_FULLWIDTH ".4" PRFxSIZ +#elif __SIZEOF_SIZE_T__ == 1 +#define PRFxSIZ_FULLWIDTH ".2" PRFxSIZ +#else /* __SIZEOF_SIZE_T__ == ... */ +#define PRFxSIZ_FULLWIDTH PRFxSIZ +#endif /* __SIZEOF_SIZE_T__ != ... */ + +/* Debug version of malloc buffer size calculation functions. + * These will trigger an assertion failure when an overflow *does* happen. + * As such, these functions should be used in debug builds to assert that + * no unexpected overflows happen. */ +PUBLIC ATTR_CONST WUNUSED size_t +(DCALL _Dee_MalloccBufsizeDbg)(size_t elem_count, size_t elem_size, + char const *file, int line) { + size_t result; + if (OVERFLOW_UMUL(elem_count, elem_size, &result)) { + _DeeAssert_Failf("_Dee_MalloccBufsizeDbg(...)", file, line, + "Unexpected overflow when multiplying elem_count * elem_size:\n" + "elem_count = %#" PRFxSIZ_FULLWIDTH " (%" PRFuSIZ ")\n" + "elem_size = %#" PRFxSIZ_FULLWIDTH " (%" PRFuSIZ ")", + elem_count, elem_count, + elem_size, elem_size); + return (size_t)-1; + } + return result; +} + +PUBLIC ATTR_CONST WUNUSED size_t +(DCALL _Dee_MallococBufsizeDbg)(size_t base_offset, size_t elem_count, size_t elem_size, + char const *file, int line) { + size_t result; + if (OVERFLOW_UMUL(elem_count, elem_size, &result)) { + _DeeAssert_Failf("_Dee_MallococBufsizeDbg(...)", file, line, + "Unexpected overflow when multiplying `elem_count * elem_size':\n" + "elem_count = %#" PRFxSIZ_FULLWIDTH " (%" PRFuSIZ ")\n" + "elem_size = %#" PRFxSIZ_FULLWIDTH " (%" PRFuSIZ ")\n" + "[base_offset = %#" PRFxSIZ_FULLWIDTH " (%" PRFuSIZ ")]", + elem_count, elem_count, + elem_size, elem_size, + base_offset, base_offset); + return (size_t)-1; + } + if (OVERFLOW_UADD(result, base_offset, &result)) { + _DeeAssert_Failf("_Dee_MallococBufsizeDbg(...)", file, line, + "Unexpected overflow when adding `base_offset' to `elem_count * elem_size':\n" + "base_offset = %#" PRFxSIZ_FULLWIDTH " (%" PRFuSIZ ")\n" + "elem_count * elem_size = %#" PRFxSIZ_FULLWIDTH " (%" PRFuSIZ ")\n" + "[elem_count = %#" PRFxSIZ_FULLWIDTH " (%" PRFuSIZ ")]\n" + "[elem_size = %#" PRFxSIZ_FULLWIDTH " (%" PRFuSIZ ")]", + base_offset, base_offset, result, result, + elem_count, elem_count, + elem_size, elem_size); + return (size_t)-1; + } + return result; +} + DECL_END diff --git a/src/deemon/runtime/mro.c b/src/deemon/runtime/mro.c index 2ce2bd30..45830dde 100644 --- a/src/deemon/runtime/mro.c +++ b/src/deemon/runtime/mro.c @@ -151,9 +151,9 @@ Dee_membercache_clearall(size_t max_clear) { /* Try to allocate a new member-cache table. */ -#define Dee_membercache_table_trycalloc(mask) \ - (struct Dee_membercache_table *)Dee_TryCalloc(offsetof(struct Dee_membercache_table, mc_table) + \ - ((mask) + 1) * sizeof(struct Dee_membercache_slot)) +#define Dee_membercache_table_trycalloc(mask) \ + (struct Dee_membercache_table *)Dee_TryCallococ(offsetof(struct Dee_membercache_table, mc_table), \ + (mask) + 1, sizeof(struct Dee_membercache_slot)) STATIC_ASSERT(MEMBERCACHE_UNUSED == 0); PRIVATE NONNULL((1, 2)) void DCALL diff --git a/src/deemon/runtime/operator.c b/src/deemon/runtime/operator.c index 8f174dc5..7d1d8a80 100644 --- a/src/deemon/runtime/operator.c +++ b/src/deemon/runtime/operator.c @@ -15187,21 +15187,21 @@ seq_featureset_init(seq_featureset_t self, struct type_seq *__restrict seq, unsi seq_featureset_set(self, FEAT_tp_delitem_string_hash); if (seq->tp_setitem_string_hash && !DeeType_IsDefaultSetItemStringHash(seq->tp_setitem_string_hash)) seq_featureset_set(self, FEAT_tp_setitem_string_hash); - if (Dee_type_seq_has_custom_tp_bounditem_string_hash(seq) && seq->tp_bounditem_string_hash && !DeeType_IsDefaultBoundItemStringHash(seq->tp_bounditem_string_hash)) + if (Dee_type_seq_has_custom_tp_bounditem_string_hash(seq)) seq_featureset_set(self, FEAT_tp_bounditem_string_hash); - if (Dee_type_seq_has_custom_tp_hasitem_string_hash(seq) && seq->tp_hasitem_string_hash && !DeeType_IsDefaultHasItemStringHash(seq->tp_hasitem_string_hash)) + if (Dee_type_seq_has_custom_tp_hasitem_string_hash(seq)) seq_featureset_set(self, FEAT_tp_hasitem_string_hash); - if (Dee_type_seq_has_custom_tp_trygetitem_string_len_hash(seq) && seq->tp_trygetitem_string_len_hash && !DeeType_IsDefaultTryGetItemStringLenHash(seq->tp_trygetitem_string_len_hash)) + if (Dee_type_seq_has_custom_tp_trygetitem_string_len_hash(seq)) seq_featureset_set(self, FEAT_tp_trygetitem_string_len_hash); - if (Dee_type_seq_has_custom_tp_getitem_string_len_hash(seq) && seq->tp_getitem_string_len_hash && !DeeType_IsDefaultGetItemStringLenHash(seq->tp_getitem_string_len_hash)) + if (Dee_type_seq_has_custom_tp_getitem_string_len_hash(seq)) seq_featureset_set(self, FEAT_tp_getitem_string_len_hash); - if (Dee_type_seq_has_custom_tp_delitem_string_len_hash(seq) && seq->tp_delitem_string_len_hash && !DeeType_IsDefaultDelItemStringLenHash(seq->tp_delitem_string_len_hash)) + if (Dee_type_seq_has_custom_tp_delitem_string_len_hash(seq)) seq_featureset_set(self, FEAT_tp_delitem_string_len_hash); - if (Dee_type_seq_has_custom_tp_setitem_string_len_hash(seq) && seq->tp_setitem_string_len_hash && !DeeType_IsDefaultSetItemStringLenHash(seq->tp_setitem_string_len_hash)) + if (Dee_type_seq_has_custom_tp_setitem_string_len_hash(seq)) seq_featureset_set(self, FEAT_tp_setitem_string_len_hash); - if (Dee_type_seq_has_custom_tp_bounditem_string_len_hash(seq) && seq->tp_bounditem_string_len_hash && !DeeType_IsDefaultBoundItemStringLenHash(seq->tp_bounditem_string_len_hash)) + if (Dee_type_seq_has_custom_tp_bounditem_string_len_hash(seq)) seq_featureset_set(self, FEAT_tp_bounditem_string_len_hash); - if (Dee_type_seq_has_custom_tp_hasitem_string_len_hash(seq) && seq->tp_hasitem_string_len_hash && !DeeType_IsDefaultHasItemStringLenHash(seq->tp_hasitem_string_len_hash)) + if (Dee_type_seq_has_custom_tp_hasitem_string_len_hash(seq)) seq_featureset_set(self, FEAT_tp_hasitem_string_len_hash); } diff --git a/src/deemon/runtime/thread.c b/src/deemon/runtime/thread.c index b3d80134..4b376838 100644 --- a/src/deemon/runtime/thread.c +++ b/src/deemon/runtime/thread.c @@ -5128,8 +5128,8 @@ DeeThread_Trace(/*Thread*/ DeeObject *__restrict self) { DeeTracebackObject *result; struct localheap heap; traceback_size = atomic_read(&me->t_execsz); - result = (DeeTracebackObject *)DeeGCObject_Malloc(offsetof(DeeTracebackObject, tb_frames) + - traceback_size * sizeof(struct code_frame)); + result = (DeeTracebackObject *)DeeGCObject_Mallocc(offsetof(DeeTracebackObject, tb_frames), + traceback_size, sizeof(struct code_frame)); if unlikely(!result) goto err; @@ -5170,8 +5170,8 @@ DeeThread_Trace(/*Thread*/ DeeObject *__restrict self) { COMPILER_BARRIER(); traceback_size = traceback_used; - new_result = (DeeTracebackObject *)DeeGCObject_Realloc(result, offsetof(DeeTracebackObject, tb_frames) + - traceback_size * sizeof(struct code_frame)); + new_result = (DeeTracebackObject *)DeeGCObject_Reallocc(result, offsetof(DeeTracebackObject, tb_frames), + traceback_size, sizeof(struct code_frame)); if unlikely(!new_result) goto err_free_result; result = new_result; @@ -5218,9 +5218,8 @@ DeeThread_Trace(/*Thread*/ DeeObject *__restrict self) { done_traceback_with_heap: if (traceback_size != traceback_used) { DeeTracebackObject *new_result; - new_result = (DeeTracebackObject *)DeeGCObject_TryRealloc(result, - offsetof(DeeTracebackObject, tb_frames) + - traceback_used * sizeof(struct code_frame)); + new_result = (DeeTracebackObject *)DeeGCObject_TryReallocc(result, offsetof(DeeTracebackObject, tb_frames), + traceback_used, sizeof(struct code_frame)); if likely(new_result) result = new_result; } diff --git a/src/dex/_hostasm/assembler.c b/src/dex/_hostasm/assembler.c index fc9b44d6..5a2796ec 100644 --- a/src/dex/_hostasm/assembler.c +++ b/src/dex/_hostasm/assembler.c @@ -856,7 +856,7 @@ fg_gretNULL(struct fungen *__restrict self) { PRIVATE WUNUSED NONNULL((1)) int DCALL function_assembler_compileexcept(struct function_assembler *__restrict self) { - void *_memstatebuf[memstate_sizeof(1) / sizeof(void *)]; + void *_memstatebuf[memstate_sizeof_constexpr(1) / sizeof(void *)]; void *_exitidbuf[offsetof(struct except_exitinfo_id, exi_memrefv) / sizeof(void *)]; struct memstate *state = (struct memstate *)_memstatebuf; struct except_exitinfo_id *exit_id = (struct except_exitinfo_id *)_exitidbuf; diff --git a/src/dex/_hostasm/common.c b/src/dex/_hostasm/common.c index 5f210eb5..4aff4e4d 100644 --- a/src/dex/_hostasm/common.c +++ b/src/dex/_hostasm/common.c @@ -817,8 +817,8 @@ memobj_reqxinfo(struct memobj *__restrict self) { INTERN WUNUSED NONNULL((1)) struct memobjs *DCALL memobjs_new(size_t objc) { struct memobjs *result; - size_t size = offsetof(struct memobjs, mos_objv) + (objc * sizeof(struct memobj)); - result = (struct memobjs *)Dee_Malloc(size); + result = (struct memobjs *)Dee_Mallococ(offsetof(struct memobjs, mos_objv), + objc, sizeof(struct memobj)); if likely(result) { result->mos_refcnt = 1; RINGQ_INIT(result, mos_copies); diff --git a/src/dex/_hostasm/generator-deemon.c b/src/dex/_hostasm/generator-deemon.c index ee1b6645..f2f03dc5 100644 --- a/src/dex/_hostasm/generator-deemon.c +++ b/src/dex/_hostasm/generator-deemon.c @@ -25,6 +25,7 @@ /**/ #ifdef CONFIG_HAVE_LIBHOSTASM +#include #include #include #include @@ -1472,8 +1473,9 @@ fg_geninstr(struct fungen *__restrict self, goto err; } calloc_used = false; - sizeof_function = offsetof(DeeFunctionObject, fo_refv) + - ((size_t)code->co_refstaticc * sizeof(DREF DeeObject *)); + sizeof_function = _Dee_MallococBufsize(offsetof(DeeFunctionObject, fo_refv), + (size_t)code->co_refstaticc, + sizeof(DREF DeeObject *)); ASSERT(code->co_refstaticc >= refc); if likely(code->co_refstaticc <= refc) { DO(fg_vcall_DeeGCObject_Malloc(self, sizeof_function, false)); /* [refs...], ref:function */ @@ -1526,8 +1528,8 @@ fg_geninstr(struct fungen *__restrict self, DO(fg_vswap(self)); /* [refs...], ref:function, ref */ DO(fg_vref2(self, (vstackaddr_t)(refc + 2))); /* [refs...], ref:function, ref:ref */ DO(fg_vpopind(self, /* [refs...], ref:function */ - offsetof(DeeFunctionObject, fo_refv) + - (refc * sizeof(DREF DeeObject *)))); + _Dee_MallococBufsize(offsetof(DeeFunctionObject, fo_refv), + refc, sizeof(DREF DeeObject *)))); } ASSERT(fg_vtop_direct_isref(self)); /* ref:function */ fg_vtop_direct_clearref(self); diff --git a/src/dex/_hostasm/generator-vstack-ex.c b/src/dex/_hostasm/generator-vstack-ex.c index 83ec5568..f4a14046 100644 --- a/src/dex/_hostasm/generator-vstack-ex.c +++ b/src/dex/_hostasm/generator-vstack-ex.c @@ -2695,9 +2695,9 @@ vopgetattr_constattr(struct fungen *__restrict self, DO(fg_vdelta(self, desc->cd_offset)); /* this, ref:result, DeeInstance_DESC(desc, this) */ DO(fg_vrwlock_read_field(self, offsetof(struct Dee_instance_desc, id_lock))); /* this, ref:result, DeeInstance_DESC(desc, this) */ DO(fg_vdup(self)); /* this, ref:result, DeeInstance_DESC(desc, this), DeeInstance_DESC(desc, this) */ - DO(fg_vind(self, offsetof(struct Dee_instance_desc, id_vtab) + - (item->ca_addr + Dee_CLASS_GETSET_GET) * - sizeof(DREF DeeObject *))); /* this, ref:result, DeeInstance_DESC(desc, this), GETTER */ + DO(fg_vind(self, _Dee_MallococBufsize(offsetof(struct Dee_instance_desc, id_vtab), + item->ca_addr + Dee_CLASS_GETSET_GET, + sizeof(DREF DeeObject *)))); /* this, ref:result, DeeInstance_DESC(desc, this), GETTER */ if (!(item->ca_flag & Dee_CLASS_ATTRIBUTE_FREADONLY)) { DO(fg_vdirect1(self)); /* this, ref:result, DeeInstance_DESC(desc, this), ref:GETTER */ DO(fg_gxincref_loc(self, fg_vtopdloc(self), 1)); /* this, ref:result, DeeInstance_DESC(desc, this), ref:GETTER */ @@ -2705,17 +2705,17 @@ vopgetattr_constattr(struct fungen *__restrict self, DO(fg_vswap(self)); /* this, ref:result, DeeInstance_DESC(desc, this), result, ref:GETTER */ DO(fg_vpopind(self, offsetof(DeePropertyObject, p_get))); /* this, ref:result, DeeInstance_DESC(desc, this), result */ DO(fg_vdup_at(self, 2)); /* this, ref:result, DeeInstance_DESC(desc, this), result, DeeInstance_DESC(desc, this) */ - DO(fg_vind(self, offsetof(struct Dee_instance_desc, id_vtab) + - (item->ca_addr + Dee_CLASS_GETSET_DEL) * - sizeof(DREF DeeObject *))); /* this, ref:result, DeeInstance_DESC(desc, this), result, DELETE */ + DO(fg_vind(self, _Dee_MallococBufsize(offsetof(struct Dee_instance_desc, id_vtab), + item->ca_addr + Dee_CLASS_GETSET_DEL, + sizeof(DREF DeeObject *)))); /* this, ref:result, DeeInstance_DESC(desc, this), result, DELETE */ DO(fg_vdirect1(self)); /* this, ref:result, DeeInstance_DESC(desc, this), result, ref:DELETE */ DO(fg_gxincref_loc(self, fg_vtopdloc(self), 1)); /* this, ref:result, DeeInstance_DESC(desc, this), result, ref:DELETE */ DO(fg_vpopind(self, offsetof(DeePropertyObject, p_del))); /* this, ref:result, DeeInstance_DESC(desc, this), result */ DO(fg_vpop(self)); /* this, ref:result, DeeInstance_DESC(desc, this) */ DO(fg_vdup(self)); /* this, ref:result, DeeInstance_DESC(desc, this), DeeInstance_DESC(desc, this) */ - DO(fg_vind(self, offsetof(struct Dee_instance_desc, id_vtab) + - (item->ca_addr + Dee_CLASS_GETSET_SET) * - sizeof(DREF DeeObject *))); /* this, ref:result, DeeInstance_DESC(desc, this), SETTER */ + DO(fg_vind(self, _Dee_MallococBufsize(offsetof(struct Dee_instance_desc, id_vtab), + item->ca_addr + Dee_CLASS_GETSET_SET, + sizeof(DREF DeeObject *)))); /* this, ref:result, DeeInstance_DESC(desc, this), SETTER */ } /* this, ref:result, DeeInstance_DESC(desc, this), GETTER_OR_SETTER */ DO(fg_vdirect1(self)); /* this, ref:result, DeeInstance_DESC(desc, this), GETTER_OR_SETTER */ DO(fg_gxincref_loc(self, fg_vtopdloc(self), 1)); /* this, ref:result, DeeInstance_DESC(desc, this), ref:GETTER_OR_SETTER */ @@ -6351,10 +6351,10 @@ fg_vopunpack(struct fungen *__restrict self, vstackaddr_t n) { DO(fg_vlrot(self, n_pushed + 1)); /* [items...], seq */ } /* [seq], [items...], seq */ DO(fg_vdup(self)); /* [seq], [items...], seq, seq */ - DO(fg_vind(self, offsetof(DeeTupleObject, t_elem) + - i * sizeof(DREF DeeObject *))); /* [seq], [items...], seq, elem */ - DO(fg_vdep(self)); /* [seq], [items...], seq, elem */ - DO(fg_vpop_at(self, 2)); /* [seq], [items...], elem */ + DO(fg_vind(self, _Dee_MallococBufsize(offsetof(DeeTupleObject, t_elem), + i, sizeof(DREF DeeObject *)))); /* [seq], [items...], seq, elem */ + DO(fg_vdep(self)); /* [seq], [items...], seq, elem */ + DO(fg_vpop_at(self, 2)); /* [seq], [items...], elem */ } if (n == 0) return fg_vpop(self); diff --git a/src/dex/_hostasm/generator-vstack.c b/src/dex/_hostasm/generator-vstack.c index 50dfc704..00696f08 100644 --- a/src/dex/_hostasm/generator-vstack.c +++ b/src/dex/_hostasm/generator-vstack.c @@ -219,8 +219,8 @@ fg_vpush_rid(struct fungen *__restrict self, uint16_t rid) { /* Special case: must access the "fo_refv" field of the runtime "func" parameter. */ DO(_fg_vpush_xlocal(self, NULL, MEMSTATE_XLOCAL_A_FUNC)); return fg_vind(self, - offsetof(DeeFunctionObject, fo_refv) + - rid * sizeof(DREF DeeObject *)); + _Dee_MallococBufsize(offsetof(DeeFunctionObject, fo_refv), + rid, sizeof(DREF DeeObject *))); } /* Simple case: able to directly inline function references */ @@ -1921,8 +1921,8 @@ fg_vbound_cmember(struct fungen *__restrict self, } else { DO(fg_vind(self, offsetof(DeeTypeObject, tp_class))); /* type->tp_class */ DO(fg_vind(self, /* type->tp_class->cd_members[addr] */ - offsetof(struct Dee_class_desc, cd_members[0]) + - (addr * sizeof(DREF DeeObject *)))); + _Dee_MallococBufsize(offsetof(struct Dee_class_desc, cd_members[0]), + addr, sizeof(DREF DeeObject *)))); DO(fg_vreg(self, NULL)); /* reg:type->tp_class->cd_members[addr] */ vtop = fg_vtop(self); ASSERT(memval_isdirect(vtop)); @@ -1975,8 +1975,8 @@ fg_vpop_cmember(struct fungen *__restrict self, DO(fg_vind(self, offsetof(DeeTypeObject, tp_class))); /* type, value, type->tp_class */ DO(fg_vswap(self)); /* type, type->tp_class, value */ DO(fg_vpopind(self, /* type, type->tp_class */ - offsetof(struct Dee_class_desc, cd_members[0]) + - (addr * sizeof(DREF DeeObject *)))); + _Dee_MallococBufsize(offsetof(struct Dee_class_desc, cd_members[0]), + addr, sizeof(DREF DeeObject *)))); return fg_vpopmany(self, 2); /* N/A */ } } @@ -2040,8 +2040,8 @@ fg_vpush_imember_unsafe_at_runtime(struct fungen *__restrict self, #ifndef CONFIG_NO_THREADS lock_offset = desc->cd_offset + offsetof(struct instance_desc, id_lock); #endif /* !CONFIG_NO_THREADS */ - slot_offset = desc->cd_offset + offsetof(struct instance_desc, id_vtab) + - addr * sizeof(DREF DeeObject *); + slot_offset = _Dee_MallococBufsize(desc->cd_offset + offsetof(struct instance_desc, id_vtab), + addr, sizeof(DREF DeeObject *)); /* XXX: (and this is a problem with the normal executor): assert that "this" is an instance of `type' */ /* TODO: In case of reading members, if one of the next instructions also does a read, @@ -2214,8 +2214,8 @@ fg_vdel_or_pop_imember_unsafe_at_runtime(struct fungen *__restrict self, #ifndef CONFIG_NO_THREADS lock_offset = desc->cd_offset + offsetof(struct instance_desc, id_lock); #endif /* !CONFIG_NO_THREADS */ - slot_offset = desc->cd_offset + offsetof(struct instance_desc, id_vtab) + - addr * sizeof(DREF DeeObject *); + slot_offset = _Dee_MallococBufsize(desc->cd_offset + offsetof(struct instance_desc, id_vtab), + addr, sizeof(DREF DeeObject *)); /* XXX: (and this is a problem with the normal executor): assert that "this" is an instance of `type' */ #ifndef CONFIG_NO_THREADS @@ -3084,8 +3084,8 @@ fg_vind(struct fungen *__restrict self, goto push_list_mval_objc; if (ind_delta >= offsetof(DeeTupleObject, t_elem)) { struct memobjs *objs = memval_getobjn(mval); - if ((size_t)ind_delta < ((size_t)offsetof(DeeTupleObject, t_elem) + - (size_t)(objs->mos_objc * sizeof(DREF DeeObject *)))) { + if ((size_t)ind_delta < _Dee_MallococBufsize(offsetof(DeeTupleObject, t_elem), + objs->mos_objc, sizeof(DREF DeeObject *))) { size_t index = (size_t)ind_delta - (size_t)offsetof(DeeTupleObject, t_elem); if ((index % sizeof(DREF DeeObject *)) == 0) { index /= sizeof(DREF DeeObject *); @@ -4272,8 +4272,8 @@ PRIVATE DeeTypeObject DeeVectorDummy_Type = { PRIVATE WUNUSED DREF DummyVectorObject *DCALL DummyVector_New(size_t num_items) { DREF DummyVectorObject *result; - result = (DREF DummyVectorObject *)DeeObject_Malloc(offsetof(DummyVectorObject, dvo_items) + - (num_items * sizeof(void *))); + result = (DREF DummyVectorObject *)DeeObject_Mallocc(offsetof(DummyVectorObject, dvo_items), + num_items, sizeof(void *)); if likely(result) DeeObject_Init(result, &DeeVectorDummy_Type); return result; diff --git a/src/dex/_hostasm/generator-xmorph.c b/src/dex/_hostasm/generator-xmorph.c index ede79527..e1c0101a 100644 --- a/src/dex/_hostasm/generator-xmorph.c +++ b/src/dex/_hostasm/generator-xmorph.c @@ -454,7 +454,7 @@ bind_next_newref:; { int temp; - void *_newstatebuf[memstate_sizeof(1) / sizeof(void *)]; + void *_newstatebuf[memstate_sizeof_constexpr(1) / sizeof(void *)]; struct memstate *newstate = (struct memstate *)_newstatebuf; /* #4: Construct a fake `memstate' for "newinfo" */ diff --git a/src/dex/_hostasm/libhostasm.h b/src/dex/_hostasm/libhostasm.h index 7feb0c2d..6dfca8cf 100644 --- a/src/dex/_hostasm/libhostasm.h +++ b/src/dex/_hostasm/libhostasm.h @@ -1433,7 +1433,9 @@ struct memstate { } __WHILE0 #define memstate_sizeof(localc) \ - (offsetof(struct memstate, ms_localv) + (localc) * sizeof(struct memval)) + _Dee_MallococBufsize(offsetof(struct memstate, ms_localv), localc, sizeof(struct memval)) +#define memstate_sizeof_constexpr(localc) \ + (offsetof(struct memstate, ms_localv) + ((localc) * sizeof(struct memval))) #define memstate_alloc(localc) \ ((struct memstate *)Dee_Malloc(memstate_sizeof(localc))) #define memstate_free(self) Dee_Free(self) diff --git a/src/dex/_jit/function.c b/src/dex/_jit/function.c index 218223f9..76bf267b 100644 --- a/src/dex/_jit/function.c +++ b/src/dex/_jit/function.c @@ -694,8 +694,8 @@ jf_call_kw(JITFunction *self, size_t argc, if ((self->jf_flags & (JIT_FUNCTION_FYIELDING | JIT_FUNCTION_FRETEXPR)) == JIT_FUNCTION_FYIELDING) { DREF JITYieldFunctionObject *yfo; /* Yield function support */ - yfo = (DREF JITYieldFunctionObject *)DeeObject_Malloc(offsetof(JITYieldFunctionObject, jy_argv) + - (argc * sizeof(DREF DeeObject *))); + yfo = (DREF JITYieldFunctionObject *)DeeObject_Mallocc(offsetof(JITYieldFunctionObject, jy_argv), + argc, sizeof(DREF DeeObject *)); if unlikely(!yfo) goto err; yfo->jy_func = self; diff --git a/src/dex/collections/fixedlist.c b/src/dex/collections/fixedlist.c index 8c9d9991..2a1f37e8 100644 --- a/src/dex/collections/fixedlist.c +++ b/src/dex/collections/fixedlist.c @@ -75,8 +75,8 @@ PRIVATE WUNUSED DREF FixedList *DCALL fl_ctor(void) { PRIVATE WUNUSED NONNULL((1)) DREF FixedList *DCALL fl_copy(FixedList *__restrict self) { DREF FixedList *result; - result = (DREF FixedList *)DeeGCObject_Malloc(offsetof(FixedList, fl_elem) + - (self->fl_size * sizeof(DREF DeeObject *))); + result = (DREF FixedList *)DeeGCObject_Mallocc(offsetof(FixedList, fl_elem), + self->fl_size, sizeof(DREF DeeObject *)); if unlikely(!result) goto err; Dee_atomic_rwlock_init(&result->fl_lock); @@ -106,8 +106,8 @@ fl_init_iterator(DeeObject *__restrict iterator) { next = DeeObject_IterNext(iterator); if (!ITER_ISOK(next)) { if (next == ITER_DONE) { - result = (DREF FixedList *)DeeGCObject_Malloc(offsetof(FixedList, fl_elem) + - (1 * sizeof(DREF DeeObject *))); + result = (DREF FixedList *)DeeGCObject_Mallocc(offsetof(FixedList, fl_elem), + 1, sizeof(DREF DeeObject *)); if unlikely(!result) goto err; itemc = 1; @@ -117,12 +117,12 @@ fl_init_iterator(DeeObject *__restrict iterator) { goto err; } itemc = 2, itema = 4; - result = (DREF FixedList *)DeeGCObject_TryMalloc(offsetof(FixedList, fl_elem) + - (4 * sizeof(DREF DeeObject *))); + result = (DREF FixedList *)DeeGCObject_TryMallocc(offsetof(FixedList, fl_elem), + 4, sizeof(DREF DeeObject *)); if unlikely(!result) { itema = 2; - result = (DREF FixedList *)DeeGCObject_Malloc(offsetof(FixedList, fl_elem) + - (2 * sizeof(DREF DeeObject *))); + result = (DREF FixedList *)DeeGCObject_Mallocc(offsetof(FixedList, fl_elem), + 2, sizeof(DREF DeeObject *)); if unlikely(!result) goto err; } @@ -132,14 +132,12 @@ fl_init_iterator(DeeObject *__restrict iterator) { ASSERT(itemc <= itema); if (itemc >= itema) { itema *= 2; - new_result = (DREF FixedList *)DeeGCObject_TryRealloc(result, - offsetof(FixedList, fl_elem) + - (itema * sizeof(DREF DeeObject *))); + new_result = (DREF FixedList *)DeeGCObject_TryReallocc(result, offsetof(FixedList, fl_elem), + itema, sizeof(DREF DeeObject *)); if unlikely(!new_result) { itema = itemc + 1; - new_result = (DREF FixedList *)DeeGCObject_Realloc(result, - offsetof(FixedList, fl_elem) + - (itema * sizeof(DREF DeeObject *))); + new_result = (DREF FixedList *)DeeGCObject_Reallocc(result, offsetof(FixedList, fl_elem), + itema, sizeof(DREF DeeObject *)); if unlikely(!new_result) goto err_r; } @@ -153,9 +151,8 @@ fl_init_iterator(DeeObject *__restrict iterator) { if unlikely(!elem) goto err_r; if (itema > itemc) { - new_result = (DREF FixedList *)DeeGCObject_TryRealloc(result, - offsetof(FixedList, fl_elem) + - (itemc * sizeof(DREF DeeObject *))); + new_result = (DREF FixedList *)DeeGCObject_TryReallocc(result, offsetof(FixedList, fl_elem), + itemc, sizeof(DREF DeeObject *)); if likely(new_result) result = new_result; } @@ -179,8 +176,8 @@ fl_init_getitem(DREF DeeObject *(DCALL *getitem)(DeeObject *__restrict self, DREF FixedList *result; size_t i; DREF DeeObject *index_ob, *elem; - result = (DREF FixedList *)DeeGCObject_Malloc(offsetof(FixedList, fl_elem) + - (length * sizeof(DREF DeeObject *))); + result = (DREF FixedList *)DeeGCObject_MalloccSafe(offsetof(FixedList, fl_elem), + length, sizeof(DREF DeeObject *)); if unlikely(!result) goto err; for (i = 0; i < length; ++i) { @@ -218,8 +215,8 @@ fl_init(size_t argc, DeeObject *const *argv) { if (init) { if (DeeObject_AsSize(size_ob, &size)) goto err; - result = (DREF FixedList *)DeeGCObject_Malloc(offsetof(FixedList, fl_elem) + - (size * sizeof(DREF DeeObject *))); + result = (DREF FixedList *)DeeGCObject_MalloccSafe(offsetof(FixedList, fl_elem), + size, sizeof(DREF DeeObject *)); if unlikely(!result) goto err; Dee_atomic_rwlock_init(&result->fl_lock); @@ -229,8 +226,8 @@ fl_init(size_t argc, DeeObject *const *argv) { } else if (DeeInt_Check(size_ob)) { if (DeeObject_AsSize(size_ob, &size)) goto err; - result = (DREF FixedList *)DeeGCObject_Calloc(offsetof(FixedList, fl_elem) + - (size * sizeof(DREF DeeObject *))); + result = (DREF FixedList *)DeeGCObject_CalloccSafe(offsetof(FixedList, fl_elem), + size, sizeof(DREF DeeObject *)); if unlikely(!result) goto err; Dee_atomic_rwlock_cinit(&result->fl_lock); @@ -283,8 +280,8 @@ fl_init(size_t argc, DeeObject *const *argv) { return result; } /* Initialize from a fast sequence */ - result = (DREF FixedList *)DeeGCObject_Malloc(offsetof(FixedList, fl_elem) + - (size * sizeof(DREF DeeObject *))); + result = (DREF FixedList *)DeeGCObject_MalloccSafe(offsetof(FixedList, fl_elem), + size, sizeof(DREF DeeObject *)); if unlikely(!result) goto err; Dee_atomic_rwlock_init(&result->fl_lock); @@ -630,8 +627,8 @@ fl_getrange_index(FixedList *__restrict self, Dee_ssize_t i_begin, Dee_ssize_t i range_size = range.sr_end - range.sr_start; if unlikely(range_size <= 0) return_reference_(Dee_EmptySeq); - result = (DREF FixedList *)DeeGCObject_Malloc(offsetof(FixedList, fl_elem) + - range_size * sizeof(DREF DeeObject *)); + result = (DREF FixedList *)DeeGCObject_Mallocc(offsetof(FixedList, fl_elem), + range_size, sizeof(DREF DeeObject *)); if unlikely(!result) goto err; Dee_atomic_rwlock_init(&result->fl_lock); @@ -659,8 +656,8 @@ fl_getrange_index_n(FixedList *__restrict self, Dee_ssize_t i_begin) { range_size = self->fl_size - start; if unlikely(range_size <= 0) return_reference_(Dee_EmptySeq); - result = (DREF FixedList *)DeeGCObject_Malloc(offsetof(FixedList, fl_elem) + - range_size * sizeof(DREF DeeObject *)); + result = (DREF FixedList *)DeeGCObject_Mallocc(offsetof(FixedList, fl_elem), + range_size, sizeof(DREF DeeObject *)); if unlikely(!result) goto err; Dee_atomic_rwlock_init(&result->fl_lock); @@ -1633,8 +1630,10 @@ PRIVATE struct type_seq fl_seq = { PRIVATE WUNUSED NONNULL((1)) DREF DeeObject *DCALL fl_sizeof(FixedList *self) { - return DeeInt_NewSize(offsetof(FixedList, fl_elem) + - (self->fl_size * sizeof(DREF DeeObject *))); + size_t result; + result = _Dee_MallococBufsize(offsetof(FixedList, fl_elem), + self->fl_size, sizeof(DREF DeeObject *)); + return DeeInt_NewSize(result); } PRIVATE struct type_getset tpconst fl_getsets[] = { diff --git a/src/dex/collections/libcollections.h b/src/dex/collections/libcollections.h index c4aad1d9..384a341f 100644 --- a/src/dex/collections/libcollections.h +++ b/src/dex/collections/libcollections.h @@ -43,7 +43,7 @@ typedef struct deque_bucket { #define DEQUEBUCKET_HASNEXT(deq, x) ((x) != (deq)->d_tail) #define SIZEOF_BUCKET(bucket_size) \ - (offsetof(DequeBucket, db_items) + (bucket_size) * sizeof(DREF DeeObject *)) + _Dee_MallococBufsize(offsetof(DequeBucket, db_items), bucket_size, sizeof(DREF DeeObject *)) #define NEW_BUCKET(bucket_size) \ ((DequeBucket *)Dee_Malloc(SIZEOF_BUCKET(bucket_size))) #define TRY_NEW_BUCKET(bucket_size) \ diff --git a/src/dex/collections/udict.c b/src/dex/collections/udict.c index 640a94f4..6446630a 100644 --- a/src/dex/collections/udict.c +++ b/src/dex/collections/udict.c @@ -1763,7 +1763,7 @@ STATIC_ASSERT(offsetof(URoDict, urd_size) == offsetof(UDict, ud_used)); #define urodict_bool udict_bool #define URODICT_ALLOC(mask) ((DREF URoDict *)DeeObject_Calloc(SIZEOF_URODICT(mask))) -#define SIZEOF_URODICT(mask) (offsetof(URoDict, urd_elem) + (((mask) + 1) * sizeof(struct udict_item))) +#define SIZEOF_URODICT(mask) _Dee_MallococBufsize(offsetof(URoDict, urd_elem), (mask) + 1, sizeof(struct udict_item)) #define URODICT_INITIAL_MASK 0x03 INTERN WUNUSED DREF URoDict *DCALL URoDict_New(void) { @@ -2277,9 +2277,11 @@ urodict_get(URoDict *self, size_t argc, DeeObject *const *argv) { PRIVATE WUNUSED NONNULL((1)) DREF DeeObject *DCALL urodict_sizeof(URoDict *self) { - return DeeInt_NewSize(offsetof(URoDict, urd_elem) + - ((self->urd_mask + 1) * - sizeof(struct udict_item))); + size_t result; + result = _Dee_MallococBufsize(offsetof(URoDict, urd_elem), + self->urd_mask + 1, + sizeof(struct udict_item)); + return DeeInt_NewSize(result); } diff --git a/src/dex/collections/uset.c b/src/dex/collections/uset.c index 726133fb..7185bbf0 100644 --- a/src/dex/collections/uset.c +++ b/src/dex/collections/uset.c @@ -1733,8 +1733,8 @@ uroset_visit(URoSet *__restrict self, dvisit_t proc, void *arg) { INTERN WUNUSED DREF URoSet *DCALL URoSet_New(void) { DREF URoSet *result; - result = (DREF URoSet *)DeeObject_Malloc(offsetof(URoSet, urs_elem) + - 1 * sizeof(struct uset_item)); + result = (DREF URoSet *)DeeObject_Mallocc(offsetof(URoSet, urs_elem), + 1, sizeof(struct uset_item)); if likely(result) { result->urs_mask = 0; result->urs_size = 0; @@ -1790,9 +1790,9 @@ URoSet_DoInsertOrRehash(URoSet *__restrict self, size_t newmsk; URoSet *newset; newmsk = (self->urs_mask << 1) | 1; - newset = (URoSet *)DeeObject_Calloc(offsetof(URoSet, urs_elem) + - (newmsk + 1) * - sizeof(struct uset_item)); + newset = (URoSet *)DeeObject_Callocc(offsetof(URoSet, urs_elem), + newmsk + 1, + sizeof(struct uset_item)); if unlikely(!newset) goto err_ob; newset->urs_size = self->urs_size; @@ -1832,8 +1832,8 @@ INTERN WUNUSED NONNULL((1)) DREF URoSet *DCALL URoSet_FromIterator(DeeObject *__restrict iterator) { DREF DeeObject *elem; DREF URoSet *result; - result = (DREF URoSet *)DeeObject_Malloc(offsetof(URoSet, urs_elem) + - 1 * sizeof(struct uset_item)); + result = (DREF URoSet *)DeeObject_Mallocc(offsetof(URoSet, urs_elem), + 1, sizeof(struct uset_item)); if unlikely(!result) goto err; result->urs_mask = 0; @@ -1873,16 +1873,14 @@ URoSet_FromUSet(USet *__restrict self) { mask = 1; while ((self->us_used & mask) != self->us_used) mask = (mask << 1) | 1; - result = (DREF URoSet *)DeeObject_TryCalloc(offsetof(URoSet, urs_elem) + - (mask + 1) * - sizeof(struct uset_item)); + result = (DREF URoSet *)DeeObject_TryCallocc(offsetof(URoSet, urs_elem), + mask + 1, sizeof(struct uset_item)); if unlikely(!result) { size_t oldsize; oldsize = self->us_used; USet_LockEndRead(self); - result = (DREF URoSet *)DeeObject_Calloc(offsetof(URoSet, urs_elem) + - (mask + 1) * - sizeof(struct uset_item)); + result = (DREF URoSet *)DeeObject_Callocc(offsetof(URoSet, urs_elem), + mask + 1, sizeof(struct uset_item)); if unlikely(!result) goto done; USet_LockRead(self); @@ -1936,16 +1934,14 @@ URoSet_FromSequence(DeeObject *__restrict sequence) { mask = 1; while ((src->hs_used & mask) != src->hs_used) mask = (mask << 1) | 1; - result = (DREF URoSet *)DeeObject_TryCalloc(offsetof(URoSet, urs_elem) + - (mask + 1) * - sizeof(struct uset_item)); + result = (DREF URoSet *)DeeObject_TryCallocc(offsetof(URoSet, urs_elem), + mask + 1, sizeof(struct uset_item)); if unlikely(!result) { size_t oldsize; oldsize = src->hs_used; DeeHashSet_LockEndRead(src); - result = (DREF URoSet *)DeeObject_Calloc(offsetof(URoSet, urs_elem) + - (mask + 1) * - sizeof(struct uset_item)); + result = (DREF URoSet *)DeeObject_Callocc(offsetof(URoSet, urs_elem), + mask + 1, sizeof(struct uset_item)); if unlikely(!result) goto err; DeeHashSet_LockRead(src); @@ -1974,9 +1970,9 @@ URoSet_FromSequence(DeeObject *__restrict sequence) { size_t i; DeeRoSetObject *src; src = (DeeRoSetObject *)sequence; - result = (DREF URoSet *)DeeObject_Calloc(offsetof(URoSet, urs_elem) + - (src->rs_mask + 1) * - sizeof(struct uset_item)); + result = (DREF URoSet *)DeeObject_Callocc(offsetof(URoSet, urs_elem), + src->rs_mask + 1, + sizeof(struct uset_item)); if unlikely(!result) goto err; result->urs_mask = src->rs_mask; @@ -2002,9 +1998,9 @@ URoSet_FromSequence(DeeObject *__restrict sequence) { /* Figure out how large the mask of the set is going to be. */ while ((fastsize & mask) != fastsize) mask = (mask << 1) | 1; - result = (DREF URoSet *)DeeObject_Calloc(offsetof(URoSet, urs_elem) + - (mask + 1) * - sizeof(struct uset_item)); + result = (DREF URoSet *)DeeObject_Callocc(offsetof(URoSet, urs_elem), + mask + 1, + sizeof(struct uset_item)); if unlikely(!result) goto err; /* Without any dummy items, these are identical. */ @@ -2047,9 +2043,9 @@ PRIVATE WUNUSED NONNULL((1)) DREF URoSet *DCALL uroset_deepcopy(URoSet *__restrict self) { DREF URoSet *result; size_t i; - result = (DREF URoSet *)DeeObject_Calloc(offsetof(URoSet, urs_elem) + - (self->urs_mask + 1) * - sizeof(struct uset_item)); + result = (DREF URoSet *)DeeObject_Callocc(offsetof(URoSet, urs_elem), + self->urs_mask + 1, + sizeof(struct uset_item)); if unlikely(!result) goto err; result->urs_mask = self->urs_mask; @@ -2095,9 +2091,11 @@ uroset_fini(URoSet *__restrict self) { PRIVATE WUNUSED NONNULL((1)) DREF DeeObject *DCALL uroset_sizeof(URoSet *self) { - return DeeInt_NewSize(offsetof(URoSet, urs_elem) + - ((self->urs_mask + 1) * - sizeof(struct uset_item))); + size_t result; + result = _Dee_MallococBufsize(offsetof(URoSet, urs_elem), + self->urs_mask + 1, + sizeof(struct uset_item)); + return DeeInt_NewSize(result); } PRIVATE struct type_getset tpconst uroset_getsets[] = { diff --git a/src/dex/ctypes/libctypes.h b/src/dex/ctypes/libctypes.h index 2ef9fc7a..538639f5 100644 --- a/src/dex/ctypes/libctypes.h +++ b/src/dex/ctypes/libctypes.h @@ -1073,9 +1073,8 @@ INTDEF struct empty_struct_type_object DeeStruct_Type; #define DeeStructType_Check(ob) \ DeeObject_InstanceOfExact((DeeObject *)(ob), &DeeStructType_Type) /* `struct_type' is final */ -/* Construct a new struct-type from `fields', which - * is a `sequence>' */ -INTDEF WUNUSED DREF DeeStructTypeObject *DCALL +/* Construct a new struct-type from `fields', which is a `{(string, StructuredType)...}' */ +INTDEF WUNUSED NONNULL((2)) DREF DeeStructTypeObject *DCALL DeeStructType_FromSequence(DeeObject *name, DeeObject *__restrict fields, unsigned int flags); diff --git a/src/dex/ctypes/struct.c b/src/dex/ctypes/struct.c index 38a7d7b3..ba36edc6 100644 --- a/src/dex/ctypes/struct.c +++ b/src/dex/ctypes/struct.c @@ -44,8 +44,8 @@ struct_type_rehash(DeeStructTypeObject *__restrict self) { DREF DeeStructTypeObject *result; size_t i, j, perturb, new_mask; new_mask = (self->st_fmsk << 1) | 1; - result = (DREF DeeStructTypeObject *)DeeGCObject_Calloc(offsetof(DeeStructTypeObject, st_fvec) + - (new_mask + 1) * sizeof(struct struct_field)); + result = (DREF DeeStructTypeObject *)DeeGCObject_Callocc(offsetof(DeeStructTypeObject, st_fvec), + new_mask + 1, sizeof(struct struct_field)); if unlikely(!result) goto err; result->st_fmsk = new_mask; @@ -70,216 +70,126 @@ struct_type_rehash(DeeStructTypeObject *__restrict self) { return NULL; } -PRIVATE WUNUSED DREF DeeStructTypeObject *DCALL -struct_type_alloc_iterator(DeeObject *__restrict iter, - unsigned int flags) { - DREF DeeStructTypeObject *result; - size_t field_count = 0; - DREF DeeObject *elem; - DREF DeeObject *field_name_and_type[2]; - size_t i, min_align = 1, instance_size = 0; - result = (DREF DeeStructTypeObject *)DeeGCObject_Calloc(offsetof(DeeStructTypeObject, st_fvec) + - (2 * sizeof(struct struct_field))); - if unlikely(!result) +struct struct_type_alloc_foreach_data { + DREF DeeStructTypeObject *staf_result; + size_t staf_nfields; + size_t staf_alignof; + size_t staf_sizeof; + unsigned int staf_flags; +}; + +PRIVATE WUNUSED NONNULL((1, 2, 3)) Dee_ssize_t DCALL +struct_type_alloc_foreach_cb(void *arg, DeeObject *key, DeeObject *value) { + size_t i; + Dee_hash_t perturb, hash; + struct struct_type_alloc_foreach_data *data; + data = (struct struct_type_alloc_foreach_data *)arg; + if (data->staf_nfields >= data->staf_result->st_fmsk) { + /* Must allocate more fields. */ + DREF DeeStructTypeObject *new_result; + new_result = struct_type_rehash(data->staf_result); + if unlikely(!new_result) + goto err; + DeeGCObject_Free(data->staf_result); + data->staf_result = new_result; + } + ASSERT(data->staf_nfields < data->staf_result->st_fmsk); + + /* Validate that this is a string/struct_type-pair. */ + if (DeeObject_AssertTypeExact(key, &DeeString_Type)) goto err; - result->st_fmsk = 1; - while (ITER_ISOK(elem = DeeObject_IterNext(iter))) { - int temp; - dhash_t perturb, hash; - if (field_count >= result->st_fmsk) { - /* Must allocate more fields. */ - DREF DeeStructTypeObject *new_result; - new_result = struct_type_rehash(result); - if unlikely(!new_result) - goto err_r; - DeeGCObject_Free(result); - result = new_result; - } - ASSERT(field_count < result->st_fmsk); - temp = DeeObject_Unpack(elem, 2, field_name_and_type); - Dee_Decref(elem); - if unlikely(temp) - goto err_r; - /* Validate that this is a string/struct_type-pair. */ - if (DeeObject_AssertTypeExact(field_name_and_type[0], &DeeString_Type) || - DeeObject_AssertType(field_name_and_type[1], &DeeSType_Type)) { - Dee_Decref(field_name_and_type[1]); - Dee_Decref(field_name_and_type[0]); - goto err_r; - } - hash = DeeString_Hash(field_name_and_type[0]); - i = perturb = STRUCT_TYPE_HASHST(result, hash); - for (;; STRUCT_TYPE_HASHNX(i, perturb)) { - struct struct_field *field; - size_t align; - field = STRUCT_TYPE_HASHIT(result, i); - if (field->sf_name) - continue; - align = DeeSType_Alignof(field_name_and_type[1]); - if (!(flags & STRUCT_TYPE_FPACKED) && (min_align < align)) - min_align = align; - if (flags & STRUCT_TYPE_FUNION) { - field->sf_offset = 0; - if (instance_size < DeeSType_Sizeof(field_name_and_type[1])) - instance_size = DeeSType_Sizeof(field_name_and_type[1]); - } else { - if (!(flags & STRUCT_TYPE_FPACKED)) { - instance_size += (align - 1); - instance_size &= ~(align - 1); - } - field->sf_offset = instance_size; - instance_size += DeeSType_Sizeof(field_name_and_type[1]); - } - field->sf_hash = DeeString_Hash(field_name_and_type[0]); - field->sf_name = (DREF struct string_object *)field_name_and_type[0]; /* Inherit reference. */ - field->sf_type = DeeSType_LValue((DeeSTypeObject *)field_name_and_type[1]); /* Inherit reference. */ - Dee_Decref(field_name_and_type[1]); - if unlikely(!field->sf_type) { - Dee_Decref(field_name_and_type[0]); - field->sf_name = NULL; - goto err_r; + if (DeeObject_AssertType(value, &DeeSType_Type)) + goto err; + + hash = DeeString_Hash(key); + i = perturb = STRUCT_TYPE_HASHST(data->staf_result, hash); + for (;; STRUCT_TYPE_HASHNX(i, perturb)) { + struct struct_field *field; + size_t align; + field = STRUCT_TYPE_HASHIT(data->staf_result, i); + if (field->sf_name) + continue; + align = DeeSType_Alignof(value); + if (!(data->staf_flags & STRUCT_TYPE_FPACKED) && (data->staf_alignof < align)) + data->staf_alignof = align; + if (data->staf_flags & STRUCT_TYPE_FUNION) { + field->sf_offset = 0; + if (data->staf_sizeof < DeeSType_Sizeof(value)) + data->staf_sizeof = DeeSType_Sizeof(value); + } else { + if (!(data->staf_flags & STRUCT_TYPE_FPACKED)) { + data->staf_sizeof += (align - 1); + data->staf_sizeof &= ~(align - 1); } - break; + field->sf_offset = data->staf_sizeof; + data->staf_sizeof += DeeSType_Sizeof(value); } - ++field_count; - if (DeeThread_CheckInterrupt()) - goto err_r; - } - if unlikely(!elem) - goto err_r; - /* Fill in size & alignment info. */ - result->st_base.st_sizeof = instance_size; - result->st_base.st_align = min_align; - result->st_base.st_base.tp_init.tp_alloc.tp_instance_size = sizeof(DeeObject) + instance_size; - return result; -err_r: - for (i = 0; i <= result->st_fmsk; ++i) { - if (!result->st_fvec[i].sf_name) - continue; - Dee_Decref(result->st_fvec[i].sf_name); - Dee_Decref(DeeLValueType_AsObject(result->st_fvec[i].sf_type)); + field->sf_hash = DeeString_Hash(key); + field->sf_name = (DREF DeeStringObject *)key; + field->sf_type = DeeSType_LValue((DeeSTypeObject *)value); + if unlikely(!field->sf_type) { + Dee_Decref(key); + field->sf_name = NULL; + goto err; + } + Dee_Incref(key); + break; } - DeeGCObject_Free(result); + ++data->staf_nfields; + return 0; err: - return NULL; + return -1; } - -INTERN WUNUSED DREF DeeStructTypeObject *DCALL +/* Construct a new struct-type from `fields', which is a `{(string, StructuredType)...}' */ +INTERN WUNUSED NONNULL((2)) DREF DeeStructTypeObject *DCALL DeeStructType_FromSequence(DeeObject *name, DeeObject *__restrict fields, unsigned int flags) { - DREF DeeStructTypeObject *result; - size_t i, field_count; - - /* TODO: Use DeeObject_ForeachPair(), and get rid of DeeFastSeq_GetSize_deprecated() */ + struct struct_type_alloc_foreach_data data; + Dee_hash_t i; + data.staf_nfields = 0; + data.staf_flags = flags; + data.staf_sizeof = 0; + data.staf_alignof = 1; + data.staf_result = (DREF DeeStructTypeObject *)DeeGCObject_Callocc(offsetof(DeeStructTypeObject, st_fvec), + 2, sizeof(struct struct_field)); + if unlikely(!data.staf_result) + goto err; + data.staf_result->st_fmsk = 1; - /* Optimization for fast sequence types. */ - field_count = DeeFastSeq_GetSize_deprecated(fields); - if (field_count != DEE_FASTSEQ_NOTFAST_DEPRECATED) { - size_t result_mask = 1; - size_t min_align = 1, instance_size = 0; - while (result_mask <= field_count) - result_mask = (result_mask << 1) | 1; - result = (DREF DeeStructTypeObject *)DeeGCObject_Calloc(offsetof(DeeStructTypeObject, st_fvec) + - (result_mask + 1) * sizeof(struct struct_field)); - if unlikely(!result) - goto err; - result->st_fmsk = result_mask; - for (i = 0; i < field_count; ++i) { - DREF DeeObject *elem; - DREF DeeObject *field_name_and_type[2]; - int temp; - dhash_t j, perturb, hash; - elem = DeeFastSeq_GetItem_deprecated(fields, i); - if unlikely(!elem) - goto err_r; - temp = DeeObject_Unpack(elem, 2, field_name_and_type); - Dee_Decref(elem); - if unlikely(temp) - goto err_r; - - /* Validate that this is a string/struct_type-pair. */ - if (DeeObject_AssertTypeExact(field_name_and_type[0], &DeeString_Type) || - DeeObject_AssertType(field_name_and_type[1], &DeeSType_Type)) { - Dee_Decref(field_name_and_type[1]); - Dee_Decref(field_name_and_type[0]); - goto err_r; - } - hash = DeeString_Hash(field_name_and_type[0]); - j = perturb = STRUCT_TYPE_HASHST(result, hash); - for (;; STRUCT_TYPE_HASHNX(j, perturb)) { - struct struct_field *field; - size_t align; - field = STRUCT_TYPE_HASHIT(result, j); - if (field->sf_name) - continue; - align = DeeSType_Alignof(field_name_and_type[1]); - if (!(flags & STRUCT_TYPE_FPACKED) && (min_align < align)) - min_align = align; - if (flags & STRUCT_TYPE_FUNION) { - field->sf_offset = 0; - if (instance_size < DeeSType_Sizeof(field_name_and_type[1])) - instance_size = DeeSType_Sizeof(field_name_and_type[1]); - } else { - if (!(flags & STRUCT_TYPE_FPACKED)) { - instance_size += (align - 1); - instance_size &= ~(align - 1); - } - field->sf_offset = instance_size; - instance_size += DeeSType_Sizeof(field_name_and_type[1]); - } - field->sf_hash = DeeString_Hash(field_name_and_type[0]); - field->sf_name = (DREF struct string_object *)field_name_and_type[0]; /* Inherit reference. */ - field->sf_type = DeeSType_LValue((DeeSTypeObject *)field_name_and_type[1]); /* Inherit reference. */ - Dee_Decref(field_name_and_type[1]); - if unlikely(!field->sf_type) { - Dee_Decref(field_name_and_type[0]); - field->sf_name = NULL; - goto err_r; - } - break; - } - } + /* Enumerate key/value pairs of "fields" */ + if unlikely(DeeObject_ForeachPair(fields, &struct_type_alloc_foreach_cb, &data) < 0) + goto err_r; - /* Fill in size & alignment info. */ - result->st_base.st_sizeof = instance_size; - result->st_base.st_align = min_align; - result->st_base.st_base.tp_init.tp_alloc.tp_instance_size = sizeof(DeeObject) + instance_size; - } else { - /* Use iterators to construct the struct-type. */ - fields = DeeObject_Iter(fields); - if unlikely(!fields) - goto err; - result = struct_type_alloc_iterator(fields, flags); - Dee_Decref(fields); - if unlikely(!result) - goto err; - } + /* Fill in size & alignment info. */ + data.staf_result->st_base.st_sizeof = data.staf_sizeof; + data.staf_result->st_base.st_align = data.staf_alignof; + data.staf_result->st_base.st_base.tp_init.tp_alloc.tp_instance_size = sizeof(DeeObject) + data.staf_sizeof; /* Fill in remaining fields and start tracking the new struct type. */ Dee_Incref(DeeStructType_AsObject(&DeeStruct_Type)); - Dee_atomic_rwlock_cinit(&result->st_base.st_cachelock); - result->st_base.st_base.tp_base = (DREF DeeTypeObject *)&DeeStruct_Type; - result->st_base.st_base.tp_name = DeeStruct_Type.st_base.st_base.tp_name; - result->st_base.st_base.tp_flags = TP_FTRUNCATE | TP_FINHERITCTOR | TP_FHEAP | TP_FMOVEANY; + Dee_atomic_rwlock_cinit(&data.staf_result->st_base.st_cachelock); + data.staf_result->st_base.st_base.tp_base = (DREF DeeTypeObject *)&DeeStruct_Type; + data.staf_result->st_base.st_base.tp_name = DeeStruct_Type.st_base.st_base.tp_name; + data.staf_result->st_base.st_base.tp_flags = TP_FTRUNCATE | TP_FINHERITCTOR | TP_FHEAP | TP_FMOVEANY; - /* Set the name of the new struct-type. */ + /* If given, set the name of the new struct-type. */ if (name) { - result->st_base.st_base.tp_name = DeeString_STR(name); - result->st_base.st_base.tp_flags |= TP_FNAMEOBJECT; + data.staf_result->st_base.st_base.tp_name = DeeString_STR(name); + data.staf_result->st_base.st_base.tp_flags |= TP_FNAMEOBJECT; Dee_Incref(name); } - DeeObject_Init((DeeObject *)result, &DeeStructType_Type); - return DeeType_AsStructType((DeeTypeObject *)DeeGC_Track(DeeStructType_AsObject(result))); + DeeObject_Init((DeeObject *)data.staf_result, &DeeStructType_Type); + return DeeType_AsStructType((DeeTypeObject *)DeeGC_Track(DeeStructType_AsObject(data.staf_result))); err_r: - for (i = 0; i <= result->st_fmsk; ++i) { - if (!result->st_fvec[i].sf_name) + for (i = 0; i <= data.staf_result->st_fmsk; ++i) { + if (!data.staf_result->st_fvec[i].sf_name) continue; - Dee_Decref(result->st_fvec[i].sf_name); - Dee_Decref(DeeLValueType_AsObject(result->st_fvec[i].sf_type)); + Dee_Decref(data.staf_result->st_fvec[i].sf_name); + Dee_Decref(DeeLValueType_AsObject(data.staf_result->st_fvec[i].sf_type)); } - DeeGCObject_Free(result); + DeeGCObject_Free(data.staf_result); err: return NULL; } @@ -328,7 +238,7 @@ struct_type_visit(DeeStructTypeObject *__restrict self, dvisit_t proc, void *arg PRIVATE WUNUSED NONNULL((1)) DREF DeeObject *DCALL struct_type_offsetof(DeeStructTypeObject *self, size_t argc, DeeObject *const *argv) { - dhash_t i, perturb, hash; + Dee_hash_t i, perturb, hash; DeeObject *name; if (DeeArg_Unpack(argc, argv, "o:offsetof", &name)) goto err; @@ -355,7 +265,7 @@ struct_type_offsetof(DeeStructTypeObject *self, size_t argc, DeeObject *const *a PRIVATE WUNUSED NONNULL((1)) DREF DeeObject *DCALL struct_type_offsetafter(DeeStructTypeObject *self, size_t argc, DeeObject *const *argv) { - dhash_t i, perturb, hash; + Dee_hash_t i, perturb, hash; DeeObject *name; if (DeeArg_Unpack(argc, argv, "o:offsetafter", &name)) goto err; @@ -384,7 +294,7 @@ struct_type_offsetafter(DeeStructTypeObject *self, size_t argc, DeeObject *const PRIVATE WUNUSED NONNULL((1)) DREF DeeObject *DCALL struct_type_typeof(DeeStructTypeObject *self, size_t argc, DeeObject *const *argv) { - dhash_t i, perturb, hash; + Dee_hash_t i, perturb, hash; DeeObject *name; if (DeeArg_Unpack(argc, argv, "o:typeof", &name)) goto err; @@ -496,7 +406,7 @@ PRIVATE WUNUSED NONNULL((1, 3)) DREF struct lvalue_object *DCALL struct_getattr(DeeStructTypeObject *tp_self, void *self, DeeObject *name) { DREF struct lvalue_object *result; - dhash_t i, perturb, hash; + Dee_hash_t i, perturb, hash; hash = DeeString_Hash(name); i = perturb = STRUCT_TYPE_HASHST(tp_self, hash); for (;; STRUCT_TYPE_HASHNX(i, perturb)) { @@ -525,7 +435,7 @@ struct_getattr(DeeStructTypeObject *tp_self, PRIVATE WUNUSED NONNULL((1, 3)) int DCALL struct_delattr(DeeStructTypeObject *tp_self, void *self, DeeObject *name) { - dhash_t i, perturb, hash; + Dee_hash_t i, perturb, hash; hash = DeeString_Hash(name); i = perturb = STRUCT_TYPE_HASHST(tp_self, hash); for (;; STRUCT_TYPE_HASHNX(i, perturb)) { @@ -553,7 +463,7 @@ PRIVATE WUNUSED NONNULL((1, 3, 4)) int DCALL struct_setattr(DeeStructTypeObject *tp_self, void *self, DeeObject *name, DeeObject *value) { - dhash_t i, perturb, hash; + Dee_hash_t i, perturb, hash; hash = DeeString_Hash(name); i = perturb = STRUCT_TYPE_HASHST(tp_self, hash); for (;; STRUCT_TYPE_HASHNX(i, perturb)) { diff --git a/src/dex/net/sockaddr.c b/src/dex/net/sockaddr.c index 59a71f85..82fa3291 100644 --- a/src/dex/net/sockaddr.c +++ b/src/dex/net/sockaddr.c @@ -420,12 +420,12 @@ sock_getprotoname(int value) { DBG_ALIGNMENT_ENABLE(); if (ent && (name = ent->p_name) != NULL) { name_length = strlen(name); - result = (DREF DeeStringObject *)DeeObject_TryMalloc(offsetof(DeeStringObject, s_str) + - (name_length + 1) * sizeof(char)); + result = (DREF DeeStringObject *)DeeObject_TryMallocc(offsetof(DeeStringObject, s_str), + name_length + 1, sizeof(char)); if unlikely(!result) { sysdb_lock_endwrite(); - if (Dee_CollectMemory(offsetof(DeeStringObject, s_str) + - (name_length + 1) * sizeof(char))) + if (Dee_CollectMemoryoc(offsetof(DeeStringObject, s_str), + name_length + 1, sizeof(char))) goto again; return NULL; } @@ -778,12 +778,12 @@ sock_gethostbyaddr(void const *__restrict data, socklen_t datalen, goto nodns2; name_length = strlen(hp->h_name); /* Safely copy the host's name. */ - result = (DeeStringObject *)DeeObject_TryMalloc(offsetof(DeeStringObject, s_str) + - (name_length + 1) * sizeof(char)); + result = (DeeStringObject *)DeeObject_TryMallocc(offsetof(DeeStringObject, s_str), + name_length + 1, sizeof(char)); if unlikely(!result) { sysdb_lock_endwrite(); - if (Dee_CollectMemory(offsetof(DeeStringObject, s_str) + - (name_length + 1) * sizeof(char))) + if (Dee_CollectMemoryoc(offsetof(DeeStringObject, s_str), + name_length + 1, sizeof(char))) goto restart; goto err; } diff --git a/src/dex/posix/libposix.h b/src/dex/posix/libposix.h index 9e634a57..52b3f4ae 100644 --- a/src/dex/posix/libposix.h +++ b/src/dex/posix/libposix.h @@ -934,7 +934,7 @@ typedef struct { DWORD SubAuthority[256]; } NT_SID; -#define NT_SID_SIZEOF(SubAuthorityCount) (offsetof(NT_SID, SubAuthority) + (SubAuthorityCount) * sizeof(DWORD)) +#define NT_SID_SIZEOF(SubAuthorityCount) _Dee_MallococBufsize(offsetof(NT_SID, SubAuthority), SubAuthorityCount, sizeof(DWORD)) #define NT_SID_GET_SIZEOF(self) NT_SID_SIZEOF((self)->SubAuthorityCount) /* Encode an SID as a deemon integer */ diff --git a/src/dex/rt/slab.c b/src/dex/rt/slab.c index bc7ee6eb..54fdb211 100644 --- a/src/dex/rt/slab.c +++ b/src/dex/rt/slab.c @@ -45,16 +45,16 @@ PRIVATE WUNUSED DREF SlabStatObject *DCALL ss_ctor(void) { size_t reqsize; DREF SlabStatObject *result; DREF SlabStatObject *new_result; - result = (DREF SlabStatObject *)DeeObject_Malloc(offsetof(SlabStatObject, st_stat.st_slabs) + - Dee_SLAB_COUNT * sizeof(DeeSlabInfo)); + result = (DREF SlabStatObject *)DeeObject_Mallocc(offsetof(SlabStatObject, st_stat.st_slabs), + Dee_SLAB_COUNT, sizeof(DeeSlabInfo)); if unlikely(!result) goto done; reqsize = DeeSlab_Stat(&result->st_stat, - offsetof(DeeSlabStat, st_slabs) + - (Dee_SLAB_COUNT * sizeof(DeeSlabInfo))); + _Dee_MallococBufsize(offsetof(DeeSlabStat, st_slabs), + Dee_SLAB_COUNT, sizeof(DeeSlabInfo))); if unlikely(reqsize > - offsetof(DeeSlabStat, st_slabs) + - (Dee_SLAB_COUNT * sizeof(DeeSlabInfo))) { + _Dee_MallococBufsize(offsetof(DeeSlabStat, st_slabs), + Dee_SLAB_COUNT, sizeof(DeeSlabInfo))) { size_t oldsize; do_realloc_result: oldsize = reqsize; @@ -68,8 +68,8 @@ PRIVATE WUNUSED DREF SlabStatObject *DCALL ss_ctor(void) { if unlikely(reqsize > oldsize) goto do_realloc_result; } else if unlikely(reqsize < - offsetof(DeeSlabStat, st_slabs) + - (Dee_SLAB_COUNT * sizeof(DeeSlabInfo))) { + _Dee_MallococBufsize(offsetof(DeeSlabStat, st_slabs), + Dee_SLAB_COUNT, sizeof(DeeSlabInfo))) { new_result = (DREF SlabStatObject *)DeeObject_TryRealloc(result, offsetof(SlabStatObject, st_stat) + reqsize); @@ -84,9 +84,8 @@ PRIVATE WUNUSED DREF SlabStatObject *DCALL ss_ctor(void) { return NULL; } -#define SLABSTAT_DATASIZE(x) \ - (offsetof(DeeSlabStat, st_slabs) + \ - ((x)->st_stat.st_slabcount * sizeof(DeeSlabInfo))) +#define SLABSTAT_DATASIZE(x) \ + _Dee_MallococBufsize(offsetof(DeeSlabStat, st_slabs), (x)->st_stat.st_slabcount, sizeof(DeeSlabInfo)) PRIVATE WUNUSED NONNULL((1)) Dee_hash_t DCALL ss_hash(SlabStatObject *__restrict self) { diff --git a/src/dex/threading/lock.c b/src/dex/threading/lock.c index 905b7758..cdf98239 100644 --- a/src/dex/threading/lock.c +++ b/src/dex/threading/lock.c @@ -2106,11 +2106,11 @@ typedef struct { COMPILER_FLEXIBLE_ARRAY(DREF DeeObject *, lu_elem); /* [1..1][const][lu_size] Managed locks. */ } LockUnion; #define LockUnion_Alloc(size) \ - (LockUnion *)DeeObject_Malloc(offsetof(LockUnion, lu_elem) + ((size) * sizeof(DREF DeeObject *))) + (LockUnion *)DeeObject_Mallocc(offsetof(LockUnion, lu_elem), size, sizeof(DREF DeeObject *)) #define LockUnion_Realloc(ptr, size) \ - (LockUnion *)DeeObject_Realloc(ptr, offsetof(LockUnion, lu_elem) + ((size) * sizeof(DREF DeeObject *))) + (LockUnion *)DeeObject_Reallocc(ptr, offsetof(LockUnion, lu_elem), size, sizeof(DREF DeeObject *)) #define LockUnion_TryRealloc(ptr, size) \ - (LockUnion *)DeeObject_TryRealloc(ptr, offsetof(LockUnion, lu_elem) + ((size) * sizeof(DREF DeeObject *))) + (LockUnion *)DeeObject_TryReallocc(ptr, offsetof(LockUnion, lu_elem), size, sizeof(DREF DeeObject *)) #define LockUnion_Free(ptr) DeeObject_Free(ptr) struct lock_union_allocator { diff --git a/src/dex/threading/tls.c b/src/dex/threading/tls.c index 8cf55b41..b84c2c37 100644 --- a/src/dex/threading/tls.c +++ b/src/dex/threading/tls.c @@ -61,9 +61,8 @@ thread_tls_get(size_t index) { goto err; } old_size = desc ? desc->td_size : 0; - desc = (struct tls_descriptor *)Dee_Realloc(desc, - offsetof(struct tls_descriptor, td_elem) + - (index + 1) * sizeof(DREF DeeObject *)); + desc = (struct tls_descriptor *)Dee_Reallococ(desc, offsetof(struct tls_descriptor, td_elem), + index + 1, sizeof(DREF DeeObject *)); if unlikely(!desc) goto err; diff --git a/util/test/ctypes-struct.dee b/util/test/ctypes-struct.dee new file mode 100644 index 00000000..81ca403f --- /dev/null +++ b/util/test/ctypes-struct.dee @@ -0,0 +1,38 @@ +#!/usr/bin/deemon +/* Copyright (c) 2018-2024 Griefer@Work * + * * + * This software is provided 'as-is', without any express or implied * + * warranty. In no event will the authors be held liable for any damages * + * arising from the use of this software. * + * * + * Permission is granted to anyone to use this software for any purpose, * + * including commercial applications, and to alter it and redistribute it * + * freely, subject to the following restrictions: * + * * + * 1. The origin of this software must not be misrepresented; you must not * + * claim that you wrote the original software. If you use this software * + * in a product, an acknowledgement (see the following) in the product * + * documentation is required: * + * Portions Copyright (c) 2018-2024 Griefer@Work * + * 2. Altered source versions must be plainly marked as such, and must not be * + * misrepresented as being the original software. * + * 3. This notice may not be removed or altered from any source distribution. * + */ + +import deemon; +import * from ctypes; + +struct Point { + ("x", int), + ("y", int), +}; + +local p = Point(); + +assert p.x == 0; +assert p.y == 0; +p.x = 10; +p.y = 20; +assert p.x == 10; +assert p.y == 20; +