2 \brief IR Memory Implementation
3 \details Intermediary memory management
6 ----------------------------------------------------------------------------*/
9 #include <stdint.h> //uint64_t
10 #include <string.h> //memmove
11 #include <stdlib.h> //malloc
22 /* The initalization function of the IR. Mallocs the
23 first c/v/odat and the first links and refs and
24 inits the cdat_stack */
29 /* Init root cdat and stack */
30 char root
[4] = "root";
32 cdat_buf
[num_cdats
] = (struct cdat
*) malloc(sizeof(struct cdat
) );
33 cdat_buf
[num_cdats
]->idx
= 0;
34 memmove(cdat_buf
[num_cdats
]->name
, root
, 4);
36 cdat_stackp
= cdat_stack
;
37 *cdat_stackp
= cdat_buf
[num_cdats
++];
45 if(curr_max_cdats
<= num_cdats
)
46 { if( (realloc((void*) cdat_buf
, PTRS_IN_PAGE
* 4)) == NULL
)
47 perror("realloc cdat_buf failed");
48 curr_max_cdats
+= PTRS_IN_PAGE
;
49 if( (realloc( (void*) cdat_stack
, PTRS_IN_PAGE
* 4)) == NULL
) //increase cdat_stack also
50 perror("realloc cdat_stack failed");
52 if( (cdat_buf
[num_cdats
] = (struct cdat
*) malloc(sizeof (struct cdat
)) ) == NULL
)
53 perror("malloc cdat failed");
58 /* Dynamically allocate memory for a class data structure,
59 or cdat, after a class has been identified in a grammar.
60 We also create a stack of class pointers so that
61 we can access the cdat during processing of that
62 cdats sets and elements, a requirement because the
63 nature of recursive classes prevents us from accessing
64 the cdat based on the previous index into cdat_buf,
65 which is a list of all allocated cdats*/
73 memmove(cdat_buf
[num_cdats
]->name
, name
, 32);
74 cdat_buf
[num_cdats
]->idx
= num_cdats
;
76 /* Set the cdat as a class of the previous cdat */
77 (*cdat_stackp
)->class_list
[(*cdat_stackp
)->num_classes
++] = cdat_buf
[num_cdats
];
79 /* Push the cdat onto the cdat_stack */
80 *++cdat_stackp
= cdat_buf
[num_cdats
++];
92 /* Called in the reduction of a set. While both odats (eles and sets)
93 have identical label terminals, we are unable to give a single grammatical rule
94 for both due to how we allocate odats in the odat buf. Due to the
95 nature of bottom up parsing, all the elements will be inserted into the
96 odat_buf first, and then the set that contains these element is inserted. Since
97 the sets label comes before the element list in the grammar, we would be giving an element
98 a set label in its respective odat, which would then be replaced by the
99 elements label. Instead, we store the label in the sets representation inside
100 CURR_CDAT and after we are done parsing the element_list and know that the CURR_ODAT
101 is the set, we populate the sets label members in CURR_ODAT with the values we stored
102 previously in CURR_CDAT. */
110 struct set
* curr_set
;
112 curr_set
= curr_set();
113 memmove(curr_set
.name
,name
,32);
114 curr_set
.ref_id
= ref_id
;
122 struct set
* curr_set
;
123 struct cdat
* curr_cdat
;
124 struct link
* curr_link
;
126 curr_set
= curr_set();
127 curr_cdat
= curr_cdat();
128 curr_link
= alloc_link();
130 curr_set
.cdat_idx
= curr_cdat
->idx
;
131 curr_set
.ref_id
= ref_id
; /* Will be resolved to offset
132 when link is processed */
134 curr_link
->link_t
.olink
.ref_id
= ref_id
;
135 curr_link
->cdat_idx
= curr_cdat
->idx
;
136 curr_link
->set_idx
= curr_cdat
->num_sets
++;
137 curr_link
->ele_idx
= -1;
147 struct cdat
* curr_cdat
;
148 struct link
* curr_link
;
150 curr_cdat
= curr_cdat();
151 curr_link
= alloc_link();
153 /* Insert vlink into link_stack so that it gets processed at
156 curr_link
->cdat_idx
= curr_cdat
->idx
;
157 curr_link
->set_idx
= curr_cdat
->num_sets
;
158 curr_link
->link_t
.vlink
.ref_id
= ref_id
;
159 memmove(curr_link
->link_t
.vlink
.anim_name
, anim_name
, 32);
163 /* Svlinks dont have animation names */
169 struct cdat
* curr_cdat
;
170 struct link
* curr_link
;
172 curr_cdat
= curr_cdat();
173 curr_link
= alloc_link();
175 /* Insert vlink into link_stack so that it gets processed at
178 curr_link
->cdat_idx
= curr_cdat
->idx
;
179 curr_link
->set_idx
= curr_cdat
->num_sets
;
180 curr_link
->link_t
.svlink
.ref_id
= ref_id
;
184 /* At the point of reducing to a set, most of the
185 sets odat information has already been populated
186 during the reduction of its right hand side
187 non terminals (hitbox, root, quad_list). */
192 struct odat
* curr_odat
;
193 struct cdat
* curr_cdat
;
194 struct ref
* prev_ref
;
195 struct ref
* curr_ref
;
197 curr_odat
= alloc_odat();
198 curr_cdat
= curr_cdat();
199 curr_set
= curr_set();
200 prev_ref
= prev_ref();
201 curr_ref
= alloc_ref();
203 ref_id
= curr_set
.ref_id
; // ref_id set by insert_set_label(name, ref_id)
205 curr_set
.cdat_idx
= curr_cdat
->idx
;
206 memmove(curr_odat
->name
, curr_set
.name
, 32);
207 curr_cdat
.num_sets
++;
209 curr_odat
->cdat_idx
= curr_cdaat
->idx
;
210 curr_odat
->refp
= curr_ref
;
213 curr_ref
->lastref
= prev_ref
;
214 prev_ref
->nextref
= curr_ref
;
215 curr_ref
->odatp
= curr_odat
;
218 if(ref_id
== -1) /* user did not define a ref_id so */
219 { ref_id
= ss_ref_id
;
223 curr_ref
->ref_id
= ref_id
;
226 /* Created as a seperate function, instead of setting the ODATS vdat_id and
227 calling inc_vdat() inside of insert_set(), to account for the set reduction
228 where a vdat is not created (o/v/svlinks). */
234 struct odat
* curr_odat
;
235 curr_odat
= curr_odat();
236 curr_odat
->vdat_id
= num_vdats
; //no vdat_id for odats that have vlinks/svlinks
239 /* Populates both the odat name and ref_id
247 struct ele
* curr_ele
;
249 curr_ele
= curr_ele();
251 memmove(curr_ele
.name
, name
, 32);
252 curr_ele
.ref_id
= ref_id
;
260 CURR_CDAT
->CURR_SET
.CURR_ELE
.cdat_idx
= CURR_CDAT
->idx
;
261 CURR_CDAT
->CURR_SET
.CURR_ELE
.ref_id
= ref_id
; /* Will be resolved to offset
262 when link is processed */
264 CURR_LINK
->link_t
.olink
.ref_id
= ref_id
;
265 CURR_LINK
->cdat_idx
= CURR_CDAT
->idx
;
266 CURR_LINK
->set_idx
= CURR_CDAT
->num_sets
++;
267 CURR_LINK
->ele_idx
= CURR_CDAT
->CURR_SET
.num_ele
++;
278 /* Insert vlink into link_stack so that it gets processed at
280 CURR_LINK
->cdat_idx
= CURR_CDAT
->idx
;
282 CURR_LINK
->set_idx
= CURR_CDAT
->num_sets
;
283 CURR_LINK
->ele_idx
= CURR_CDAT
->CURR_SET
.num_ele
;
284 CURR_LINK
->link_t
.vlink
.ref_id
= ref_id
;
285 memmove(CURR_LINK
->link_t
.vlink
.anim_name
, anim_name
, 32);
295 CURR_LINK
->cdat_idx
= CURR_CDAT
->idx
;
297 CURR_LINK
->set_idx
= CURR_CDAT
->num_sets
;
298 CURR_LINK
->ele_idx
= CURR_CDAT
->CURR_SET
.num_ele
;
299 CURR_LINK
->link_t
.svlink
.ref_id
= ref_id
;
304 //Insert element into odat_buf and cdatpages
310 ref_id
= CURR_CDAT
->CURR_SET
.CURR_ELE
.ref_id
;
312 CURR_CDAT
->CURR_SET
.CURR_ELE
.cdat_idx
= CURR_CDAT
->idx
;
313 memmove(CURR_ODAT
->name
,CURR_CDAT
->CURR_SET
.CURR_ELE
.name
, 32);
314 CURR_CDAT
->CURR_SET
.num_ele
++;
316 CURR_ODAT
->cdat_idx
= CURR_CDAT
->idx
;
317 CURR_ODAT
->refp
= CURR_REF
;
319 if(ref_id
== -1) /* user did not define a ref_id so */
320 { ref_id
= ss_ref_id
;
324 CURR_REF
->ref_id
= ref_id
;
341 CURR_VDAT
->CURR_MODEL
.spritesheet
[(int)direction
].height
= height
;
342 CURR_VDAT
->CURR_MODEL
.spritesheet
[(int)direction
].width
= width
;
343 CURR_VDAT
->CURR_MODEL
.spritesheet
[(int)direction
].num_frames
= num_frames
;
344 CURR_VDAT
->num_models
++;
354 #define CURR_QUAD (CURR_ODAT->quad_list[CURR_ODAT->num_quads])
359 CURR_QUAD
.ref_id
= ref_id
;
360 CURR_ODAT
->num_quads
++;
363 /* Inserting the hitbox into the set
364 odat. Elements that don't have
365 a hitbox will use the sets root. */
371 CURR_ODAT
->hitbox
= hitbox
;
374 /* Inserting the root into the set
375 odat. Elements that don't have
376 a root will use the sets root. */
385 CURR_ODAT
->root
.x
= x
;
386 CURR_ODAT
->root
.y
= y
;
387 CURR_ODAT
->root
.z
= z
;
396 CURR_VDAT
->CURR_MODEL
.spritesheet
[(int)direction
].frames
[CURR_VDAT
->CURR_MODEL
.spritesheet
[(int)direction
].num_frames
++] = frame
;