@@ -90,6 +90,16 @@ typedef struct objc_category* Category;
9090
9191#import " Foundation/NSString.h"
9292
93+ /* * Macro to call malloc() to allocate memory from the heap for N items of
94+ * type T. If the call to malloc() fails, this raises an exception reporting
95+ * the number and size of the items requested.
96+ */
97+ #define GS_MALLOC (N, T ) \
98+ ((T*)malloc((N) * sizeof (T)) ?: (\
99+ [NSException raise: NSInternalInconsistencyException \
100+ format: @" Failed to create buffer for %lu items of size %u " ,\
101+ (unsigned long )(N), (unsigned )sizeof (T)], __builtin_unreachable(), (T*)0 ))
102+
93103/* *
94104 * Macro to manage memory for chunks of code that need to work with
95105 * arrays of items. Use this to start the block of code using
@@ -108,36 +118,36 @@ __attribute__((unused)) static void GSFreeTempBuffer(void **b)
108118}
109119# define GS_BEGINITEMBUF (P, S, T ) { \
110120 unsigned _ilen = (S) > 0 ? (S) : 1 ; \
111- T _ibuf[_ilen <= GS_MAX_OBJECTS_FROM_STACK ? _ilen : 1 ]; \
121+ T _ibuf[_ilen <= GS_MAX_BYTES_FROM_STACK / sizeof (T) ? _ilen : 1 ]; \
112122 T *P = _ibuf;\
113123 __attribute__ ((cleanup (GSFreeTempBuffer))) void *_base = 0 ;\
114- if (_ilen > GS_MAX_OBJECTS_FROM_STACK )\
124+ if (_ilen > GS_MAX_BYTES_FROM_STACK / sizeof (T) )\
115125 {\
116- _base = malloc (_ilen * sizeof (T) );\
126+ _base = GS_MALLOC (_ilen, T );\
117127 P = _base;\
118128 }
119129# define GS_BEGINITEMBUF2 (P, S, T ) { \
120130 unsigned _ilen2 = (S) > 0 ? (S) : 1 ; \
121- T _ibuf2[_ilen2 <= GS_MAX_OBJECTS_FROM_STACK ? _ilen2 : 1 ]; \
131+ T _ibuf2[_ilen2 <= GS_MAX_BYTES_FROM_STACK / sizeof (T) ? _ilen2 : 1 ]; \
122132 T *P = _ibuf2;\
123133 __attribute__ ((cleanup (GSFreeTempBuffer))) void *_base2 = 0 ;\
124- if (_ilen2 > GS_MAX_OBJECTS_FROM_STACK )\
134+ if (_ilen2 > GS_MAX_BYTES_FROM_STACK / sizeof (T) )\
125135 {\
126- _base2 = malloc (_ilen2 * sizeof (T) );\
136+ _base2 = GS_MALLOC (_ilen2, T );\
127137 P = _base2;\
128138 }
129139#else
130140# define GS_BEGINITEMBUF (P, S, T ) { \
131141 unsigned _ilen = (S) > 0 ? (S) : 1 ; \
132- T _ibuf[_ilen <= GS_MAX_OBJECTS_FROM_STACK ? _ilen : 1 ]; \
133- T *_base = (_ilen <= GS_MAX_OBJECTS_FROM_STACK ) ? _ibuf \
134- : (T*) malloc ( _ilen * sizeof (T) ); \
142+ T _ibuf[_ilen <= GS_MAX_BYTES_FROM_STACK / sizeof (T) ? _ilen : 1 ]; \
143+ T *_base = (_ilen <= GS_MAX_BYTES_FROM_STACK / sizeof (T) ) ? _ibuf \
144+ : GS_MALLOC ( _ilen, T ); \
135145 T *(P) = _base;
136146# define GS_BEGINITEMBUF2 (P, S, T ) { \
137147 unsigned _ilen2 = (S) > 0 ? (S) : 1 ; \
138- T _ibuf2[_ilen2 <= GS_MAX_OBJECTS_FROM_STACK ? _ilen2 : 1 ]; \
139- T *_base2 = (_ilen2 <= GS_MAX_OBJECTS_FROM_STACK ) ? _ibuf2 \
140- : (T*) malloc ( _ilen2 * sizeof (T) ); \
148+ T _ibuf2[_ilen2 <= GS_MAX_BYTES_FROM_STACK / sizeof (T) ? _ilen2 : 1 ]; \
149+ T *_base2 = (_ilen2 <= GS_MAX_BYTES_FROM_STACK / sizeof (T) ) ? _ibuf2 \
150+ : GS_MALLOC ( _ilen2, T ); \
141151 T *(P) = _base2;
142152#endif
143153
0 commit comments