minor sigsev fix
[official-gcc.git] / gcc / python / pypy.c
blobeaf9d842d7b68927c1f03b1e93d9cd9b81d7c884
1 /* This file is part of GCC.
3 GCC is free software; you can redistribute it and/or modify it under
4 the terms of the GNU General Public License as published by the Free
5 Software Foundation; either version 3, or (at your option) any later
6 version.
8 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
9 WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
11 for more details.
13 You should have received a copy of the GNU General Public License
14 along with GCC; see the file COPYING3. If not see
15 <http://www.gnu.org/licenses/>. */
17 #include "config.h"
18 #include "system.h"
19 #include "ansidecl.h"
20 #include "coretypes.h"
21 #include "opts.h"
22 #include "tree.h"
23 #include "tree-iterator.h"
24 #include "gimple.h"
25 #include "toplev.h"
26 #include "debug.h"
27 #include "options.h"
28 #include "flags.h"
29 #include "convert.h"
30 #include "diagnostic-core.h"
31 #include "langhooks.h"
32 #include "langhooks-def.h"
33 #include "target.h"
34 #include "cgraph.h"
36 #include <gmp.h>
37 #include <mpfr.h>
39 #include "vec.h"
40 #include "hashtab.h"
42 #include "gpy.h"
43 #include "opcodes.def"
44 #include "symbols.h"
45 #include "pypy-tree.h"
46 #include "runtime.h"
48 static VEC( gpy_sym,gc ) * gpy_decls;
49 VEC(gpy_ctx_t,gc) * gpy_ctx_table;
50 VEC(tree,gc) * global_decls;
52 void gpy_process_decl( gpy_symbol_obj * sym )
54 /* Push the declaration! */
55 VEC_safe_push( gpy_sym, gc, gpy_decls, sym );
56 debug("decl <%p> was pushed!\n", (void*)sym );
59 /**
60 * Fairly Confusing Function to read.
62 * example:
63 * >>> x = y = z = 2 + 2 + 2;
65 * --- Currently Yacc parses that expression into this Tree:
68 / \
69 + 2
72 / \
73 x =
74 / \
75 y =
76 / \
77 z 2
79 -- Is converted into the procedure:
81 1. z = 2 + 2 + 2;
82 2. y = z;
83 3. x = y;
85 -- Tree structure as so:
88 / \
89 x =
90 / \
91 y =
92 / \
93 z +
94 / \
95 + 2
96 / \
97 2 2
98 **/
99 static
100 gpy_symbol_obj * gpy_process_AST_Align( gpy_symbol_obj ** sym )
102 gpy_symbol_obj *nn = NULL;
103 gpy_symbol_obj *retval = NULL;
104 if( (*sym)->next )
106 nn = (*sym)->next;
107 (*sym)->next = NULL;
109 retval = (*sym);
111 if( (*sym)->exp == OP_EXPRESS )
113 debug("Processing Expression AST!\n");
114 if( retval->type != OP_ASSIGN_EVAL )
116 gpy_symbol_obj *o= retval;
117 gpy_symbol_obj *h= NULL;
118 while( o )
120 if( o->op_a_t == TYPE_SYMBOL )
122 if( o->op_a.symbol_table->type == OP_ASSIGN_EVAL )
124 h = o;
125 break;
127 else
129 o = o->op_a.symbol_table;
132 else break;
134 if( h )
136 gpy_symbol_obj *head = h->op_a.symbol_table;
137 if( head->op_b.symbol_table->type == OP_ASSIGN_EVAL )
139 gpy_symbol_obj *t = head, *m = NULL;
140 while( t )
142 if( t->op_b_t == TYPE_SYMBOL )
144 if( t->op_b.symbol_table->type != OP_ASSIGN_EVAL )
146 m = t;
147 break;
149 else
151 t = t->op_b.symbol_table;
154 else break;
156 if( m )
158 h->op_a.symbol_table = m->op_b.symbol_table;
159 m->op_b.symbol_table = retval;
161 else
163 fatal_error("error processing the expression AST!\n");
166 else
168 h->op_a.symbol_table = head->op_b.symbol_table;
169 head->op_b.symbol_table = retval;
171 retval = head;
176 if( nn )
178 retval->next = nn;
180 (*sym) = retval;
182 return retval;
185 VEC(tree,gc) * gpy_process_expression( const gpy_symbol_obj * const sym,
186 VEC(gpy_ctx_t,gc) * context )
188 VEC(tree,gc) * retval = NULL;
189 if( sym->type == SYMBOL_PRIMARY )
191 retval = VEC_alloc(tree,gc,0);
192 VEC(tree,gc) *primitive = gpy_fold_primitive( sym );
193 gcc_assert( VEC_length(tree,primitive) == 1 );
194 VEC_safe_push( tree,gc,retval,VEC_index(tree,primitive,0) );
196 else if( sym->type == SYMBOL_REFERENCE )
198 gcc_assert( sym->op_a_t == TYPE_STRING );
199 tree decl = gpy_ctx_lookup_decl( context, sym->op_a.string, VAR );
200 if( decl )
202 retval = VEC_alloc(tree,gc,0);
203 debug("tree reference <%s>!\n", sym->op_a.string);
204 VEC_safe_push( tree,gc,retval,decl );
206 else
208 error("undeclared symbol reference <%s>!\n",
209 sym->op_a.string );
212 else
214 gpy_symbol_obj *opa= NULL, *opb= NULL; VEC(tree,gc) *res = NULL;
215 debug("expression evalution <0x%x>!\n", sym->type );
217 opa= sym->op_a.symbol_table;
218 opb= sym->op_b.symbol_table;
220 debug( "opa->type = <0x%x>, opb->type = <0x%x>!\n",
221 opa->type, opb->type );
223 switch( sym->type )
225 case OP_ASSIGN_EVAL:
226 res = gpy_process_assign( &opa, &opb, context );
227 break;
229 case OP_BIN_ADDITION:
230 res = gpy_process_bin_expression( &opa, &opb, sym->type, context );
231 break;
233 default:
234 fatal_error( "invalid expression evaluation symbol type <0x%x>!\n",
235 sym->type );
236 break;
238 if( res ) { retval = res; }
239 else { fatal_error("error evaluating expression!\n"); }
242 return retval;
245 VEC(tree,gc) * gpy_process_functor( const gpy_symbol_obj * const functor,
246 const char * base_ident,
247 VEC(gpy_ctx_t,gc) * context )
249 VEC(tree,gc) * retval_vec = VEC_alloc( tree,gc,0 );
251 gpy_symbol_obj * o = functor->op_a.symbol_table;
252 tree fntype = build_function_type(void_type_node, void_list_node);
253 tree retval = build_decl( UNKNOWN_LOCATION, FUNCTION_DECL,
254 get_identifier( functor->identifier ),
255 fntype );
257 tree declare_vars = NULL_TREE;
258 tree bind = NULL_TREE;
259 tree block = alloc_stmt_list( );
260 tree resdecl = NULL_TREE;
261 tree restype = TREE_TYPE(retval);
263 int idx = 0;
264 gpy_context_branch *co = NULL;
265 gpy_ident it = NULL;
267 if( base_ident )
269 size_t len = strlen( functor->identifier ) + strlen( base_ident );
270 size_t idx = 0, idy = 0;
271 char * buffer = (char *) xmalloc( (sizeof(char) * len)+2 );
272 for( ; idx<strlen( base_ident ); ++idx )
274 buffer[ idy ] = base_ident[ idx ];
275 idy++;
277 buffer[ idy ] = '.'; idy++;
278 for( idx=0; idx<strlen( functor->identifier ); ++idx )
280 buffer[ idy ] = functor->identifier[ idx ];
281 idy++;
283 buffer[idy] = '\0';
284 debug("buffer = <%s>!\n", buffer );
285 SET_DECL_ASSEMBLER_NAME( retval, get_identifier( buffer ) );
286 free( buffer );
288 else
289 SET_DECL_ASSEMBLER_NAME( retval, get_identifier(functor->identifier) );
291 TREE_PUBLIC(retval) = 1;
292 TREE_STATIC(retval) = 1;
294 resdecl = build_decl( UNKNOWN_LOCATION, RESULT_DECL, NULL_TREE,
295 restype );
296 DECL_CONTEXT(resdecl) = retval;
297 DECL_RESULT(retval) = resdecl;
299 DECL_INITIAL(retval) = block;
301 /* push a new context for local symbols */
302 co = (gpy_context_branch *)
303 xmalloc( sizeof(gpy_context_branch) );
304 gpy_init_ctx_branch( &co );
305 VEC_safe_push( gpy_ctx_t, gc, context, co );
307 while( o )
309 /* looping over the gpy_symbol_obj block of function statements
310 and getting the respective tree's and creating the GENERIC block
312 VEC(tree,gc) * x = gpy_get_tree( o,context );
313 int itx = 0; tree xt;
314 for( ; VEC_iterate(tree,x,itx,xt); ++itx )
316 gcc_assert( xt );
317 append_to_statement_list( xt, &block );
319 o = o->next;
322 for( ; VEC_iterate( gpy_ident,co->var_decl_t, idx, it ); ++idx )
324 /* get all block var_decls */
325 tree x = gpy_ctx_lookup_decl( context, it->ident, VAR );
326 gcc_assert( TREE_CODE( x ) == VAR_DECL );
327 debug("got var decl <%p>:<%s> within func <%s>!\n", (void*)x,
328 it->ident, functor->identifier );
329 TREE_CHAIN( x ) = declare_vars;
330 declare_vars = x;
333 if( declare_vars != NULL_TREE )
335 tree bl = make_node(BLOCK);
336 BLOCK_SUPERCONTEXT(bl) = retval;
337 DECL_INITIAL(retval) = bl;
338 BLOCK_VARS(bl) = declare_vars;
339 TREE_USED(bl) = 1;
340 bind = build3(BIND_EXPR, void_type_node, BLOCK_VARS(bl),
341 NULL_TREE, bl);
342 TREE_SIDE_EFFECTS(bind) = 1;
344 BIND_EXPR_BODY(bind) = block;
345 block = bind;
346 DECL_SAVED_TREE(retval) = block;
348 VEC_pop( gpy_ctx_t, gpy_ctx_table );
350 gimplify_function_tree( retval );
352 cgraph_add_new_function(retval, false);
353 cgraph_finalize_function(retval, true);
355 VEC_safe_push( tree,gc,retval_vec,retval );
357 return retval_vec;
360 VEC(tree,gc) * gpy_process_print( gpy_symbol_obj *sym, VEC(gpy_ctx_t,gc) * context )
362 VEC(tree,gc) * retval = NULL;
363 gcc_assert( sym->op_a_t == TYPE_SYMBOL );
364 gpy_symbol_obj * argument_list = sym->op_a.symbol_table;
366 if( argument_list )
368 int len = 0;
369 gpy_symbol_obj * t = argument_list;
370 while( t )
372 len++;
373 t=t->next;
376 int idx, idy = 0; t = argument_list;
377 tree * args = XNEWVEC( tree,len );
378 for( idx=0; idx<len; ++idx )
380 VEC(tree,gc) * x = gpy_get_tree( t, context );
381 gcc_assert( VEC_length(tree,x) == 1 );
382 args[ idy ] = VEC_index(tree,x,0);
383 idy++;
384 t = t->next;
387 VEC_safe_push( tree,gc,retval,gpy_builtin_get_print_call( len, args ) );
389 else
390 error("print call without any arguments!\n");
392 return retval;
395 VEC(tree,gc) * gpy_process_class( gpy_symbol_obj * const sym,
396 VEC(gpy_ctx_t,gc) * context )
398 VEC(tree,gc) * retval = NULL;
399 return retval;
402 VEC(tree,gc) * gpy_get_tree( gpy_symbol_obj * sym, VEC(gpy_ctx_t,gc) * context )
404 VEC(tree,gc) * retval = NULL;
406 debug( "processing decl of type <0x%X> object <%p>\n",
407 sym->type, (void*) sym );
409 if( sym->exp == OP_EXPRESS )
411 sym = gpy_process_AST_Align( &sym );
412 retval = gpy_process_expression( sym, context );
414 else
416 switch( sym->type )
418 case STRUCTURE_OBJECT_DEF:
420 VEC(gpy_ctx_t,gc) * class_ctx = VEC_alloc(gpy_ctx_t,gc,0);
421 retval = gpy_process_class( sym, class_ctx );
423 break;
425 case STRUCTURE_FUNCTION_DEF:
427 VEC(gpy_ctx_t,gc) * func_ctx = VEC_alloc(gpy_ctx_t,gc,0);
428 retval = gpy_process_functor( sym, NULL, func_ctx );
430 break;
432 case KEY_PRINT:
433 retval = gpy_process_print( sym, context );
434 break;
436 default:
437 fatal_error("unhandled symbol type <0x%x>\n", sym->type );
438 break;
442 return retval;
445 tree gpy_main_method_decl( VEC(tree,gc) * block, gpy_context_branch * co )
447 tree retval = NULL_TREE; int idx;
449 tree main_fn_type = build_function_type_list( integer_type_node, NULL_TREE );
450 tree main_fn_decl = build_decl( BUILTINS_LOCATION, FUNCTION_DECL,
451 get_identifier("main"), main_fn_type );
453 DECL_CONTEXT(main_fn_decl) = NULL_TREE;
454 TREE_STATIC(main_fn_decl) = true;
455 TREE_PUBLIC(main_fn_decl) = true;
456 DECL_ARGUMENTS(main_fn_decl) = NULL_TREE;
458 /* Define the return type (represented by RESULT_DECL) for the main functin */
459 tree main_ret = build_decl( BUILTINS_LOCATION, RESULT_DECL,
460 NULL_TREE, TREE_TYPE(main_fn_type) );
461 DECL_CONTEXT(main_ret) = main_fn_decl;
462 DECL_ARTIFICIAL(main_ret) = true;
463 DECL_IGNORED_P(main_ret) = true;
465 DECL_RESULT(main_fn_decl) = main_ret;
467 tree main_art_block = build_block(NULL_TREE, NULL_TREE, NULL_TREE, NULL_TREE);
468 DECL_INITIAL(main_fn_decl) = main_art_block;
470 tree declare_vars = NULL_TREE;
471 tree main_stmts = alloc_stmt_list( );
473 append_to_statement_list( gpy_builtin_get_init_call( ), &main_stmts );
475 tree it = NULL_TREE;
476 for( idx = 0; VEC_iterate(tree,block,idx,it); ++idx )
478 gcc_assert( it );
479 append_to_statement_list( it, &main_stmts );
482 int block_decl_len = 0; gpy_ident vit = NULL;
483 for( idx = 0; VEC_iterate( gpy_ident,co->var_decl_t, idx, vit ); ++idx )
485 /* get all block var_decls */
486 tree x = gpy_ctx_lookup_decl( gpy_ctx_table, vit->ident, VAR );
487 gcc_assert( TREE_CODE( x ) == VAR_DECL );
488 debug("got var decl <%p>:<%s> within func <%s>!\n", (void*)x,
489 vit->ident, "main" );
490 TREE_CHAIN( x ) = declare_vars;
491 declare_vars = x;
492 block_decl_len++;
495 if( block_decl_len > 0 )
497 tree * block_decl_vec = XNEWVEC( tree, block_decl_len );
498 int idy = 0;
500 for( idx = 0; VEC_iterate( gpy_ident,co->var_decl_t, idx, vit ); ++idx )
502 tree x = gpy_ctx_lookup_decl( gpy_ctx_table, vit->ident, VAR );
503 gcc_assert( TREE_CODE( x ) == VAR_DECL );
505 block_decl_vec[ idy ] = x;
506 idy++;
508 //block_decl_vec[ idy ] = main_ret; idy++;
509 append_to_statement_list( gpy_builtin_get_finalize_block_call( block_decl_len,
510 block_decl_vec ),
511 &main_stmts );
513 else
515 declare_vars = main_ret;
518 append_to_statement_list( gpy_builtin_get_cleanup_final_call( ), &main_stmts );
520 tree main_set_ret = build2( MODIFY_EXPR, TREE_TYPE(main_ret),
521 main_ret, build_int_cst(integer_type_node, 0));
522 tree main_ret_expr = build1( RETURN_EXPR, void_type_node, main_set_ret );
523 append_to_statement_list( main_ret_expr, &main_stmts );
525 tree bind = NULL_TREE;
526 if( declare_vars != NULL_TREE )
528 tree bl = make_node(BLOCK);
529 BLOCK_SUPERCONTEXT(bl) = main_fn_decl;
530 DECL_INITIAL(main_fn_decl) = bl;
531 BLOCK_VARS(bl) = declare_vars;
532 TREE_USED(bl) = 1;
533 bind = build3( BIND_EXPR, void_type_node, BLOCK_VARS(bl),
534 NULL_TREE, bl );
535 TREE_SIDE_EFFECTS(bind) = 1;
537 BIND_EXPR_BODY(bind) = main_stmts;
538 main_stmts = bind;
539 DECL_SAVED_TREE(main_fn_decl) = main_stmts;
541 gimplify_function_tree( main_fn_decl );
542 cgraph_finalize_function( main_fn_decl, false );
544 retval = main_fn_decl;
546 return retval;
549 /* @see coverage.c build_fn_info_type ( unsigned int )
550 for more examples on RECORD_TYPE's
552 static
553 tree gpy_build_callable_record_type( void )
556 tree type = lang_hooks.types.make_type ( RECORD_TYPE );
557 tree field, fields;
559 fields = build_decl( BUILTINS_LOCATION,
560 FIELD_DECL, NULL_TREE, void );
562 field = build_decl( BUILTINS_LOCATION,
563 FIELD_DECL, NULL_TREE, integer_type_node );
565 DECL_CHAIN( field ) = fields;
566 fields = field;
568 fields = build_decl( BUILTINS_LOCATION,
569 FIELD_DECL, NULL_TREE, void );
571 return;
574 void gpy_write_globals( void )
576 gpy_context_branch *co = NULL;
577 gpy_symbol_obj * it = NULL;
578 VEC(tree,gc) * main_stmts_vec = VEC_alloc(tree,gc,0);
580 /* push a new context for local symbols */
581 co = (gpy_context_branch *)
582 xmalloc( sizeof(gpy_context_branch) );
583 gpy_init_ctx_branch( &co );
584 VEC_safe_push( gpy_ctx_t, gc, gpy_ctx_table, co );
586 int idx;
587 for( idx= 0; VEC_iterate(gpy_sym,gpy_decls,idx,it); ++idx )
589 VEC(tree,gc) * x = gpy_get_tree( it, gpy_ctx_table );
590 gcc_assert( x ); int itx = 0; tree xt;
591 for( ; VEC_iterate(tree,x,itx,xt); ++itx )
593 if( TREE_CODE(xt) == FUNCTION_DECL )
595 VEC_safe_push( tree,gc,global_decls,xt );
597 else if( TREE_CODE(xt) == VAR_DECL )
599 VEC_safe_push( tree,gc,global_decls,xt );
601 else
603 VEC_safe_push( tree,gc,main_stmts_vec,xt );
608 /* Need to generate table of gpy_callable_def_t[] and gpy_type_obj_def_t[] */
609 // .....
611 /* Add in the main method decl! */
612 VEC_safe_push( tree,gc,global_decls,gpy_main_method_decl( main_stmts_vec,co ) );
614 VEC_pop( gpy_ctx_t, gpy_ctx_table );
616 tree itx = NULL_TREE; int idy = 0; int global_vec_len = VEC_length(tree, global_decls);
617 tree * global_vec = XNEWVEC( tree, global_vec_len );
618 for( idx=0; VEC_iterate(tree,global_decls,idx,itx); ++idx )
620 global_vec[ idy ] = itx;
621 idy++;
624 debug("Finished processing!\n\n");
626 wrapup_global_declarations( global_vec, global_vec_len );
628 check_global_declarations( global_vec, global_vec_len );
629 emit_debug_global_declarations( global_vec, global_vec_len );
631 cgraph_finalize_compilation_unit( );
633 debug("finished passing to middle-end!\n\n");