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
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
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/>. */
27 #include <gpython/gpython.h>
28 #include <gpython/objects.h>
29 #include <gpython/vectors.h>
30 #include <gpython/garbage.h>
32 gpy_vector_t
* gpy_primitives
;
33 gpy_vector_t
* gpy_namespace_vec
;
35 /* Used for stack-traces ... */
36 gpy_vector_t
* gpy_call_stack
;
38 void gpy_rr_init_primitives( void )
40 gpy_primitives
= (gpy_vector_t
*)
41 gpy_malloc( sizeof(gpy_vector_t
) );
42 gpy_vec_init( gpy_primitives
);
44 gpy_obj_integer_mod_init( gpy_primitives
);
47 void gpy_dump_current_stack_trace (void)
52 void gpy_rr_init_runtime( void )
55 Setup runtime namespace Init builtin's
57 gpy_rr_init_primitives( );
59 gpy_namespace_vec
= (gpy_vector_t
*)
60 gpy_malloc( sizeof(gpy_vector_t
) );
61 gpy_vec_init( gpy_namespace_vec
);
63 gpy_call_stack
= (gpy_vector_t
*)
64 gpy_malloc(sizeof(gpy_vector_t
));
65 gpy_vec_init( gpy_call_stack
);
67 gpy_context_t
* head
= (gpy_context_t
*)
68 gpy_malloc( sizeof(gpy_context_t
) );
70 head
->symbols
= (gpy_vector_t
*)
71 gpy_malloc( sizeof(gpy_vector_t
) );
72 gpy_vec_init( head
->symbols
);
74 gpy_vec_push( gpy_namespace_vec
, head
);
77 void gpy_rr_cleanup_final( void )
79 gpy_rr_pop_context( );
81 if( gpy_namespace_vec
->length
> 0 )
82 error( "<%i> un-free'd conexts!\n", gpy_namespace_vec
->length
);
84 gpy_vec_free( gpy_namespace_vec
);
85 gpy_vec_free( gpy_primitives
);
86 gpy_vec_free( gpy_call_stack
);
89 gpy_object_t
* gpy_rr_fold_integer( int x
)
91 gpy_object_t
* retval
= NULL_OBJECT
;
93 gpy_object_state_t
* o
= NULL_OBJ_STATE
;
94 Gpy_Object_State_Init_Ctx( o
, gpy_namespace_vec
);
96 gpy_object_t
** args
= (gpy_object_t
**)
97 gpy_calloc(2, sizeof(gpy_object_t
*));
100 i
.type
= TYPE_INTEGER
;
101 i
.literal
.integer
= x
;
103 gpy_object_t a1
= { .T
= TYPE_OBJECT_LIT
, .o
.literal
= &i
};
104 gpy_object_t a2
= { .T
= TYPE_NULL
, .o
.literal
= NULL
};
109 gpy_type_obj_def_t
* Int_def
= (gpy_type_obj_def_t
*)
110 gpy_primitives
->vector
[ 0 ];
111 gpy_assert( Int_def
);
113 retval
= Int_def
->init_hook (args
);
116 debug("initilized integer object <%p> to <%i>!\n",
119 gpy_assert (retval
->T
== TYPE_OBJECT_STATE
);
120 Gpy_Incr_Ref (retval
->o
.object_state
);
126 * int fd: we could use bit masks to represent:
129 void gpy_rr_eval_print( int fd
, int count
, ... )
132 va_start( vl
,count
);
134 /* gpy_object_t is a typedef of gpy_object_state_t *
135 to keep stdarg.h happy
137 gpy_object_t
* it
= NULL
;
138 for( idx
= 0; idx
<count
; ++idx
)
140 it
= va_arg( vl
, gpy_object_t
* );
141 gpy_assert(it
->T
== TYPE_OBJECT_STATE
);
142 struct gpy_type_obj_def_t
* definition
= it
->o
.object_state
->definition
;
147 (*definition
).print_hook( it
, stdout
, false );
151 (*definition
).print_hook( it
, stderr
, false );
155 fatal("invalid print file-descriptor <%i>!\n", fd
);
160 fprintf( stdout
, "\n" );
165 void gpy_rr_incr_ref_count( gpy_object_state_t
* x
)
168 debug("incrementing ref count on <%p>:<%i> to <%i>!\n",
169 (void*) x
, x
->ref_count
, (x
->ref_count
+ 1) );
174 void gpy_rr_decr_ref_count( gpy_object_state_t
* x
)
177 debug("decrementing ref count on <%p>:<%i> to <%i>!\n",
178 (void*) x
, x
->ref_count
, (x
->ref_count
- 1) );
182 void gpy_rr_push_context( void )
184 gpy_context_t
* ctx
= (gpy_context_t
*)
185 gpy_malloc( sizeof(gpy_context_t
) );
186 ctx
->symbols
= (gpy_vector_t
*)
187 gpy_malloc( sizeof(gpy_vector_t
) );
188 gpy_vec_init( ctx
->symbols
);
190 gpy_vec_push( gpy_namespace_vec
, ctx
);
193 void gpy_rr_pop_context( void )
195 gpy_context_t
* head
= Gpy_Namespace_Head
;
196 void ** vec
= head
->symbols
->vector
;
198 unsigned int idx
= 0;
199 for( ; idx
<(head
->symbols
->length
); ++idx
)
201 gpy_object_state_t
* i
= (gpy_object_state_t
*) vec
[ idx
];
205 gpy_garbage_invoke_sweep( gpy_namespace_vec
);
207 /* Loop over for stragglers like returns which need pushed up a
208 context soo they can still be garbage collected....
210 straggler is something which will have a (ref_count > 0) after
211 this set of decreasing references...
214 gpy_context_t
* popd
= gpy_vec_pop( gpy_namespace_vec
);
215 gpy_vec_free( popd
->symbols
);
219 void gpy_rr_finalize_block_decls( int n
, ... )
224 /* gpy_object_t is a typedef of gpy_object_state_t *
225 to keep stdarg.h happy
227 gpy_object_t
* it
= NULL
;
228 for( idx
= 0; idx
<n
; ++idx
)
230 it
= va_arg( vl
, gpy_object_t
* );
231 gpy_assert(it
->T
== TYPE_OBJECT_STATE
);
232 /* no assert this macro auto inserts an assert */
233 Gpy_Decr_Ref( it
->o
.object_state
);
238 gpy_object_t
* gpy_rr_fold_call(struct gpy_callable_def_t
* callables
,
239 const char * ident
, int n_args
, ... )
245 gpy_rr_eval_dot_operator( gpy_object_t
* x
, gpy_object_t
* y
)
251 gpy_rr_eval_expression (gpy_object_t
* x1
, gpy_object_t
* y1
,
254 char * op_str
= NULL
;
255 gpy_object_t
* retval
= NULL
;
257 gpy_assert(x1
->T
== TYPE_OBJECT_STATE
);
258 gpy_assert(y1
->T
== TYPE_OBJECT_STATE
);
259 gpy_object_state_t
* x
= x1
->o
.object_state
;
260 gpy_object_state_t
* y
= y1
->o
.object_state
;
262 struct gpy_type_obj_def_t
* def
= x
->definition
;
263 struct gpy_number_prot_t
* binops
= (*def
).binary_protocol
;
264 struct gpy_number_prot_t binops_l
= (*binops
);
271 case OP_BIN_ADDITION
:
277 fatal("unhandled binary operation <%x>!\n", op
);
282 x
->definition
->print_hook( x1
, stdout
, false );
283 fprintf(stdout
, "%s", op_str
);
284 y
->definition
->print_hook( y1
, stdout
, true );
292 fprintf(stdout
, "evaluated to: ");
293 retval
->o
.object_state
->definition
->print_hook (retval
, stdout
, false);
294 fprintf(stdout
, "!\n");
300 fatal("object type <%s> has no binary protocol!\n",