Tagging trunk at r29566 so that the revisionpm can later be synched to it.
[parrot.git] / compilers / bcg / src / bcg.c
blob41e3758dcc0f17a8ae3c6723d1454df7e17d597b
1 /*
2 * $Id$
3 * Copyright (C) 2006-2007, The Perl Foundation.
4 */
6 /*
8 =head1 NAME
10 bcg.c Byte Code Generator (BCG) Public API implementation.
12 =head1 DESCRIPTION
14 The functions in this file implement the API defined in bcg.h, the public API
15 for BCG.
17 =head2 Methods
19 List of methods imlemented in this file.
21 =over 4
23 =cut
27 #include <string.h>
28 #include "bcg.h"
29 #include "bcg_private.h"
30 #include "bcg_logger.h"
31 #include "bcg_reg_alloc.h"
32 #include "bcg_emitter.h"
34 /* Forward decleration */
36 /* BCG state management functions. */
37 static void set_state(BCG_info * bcg_info, bcg_state state);
38 static void unset_state(BCG_info * bcg_info, bcg_state state);
39 static int in_state(BCG_info * bcg_info, bcg_state state);
43 =item C<BCG_info *
44 BCG_create(void)>
46 This function create an instance of Byte Code Generator.
48 =cut
51 BCG_info *
52 BCG_create(void)
54 BCG_info *bcg_info;
56 bcg_info = (BCG_info *) mem_sys_allocate_zeroed(sizeof (BCG_info));
57 bcg_info->private_info = bcg_info_private_create(bcg_info);
58 BCG_INFO_PRIV(bcg_info)->state = 0;
59 set_state(bcg_info, BCG_STATE_INIT);
60 return bcg_info;
65 =item C<void
66 BCG_destroy(BCG_info *bcg_info)>
68 This methods destroys the specified instance of Byte Code Generator.
70 =cut
73 void
74 BCG_destroy(BCG_info *bcg_info)
76 bcg_info_private_destroy(bcg_info, BCG_INFO_PRIV(bcg_info));
77 if (bcg_info->error_msg != NULL) {
78 mem_sys_free(bcg_info->error_msg);
80 mem_sys_free(bcg_info);
85 =item C<void
86 BCG_start_code_gen(BCG_info * bcg_info)>
88 RT#48260: Not yet documented!!!
90 =cut
94 void
95 BCG_start_code_gen(BCG_info * bcg_info)
97 if (BCG_INFO_PRIV(bcg_info)->state != BCG_STATE_INIT) {
98 bcg_throw_exception(bcg_info, BCG_EXCEPTION,
99 "Expected BCG to be in INIT state.");
102 set_state(bcg_info, BCG_STATE_IN_CODEGEN);
108 =item C<void
109 BCG_end_code_gen(BCG_info * bcg_info)>
111 RT#48260: Not yet documented!!!
113 =cut
117 void
118 BCG_end_code_gen(BCG_info * bcg_info)
120 if (BCG_INFO_PRIV(bcg_info)->state != BCG_STATE_IN_CODEGEN) {
121 bcg_throw_exception(bcg_info, BCG_EXCEPTION,
122 "Expected BCG to be in IN_CODEGEN state.");
125 unset_state(bcg_info, BCG_STATE_IN_CODEGEN);
130 =item C<void
131 BCG_start_sub(BCG_info * bcg_info, char *sub_name, char *pragma)>
133 RT#48260: Not yet documented!!!
135 =cut
139 void
140 BCG_start_sub(BCG_info * bcg_info, char *sub_name, char *pragma)
143 bcg_unit *unit;
145 if (BCG_INFO_PRIV(bcg_info)->state != BCG_STATE_IN_CODEGEN) {
146 bcg_throw_exception(bcg_info, BCG_EXCEPTION,
147 "Expected BCG to be in IN_CODEGEN state.");
150 set_state(bcg_info, BCG_STATE_IN_SUB);
151 unit = bcg_unit_create(bcg_info, sub_name, pragma);
152 bcg_info_add_unit(bcg_info, unit);
153 unit->symbol_table = bcg_hash_create(bcg_info);
158 =item C<void
159 BCG_end_sub(BCG_info * bcg_info)>
161 RT#48260: Not yet documented!!!
163 =cut
167 void
168 BCG_end_sub(BCG_info * bcg_info)
170 bcg_unit *curr_unit;
172 if (!in_state(bcg_info, BCG_STATE_IN_SUB)) {
173 bcg_throw_exception(bcg_info, BCG_EXCEPTION,
174 "Expected BCG to be in IN_SUB state.");
177 unset_state(bcg_info, BCG_STATE_IN_SUB);
178 curr_unit = bcg_info_current_unit(bcg_info);
179 reg_alloc_vanilla(bcg_info, curr_unit);
184 =item C<void
185 BCG_start_call(BCG_info * bcg_info, char *sub_name)>
187 RT#48260: Not yet documented!!!
189 =cut
193 void
194 BCG_start_call(BCG_info * bcg_info, char *sub_name)
196 if (!in_state(bcg_info, BCG_STATE_IN_SUB)) {
197 bcg_throw_exception(bcg_info, BCG_EXCEPTION,
198 "Expected BCG to be in IN_SUB state.");
201 set_state(bcg_info, BCG_STATE_IN_CALL);
206 =item C<void
207 BCG_end_call(BCG_info * bcg_info)>
209 RT#48260: Not yet documented!!!
211 =cut
215 void
216 BCG_end_call(BCG_info * bcg_info)
218 if (!in_state(bcg_info, BCG_STATE_IN_CALL)) {
219 bcg_throw_exception(bcg_info, BCG_EXCEPTION,
220 "Expected BCG to be in IN_CALL state.");
223 unset_state(bcg_info, BCG_STATE_IN_CALL);
228 =item C<void
229 BCG_start_op(BCG_info * bcg_info, char *op_name)>
231 RT#48260: Not yet documented!!!
233 =cut
237 void
238 BCG_start_op(BCG_info * bcg_info, char *op_name)
240 bcg_unit *curr_unit;
241 bcg_op *op;
243 if (!in_state(bcg_info, BCG_STATE_IN_SUB)) {
244 bcg_throw_exception(bcg_info, BCG_EXCEPTION,
245 "Expected BCG to be in IN_SUB state.");
248 set_state(bcg_info, BCG_STATE_IN_OP);
249 curr_unit = bcg_info_current_unit(bcg_info);
250 op = bcg_op_create(bcg_info, op_name, BCG_OP);
251 bcg_unit_add_op(bcg_info, curr_unit, op);
256 =item C<void
257 BCG_end_op(BCG_info * bcg_info)>
259 RT#48260: Not yet documented!!!
261 =cut
265 void
266 BCG_end_op(BCG_info * bcg_info)
268 bcg_op *curr_op;
270 if (!in_state(bcg_info, BCG_STATE_IN_OP)) {
271 bcg_throw_exception(bcg_info, BCG_EXCEPTION,
272 "Expected BCG to be in IN_CALL state.");
275 unset_state(bcg_info, BCG_STATE_IN_OP);
276 curr_op = bcg_info_current_op(bcg_info);
277 bcg_op_resolve_full_name(bcg_info, curr_op);
282 =item C<void
283 BCG_var(BCG_info * bcg_info, char *var_name, char var_type)>
285 RT#48260: Not yet documented!!!
287 =cut
291 void
292 BCG_var(BCG_info * bcg_info, char *var_name, char var_type)
294 bcg_unit *curr_unit;
295 bcg_op *curr_op;
296 bcg_op_arg *op_arg;
298 if (!in_state(bcg_info, BCG_STATE_IN_OP)) {
299 bcg_throw_exception(bcg_info, BCG_EXCEPTION,
300 "Expected BCG to be in IN_OP state.");
303 curr_unit = bcg_info_current_unit(bcg_info);
304 curr_op = bcg_info_current_op(bcg_info);
305 op_arg = (bcg_op_arg *)bcg_hash_get(bcg_info, curr_unit->symbol_table, var_name);
307 if (!op_arg)
308 op_arg = bcg_op_arg_create(bcg_info, var_name, BCG_OP_ARG_VARIABLE,
309 var_type);
311 bcg_op_add_arg(bcg_info, curr_op, op_arg);
312 bcg_hash_put(bcg_info, curr_unit->symbol_table, var_name, op_arg);
317 =item C<void
318 BCG_val(BCG_info * bcg_info, char *val, char val_type)>
320 RT#48260: Not yet documented!!!
322 =cut
326 void
327 BCG_val(BCG_info * bcg_info, char *val, char val_type)
329 bcg_op *curr_op;
330 bcg_op_arg *op_arg;
332 if (!in_state(bcg_info, BCG_STATE_IN_OP)) {
333 bcg_throw_exception(bcg_info, BCG_EXCEPTION,
334 "Expected BCG to be in IN_OP state.");
337 curr_op = bcg_info_current_op(bcg_info);
338 op_arg = bcg_op_arg_create(bcg_info, val, BCG_OP_ARG_CONSTANT, val_type);
339 bcg_op_add_arg(bcg_info, curr_op, op_arg);
344 =item C<void
345 BCG_label(BCG_info * bcg_info, char *label)>
347 RT#48260: Not yet documented!!!
349 =cut
353 void
354 BCG_label(BCG_info * bcg_info, char *label)
356 bcg_unit *curr_unit;
357 bcg_op *op;
359 if (!in_state(bcg_info, BCG_STATE_IN_SUB)) {
360 bcg_throw_exception(bcg_info, BCG_EXCEPTION,
361 "Expected BCG to be in IN_SUB state.");
364 curr_unit = bcg_info_current_unit(bcg_info);
365 op = bcg_op_create(bcg_info, label, BCG_OP_LABEL);
366 bcg_unit_add_op(bcg_info, curr_unit, op);
371 =item C<void
372 BCG_print_pasm(BCG_info * bcg_info)>
374 RT#48260: Not yet documented!!!
376 =cut
380 void
381 BCG_print_pasm(BCG_info * bcg_info)
383 emit_pasm(bcg_info);
388 =item C<bcg_info_private *
389 bcg_info_private_create(BCG_info * bcg_info)>
391 RT#48260: Not yet documented!!!
393 =cut
397 bcg_info_private *
398 bcg_info_private_create(BCG_info * bcg_info)
400 bcg_info_private *bcg_info_priv;
402 UNUSED(bcg_info);
403 bcg_info_priv = (bcg_info_private *)
404 mem_sys_allocate_zeroed(sizeof (bcg_info_private));
405 return bcg_info_priv;
410 =item C<void
411 bcg_info_private_destroy(BCG_info * bcg_info, bcg_info_private * bcg_info_priv)>
413 RT#48260: Not yet documented!!!
415 =cut
419 void
420 bcg_info_private_destroy(BCG_info * bcg_info, bcg_info_private * bcg_info_priv)
422 bcg_unit *unit, *cur_unit;
424 UNUSED(bcg_info);
426 unit = bcg_info_priv->first_unit;
427 while (!unit) {
428 cur_unit = unit;
429 unit = unit->next;
430 bcg_unit_destroy(bcg_info, cur_unit);
433 mem_sys_free(bcg_info_priv);
438 =item C<void
439 bcg_info_add_unit(BCG_info * bcg_info, bcg_unit * unit)>
441 RT#48260: Not yet documented!!!
443 =cut
447 void
448 bcg_info_add_unit(BCG_info * bcg_info, bcg_unit * unit)
450 bcg_info_private *bcg_info_priv = BCG_INFO_PRIV(bcg_info);
451 if (!bcg_info_priv->first_unit) {
452 bcg_info_priv->first_unit = unit;
453 unit->next = NULL;
454 unit->prev = NULL;
456 else {
457 bcg_info_priv->last_unit->next = unit;
458 unit->prev = bcg_info_priv->last_unit;
460 bcg_info_priv->last_unit = unit;
466 =item C<static void
467 set_state(BCG_info * bcg_info, bcg_state state)>
469 RT#48260: Not yet documented!!!
471 =cut
475 static void
476 set_state(BCG_info * bcg_info, bcg_state state)
478 BCG_INFO_PRIV(bcg_info)->state |= state;
483 =item C<static void
484 unset_state(BCG_info * bcg_info, bcg_state state)>
486 RT#48260: Not yet documented!!!
488 =cut
492 static void
493 unset_state(BCG_info * bcg_info, bcg_state state)
495 BCG_INFO_PRIV(bcg_info)->state &= (~state);
500 =item C<static int
501 in_state(BCG_info * bcg_info, bcg_state state)>
503 RT#48260: Not yet documented!!!
505 =cut
509 static int
510 in_state(BCG_info * bcg_info, bcg_state state)
512 return state == (state & BCG_INFO_PRIV(bcg_info)->state);
517 =back
519 =head1 LICENSE
521 Copyright (C) 2006, The Perl Foundation.
523 This is free software; you may redistribute it and/or modify
524 it under the same terms as Parrot.
526 =head1 AUTHOR
528 Vishal Soni <vishalrsoni@gmail.com>
530 =cut
535 * Local variables:
536 * c-file-style: "parrot"
537 * End:
538 * vim: expandtab shiftwidth=4: