1 2 #ifdef __STDC__ 3 #include <stdlib.h> 4 #else 5 #include <memory.h> 6 #include <string.h> 7 #endif 8 9 #if defined(__TINYC__) || defined(__HP_cc) 10 typedef union mem_cell 11 { 12 union mem_cell *next; /* A pointer to the next mem */ 13 unsigned int size; /* An int >= sizeof pointer */ 14 char *depth; /* For the alloca hack */ 15 } 16 mem; 17 18 #define m_size(p) ((p) [0].size) /* For malloc */ 19 #define m_next(p) ((p) [1].next) /* For malloc and alloca */ 20 #define m_deep(p) ((p) [0].depth) /* For alloca */ 21 22 static mem *alloca_stack = 0; 23 24 void * alloca(size)25alloca(size) 26 size_t size; 27 { 28 auto char probe; /* Probes stack depth: */ 29 register mem *hp; 30 31 /* 32 * Reclaim garbage, defined as all alloca'd storage that was allocated 33 * from deeper in the stack than currently. 34 */ 35 36 for (hp = alloca_stack; hp != 0;) 37 if (m_deep(hp) < &probe) 38 { 39 register mem *np = m_next(hp); 40 free((void *) hp); /* Collect garbage. */ 41 hp = np; /* -> next header. */ 42 } 43 else 44 break; /* Rest are not deeper. */ 45 46 alloca_stack = hp; /* -> last valid storage. */ 47 if (size == 0) 48 return 0; /* No allocation required. */ 49 50 hp = (mem *) malloc(sizeof(mem)*2 + size); 51 if (hp == 0) 52 return hp; 53 54 m_next(hp) = alloca_stack; 55 m_deep(hp) = &probe; 56 alloca_stack = hp; 57 58 /* User storage begins just after header. */ 59 return (void *) (hp + 2); 60 } 61 #endif 62