1 /*
2 * Copyright (C) 2002-2009, Parrot Foundation.
3 */
4
5 /*
6
7 =head1 NAME
8
9 compilers/imcc/imc.c
10
11 =head1 DESCRIPTION
12
13 Routines for handling imc_units, which represent subs.
14
15 Moved all register allocation and spill code to reg_alloc.c
16
17 =head2 Functions
18
19 =over 4
20
21 =cut
22
23 */
24
25 #include <string.h>
26 #include "imc.h"
27 #include "optimizer.h"
28
29 /* HEADERIZER HFILE: compilers/imcc/imc.h */
30
31 /* HEADERIZER BEGIN: static */
32 /* Don't modify between HEADERIZER BEGIN / HEADERIZER END. Your changes will be lost. */
33
34 static void imc_free_unit(ARGMOD(imc_info_t * imcc), ARGMOD(IMC_Unit *unit))
35 __attribute__nonnull__(1)
36 __attribute__nonnull__(2)
37 FUNC_MODIFIES(* imcc)
38 FUNC_MODIFIES(*unit);
39
40 PARROT_CANNOT_RETURN_NULL
41 PARROT_MALLOC
42 static IMC_Unit * imc_new_unit(ARGMOD(imc_info_t * imcc), IMC_Unit_Type t)
43 __attribute__nonnull__(1)
44 FUNC_MODIFIES(* imcc);
45
46 #define ASSERT_ARGS_imc_free_unit __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
47 PARROT_ASSERT_ARG(imcc) \
48 , PARROT_ASSERT_ARG(unit))
49 #define ASSERT_ARGS_imc_new_unit __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
50 PARROT_ASSERT_ARG(imcc))
51 /* Don't modify between HEADERIZER BEGIN / HEADERIZER END. Your changes will be lost. */
52 /* HEADERIZER END: static */
53
54 #define COMPILE_IMMEDIATE 1
55
56 /*
57
58 =item C<void imc_compile_all_units(imc_info_t * imcc)>
59
60 Compiles all imc_units, and free all memory of instructions and structures
61 afterwards.
62
63 =cut
64
65 */
66
67 void
imc_compile_all_units(ARGMOD (imc_info_t * imcc))68 imc_compile_all_units(ARGMOD(imc_info_t * imcc))
69 {
70 ASSERT_ARGS(imc_compile_all_units)
71 /* compile all units created during the parse */
72 IMC_Unit *unit;
73
74 #if ! COMPILE_IMMEDIATE
75 for (unit = imcc->imc_units; unit;) {
76 IMC_Unit * const unit_next = unit->next;
77 imc_compile_unit(imcc, unit);
78 unit = unit_next;
79 }
80 #endif
81
82 emit_close(imcc, NULL);
83
84 /* All done with compilation, now free all memory allocated
85 * for instructions and other structures. */
86 for (unit = imcc->imc_units; unit;) {
87 IMC_Unit * const unit_next = unit->next;
88 Instruction *ins;
89
90 for (ins = unit->instructions; ins;) {
91 Instruction * const ins_next = ins->next;
92 free_ins(ins);
93 ins = ins_next;
94 }
95
96 imc_free_unit(imcc, unit);
97 unit = unit_next;
98 }
99
100 imcc->imc_units = NULL;
101 imcc->cur_unit = NULL;
102 imcc->last_unit = NULL;
103 }
104
105
106 /*
107
108 =item C<void imc_compile_unit(imc_info_t * imcc, IMC_Unit *unit)>
109
110 Compiles each unit in IMCC. This is the main loop of the compiler; it operates
111 on a single compilation unit at a time.
112
113 =cut
114
115 */
116
117 void
imc_compile_unit(ARGMOD (imc_info_t * imcc),ARGIN (IMC_Unit * unit))118 imc_compile_unit(ARGMOD(imc_info_t * imcc), ARGIN(IMC_Unit *unit))
119 {
120 ASSERT_ARGS(imc_compile_unit)
121 /* Not much here for now except the allocator */
122 imcc->cur_unit = unit;
123
124 imc_reg_alloc(imcc, unit);
125 emit_flush(imcc, NULL, unit);
126 }
127
128
129 /*
130
131 =item C<void imc_cleanup(imc_info_t * imcc, void *yyscanner)>
132
133 Cleans up the compiler state in preparation for another compiler invocation.
134
135 =cut
136
137 */
138
139 void
imc_cleanup(ARGMOD (imc_info_t * imcc),ARGIN_NULLOK (void * yyscanner))140 imc_cleanup(ARGMOD(imc_info_t * imcc), ARGIN_NULLOK(void *yyscanner))
141 {
142 ASSERT_ARGS(imc_cleanup)
143 IMCC_pop_parser_state(imcc, yyscanner);
144 clear_globals(imcc);
145 mem_sys_free(imcc->ghash.data);
146 imcc->ghash.data = NULL;
147
148 if (imcc->state)
149 imcc->state->file = STRINGNULL;
150 imcc->last_unit = NULL;
151 }
152
153
154 /*
155
156 =item C<static IMC_Unit * imc_new_unit(imc_info_t * imcc, IMC_Unit_Type t)>
157
158 Creates a new IMC_Unit of the given IMC_Unit_Type C<t>.
159
160 =cut
161
162 */
163
164 PARROT_CANNOT_RETURN_NULL
165 PARROT_MALLOC
166 static IMC_Unit *
imc_new_unit(ARGMOD (imc_info_t * imcc),IMC_Unit_Type t)167 imc_new_unit(ARGMOD(imc_info_t * imcc), IMC_Unit_Type t)
168 {
169 ASSERT_ARGS(imc_new_unit)
170 IMC_Unit * const unit = mem_gc_allocate_zeroed_typed(imcc->interp, IMC_Unit);
171 create_symhash(imcc, &unit->hash);
172 unit->type = t;
173 return unit;
174 }
175
176
177 /*
178
179 =item C<IMC_Unit * imc_open_unit(imc_info_t * imc_info, IMC_Unit_Type t)>
180
181 Creates a new IMC_Unit and "open" it for construction. This sets the current
182 state of the parser. You can close the unit later while retaining all the
183 current state.
184
185 =cut
186
187 */
188
189 PARROT_CANNOT_RETURN_NULL
190 IMC_Unit *
imc_open_unit(ARGMOD (imc_info_t * imc_info),IMC_Unit_Type t)191 imc_open_unit(ARGMOD(imc_info_t * imc_info), IMC_Unit_Type t)
192 {
193 ASSERT_ARGS(imc_open_unit)
194 IMC_Unit * const unit = imc_new_unit(imc_info, t);
195
196 if (!imc_info->imc_units)
197 imc_info->imc_units = unit;
198
199 if (!imc_info->ghash.data)
200 create_symhash(imc_info, &imc_info->ghash);
201
202 unit->prev = imc_info->last_unit;
203
204 if (imc_info->last_unit)
205 imc_info->last_unit->next = unit;
206
207 imc_info->last_unit = unit;
208 imc_info->n_comp_units++;
209
210 unit->file = imc_info->state->file;
211 unit->pasm_file = imc_info->state->pasm_file;
212
213 return unit;
214 }
215
216
217 /*
218
219 =item C<void imc_close_unit(imc_info_t * imcc, IMC_Unit *unit)>
220
221 Closes a unit from compilation. This does not destroy the unit, but leaves it
222 on the list of units.
223
224 =cut
225
226 */
227
228 void
imc_close_unit(ARGMOD (imc_info_t * imcc),ARGIN_NULLOK (IMC_Unit * unit))229 imc_close_unit(ARGMOD(imc_info_t * imcc), ARGIN_NULLOK(IMC_Unit *unit))
230 {
231 ASSERT_ARGS(imc_close_unit)
232 #if COMPILE_IMMEDIATE
233 if (unit)
234 imc_compile_unit(imcc, unit);
235 #endif
236
237 imcc->cur_unit = NULL;
238 }
239
240
241 /*
242
243 =item C<static void imc_free_unit(imc_info_t * imcc, IMC_Unit *unit)>
244
245 Frees an IMC_Unit and all of its associated memory.
246
247 =cut
248
249 */
250
251 static void
imc_free_unit(ARGMOD (imc_info_t * imcc),ARGMOD (IMC_Unit * unit))252 imc_free_unit(ARGMOD(imc_info_t * imcc), ARGMOD(IMC_Unit *unit))
253 {
254 ASSERT_ARGS(imc_free_unit)
255
256 free_reglist(unit);
257
258 /* and cfg ... */
259 clear_basic_blocks(unit);
260
261 if (!imcc->n_comp_units)
262 IMCC_fatal(imcc, 1, "imc_free_unit: non existent unit\n");
263
264 imcc->n_comp_units--;
265
266 clear_locals(unit);
267
268 if (unit->_namespace && unit->owns_namespace)
269 free_sym(unit->_namespace);
270 if (unit->vtable_name)
271 mem_sys_free(unit->vtable_name);
272 if (unit->instance_of)
273 mem_sys_free(unit->instance_of);
274
275 mem_sys_free(unit->hash.data);
276 mem_sys_free(unit);
277 }
278
279 /*
280
281 =back
282
283 =cut
284
285 */
286
287 /*
288 * Local variables:
289 * c-file-style: "parrot"
290 * End:
291 * vim: expandtab shiftwidth=4 cinoptions='\:2=2' :
292 */
293