fix codetest failure - ASSERT_ARGS does not have a ; after and
[parrot.git] / compilers / imcc / imc.c
blob6c64dd93305f4c0e580d255b78135ad7c5dab2b9
1 /*
2 * $Id$
3 * Copyright (C) 2002-2009, Parrot Foundation.
4 */
6 /*
8 =head1 NAME
10 compilers/imcc/imc.c
12 =head1 DESCRIPTION
14 Routines for handling imc_units, which represent subs.
16 Moved all register allocation and spill code to reg_alloc.c
18 =head2 Functions
20 =over 4
22 =cut
26 #include <string.h>
27 #include "imc.h"
28 #include "optimizer.h"
30 /* HEADERIZER HFILE: compilers/imcc/imc.h */
32 /* HEADERIZER BEGIN: static */
33 /* Don't modify between HEADERIZER BEGIN / HEADERIZER END. Your changes will be lost. */
35 static void imc_free_unit(PARROT_INTERP, ARGMOD(IMC_Unit *unit))
36 __attribute__nonnull__(1)
37 __attribute__nonnull__(2)
38 FUNC_MODIFIES(*unit);
40 PARROT_CANNOT_RETURN_NULL
41 PARROT_MALLOC
42 static IMC_Unit * imc_new_unit(PARROT_INTERP, IMC_Unit_Type t)
43 __attribute__nonnull__(1);
45 #define ASSERT_ARGS_imc_free_unit __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
46 PARROT_ASSERT_ARG(interp) \
47 , PARROT_ASSERT_ARG(unit))
48 #define ASSERT_ARGS_imc_new_unit __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
49 PARROT_ASSERT_ARG(interp))
50 /* Don't modify between HEADERIZER BEGIN / HEADERIZER END. Your changes will be lost. */
51 /* HEADERIZER END: static */
53 #define COMPILE_IMMEDIATE 1
57 =item C<void imc_compile_all_units(PARROT_INTERP)>
59 Compiles all imc_units, and free all memory of instructions and structures
60 afterwards.
62 =cut
66 void
67 imc_compile_all_units(PARROT_INTERP)
69 ASSERT_ARGS(imc_compile_all_units)
70 /* compile all units created during the parse */
71 IMC_Unit *unit;
73 #if ! COMPILE_IMMEDIATE
74 for (unit = IMCC_INFO(interp)->imc_units; unit;) {
75 IMC_Unit * const unit_next = unit->next;
76 imc_compile_unit(interp, unit);
77 unit = unit_next;
79 #endif
81 emit_close(interp, NULL);
83 /* All done with compilation, now free all memory allocated
84 * for instructions and other structures. */
85 for (unit = IMCC_INFO(interp)->imc_units; unit;) {
86 IMC_Unit * const unit_next = unit->next;
87 Instruction *ins;
89 for (ins = unit->instructions; ins;) {
90 Instruction * const ins_next = ins->next;
91 free_ins(ins);
92 ins = ins_next;
95 imc_free_unit(interp, unit);
96 unit = unit_next;
99 IMCC_INFO(interp)->imc_units = NULL;
100 IMCC_INFO(interp)->cur_unit = NULL;
101 IMCC_INFO(interp)->last_unit = NULL;
107 =item C<void imc_compile_unit(PARROT_INTERP, IMC_Unit *unit)>
109 Compiles each unit in IMCC. This is the main loop of the compiler; it operates
110 on a single compilation unit at a time.
112 =cut
116 void
117 imc_compile_unit(PARROT_INTERP, ARGIN(IMC_Unit *unit))
119 ASSERT_ARGS(imc_compile_unit)
120 /* Not much here for now except the allocator */
121 IMCC_INFO(interp)->cur_unit = unit;
123 imc_reg_alloc(interp, unit);
124 emit_flush(interp, NULL, unit);
130 =item C<void imc_cleanup(PARROT_INTERP, void *yyscanner)>
132 Cleans up the compiler state in preparation for another compiler invocation.
134 =cut
138 void
139 imc_cleanup(PARROT_INTERP, ARGIN_NULLOK(void *yyscanner))
141 ASSERT_ARGS(imc_cleanup)
142 IMCC_pop_parser_state(interp, yyscanner);
143 clear_globals(interp);
144 mem_sys_free(IMCC_INFO(interp)->ghash.data);
145 IMCC_INFO(interp)->ghash.data = NULL;
147 if (IMCC_INFO(interp)->state) {
148 mem_sys_free(IMCC_INFO(interp)->state->file);
149 IMCC_INFO(interp)->state->file = NULL;
156 =item C<static IMC_Unit * imc_new_unit(PARROT_INTERP, IMC_Unit_Type t)>
158 Creates a new IMC_Unit of the given IMC_Unit_Type C<t>.
160 =cut
164 PARROT_CANNOT_RETURN_NULL
165 PARROT_MALLOC
166 static IMC_Unit *
167 imc_new_unit(PARROT_INTERP, IMC_Unit_Type t)
169 ASSERT_ARGS(imc_new_unit)
170 IMC_Unit * const unit = mem_gc_allocate_zeroed_typed(interp, IMC_Unit);
171 create_symhash(interp, &unit->hash);
172 unit->type = t;
173 return unit;
179 =item C<IMC_Unit * imc_open_unit(PARROT_INTERP, IMC_Unit_Type t)>
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.
185 =cut
189 PARROT_CANNOT_RETURN_NULL
190 IMC_Unit *
191 imc_open_unit(PARROT_INTERP, IMC_Unit_Type t)
193 ASSERT_ARGS(imc_open_unit)
194 IMC_Unit * const unit = imc_new_unit(interp, t);
195 imc_info_t * const imc_info = IMCC_INFO(interp);
197 if (!imc_info->imc_units)
198 imc_info->imc_units = unit;
200 if (!imc_info->ghash.data)
201 create_symhash(interp, &imc_info->ghash);
203 unit->prev = imc_info->last_unit;
205 if (imc_info->last_unit)
206 imc_info->last_unit->next = unit;
208 imc_info->last_unit = unit;
209 imc_info->n_comp_units++;
211 unit->file = imc_info->state->file;
212 unit->pasm_file = imc_info->state->pasm_file;
214 return unit;
220 =item C<void imc_close_unit(PARROT_INTERP, IMC_Unit *unit)>
222 Closes a unit from compilation. This does not destroy the unit, but leaves it
223 on the list of units.
225 =cut
229 void
230 imc_close_unit(PARROT_INTERP, ARGIN_NULLOK(IMC_Unit *unit))
232 ASSERT_ARGS(imc_close_unit)
233 #if COMPILE_IMMEDIATE
234 if (unit)
235 imc_compile_unit(interp, unit);
236 #endif
238 IMCC_INFO(interp)->cur_unit = NULL;
244 =item C<static void imc_free_unit(PARROT_INTERP, IMC_Unit *unit)>
246 Frees an IMC_Unit and all of its associated memory.
248 =cut
252 static void
253 imc_free_unit(PARROT_INTERP, ARGMOD(IMC_Unit *unit))
255 ASSERT_ARGS(imc_free_unit)
256 imc_info_t * const imc = IMCC_INFO(interp);
258 free_reglist(unit);
260 /* and cfg ... */
261 clear_basic_blocks(unit);
263 if (!imc->n_comp_units)
264 IMCC_fatal(interp, 1, "imc_free_unit: non existent unit\n");
266 imc->n_comp_units--;
268 clear_locals(unit);
270 if (unit->_namespace && unit->owns_namespace)
271 free_sym(unit->_namespace);
272 if (unit->vtable_name)
273 mem_sys_free(unit->vtable_name);
274 if (unit->instance_of)
275 mem_sys_free(unit->instance_of);
277 mem_sys_free(unit->hash.data);
278 mem_sys_free(unit);
283 =back
285 =cut
290 * Local variables:
291 * c-file-style: "parrot"
292 * End:
293 * vim: expandtab shiftwidth=4: