Skip to content

Commit ddb4fa5

Browse files
committed
compat: initialize obstack chunks
1 parent efeae16 commit ddb4fa5

1 file changed

Lines changed: 40 additions & 10 deletions

File tree

src/compat.c

Lines changed: 40 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -41,14 +41,20 @@ void xmalloc_set_program_name(const char *name) {
4141

4242
/* Minimal obstack runtime to satisfy obstack.h macros */
4343

44-
static struct _obstack_chunk *alloc_chunk(long size)
44+
static struct _obstack_chunk *init_chunk(struct _obstack_chunk *c, long total_size)
4545
{
46-
struct _obstack_chunk *c = (struct _obstack_chunk *)xmalloc(sizeof(struct _obstack_chunk) + size);
47-
c->limit = (char *)c + sizeof(struct _obstack_chunk) + size;
46+
c->limit = (char *)c + total_size;
4847
c->prev = NULL;
4948
return c;
5049
}
5150

51+
static struct _obstack_chunk *alloc_chunk(long size)
52+
{
53+
long total_size = (long)sizeof(struct _obstack_chunk) + size;
54+
return init_chunk((struct _obstack_chunk *)xmalloc((size_t)total_size),
55+
total_size);
56+
}
57+
5258
int _obstack_begin(struct obstack *h, int size, int alignment,
5359
void *(*chunk_alloc)(long), void (*chunk_free)(void *))
5460
{
@@ -61,7 +67,11 @@ int _obstack_begin(struct obstack *h, int size, int alignment,
6167
/* Allocate first chunk */
6268
struct _obstack_chunk *c;
6369
if (chunk_alloc)
64-
c = (struct _obstack_chunk *)(*chunk_alloc)((long)(size + sizeof(struct _obstack_chunk)));
70+
{
71+
long total_size = (long)sizeof(struct _obstack_chunk) + size;
72+
c = init_chunk((struct _obstack_chunk *)(*chunk_alloc)(total_size),
73+
total_size);
74+
}
6575
else
6676
c = alloc_chunk(size);
6777
c->prev = NULL;
@@ -79,12 +89,29 @@ int _obstack_begin_1(struct obstack *h, int size, int alignment,
7989
void *(*chunk_alloc)(void *, long),
8090
void (*chunk_free)(void *, void *), void *arg)
8191
{
82-
int ok = _obstack_begin(h, size, alignment, NULL, NULL);
92+
if (size <= 0) size = 4096;
93+
h->chunk_size = size;
94+
h->alignment_mask = alignment ? alignment - 1 : 0;
95+
h->maybe_empty_object = 0;
96+
h->alloc_failed = 0;
8397
h->use_extra_arg = 1;
98+
99+
struct _obstack_chunk *c;
100+
if (chunk_alloc)
101+
{
102+
long total_size = (long)sizeof(struct _obstack_chunk) + size;
103+
c = init_chunk((struct _obstack_chunk *)(*chunk_alloc)(arg, total_size),
104+
total_size);
105+
}
106+
else
107+
c = alloc_chunk(size);
108+
h->chunk = c;
109+
h->object_base = h->next_free = c->contents;
110+
h->chunk_limit = c->limit;
84111
h->chunkfun = (struct _obstack_chunk *(*)(void *, long))chunk_alloc;
85112
h->freefun = (void (*)(void *, struct _obstack_chunk *))chunk_free;
86113
h->extra_arg = arg;
87-
return ok;
114+
return 1;
88115
}
89116

90117
void _obstack_newchunk(struct obstack *h, int length)
@@ -95,13 +122,18 @@ void _obstack_newchunk(struct obstack *h, int length)
95122
needed = length + objlen;
96123
struct _obstack_chunk *newc;
97124
if (h->use_extra_arg && h->chunkfun)
98-
newc = (*h->chunkfun)(h->extra_arg, needed + sizeof(struct _obstack_chunk));
125+
{
126+
long total_size = needed + (long)sizeof(struct _obstack_chunk);
127+
newc = init_chunk((*h->chunkfun)(h->extra_arg, total_size),
128+
total_size);
129+
}
99130
else if (h->chunkfun)
100131
{
101132
/* When extra arg is not in use, the allocator has the signature void*(long). */
102133
struct _obstack_chunk *(*alloc_one_arg)(long)
103134
= (struct _obstack_chunk *(*)(long))(void *)h->chunkfun;
104-
newc = alloc_one_arg(needed + sizeof(struct _obstack_chunk));
135+
long total_size = needed + (long)sizeof(struct _obstack_chunk);
136+
newc = init_chunk(alloc_one_arg(total_size), total_size);
105137
}
106138
else
107139
newc = alloc_chunk(needed);
@@ -155,5 +187,3 @@ void obstack_free(struct obstack *h, void *obj)
155187
{
156188
_obstack_free(h, obj);
157189
}
158-
159-

0 commit comments

Comments
 (0)