description header added
[henge/webcc.git] / src / apc / ir-mem.c
1 /*!@file
2 \brief IR Memory Implementation
3 \details Intermediary memory management
4 \author Jordan Lavatai
5 \date Aug 2016
6 ----------------------------------------------------------------------------*/
7 #include <errno.h>
8 #include <stdio.h>
9 #include <stdint.h> //uint64_t
10 #include <string.h> //memmove
11 #include <stdlib.h> //malloc
12 #include <apc/ir.h>
13
14 #define CURR_CDAT (*cdat_stackp)
15 #define CURR_SET set_list[CURR_CDAT->num_sets]
16 #define CURR_ELE ele_list[CURR_CDAT->CURR_SET.num_ele]
17 #define PREV_REF (ref_buf[num_refs-1])
18 #define CURR_REF (ref_buf[num_refs])
19 #define PREV_ODAT (odat_buf[num_odats-1])
20 #define CURR_ODAT (odat_buf[num_odats])
21 #define CURR_VDAT (vdat_buf[num_vdats])
22 #define PREV_VDAT (vdat_buf[num_vdats-1])
23 #define CURR_MODEL model_list[CURR_VDAT->num_models]
24 #define CURR_LINK (link_buf[num_links])
25 #define CURR_POST (post_buf[num_posts])
26
27 int num_cdats = 0;
28 int curr_max_cdats = PTRS_IN_PAGE;
29
30 int num_odats = 0;
31 int curr_max_odats = PTRS_IN_PAGE;
32
33
34 int num_vdats = 0;
35 int curr_max_vdats = PTRS_IN_PAGE;
36
37 int num_refs = 0;
38 int curr_max_refs = PTRS_IN_PAGE;
39 uint64_t ss_ref_id = 0x00FFFFFF; /* system space for ref_ids */
40
41 int num_links = 0;
42 int curr_max_links = PTRS_IN_PAGE;
43
44 int num_posts = 0;
45 int curr_max_posts = PTRS_IN_PAGE;
46
47 void
48 ir_init()
49 {
50 /* Init root cdat and stack */
51 char root[4] = "root";
52
53 cdat_buf[num_cdats] = (struct cdat*) malloc(sizeof(struct cdat) );
54 cdat_buf[num_cdats]->idx = 0;
55 memmove(cdat_buf[num_cdats]->name, root, 4);
56
57 cdat_stackp = cdat_stack;
58 *cdat_stackp = cdat_buf[num_cdats++];
59
60 /* Init first odat */
61 if( (CURR_ODAT = (struct odat*) malloc(sizeof(struct odat))) == NULL)
62 perror("malloc first odat failed");
63
64 /* init first vdat*/
65 if( (CURR_VDAT = (struct vdat*) malloc(sizeof(struct vdat))) == NULL)
66 perror("malloc first vdat failed");
67
68 /* Init first ref */
69 if( (CURR_REF = (struct ref*) malloc(sizeof(struct ref))) == NULL)
70 perror("malloc first ref failed");
71
72 /* Init first link */
73 if( (CURR_LINK = (struct link*) malloc(sizeof(struct link))) == NULL)
74 perror("malloc first link failed");
75
76 /* Init first post */
77 if( (CURR_POST = (struct ref*) malloc(sizeof(struct ref))) == NULL)
78 perror("malloc first post failed");
79 }
80
81 //TODO: FREE MEMORY!
82 void
83 malloc_cdat()
84 {
85
86 if(curr_max_cdats <= num_cdats)
87 {
88 if( (realloc((void*) cdat_buf, PTRS_IN_PAGE * 4)) == NULL)
89 perror("realloc cdat_buf failed");
90 curr_max_cdats += PTRS_IN_PAGE;
91 if( (realloc( (void*) cdat_stack, PTRS_IN_PAGE * 4)) == NULL) //increase cdat_stack also
92 perror("realloc cdat_stack failed");
93 }
94 if( (cdat_buf[num_cdats] = (struct cdat*) malloc(sizeof (struct cdat)) ) == NULL )
95 perror("malloc cdat failed");
96
97
98 }
99
100 /* Dynamically allocate memory for a class data structure,
101 or cdat, after a class has been identified in a grammar.
102 We also create a stack of class pointers so that
103 we can access the cdat during processing of that
104 cdats sets and elements, a requirement because the
105 nature of recursive classes prevents us from accessing
106 the cdat based on the previous index into cdat_buf,
107 which is a list of all allocated cdats*/
108 void
109 push_cdat(char* name)
110 {
111
112 malloc_cdat();
113
114 memmove(cdat_buf[num_cdats]->name, name, 32);
115 cdat_buf[num_cdats]->idx = num_cdats;
116
117 /* Set the cdat as a class of the previous cdat */
118 (*cdat_stackp)->class_list[(*cdat_stackp)->num_classes++] = cdat_buf[num_cdats];
119
120 /* Push the cdat onto the cdat_stack */
121 *++cdat_stackp = cdat_buf[num_cdats++];
122
123 }
124
125 void
126 pop_cdat()
127 {
128 *cdat_stackp = NULL;
129 cdat_stackp--;
130 }
131
132 void
133 inc_posts()
134 {
135 num_posts++;
136 if(num_posts >= curr_max_posts)
137 {
138 if( (realloc((void*) post_buf, PTRS_IN_PAGE * 4)) == NULL)
139 perror("realloc post_buf failed");
140 curr_max_posts += PTRS_IN_PAGE;
141 }
142 if( (CURR_POST = (struct ref*) malloc(sizeof (struct ref))) == NULL)
143 {
144 perror("malloc post failed");
145 }
146
147 }
148 void
149 inc_odat()
150 {
151 num_odats++;
152 if(num_odats >= curr_max_odats)
153 {
154 if( (realloc((void*) odat_buf, PTRS_IN_PAGE * 4)) == NULL)
155 perror("realloc odat_buf failed");
156 curr_max_odats += PTRS_IN_PAGE;
157 }
158 if( (CURR_ODAT = (struct odat*) malloc(sizeof (struct odat))) == NULL)
159 {
160 perror("malloc odat failed");
161 }
162
163 }
164
165 void
166 inc_vdat()
167 {
168 num_vdats++;
169 if(num_vdats >= curr_max_vdats)
170 {
171 if( (realloc((void*) vdat_buf, PTRS_IN_PAGE * 4)) == NULL)
172 perror("realloc vdat_buf failed");
173 curr_max_vdats += PTRS_IN_PAGE;
174 }
175 if((CURR_VDAT = (struct vdat*) malloc(sizeof (struct vdat))) == NULL)
176 {
177 perror("malloc vdat failed");
178 }
179
180 }
181
182 void
183 inc_link()
184 {
185 num_links++;
186 if(num_links >= curr_max_links)
187 {
188 if( (realloc((void*) link_buf, PTRS_IN_PAGE * 4)) == NULL)
189 perror("realloc vdat_buf failed");
190 curr_max_links += PTRS_IN_PAGE;
191 }
192 if((CURR_LINK = (struct link*) malloc(sizeof (struct link))) == NULL)
193 {
194 perror("malloc link failed");
195 }
196 }
197
198 void
199 inc_ref()
200 {
201
202 if(num_refs % 16 == 0)
203 {
204 CURR_POST = CURR_REF;
205 inc_posts();
206 }
207
208 num_refs++;
209 if(num_refs >= curr_max_refs)
210 {
211 if( (realloc((void*) ref_buf, PTRS_IN_PAGE * 4)) == NULL)
212 perror("realloc ref_buf failed");
213 curr_max_refs += PTRS_IN_PAGE;
214 }
215 if((CURR_REF = (struct ref*) malloc(sizeof (struct ref))) == NULL)
216 perror("malloc ref failed");
217 }
218
219 void
220 insert_set_label(char* name, uint64_t ref_id)
221 {
222
223
224 memmove(CURR_CDAT->CURR_SET.name,name,32);
225 memmove(&CURR_CDAT->CURR_SET.ref_id,&ref_id,64);
226
227 }
228 void
229 insert_set_olink(uint64_t ref_id)
230 {
231 CURR_CDAT->CURR_SET.cdat_idx = CURR_CDAT->idx;
232 CURR_CDAT->CURR_SET.ref_id = ref_id; /* Will be resolved to offset
233 when link is processed */
234 CURR_LINK->type = 1;
235 CURR_LINK->link_t.olink.ref_id = ref_id;
236 CURR_LINK->cdat_idx = CURR_CDAT->idx;
237 CURR_LINK->set_idx = CURR_CDAT->num_sets++;
238 CURR_LINK->ele_idx = -1;
239
240 inc_link();
241 }
242
243 void
244 insert_set_vlink(uint64_t ref_id, char* anim_name)
245 {
246 /* Insert vlink into link_stack so that it gets processed at
247 output time */
248 CURR_LINK->cdat_idx = CURR_CDAT->idx;
249 CURR_LINK->set_idx = CURR_CDAT->num_sets;
250 CURR_LINK->type = 2;
251 CURR_LINK->link_t.vlink.ref_id = ref_id;
252 memmove(CURR_LINK->link_t.vlink.anim_name, anim_name, 32);
253
254
255 }
256
257 void
258 insert_set_svlink(uint64_t ref_id)
259 {
260
261 /* Insert vlink into link_stack so that it gets processed at
262 output time */
263 CURR_LINK->cdat_idx = CURR_CDAT->idx;
264 CURR_LINK->set_idx = CURR_CDAT->num_sets;
265 CURR_LINK->type = 3;
266 CURR_LINK->link_t.svlink.ref_id = ref_id;
267
268 }
269
270 /* At the point of reducing to a set, most of the
271 sets odat information has already been populated
272 during the reduction of its right hand side
273 non terminals (hitbox, root, quad_list). */
274 void
275 insert_set()
276 {
277 uint64_t ref_id;
278
279 ref_id = CURR_CDAT->CURR_SET.ref_id;
280
281 CURR_CDAT->CURR_SET.cdat_idx = CURR_CDAT->idx;
282 memmove(CURR_ODAT->name, CURR_CDAT->CURR_SET.name, 32);
283 CURR_CDAT->num_sets++;
284
285 CURR_ODAT->cdat_idx = CURR_CDAT->idx;
286 CURR_ODAT->refp = CURR_REF;
287
288
289 CURR_REF->lastref = PREV_REF;
290 PREV_REF->nextref = CURR_REF;
291 CURR_REF->odatp = CURR_ODAT;
292
293
294 if(ref_id == -1) /* user did not define a ref_id so */
295 { /* use a ref_id from system_space */
296 ref_id = ss_ref_id;
297 ss_ref_id++;
298 }
299
300 CURR_REF->ref_id = ref_id;
301
302
303
304 inc_ref();
305 inc_odat();
306 }
307
308 void
309 insert_vdat()
310 {
311 PREV_ODAT->vdat_id = num_vdats; //NULL for vlink, svlink
312 inc_vdat();
313 }
314
315 /* Populates both the odat name and ref_id
316 for element. */
317 void
318 insert_ele_label(char* name, uint64_t ref_id)
319 {
320 memmove(CURR_CDAT->CURR_SET.CURR_ELE.name, name, 32);
321 memmove(&CURR_CDAT->CURR_SET.ele_list[CURR_CDAT->CURR_SET.ref_id].ref_id, &ref_id, 64);
322 }
323
324 void
325 insert_ele_olink(uint64_t ref_id)
326 {
327 CURR_CDAT->CURR_SET.CURR_ELE.cdat_idx = CURR_CDAT->idx;
328 CURR_CDAT->CURR_SET.CURR_ELE.ref_id = ref_id; /* Will be resolved to offset
329 when link is processed */
330 CURR_LINK->type = 1;
331 CURR_LINK->link_t.olink.ref_id = ref_id;
332 CURR_LINK->cdat_idx = CURR_CDAT->idx;
333 CURR_LINK->set_idx = CURR_CDAT->num_sets++;
334 CURR_LINK->ele_idx = CURR_CDAT->CURR_SET.num_ele++;
335
336 }
337 void
338 insert_ele_vlink(uint64_t ref_id, char* anim_name)
339 {
340
341 /* Insert vlink into link_stack so that it gets processed at
342 output time */
343 CURR_LINK->cdat_idx = CURR_CDAT->idx;
344 CURR_LINK->type = 2;
345 CURR_LINK->set_idx = CURR_CDAT->num_sets;
346 CURR_LINK->ele_idx = CURR_CDAT->CURR_SET.num_ele;
347 CURR_LINK->link_t.vlink.ref_id = ref_id;
348 memmove(CURR_LINK->link_t.vlink.anim_name, anim_name, 32);
349
350
351 }
352 void
353 insert_ele_svlink(uint64_t ref_id)
354 {
355
356 CURR_LINK->cdat_idx = CURR_CDAT->idx;
357 CURR_LINK->type = 3;
358 CURR_LINK->set_idx = CURR_CDAT->num_sets;
359 CURR_LINK->ele_idx = CURR_CDAT->CURR_SET.num_ele;
360 CURR_LINK->link_t.svlink.ref_id = ref_id;
361
362
363 }
364 //Insert element into odat_buf and cdatpages
365 void
366 insert_ele()
367 {
368
369 uint64_t ref_id;
370
371 ref_id = CURR_CDAT->CURR_SET.CURR_ELE.ref_id;
372
373 CURR_CDAT->CURR_SET.CURR_ELE.cdat_idx = CURR_CDAT->idx;
374 memmove(CURR_ODAT->name,CURR_CDAT->CURR_SET.CURR_ELE.name, 32);
375 CURR_CDAT->CURR_SET.num_ele++;
376
377 CURR_ODAT->cdat_idx = CURR_CDAT->idx;
378 CURR_ODAT->refp = CURR_REF;
379
380 if(ref_id == -1) /* user did not define a ref_id so */
381 { /* use a ref_id from system_space */
382 ref_id = ss_ref_id;
383 ss_ref_id++;
384 }
385
386 CURR_REF->ref_id = ref_id;
387
388 inc_odat();
389 inc_ref();
390
391 }
392
393 void
394 insert_framesheet(char direction, char* name, uint64_t ref_id, int height , int width, int num_frames)
395 {
396 CURR_VDAT->CURR_MODEL.spritesheet[(int)direction].height = height;
397 CURR_VDAT->CURR_MODEL.spritesheet[(int)direction].width = width;
398 CURR_VDAT->CURR_MODEL.spritesheet[(int)direction].num_frames = num_frames;
399 CURR_VDAT->num_models++;
400 }
401
402 #define CURR_QUAD (CURR_ODAT->quad_list[CURR_ODAT->num_quads])
403 void
404 insert_quad(int x, int y, int z, uint64_t ref_id)
405 {
406 CURR_QUAD.x = x;
407 CURR_QUAD.y = y;
408 CURR_QUAD.z = z;
409 CURR_QUAD.ref_id = ref_id;
410 CURR_ODAT->num_quads++;
411 }
412
413 /* Inserting the hitbox into the set
414 odat. Elements that don't have
415 a hitbox will use the sets root. */
416 void
417 insert_hitbox(int hitbox)
418 {
419 CURR_ODAT->hitbox = hitbox;
420 }
421
422 /* Inserting the root into the set
423 odat. Elements that don't have
424 a root will use the sets root. */
425 void
426 insert_root(int x, int y, int z)
427 {
428
429 CURR_ODAT->root.x = x;
430 CURR_ODAT->root.y = y;
431 CURR_ODAT->root.z = z;
432 }
433
434 void
435 insert_frame_pointer(char direction, void* frame)
436 {
437 CURR_VDAT->CURR_MODEL.spritesheet[(int)direction].frames[CURR_VDAT->CURR_MODEL.spritesheet[(int)direction].num_frames++] = frame;
438 }
439