5 /* Aggregate SAA components smaller than this */
6 #define SAA_BLKSHIFT 16
7 #define SAA_BLKLEN ((size_t)1 << SAA_BLKSHIFT)
9 struct SAA *saa_init(size_t elem_len)
14 s = nasm_zalloc(sizeof(struct SAA));
16 if (elem_len >= SAA_BLKLEN)
17 s->blk_len = elem_len;
19 s->blk_len = SAA_BLKLEN - (SAA_BLKLEN % elem_len);
21 s->elem_len = elem_len;
22 s->length = s->blk_len;
23 data = nasm_malloc(s->blk_len);
24 s->nblkptrs = s->nblks = 1;
25 s->blk_ptrs = nasm_malloc(sizeof(char *));
26 s->blk_ptrs[0] = data;
27 s->wblk = s->rblk = &s->blk_ptrs[0];
32 void saa_free(struct SAA *s)
37 for (p = s->blk_ptrs, n = s->nblks; n; p++, n--)
40 nasm_free(s->blk_ptrs);
44 /* Add one allocation block to an SAA */
45 static void saa_extend(struct SAA *s)
47 size_t blkn = s->nblks++;
49 if (blkn >= s->nblkptrs) {
50 size_t rindex = s->rblk - s->blk_ptrs;
51 size_t windex = s->wblk - s->blk_ptrs;
54 s->blk_ptrs = nasm_realloc(s->blk_ptrs, s->nblkptrs*sizeof(char *));
56 s->rblk = s->blk_ptrs + rindex;
57 s->wblk = s->blk_ptrs + windex;
60 s->blk_ptrs[blkn] = nasm_malloc(s->blk_len);
61 s->length += s->blk_len;
64 void *saa_wstruct(struct SAA *s)
68 if (s->wpos % s->elem_len)
69 nasm_malloc_error(ERR_PANIC|ERR_NOFILE,
70 "misaligned wpos in saa_wstruct");
72 if (s->wpos + s->elem_len > s->blk_len) {
73 if (s->wpos != s->blk_len)
74 nasm_malloc_error(ERR_PANIC|ERR_NOFILE,
75 "unfilled block in saa_wstruct");
77 if (s->wptr + s->elem_len > s->length)
83 p = *s->wblk + s->wpos;
84 s->wpos += s->elem_len;
85 s->wptr += s->elem_len;
87 if (s->wptr > s->datalen)
93 void saa_wbytes(struct SAA *s, const void *data, size_t len)
98 size_t l = s->blk_len - s->wpos;
103 memcpy(*s->wblk + s->wpos, d, l);
106 memset(*s->wblk + s->wpos, 0, l);
111 if (s->datalen < s->wptr)
112 s->datalen = s->wptr;
115 if (s->wptr >= s->length)
123 void saa_rewind(struct SAA *s)
125 s->rblk = s->blk_ptrs;
126 s->rpos = s->rptr = 0;
129 void *saa_rstruct(struct SAA *s)
133 if (s->rptr + s->elem_len > s->datalen)
136 if (s->rpos % s->elem_len)
137 nasm_malloc_error(ERR_PANIC|ERR_NOFILE,
138 "misaligned rpos in saa_rstruct");
140 if (s->rpos + s->elem_len > s->blk_len) {
145 p = *s->rblk + s->rpos;
146 s->rpos += s->elem_len;
147 s->rptr += s->elem_len;
152 const void *saa_rbytes(struct SAA *s, size_t *lenp)
157 if (s->rptr >= s->datalen) {
162 if (s->rpos >= s->blk_len) {
168 if (len > s->datalen - s->rptr)
169 len = s->datalen - s->rptr;
170 if (len > s->blk_len - s->rpos)
171 len = s->blk_len - s->rpos;
174 p = *s->rblk + s->rpos;
182 void saa_rnbytes(struct SAA *s, void *data, size_t len)
186 if (s->rptr + len > s->datalen) {
187 nasm_malloc_error(ERR_PANIC|ERR_NOFILE, "overrun in saa_rnbytes");
196 p = saa_rbytes(s, &l);
204 /* Same as saa_rnbytes, except position the counter first */
205 void saa_fread(struct SAA *s, size_t posn, void *data, size_t len)
209 if (posn+len > s->datalen) {
210 nasm_malloc_error(ERR_PANIC|ERR_NOFILE, "overrun in saa_fread");
214 if (s->elem_len == 1) {
215 ix = posn >> SAA_BLKSHIFT;
216 s->rpos = posn & (SAA_BLKLEN-1);
218 ix = posn / s->blk_len;
219 s->rpos = posn % s->blk_len;
222 s->rblk = &s->blk_ptrs[ix];
224 saa_rnbytes(s, data, len);
227 /* Same as saa_wbytes, except position the counter first */
228 void saa_fwrite(struct SAA *s, size_t posn, const void *data, size_t len)
232 if (posn > s->datalen) {
233 /* Seek beyond the end of the existing array not supported */
234 nasm_malloc_error(ERR_PANIC|ERR_NOFILE, "overrun in saa_fwrite");
239 if (s->elem_len == 1) {
240 ix = posn >> SAA_BLKSHIFT;
241 s->wpos = posn & (SAA_BLKLEN-1);
243 ix = posn / s->blk_len;
244 s->wpos = posn % s->blk_len;
247 s->wblk = &s->blk_ptrs[ix];
250 s->wpos = s->blk_len;
254 saa_wbytes(s, data, len);
257 void saa_fpwrite(struct SAA *s, FILE * fp)
263 while (len = s->datalen, (data = saa_rbytes(s, &len)) != NULL)
264 fwrite(data, 1, len, fp);
267 void saa_write8(struct SAA *s, uint8_t v)
269 saa_wbytes(s, &v, 1);
272 #ifdef WORDS_LITTEENDIAN
274 void saa_write16(struct SAA *s, uint16_t v)
276 saa_wbytes(s, &v, 2);
279 void saa_write32(struct SAA *s, uint32_t v)
281 saa_wbytes(s, &v, 4);
284 void saa_write64(struct SAA *s, uint64_t v)
286 saa_wbytes(s, &v, 8);
289 #else /* not WORDS_LITTLEENDIAN */
291 void saa_write16(struct SAA *s, uint16_t v)
300 void saa_write32(struct SAA *s, uint32_t v)
311 void saa_write64(struct SAA *s, uint64_t v)
326 #endif /* WORDS_LITTLEENDIAN */
328 /* write unsigned LEB128 value to SAA */
329 void saa_wleb128u(struct SAA *psaa, int value)
331 char temp[64], *ptemp;
341 if (value != 0) /* more bytes to come */
346 } while (value != 0);
347 saa_wbytes(psaa, temp, len);
350 /* write signed LEB128 value to SAA */
351 void saa_wleb128s(struct SAA *psaa, int value)
353 char temp[64], *ptemp;
360 negative = (value < 0);
361 size = sizeof(int) * 8;
369 value |= - (1 <<(size - 7));
370 /* sign bit of byte is second high order bit (0x40) */
371 if ((value == 0 && ! (byte & 0x40)) ||
372 ((value == -1) && (byte & 0x40)))
380 saa_wbytes(psaa, temp, len);