@@ -84,6 +84,47 @@ static SECP256K1_INLINE void *checked_realloc(const secp256k1_callback* cb, void
8484 return ret ;
8585}
8686
87+ #if defined(__BIGGEST_ALIGNMENT__ )
88+ #define ALIGNMENT __BIGGEST_ALIGNMENT__
89+ #else
90+ /* Using 16 bytes alignment because common architectures never have alignment
91+ * requirements above 8 for any of the types we care about. In addition we
92+ * leave some room because currently we don't care about a few bytes. */
93+ #define ALIGNMENT 16
94+ #endif
95+
96+ #define ROUND_TO_ALIGN (size ) (((size + ALIGNMENT - 1) / ALIGNMENT) * ALIGNMENT)
97+
98+ /* Assume there is a contiguous memory object with bounds [base, base + max_size)
99+ * of which the memory range [base, *prealloc_ptr) is already allocated for usage,
100+ * where *prealloc_ptr is an aligned pointer. In that setting, this functions
101+ * reserves the subobject [*prealloc_ptr, *prealloc_ptr + alloc_size) of
102+ * alloc_size bytes by increasing *prealloc_ptr accordingly, taking into account
103+ * alignment requirements.
104+ *
105+ * The function returns an aligned pointer to the newly allocated subobject.
106+ *
107+ * This is useful for manual memory management: if we're simply given a block
108+ * [base, base + max_size), the caller can use this function to allocate memory
109+ * in this block and keep track of the current allocation state with *prealloc_ptr.
110+ *
111+ * It is VERIFY_CHECKed that there is enough space left in the memory object and
112+ * *prealloc_ptr is aligned relative to base.
113+ */
114+ static SECP256K1_INLINE void * manual_alloc (void * * prealloc_ptr , size_t alloc_size , void * base , size_t max_size ) {
115+ size_t aligned_alloc_size = ROUND_TO_ALIGN (alloc_size );
116+ void * ret ;
117+ VERIFY_CHECK (prealloc_ptr != NULL );
118+ VERIFY_CHECK (* prealloc_ptr != NULL );
119+ VERIFY_CHECK (base != NULL );
120+ VERIFY_CHECK ((unsigned char * )* prealloc_ptr >= (unsigned char * )base );
121+ VERIFY_CHECK (((unsigned char * )* prealloc_ptr - (unsigned char * )base ) % ALIGNMENT == 0 );
122+ VERIFY_CHECK ((unsigned char * )* prealloc_ptr - (unsigned char * )base + aligned_alloc_size <= max_size );
123+ ret = * prealloc_ptr ;
124+ * ((unsigned char * * )prealloc_ptr ) += aligned_alloc_size ;
125+ return ret ;
126+ }
127+
87128/* Macro for restrict, when available and not in a VERIFY build. */
88129#if defined(SECP256K1_BUILD ) && defined(VERIFY )
89130# define SECP256K1_RESTRICT
0 commit comments