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